changeset 3203:bc61b0e8d60e

[project @ 1998-10-30 20:26:27 by jwe]
author jwe
date Fri, 30 Oct 1998 20:26:31 +0000
parents 44d82b369c78
children 81738e630f57
files doc/interpreter/preface.texi liboctave/ChangeLog liboctave/boolMatrix.cc liboctave/boolMatrix.h src/ChangeLog src/Makefile.in src/OPERATORS/op-b-b.cc src/OPERATORS/op-bm-bm.cc src/OPERATORS/op-cm-cm.cc src/OPERATORS/op-cs-cs.cc src/OPERATORS/op-m-m.cc src/OPERATORS/op-s-s.cc src/OPERATORS/op-str-str.cc src/oct-lvalue.cc src/oct-lvalue.h src/ops.h src/ov-base.cc src/ov-base.h src/ov-bool-mat.h src/ov-bool.h src/ov-ch-mat.h src/ov-complex.h src/ov-cx-mat.h src/ov-range.cc src/ov-range.h src/ov-re-mat.h src/ov-scalar.h src/ov-str-mat.cc src/ov-str-mat.h src/ov-typeinfo.cc src/ov-typeinfo.h src/ov.cc src/ov.h src/parse.y src/pt-unop.cc src/pt-unop.h
diffstat 36 files changed, 937 insertions(+), 391 deletions(-) [+]
line wrap: on
line diff
--- a/doc/interpreter/preface.texi	Thu Oct 29 20:28:02 1998 +0000
+++ b/doc/interpreter/preface.texi	Fri Oct 30 20:26:31 1998 +0000
@@ -132,7 +132,7 @@
 @code{ferror}.
 
 @item
-Tony Richardson @email{arichard@stark.cc.oh.us} wrote Octave's
+Tony Richardson @email{arichard@@stark.cc.oh.us} wrote Octave's
 image processing functions as well as most of the original polynomial
 functions.
 
--- a/liboctave/ChangeLog	Thu Oct 29 20:28:02 1998 +0000
+++ b/liboctave/ChangeLog	Fri Oct 30 20:26:31 1998 +0000
@@ -1,3 +1,7 @@
+Thu Oct 29 18:57:50 1998  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* boolMatrix.cc (boolMatrix::operator !): New function.
+
 Fri Oct 23 21:46:20 1998  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* pathsearch.h (dir_path::default_path): New data member.
--- a/liboctave/boolMatrix.cc	Thu Oct 29 20:28:02 1998 +0000
+++ b/liboctave/boolMatrix.cc	Fri Oct 30 20:26:31 1998 +0000
@@ -75,6 +75,25 @@
   return result;
 }
 
+// unary operations
+
+boolMatrix
+boolMatrix::operator ! (void) const
+{
+  int nr = rows ();
+  int nc = cols ();
+
+  boolMatrix b (nr, nc);
+
+  for (int j = 0; j < nc; j++)
+    for (int i = 0; i < nr; i++)
+      b.elem (i, j) = ! elem (i, j);
+
+  return b;
+}
+
+// other operations
+
 boolMatrix
 boolMatrix::all (void) const
 {
--- a/liboctave/boolMatrix.h	Thu Oct 29 20:28:02 1998 +0000
+++ b/liboctave/boolMatrix.h	Fri Oct 30 20:26:31 1998 +0000
@@ -57,6 +57,12 @@
 
   boolMatrix transpose (void) const;
 
+  // unary operations
+
+  boolMatrix operator ! (void) const;
+
+  // other operations
+
   boolMatrix all (void) const;
   boolMatrix any (void) const;
 
--- a/src/ChangeLog	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/ChangeLog	Fri Oct 30 20:26:31 1998 +0000
@@ -1,5 +1,144 @@
+Fri Oct 30 08:39:30 1998  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* parse.y (matrix): Dont' forget to reset
+	lexer_flags.looking_at_matrix_or_assign_lhs.
+
+	* oct-lvalue.cc (octave_lvalue::assign): Don't call change
+	function if error occurs.
+	(octave_lvalue::do_unary_op): If we have an index, fail with message.
+
 Thu Oct 29 09:27:04 1998  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
+	* ov.cc (do_binary_op): Protect against invalid type conversions.
+	(try_assignment_with_conversion): Likewise.
+	(do_unary_op): Likewise.
+
+	* ov.h (OV_UNOP_FN, OV_UNOP_OP, OV_UNOP_FN_OP): New macros.
+	Use them to define not, uminus, transpose, hermitian functions
+	and operators ! and -.
+	(OV_BINOP_FN, OV_BINOP_OP, OV_BINOP_FN_OP): New macros.
+	Use them to define add, sub, mul, div, pow, ldiv, lshift, rshift,
+	lt, le, eq, ge, gt, ne, el_mul, el_div, el_pow, el_ldiv, el_and,
+	el_or, struct_ref, functions and operators <, <=, ==, >=, >, !=,
+	+, -, *, and /.
+
+	* ops.h (CONVDECLX): New macro.
+	* ov-base.cc (matrix_conv, complex_matrix_conv, string_conv):
+	Use it to declare these functions.
+
+	* ops.h (CONVDECL, INSTALL_WIDENOP):
+	Prefix function name with `oct_conv_'.
+	(INSTALL_BINOP, BINOPDECL): Prefix function name with `oct_binop_'.
+	(INSTALL_ASSIGNOP, INSTALL_ASSIGNANYOP, ASSIGNOPDECL):
+	Prefix function name with `oct_assignop_'.
+	(UNOPDECL, DEFNCUNOP_METHOD, INSTALL_UNOP, INSTALL_NCUNOP):
+	Prefix function name with `oct_unop_'.
+
+	* ov-str-mat.cc (default_numeric_conversion_function):
+	Return 0 if conversion fails.
+
+	* parse.y (make_prefix_op, make_postfix_op): Use
+	octave_value::unary_op enum.
+	
+	* pt-unop.cc (tree_prefix_expression::rvalue): Use new unary_op
+	functions from octave_value and octave_lvalue classes.
+	(tree_prefix_expression::rvalue): Likewise.
+
+	* pt-unop.cc (tree_unary_expression::oper): Move here.
+	(tree_prefix_expression::oper, tree_postfix_expression): From here.
+
+	* pt-unop.h (tree_prefix_expression, tree_postfix_expression):
+	Delete enums.
+	(tree_unary_expression): Use octave_value::unary_op enum.
+	* parse.y (make_prefix_op, make_postfix_op): Likewise.
+	
+	* oct-lvalue.h (octave_lvalue::do_unary_op): New function.
+	(octave_lvalue::increment, octave_lvalue::decrement): Delete.
+
+	* ov-typeinfo.h (octave_value_typeinfo::non_const_unary_ops):
+	New data member.
+	* ov-typeinfo.h (octave_value_typeinfo::lookup_non_const_unary_op):
+	New function.
+	* ov-typeinfo.cc (octave_value_typeinfo::register_non_const_unary_op):
+	New function.
+	(octave_value_typeinfo::do_register_non_const_unary_op): Ditto.
+	(octave_value_typeinfo::do_lookup_non_const_unary_op): Ditto.
+
+	* ov.cc (octave_value::do_non_const_unary_op): New function.
+
+	* Makefile.in (OP_XSRC): Add op-chm.cc and op-range.cc to the list.
+
+	* OPERATORS/op-str-str.cc: Define string matrix unary operators here.
+	(install_str_str_ops): Install them here.
+	* ov-bool-mat.h (octave_bool_matrix::transpose,
+	octave_bool_matrix_value::hermitian): Delete.
+
+	* OPERATORS/op-chm.cc: New file.  Define char matrix unary operators.
+	(install_chm_ops): Install them here.
+	* ov-ch-mat.h (octave_char_matrix::transpose,
+	octave_char_matrix_value::hermitian): Delete.
+	* ops.cc (install_ops): Call install_chm_ops.
+
+	* OPERATORS/op-bm-bm.cc: Define bool matrix unary operators here.
+	(install_bm_bm_ops): Install them here.
+	* ov-bool-mat.h (octave_bool_matrix::transpose,
+	octave_bool_matrix_value::hermitian): Delete.
+
+	* ov-bool.h (octave_bool::not, octave_bool::uminus,
+	octave_bool::transpose, octave_bool::hermitian): Delete.
+
+	* OPERATORS/op-cs-cs.cc: Define complex scalar unary operators here.
+	(install_cs_cs_ops): Install them here.
+	* ov-complex.h (octave_complex::not, octave_complex::uminus,
+	octave_complex::transpose, octave_complex::hermitian): Delete.
+
+	* OPERATORS/op-cm-cm.cc: Define complex matrix unary operators here.
+	(install_cm_cm_ops): Install them here.
+	* ov-cx-mat.h (octave_complex_matrix::not,
+	octave_complex_matrix::uminus, octave_complex_matrix::transpose,
+ 	octave_complex_matrix::hermitian): Delete.
+
+	* OPERATORS/op-m-m.cc: Define matrix unary operators here.
+	(install_m_m_ops): Install them here.
+	* ov-re-mat.h (octave_matrix::not, octave_matrix::uminus,
+	octave_matrix::transpose, octave_matrix::hermitian): Delete.
+
+	* OPERATORS/op-range.cc: New file.  Define range unary operators.
+	(install_range_ops): Install them here.
+	* ov-range.h (octave_range::not, octave_range::uminus,
+	octave_range::transpose, octave_range::hermitian): Delete.
+	* ops.cc (install_ops): Call install_range_ops.
+
+	* OPERATORS/op-s-s.cc: Define scalar unary operators here.
+	(install_s_s_ops): Install them here.
+	* ov-scalar.h (octave_scalar::not, octave_scalar::uminus,
+	octave_scalar::transpose, octave_scalar::hermitian): Delete.
+
+	* ops.h (INSTALL_UNOP, CAST_UNOP_ARG, UNOPDECL, DEFUNOPX, DEFUNOP,
+	DEFUNOP_OP, DEFUNOP_FN): New macros.
+
+	* ov.h (unary_op_fcn): New typedef.
+	(octave_value::unary_op): New enum.
+	* ov.cc (octave_value::octave_value): New function.
+
+	* ov.h (octave_value::not, octave_value::uminus,
+	octave_value::transpose, octave_value::hermitian,
+	octave_value::increment, octave_value::decrement): Delete.
+
+	* ov-base.cc (octave_base_value::not, octave_base_value::uminus,
+	octave_base_value::transpose, octave_base_value::hermitian,
+	octave_base_value::increment, octave_base_value::decrement): Delete.
+	
+	* ov.cc (gripe_unary_op): New function.
+	(do_unary_op): New function.
+	* ov-typeinfo.h (octave_value_typeinfo::unary_ops):
+	New data member.
+	* ov-typeinfo.cc (octave_value_info::register_unary_op,
+	octave_value_info::do_register_unary_op,
+	octave_value_info::lookup_unary_op,
+	octave_value_info::do_lookup_unary_op):
+	New functions.
+
 	* ov-list.cc (Fsplice): Use new octave_value::int_value function here.
 	(octave_list::do_index_op): Likewise.
 	(octave_list::assign): Likewise.
--- a/src/Makefile.in	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/Makefile.in	Fri Oct 30 20:26:31 1998 +0000
@@ -94,13 +94,13 @@
 
 TI_SRC := $(addprefix TEMPLATE-INST/, $(TI_XSRC))
 
-OP_XSRC := op-b-b.cc op-bm-bm.cc op-cm-cm.cc op-cm-cs.cc \
+OP_XSRC := op-b-b.cc op-bm-bm.cc op-chm.cc op-cm-cm.cc op-cm-cs.cc \
 	op-cm-m.cc op-cm-s.cc op-cs-cm.cc op-cs-cs.cc op-cs-m.cc \
-	op-cs-s.cc op-list.cc op-m-cm.cc op-m-cs.cc op-m-m.cc op-m-s.cc \
-	op-s-cm.cc op-s-cs.cc op-s-m.cc op-s-s.cc op-str-str.cc \
-	op-fil-b.cc op-fil-bm.cc op-fil-cm.cc op-fil-cs.cc \
+	op-cs-s.cc op-fil-b.cc op-fil-bm.cc op-fil-cm.cc op-fil-cs.cc \
 	op-fil-m.cc op-fil-s.cc op-fil-lis.cc op-fil-rec.cc \
-	op-fil-str.cc
+	op-fil-str.cc op-list.cc op-m-cm.cc op-m-cs.cc op-m-m.cc \
+	op-m-s.cc op-range.cc op-s-cm.cc op-s-cs.cc op-s-m.cc \
+	op-s-s.cc op-str-str.cc
 
 OP_SRC := $(addprefix OPERATORS/, $(OP_XSRC))
 
--- a/src/OPERATORS/op-b-b.cc	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/OPERATORS/op-b-b.cc	Fri Oct 30 20:26:31 1998 +0000
@@ -36,6 +36,14 @@
 #include "xdiv.h"
 #include "xpow.h"
 
+// bool unary ops.
+
+// scalar unary ops.
+
+DEFUNOP_OP (not, bool, !)
+DEFUNOP_OP (transpose, bool, /* no-op */)
+DEFUNOP_OP (hermitian, bool, /* no-op */)
+
 // bool by bool ops.
 
 DEFBINOP_OP (eq, bool, bool, ==)
@@ -44,6 +52,10 @@
 void
 install_b_b_ops (void)
 {
+  INSTALL_UNOP (not, octave_bool, not);
+  INSTALL_UNOP (transpose, octave_bool, transpose);
+  INSTALL_UNOP (hermitian, octave_bool, hermitian);
+
   INSTALL_BINOP (eq, octave_bool, octave_bool, eq);
   INSTALL_BINOP (ne, octave_bool, octave_bool, ne);
 }
--- a/src/OPERATORS/op-bm-bm.cc	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/OPERATORS/op-bm-bm.cc	Fri Oct 30 20:26:31 1998 +0000
@@ -36,6 +36,17 @@
 #include "xdiv.h"
 #include "xpow.h"
 
+// unary bool matrix ops.
+
+DEFUNOP_OP (not, bool_matrix, !)
+
+DEFUNOP (transpose, bool_matrix)
+{
+  CAST_UNOP_ARG (const octave_bool_matrix&);
+
+  return octave_value (v.bool_matrix_value().transpose ());
+}
+
 // bool matrix by bool matrix ops.
 
 DEFBINOP_OP (eq, bool_matrix, bool_matrix, ==)
@@ -44,6 +55,10 @@
 void
 install_bm_bm_ops (void)
 {
+  INSTALL_UNOP (not, octave_bool_matrix, not);
+  INSTALL_UNOP (transpose, octave_bool_matrix, transpose);
+  INSTALL_UNOP (hermitian, octave_bool_matrix, transpose);
+
   INSTALL_BINOP (eq, octave_bool_matrix, octave_bool_matrix, eq);
   INSTALL_BINOP (ne, octave_bool_matrix, octave_bool_matrix, ne);
 }
--- a/src/OPERATORS/op-cm-cm.cc	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/OPERATORS/op-cm-cm.cc	Fri Oct 30 20:26:31 1998 +0000
@@ -36,6 +36,28 @@
 #include "xdiv.h"
 #include "xpow.h"
 
+// unary complex matrix ops.
+
+DEFUNOP_OP (not, complex_matrix, !)
+DEFUNOP_OP (uminus, complex_matrix, -)
+
+DEFUNOP (transpose, complex_matrix)
+{
+  CAST_UNOP_ARG (const octave_complex_matrix&);
+
+  return octave_value (v.complex_matrix_value().transpose ());
+}
+
+DEFUNOP (hermitian, complex_matrix)
+{
+  CAST_UNOP_ARG (const octave_complex_matrix&);
+
+  return octave_value (v.complex_matrix_value().hermitian ());
+}
+
+DEFNCUNOP_METHOD (incr, complex_matrix, increment)
+DEFNCUNOP_METHOD (decr, complex_matrix, decrement)
+
 // complex matrix by complex matrix ops.
 
 DEFBINOP_OP (add, complex_matrix, complex_matrix, +)
@@ -78,6 +100,14 @@
 void
 install_cm_cm_ops (void)
 {
+  INSTALL_UNOP (not, octave_complex_matrix, not);
+  INSTALL_UNOP (uminus, octave_complex_matrix, uminus);
+  INSTALL_UNOP (transpose, octave_complex_matrix, transpose);
+  INSTALL_UNOP (hermitian, octave_complex_matrix, hermitian);
+
+  INSTALL_NCUNOP (incr, octave_complex_matrix, incr);
+  INSTALL_NCUNOP (decr, octave_complex_matrix, decr);
+
   INSTALL_BINOP (add, octave_complex_matrix, octave_complex_matrix, add);
   INSTALL_BINOP (sub, octave_complex_matrix, octave_complex_matrix, sub);
   INSTALL_BINOP (mul, octave_complex_matrix, octave_complex_matrix, mul);
--- a/src/OPERATORS/op-cs-cs.cc	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/OPERATORS/op-cs-cs.cc	Fri Oct 30 20:26:31 1998 +0000
@@ -37,6 +37,28 @@
 #include "xdiv.h"
 #include "xpow.h"
 
+// unary complex scalar ops.
+
+DEFUNOP (not, complex)
+{
+  CAST_UNOP_ARG (const octave_complex&);
+
+  return octave_value (v.complex_value () == 0.0);
+}
+
+DEFUNOP_OP (uminus, complex, -)
+DEFUNOP_OP (transpose, complex, /* no-op */)
+
+DEFUNOP (hermitian, complex)
+{
+  CAST_UNOP_ARG (const octave_complex&);
+
+  return octave_value (conj (v.complex_value ()));
+}
+
+DEFNCUNOP_METHOD (incr, complex, increment)
+DEFNCUNOP_METHOD (decr, complex, decrement)
+
 // complex scalar by complex scalar ops.
 
 DEFBINOP_OP (add, complex, complex, +)
@@ -163,6 +185,14 @@
 void
 install_cs_cs_ops (void)
 {
+  INSTALL_UNOP (not, octave_complex, not);
+  INSTALL_UNOP (uminus, octave_complex, uminus);
+  INSTALL_UNOP (transpose, octave_complex, transpose);
+  INSTALL_UNOP (hermitian, octave_complex, hermitian);
+
+  INSTALL_NCUNOP (incr, octave_complex, incr);
+  INSTALL_NCUNOP (decr, octave_complex, decr);
+
   INSTALL_BINOP (add, octave_complex, octave_complex, add);
   INSTALL_BINOP (sub, octave_complex, octave_complex, sub);
   INSTALL_BINOP (mul, octave_complex, octave_complex, mul);
--- a/src/OPERATORS/op-m-m.cc	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/OPERATORS/op-m-m.cc	Fri Oct 30 20:26:31 1998 +0000
@@ -36,6 +36,21 @@
 #include "xdiv.h"
 #include "xpow.h"
 
+// matrix unary ops.
+
+DEFUNOP_OP (not, matrix, !)
+DEFUNOP_OP (uminus, matrix, -)
+
+DEFUNOP (transpose, matrix)
+{
+  CAST_UNOP_ARG (const octave_matrix&);
+
+  return octave_value (v.matrix_value().transpose ());
+}
+
+DEFNCUNOP_METHOD (incr, matrix, increment)
+DEFNCUNOP_METHOD (decr, matrix, decrement)
+
 // matrix by matrix ops.
 
 DEFBINOP_OP (add, matrix, matrix, +)
@@ -83,6 +98,14 @@
 void
 install_m_m_ops (void)
 {
+  INSTALL_UNOP (not, octave_matrix, not);
+  INSTALL_UNOP (uminus, octave_matrix, uminus);
+  INSTALL_UNOP (transpose, octave_matrix, transpose);
+  INSTALL_UNOP (hermitian, octave_matrix, transpose);
+
+  INSTALL_NCUNOP (incr, octave_matrix, incr);
+  INSTALL_NCUNOP (decr, octave_matrix, decr);
+
   INSTALL_BINOP (add, octave_matrix, octave_matrix, add);
   INSTALL_BINOP (sub, octave_matrix, octave_matrix, sub);
   INSTALL_BINOP (mul, octave_matrix, octave_matrix, mul);
--- a/src/OPERATORS/op-s-s.cc	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/OPERATORS/op-s-s.cc	Fri Oct 30 20:26:31 1998 +0000
@@ -37,6 +37,16 @@
 #include "xdiv.h"
 #include "xpow.h"
 
+// scalar unary ops.
+
+DEFUNOP_OP (not, scalar, !)
+DEFUNOP_OP (uminus, scalar, -)
+DEFUNOP_OP (transpose, scalar, /* no-op */)
+DEFUNOP_OP (hermitian, scalar, /* no-op */)
+
+DEFNCUNOP_METHOD (incr, scalar, increment)
+DEFNCUNOP_METHOD (decr, scalar, decrement)
+
 // scalar by scalar ops.
 
 DEFBINOP_OP (add, scalar, scalar, +)
@@ -132,6 +142,14 @@
 void
 install_s_s_ops (void)
 {
+  INSTALL_UNOP (not, octave_scalar, not);
+  INSTALL_UNOP (uminus, octave_scalar, uminus);
+  INSTALL_UNOP (transpose, octave_scalar, transpose);
+  INSTALL_UNOP (hermitian, octave_scalar, hermitian);
+
+  INSTALL_NCUNOP (incr, octave_scalar, incr);
+  INSTALL_NCUNOP (decr, octave_scalar, decr);
+
   INSTALL_BINOP (add, octave_scalar, octave_scalar, add);
   INSTALL_BINOP (sub, octave_scalar, octave_scalar, sub);
   INSTALL_BINOP (mul, octave_scalar, octave_scalar, mul);
--- a/src/OPERATORS/op-str-str.cc	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/OPERATORS/op-str-str.cc	Fri Oct 30 20:26:31 1998 +0000
@@ -34,6 +34,15 @@
 #include "ov-typeinfo.h"
 #include "ops.h"
 
+// string unary ops.
+
+DEFUNOP (transpose, matrix)
+{
+  CAST_UNOP_ARG (const octave_char_matrix_str&);
+
+  return octave_value (v.char_matrix_value().transpose (), true);
+}
+
 // string by string ops.
 
 DEFBINOP (eq, char_matrix_str, char_matrix_str)
@@ -104,6 +113,9 @@
 void
 install_str_str_ops (void)
 {
+  INSTALL_UNOP (transpose, octave_char_matrix_str, transpose);
+  INSTALL_UNOP (hermitian, octave_char_matrix_str, transpose);
+
   INSTALL_BINOP (eq, octave_char_matrix_str, octave_char_matrix_str, eq);
   INSTALL_BINOP (ne, octave_char_matrix_str, octave_char_matrix_str, ne);
 
--- a/src/oct-lvalue.cc	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/oct-lvalue.cc	Fri Oct 30 20:26:31 1998 +0000
@@ -24,6 +24,7 @@
 #include <config.h>
 #endif
 
+#include "error.h"
 #include "oct-obj.h"
 #include "oct-lvalue.h"
 #include "ov.h"
@@ -34,7 +35,7 @@
   octave_value saved_val;
 
   if (chg_fcn)
-    octave_value saved_val = *val;
+    saved_val = *val;
 
   if (idx.empty ())
     {
@@ -51,7 +52,28 @@
 	val->assign_struct_elt (op, struct_elt_name, idx, rhs);
     }
 
-  if (chg_fcn && chg_fcn () < 0)
+  if (chg_fcn && ! error_state && chg_fcn () < 0)
+    *val = saved_val;
+}
+
+void
+octave_lvalue::do_unary_op (octave_value::unary_op op)
+{
+  octave_value saved_val;
+
+  if (chg_fcn)
+    saved_val = *val;
+
+  if (idx.empty ())
+    val->do_non_const_unary_op (op);
+  else
+    {
+      string on = octave_value::unary_op_as_string (op);
+      error ("indexed operations not implemented yet for operator `%s'",
+	     on.c_str ());
+    }
+
+  if (chg_fcn && ! error_state && chg_fcn () < 0)
     *val = saved_val;
 }
 
--- a/src/oct-lvalue.h	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/oct-lvalue.h	Fri Oct 30 20:26:31 1998 +0000
@@ -82,11 +82,7 @@
 
   void clear_index (void) { idx = octave_value_list (); }
 
-  // XXX FIXME XXX -- need to handle index increment and decrement too.
-
-  void increment (void) { val->increment (); }
-
-  void decrement (void) { val->decrement (); }
+  void do_unary_op (octave_value::unary_op op);
 
   octave_value value (void)
     {
--- a/src/ops.h	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/ops.h	Fri Oct 30 20:26:31 1998 +0000
@@ -25,17 +25,27 @@
 
 extern void install_ops (void);
 
+#define INSTALL_UNOP(op, t, f) \
+  octave_value_typeinfo::register_unary_op \
+    (octave_value::op, t::static_type_id (), oct_unop_ ## f);
+
+#define INSTALL_NCUNOP(op, t, f) \
+  octave_value_typeinfo::register_non_const_unary_op \
+    (octave_value::op, t::static_type_id (), oct_unop_ ## f);
+
 #define INSTALL_BINOP(op, t1, t2, f) \
   octave_value_typeinfo::register_binary_op \
-    (octave_value::op, t1::static_type_id (), t2::static_type_id (), f);
+    (octave_value::op, t1::static_type_id (), t2::static_type_id (), \
+     oct_binop_ ## f);
 
 #define INSTALL_ASSIGNOP(op, t1, t2, f) \
   octave_value_typeinfo::register_assign_op \
-    (octave_value::op, t1::static_type_id (), t2::static_type_id (), f);
+    (octave_value::op, t1::static_type_id (), t2::static_type_id (), \
+     oct_assignop_ ## f);
 
 #define INSTALL_ASSIGNANYOP(op, t1, f) \
   octave_value_typeinfo::register_assignany_op \
-    (octave_value::op, t1::static_type_id (), f);
+    (octave_value::op, t1::static_type_id (), oct_assignop_ ## f);
 
 #define INSTALL_ASSIGNCONV(t1, t2, tr) \
   octave_value_typeinfo::register_pref_assign_conv \
@@ -43,7 +53,7 @@
 
 #define INSTALL_WIDENOP(t1, t2, f) \
   octave_value_typeinfo::register_widening_op \
-    (t1::static_type_id (), t2::static_type_id (), f);
+    (t1::static_type_id (), t2::static_type_id (), oct_conv_ ## f);
 
 #define BOOL_OP1(xt, xn, get_x, yt, yn, get_y) \
   xt xn = get_x; \
@@ -115,6 +125,9 @@
     } \
   while (0)
 
+#define CAST_UNOP_ARG(t) \
+  t v = DYNAMIC_CAST (t, a);
+
 #define CAST_BINOP_ARGS(t1, t2) \
   t1 v1 = DYNAMIC_CAST (t1, a1); \
   t2 v2 = DYNAMIC_CAST (t2, a2);
@@ -124,7 +137,9 @@
 
 #define ASSIGNOPDECL(name) \
   static octave_value \
-  name (octave_value& a1, const octave_value_list& idx, const octave_value& a2)
+  oct_assignop_ ## name (octave_value& a1, \
+			 const octave_value_list& idx, \
+			 const octave_value& a2)
 
 #define DEFASSIGNOP(name, t1, t2) \
   ASSIGNOPDECL (name)
@@ -149,14 +164,52 @@
 
 #define CONVDECL(name) \
   static octave_value * \
-  name (const octave_value& a)
+  oct_conv_ ## name (const octave_value& a)
+
+#define CONVDECLX(name) \
+  static octave_value * \
+  oct_conv_ ## name (const octave_value&)
 
 #define DEFCONV(name, from, to) \
   CONVDECL (name)
 
+#define UNOPDECL(name, a) \
+  static octave_value \
+  oct_unop_ ## name (const octave_value& a)
+
+#define DEFUNOPX(name, t) \
+  UNOPDECL (name, , )
+
+#define DEFUNOP(name, t) \
+  UNOPDECL (name, a)
+
+#define DEFUNOP_OP(name, t, op) \
+  UNOPDECL (name, a) \
+  { \
+    CAST_UNOP_ARG (const octave_ ## t&); \
+    return octave_value (op v.t ## _value ()); \
+  }
+
+// XXX FIXME XXX -- in some cases, the constructor isn't necessary.
+
+#define DEFUNOP_FN(name, t, f) \
+  UNOPDECL (name, a) \
+  { \
+    CAST_UNOP_ARG (const octave_ ## t&); \
+    return octave_value (f (v.t ## _value ())); \
+  }
+
+#define DEFNCUNOP_METHOD(name, t, method) \
+  static void \
+  oct_unop_ ## name (octave_value& a) \
+  { \
+    CAST_UNOP_ARG (octave_ ## t&); \
+    v.method (); \
+  }
+
 #define BINOPDECL(name, a1, a2) \
   static octave_value \
-  name (const octave_value& a1, const octave_value& a2)
+  oct_binop_ ## name (const octave_value& a1, const octave_value& a2)
 
 #define DEFBINOPX(name, t1, t2) \
   BINOPDECL (name, , )
--- a/src/ov-base.cc	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/ov-base.cc	Fri Oct 30 20:26:31 1998 +0000
@@ -339,64 +339,17 @@
   return retval;
 }
 
-octave_value
-octave_base_value::not (void) const
-{
-  octave_value retval;
-  gripe_wrong_type_arg ("octave_base_value::not()", type_name ());
-  return retval;
-}
-
-octave_value
-octave_base_value::uminus (void) const
-{
-  octave_value retval;
-  gripe_wrong_type_arg ("octave_base_value::uminus()", type_name ());
-  return retval;
-}
-
-octave_value
-octave_base_value::transpose (void) const
-{
-  octave_value retval;
-  gripe_wrong_type_arg ("octave_base_value::transpose()", type_name ());
-  return retval;
-}
-
-octave_value
-octave_base_value::hermitian (void) const
-{
-  octave_value retval;
-  gripe_wrong_type_arg ("octave_base_value::hermitian()", type_name ());
-  return retval;
-}
-
-void
-octave_base_value::increment (void)
-{
-  gripe_wrong_type_arg ("octave_base_value::increment()", type_name ());
-}
-
-void
-octave_base_value::decrement (void)
-{
-  gripe_wrong_type_arg ("octave_base_value::decrement()", type_name ());
-}
-
-static octave_value *
-matrix_conv (const octave_value&)
+CONVDECLX (matrix_conv)
 {
   return new octave_matrix ();
 }
 
-static octave_value *
-complex_matrix_conv (const octave_value&)
+CONVDECLX (complex_matrix_conv)
 {
   return new octave_complex_matrix ();
 }
 
-static octave_value *
-string_conv (const octave_value&)
+CONVDECLX (string_conv)
 {
   return new octave_char_matrix_str ();
 }
--- a/src/ov-base.h	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/ov-base.h	Fri Oct 30 20:26:31 1998 +0000
@@ -184,18 +184,6 @@
 
   boolMatrix bool_matrix_value (void) const;
 
-  octave_value not (void) const;
-
-  octave_value uminus (void) const;
-
-  octave_value transpose (void) const;
-
-  octave_value hermitian (void) const;
-
-  void increment (void);
-
-  void decrement (void);
-
   octave_value convert_to_str (void) const;
 
   void convert_to_row_or_column_vector (void);
--- a/src/ov-bool-mat.h	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/ov-bool-mat.h	Fri Oct 30 20:26:31 1998 +0000
@@ -131,12 +131,6 @@
   octave_value convert_to_str (void) const
     { return octave_value (matrix); }
 
-  octave_value transpose (void) const
-    { return octave_value (matrix.transpose ()); }
-
-  octave_value hermitian (void) const
-    { return octave_value (matrix.transpose ()); }
-
   void print (ostream& os, bool pr_as_read_syntax = false) const;
 
   void print_raw (ostream& os, bool pr_as_read_syntax = false) const;
--- a/src/ov-bool.h	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/ov-bool.h	Fri Oct 30 20:26:31 1998 +0000
@@ -119,14 +119,6 @@
   boolMatrix bool_matrix_value (void) const
     { return boolMatrix (1, 1, scalar); }
 
-  octave_value not (void) const { return octave_value (! scalar); }
-
-  octave_value uminus (void) const { return octave_value (- (double) scalar); }
-
-  octave_value transpose (void) const { return octave_value (scalar); }
-
-  octave_value hermitian (void) const { return octave_value (scalar); }
-
   octave_value convert_to_str (void) const;
 
   void print (ostream& os, bool pr_as_read_syntax = false) const;
--- a/src/ov-ch-mat.h	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/ov-ch-mat.h	Fri Oct 30 20:26:31 1998 +0000
@@ -134,12 +134,6 @@
   octave_value convert_to_str (void) const
     { return octave_value (matrix, true); }
 
-  octave_value transpose (void) const
-    { return octave_value (matrix.transpose ()); }
-
-  octave_value hermitian (void) const
-    { return octave_value (matrix.transpose ()); }
-
   void print (ostream& os, bool pr_as_read_syntax = false) const;
 
   void print_raw (ostream& os, bool pr_as_read_syntax = false) const;
--- a/src/ov-complex.h	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/ov-complex.h	Fri Oct 30 20:26:31 1998 +0000
@@ -121,14 +121,6 @@
 
   ComplexMatrix complex_matrix_value (bool = false) const;
 
-  octave_value not (void) const { return octave_value (scalar == 0.0); }
-
-  octave_value uminus (void) const { return octave_value (- scalar); }
-
-  octave_value transpose (void) const { return octave_value (scalar); }
-
-  octave_value hermitian (void) const { return octave_value (conj (scalar)); }
-
   void increment (void) { scalar += 1.0; }
 
   void decrement (void) { scalar -= 1.0; }
--- a/src/ov-cx-mat.h	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/ov-cx-mat.h	Fri Oct 30 20:26:31 1998 +0000
@@ -131,16 +131,6 @@
 
   ComplexMatrix complex_matrix_value (bool = false) const;
 
-  octave_value not (void) const { return octave_value (! matrix); }
-
-  octave_value uminus (void) const { return octave_value (- matrix); }
-
-  octave_value transpose (void) const
-    { return octave_value (matrix.transpose ()); }
-
-  octave_value hermitian (void) const
-    { return octave_value (matrix.hermitian ()); }
-
   void increment (void) { matrix += Complex (1.0); }
 
   void decrement (void) { matrix -= Complex (1.0); }
--- a/src/ov-range.cc	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/ov-range.cc	Fri Oct 30 20:26:31 1998 +0000
@@ -176,27 +176,6 @@
 }
 
 octave_value
-octave_range::not (void) const
-{
-  Matrix tmp (range.matrix_value ());
-  return (! tmp);
-}
-
-octave_value
-octave_range::transpose (void) const
-{
-  Matrix tmp (range.matrix_value ());
-  return tmp.transpose ();
-}
-
-octave_value
-octave_range::hermitian (void) const
-{
-  Matrix tmp (range.matrix_value ());
-  return tmp.transpose ();
-}
-
-octave_value
 octave_range::convert_to_str (void) const
 {
   octave_value tmp (range.matrix_value ());
--- a/src/ov-range.h	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/ov-range.h	Fri Oct 30 20:26:31 1998 +0000
@@ -144,14 +144,6 @@
 
   Range range_value (void) const { return range; }
 
-  octave_value not (void) const;
-
-  octave_value uminus (void) const { return octave_value (- range); }
-
-  octave_value transpose (void) const;
-
-  octave_value hermitian (void) const;
-
   octave_value convert_to_str (void) const;
 
   void print (ostream& os, bool pr_as_read_syntax = false) const;
--- a/src/ov-re-mat.h	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/ov-re-mat.h	Fri Oct 30 20:26:31 1998 +0000
@@ -146,16 +146,6 @@
   ComplexMatrix complex_matrix_value (bool = false) const
     { return matrix; }
 
-  octave_value not (void) const { return octave_value (! matrix); }
-
-  octave_value uminus (void) const { return octave_value (- matrix); }
-
-  octave_value transpose (void) const
-    { return octave_value (matrix.transpose ()); }
-
-  octave_value hermitian (void) const
-    { return octave_value (matrix.transpose ()); }
-
   void increment (void) { matrix += 1.0; }
 
   void decrement (void) { matrix -= 1.0; }
--- a/src/ov-scalar.h	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/ov-scalar.h	Fri Oct 30 20:26:31 1998 +0000
@@ -115,14 +115,6 @@
   ComplexMatrix complex_matrix_value (bool = false) const
     { return  ComplexMatrix (1, 1, Complex (scalar)); }
 
-  octave_value not (void) const { return octave_value (! scalar); }
-
-  octave_value uminus (void) const { return octave_value (- scalar); }
-
-  octave_value transpose (void) const { return octave_value (scalar); }
-
-  octave_value hermitian (void) const { return octave_value (scalar); }
-
   void increment (void) { ++scalar; }
 
   void decrement (void) { --scalar; }
--- a/src/ov-str-mat.cc	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/ov-str-mat.cc	Fri Oct 30 20:26:31 1998 +0000
@@ -51,7 +51,9 @@
 {
   CAST_CONV_ARG (const octave_char_matrix_str&);
 
-  return new octave_matrix (v.matrix_value ());
+  Matrix m = v.matrix_value ();
+
+  return error_state ? 0 : new octave_matrix (m);
 }
 
 type_conv_fcn
--- a/src/ov-str-mat.h	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/ov-str-mat.h	Fri Oct 30 20:26:31 1998 +0000
@@ -103,12 +103,6 @@
 
   string string_value (void) const;
 
-  octave_value transpose (void) const
-    { return octave_value (matrix.transpose (), true); }
-
-  octave_value hermitian (void) const
-    { return octave_value (matrix.transpose (), true); }
-
   void print (ostream& os, bool pr_as_read_syntax = false) const;
 
   void print_raw (ostream& os, bool pr_as_read_syntax = false) const;
--- a/src/ov-typeinfo.cc	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/ov-typeinfo.cc	Fri Oct 30 20:26:31 1998 +0000
@@ -44,6 +44,12 @@
 #include <Array2.cc>
 #include <Array3.cc>
 
+template class Array<unary_op_fcn>;
+template class Array2<unary_op_fcn>;
+
+template class Array<non_const_unary_op_fcn>;
+template class Array2<non_const_unary_op_fcn>;
+
 template class Array<binary_op_fcn>;
 template class Array2<binary_op_fcn>;
 template class Array3<binary_op_fcn>;
@@ -80,6 +86,23 @@
 }
 
 bool
+octave_value_typeinfo::register_unary_op (octave_value::unary_op op,
+					   int t, unary_op_fcn f)
+{
+  return (instance_ok ())
+    ? instance->do_register_unary_op (op, t, f) : false;
+}
+
+bool
+octave_value_typeinfo::register_non_const_unary_op (octave_value::unary_op op,
+						    int t,
+						    non_const_unary_op_fcn f)
+{
+  return (instance_ok ())
+    ? instance->do_register_non_const_unary_op (op, t, f) : false;
+}
+
+bool
 octave_value_typeinfo::register_binary_op (octave_value::binary_op op,
 					   int t1, int t2,
 					   binary_op_fcn f)
@@ -138,6 +161,13 @@
 
       types.resize (len, string ());
 
+      unary_ops.resize (static_cast<int> (octave_value::num_unary_ops),
+			len, static_cast<unary_op_fcn> (0));
+
+      non_const_unary_ops.resize
+	(static_cast<int> (octave_value::num_unary_ops),
+	 len, static_cast<non_const_unary_op_fcn> (0));
+
       binary_ops.resize (static_cast<int> (octave_value::num_binary_ops),
 			 len, len, static_cast<binary_op_fcn> (0));
 
@@ -160,6 +190,24 @@
 }
 
 bool
+octave_value_typeinfo::do_register_unary_op (octave_value::unary_op op,
+					     int t, unary_op_fcn f)
+{
+  unary_ops.checkelem (static_cast<int> (op), t) = f;
+
+  return false;
+}
+
+bool
+octave_value_typeinfo::do_register_non_const_unary_op
+  (octave_value::unary_op op, int t, non_const_unary_op_fcn f)
+{
+  non_const_unary_ops.checkelem (static_cast<int> (op), t) = f;
+
+  return false;
+}
+
+bool
 octave_value_typeinfo::do_register_binary_op (octave_value::binary_op op,
 					      int t1, int t2,
 					      binary_op_fcn f)
@@ -208,6 +256,19 @@
 
 #include <iostream.h>
 
+unary_op_fcn
+octave_value_typeinfo::do_lookup_unary_op (octave_value::unary_op op, int t)
+{
+  return unary_ops.checkelem (static_cast<int> (op), t);
+}
+
+non_const_unary_op_fcn
+octave_value_typeinfo::do_lookup_non_const_unary_op
+  (octave_value::unary_op op, int t)
+{
+  return non_const_unary_ops.checkelem (static_cast<int> (op), t);
+}
+
 binary_op_fcn
 octave_value_typeinfo::do_lookup_binary_op (octave_value::binary_op op,
 					    int t1, int t2)
--- a/src/ov-typeinfo.h	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/ov-typeinfo.h	Fri Oct 30 20:26:31 1998 +0000
@@ -46,6 +46,11 @@
 
   static int register_type (const string&);
 
+  static bool register_unary_op (octave_value::unary_op, int, unary_op_fcn);
+
+  static bool register_non_const_unary_op (octave_value::unary_op, int,
+					   non_const_unary_op_fcn);
+
   static bool register_binary_op (octave_value::binary_op, int, int,
 				  binary_op_fcn);
 
@@ -59,6 +64,18 @@
 
   static bool register_widening_op (int, int, type_conv_fcn);
 
+  static unary_op_fcn
+  lookup_unary_op (octave_value::unary_op op, int t)
+  {
+    return instance->do_lookup_unary_op (op, t);
+  }
+
+  static non_const_unary_op_fcn
+  lookup_non_const_unary_op (octave_value::unary_op op, int t)
+  {
+    return instance->do_lookup_non_const_unary_op (op, t);
+  }
+
   static binary_op_fcn
   lookup_binary_op (octave_value::binary_op op, int t1, int t2)
   {
@@ -98,6 +115,10 @@
 
   octave_value_typeinfo (void)
     : num_types (0), types (init_tab_sz, string ()),
+      unary_ops (octave_value::num_unary_ops, init_tab_sz,
+		 (unary_op_fcn) 0),
+      non_const_unary_ops (octave_value::num_unary_ops, init_tab_sz,
+			   (non_const_unary_op_fcn) 0),
       binary_ops (octave_value::num_binary_ops, init_tab_sz,
 		  init_tab_sz, (binary_op_fcn) 0),
       assign_ops (octave_value::num_assign_ops, init_tab_sz,
@@ -117,6 +138,10 @@
 
   Array<string> types;
 
+  Array2<unary_op_fcn> unary_ops;
+
+  Array2<non_const_unary_op_fcn> non_const_unary_ops;
+
   Array3<binary_op_fcn> binary_ops;
 
   Array3<assign_op_fcn> assign_ops;
@@ -129,6 +154,11 @@
 
   int do_register_type (const string&);
 
+  bool do_register_unary_op (octave_value::unary_op, int, unary_op_fcn);
+
+  bool do_register_non_const_unary_op (octave_value::unary_op, int,
+				       non_const_unary_op_fcn);
+
   bool do_register_binary_op (octave_value::binary_op, int, int,
 			      binary_op_fcn);
 
@@ -142,14 +172,16 @@
 
   bool do_register_widening_op (int, int, type_conv_fcn);
 
-  binary_op_fcn
-  do_lookup_binary_op (octave_value::binary_op, int, int);
+  unary_op_fcn do_lookup_unary_op (octave_value::unary_op, int);
+
+  non_const_unary_op_fcn do_lookup_non_const_unary_op
+    (octave_value::unary_op, int);
 
-  assign_op_fcn
-  do_lookup_assign_op (octave_value::assign_op, int, int);
+  binary_op_fcn do_lookup_binary_op (octave_value::binary_op, int, int);
 
-  assign_op_fcn
-  do_lookup_assignany_op (octave_value::assign_op, int);
+  assign_op_fcn do_lookup_assign_op (octave_value::assign_op, int, int);
+
+  assign_op_fcn do_lookup_assignany_op (octave_value::assign_op, int);
 
   int do_lookup_pref_assign_conv (int, int);
 
--- a/src/ov.cc	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/ov.cc	Fri Oct 30 20:26:31 1998 +0000
@@ -122,6 +122,44 @@
 // Octave's value type.
 
 string
+octave_value::unary_op_as_string (unary_op op)
+{
+  string retval;
+
+  switch (op)
+    {
+    case not:
+      retval = "!";
+      break;
+
+    case uminus:
+      retval = "-";
+      break;
+
+    case transpose:
+      retval = ".'";
+      break;
+
+    case hermitian:
+      retval = "'";
+      break;
+
+    case incr:
+      retval = "++";
+      break;
+
+    case decr:
+      retval = "--";
+      break;
+
+    default:
+      retval = "<unknown>";
+    }
+
+  return retval;
+}
+
+string
 octave_value::binary_op_as_string (binary_op op)
 {
   string retval;
@@ -503,18 +541,24 @@
 }
 
 static void
-gripe_no_conversion (const string& tn1, const string& tn2)
+gripe_no_conversion (const string& on, const string& tn1, const string& tn2)
 {
-  error ("no suitable conversion found for assignment of `%s' to indexed `%s'",
-	 tn2.c_str (), tn1.c_str ());
+  error ("operator %s: no conversion for assignment of `%s' to indexed `%s'",
+	 on.c_str (), tn2.c_str (), tn1.c_str ());
 }
 
 void
-octave_value::assign (assign_op, const octave_value& rhs)
+octave_value::assign (assign_op op, const octave_value& rhs)
 {
   // XXX FIXME XXX -- make this work for ops other than `='.
 
-  operator = (rhs);
+  if (op == asn_eq)
+    operator = (rhs);
+  else
+    {
+      string on = assign_op_as_string (op);
+      error ("operator `%s' not supported yet", on.c_str ());
+    }
 }
 
 void
@@ -530,10 +574,11 @@
 
       if (! (error_state || assignment_ok))
 	{
-	  assignment_ok = try_assignment_with_conversion (op,idx, rhs);
+	  assignment_ok = try_assignment_with_conversion (op, idx, rhs);
 
 	  if (! (error_state || assignment_ok))
-	    gripe_no_conversion (type_name (), rhs.type_name ());
+	    gripe_no_conversion (assign_op_as_string (op),
+				 type_name (), rhs.type_name ());
 	}
 
       if (! error_state)
@@ -718,7 +763,7 @@
 }
 
 static void
-gripe_conversion_failed (const string& tn1, const string& tn2)
+gripe_assign_conversion_failed (const string& tn1, const string& tn2)
 {
   error ("type conversion for assignment of `%s' to indexed `%s' failed",
 	 tn2.c_str (), tn1.c_str ());
@@ -767,7 +812,7 @@
 		delete old_rep;
 	    }
 	  else
-	    gripe_conversion_failed (type_name (), rhs.type_name ());
+	    gripe_assign_conversion_failed (type_name (), rhs.type_name ());
 	}
       else
 	gripe_indexed_assignment (type_name (), rhs.type_name ());
@@ -789,7 +834,17 @@
       type_conv_fcn cf_rhs = rhs.numeric_conversion_function ();
 
       if (cf_rhs)
-	tmp_rhs = octave_value (cf_rhs (*rhs.rep));
+	{
+	  octave_value *tmp = cf_rhs (*rhs.rep);
+
+	  if (tmp)
+	    tmp_rhs = octave_value (tmp);
+	  else
+	    {
+	      gripe_assign_conversion_failed (type_name (), rhs.type_name ());
+	      return false;
+	    }
+	}
       else
 	tmp_rhs = rhs;
 
@@ -799,8 +854,19 @@
       if (cf_this)
 	{
 	  old_rep = rep;
-	  rep = cf_this (*rep);
-	  rep->count = 1;
+
+	  octave_value *tmp = cf_this (*rep);
+
+	  if (tmp)
+	    {
+	      rep = tmp;
+	      rep->count = 1;
+	    }
+	  else
+	    {
+	      gripe_assign_conversion_failed (type_name (), rhs.type_name ());
+	      return false;
+	    }
 	}
 
       if (cf_this || cf_rhs)
@@ -868,6 +934,12 @@
 	 on.c_str (), tn1.c_str (), tn2.c_str ());
 }
 
+static void
+gripe_binary_op_conv (const string& on)
+{
+  error ("type conversion failed for binary operator `%s'", on.c_str ());
+}
+
 octave_value
 do_binary_op (octave_value::binary_op op, const octave_value& v1,
 	      const octave_value& v2)
@@ -888,8 +960,18 @@
 
       if (cf1)
 	{
-	  tv1 = octave_value (cf1 (*v1.rep));
-	  t1 = tv1.type_id ();
+	  octave_value *tmp = cf1 (*v1.rep);
+
+	  if (tmp)
+	    {
+	      tv1 = octave_value (tmp);
+	      t1 = tv1.type_id ();
+	    }
+	  else
+	    {
+	      gripe_binary_op_conv (octave_value::binary_op_as_string (op));
+	      return retval;
+	    }
 	}
       else
 	tv1 = v1;
@@ -899,8 +981,18 @@
 
       if (cf2)
 	{
-	  tv2 = octave_value (cf2 (*v2.rep));
-	  t2 = tv2.type_id ();
+	  octave_value *tmp = cf2 (*v2.rep);
+
+	  if (tmp)
+	    {
+	      tv2 = octave_value (tmp);
+	      t2 = tv2.type_id ();
+	    }
+	  else
+	    {
+	      gripe_binary_op_conv (octave_value::binary_op_as_string (op));
+	      return retval;
+	    }
 	}
       else
 	tv2 = v2;
@@ -924,6 +1016,134 @@
   return retval;
 }
 
+static void
+gripe_unary_op (const string& on, const string& tn)
+{
+  error ("unary operator `%s' not implemented for `%s' operands",
+	 on.c_str (), tn.c_str ());
+}
+
+static void
+gripe_unary_op_conv (const string& on)
+{
+  error ("type conversion failed for unary operator `%s'", on.c_str ());
+}
+
+octave_value
+do_unary_op (octave_value::unary_op op, const octave_value& v)
+{
+  octave_value retval;
+
+  int t = v.type_id ();
+
+  unary_op_fcn f = octave_value_typeinfo::lookup_unary_op (op, t);
+
+  if (f)
+    retval = f (*v.rep);
+  else
+    {
+      octave_value tv;
+      type_conv_fcn cf = v.numeric_conversion_function ();
+
+      if (cf)
+	{
+	  octave_value *tmp = cf (*v.rep);
+
+	  if (tmp)
+	    {
+	      tv = octave_value (tmp);
+	      t = tv.type_id ();
+
+	      unary_op_fcn f = octave_value_typeinfo::lookup_unary_op (op, t);
+
+	      if (f)
+		retval = f (*tv.rep);
+	      else
+		gripe_unary_op (octave_value::unary_op_as_string (op),
+				v.type_name ());
+	    }
+	  else
+	    gripe_unary_op_conv (octave_value::unary_op_as_string (op));
+	}
+      else
+	gripe_unary_op (octave_value::unary_op_as_string (op),
+			v.type_name ());
+    }
+
+  return retval;
+}
+
+static void
+gripe_unary_op_conversion_failed (const string& op, const string& tn)
+{
+  error ("operator %s: type conversion for `%s' failed",
+	 op.c_str (), tn.c_str ());
+}
+
+void
+octave_value::do_non_const_unary_op (octave_value::unary_op op)
+{
+  octave_value retval;
+
+  int t = type_id ();
+
+  non_const_unary_op_fcn f
+    = octave_value_typeinfo::lookup_non_const_unary_op (op, t);
+
+  if (f)
+    {
+      make_unique ();
+
+      f (*rep);
+    }
+  else
+    {
+      type_conv_fcn cf = numeric_conversion_function ();
+
+      if (cf)
+	{
+	  octave_value *tmp = cf (*rep);
+
+	  if (tmp)
+	    {
+	      octave_value *old_rep = rep;
+	      rep = tmp;
+	      rep->count = 1;
+
+	      t = type_id ();
+
+	      f = octave_value_typeinfo::lookup_non_const_unary_op (op, t);
+
+	      if (f)
+		{
+		  f (*rep);
+
+		  if (old_rep && --old_rep->count == 0)
+		    delete old_rep;
+		}
+	      else
+		{
+		  if (old_rep)
+		    {
+		      if (--rep->count == 0)
+			delete rep;
+
+		      rep = old_rep;
+		    }
+
+		  gripe_unary_op (octave_value::unary_op_as_string (op),
+				  type_name ());
+		}
+	    }
+	  else
+	    gripe_unary_op_conversion_failed
+	      (octave_value::unary_op_as_string (op), type_name ());
+	}
+      else
+	gripe_unary_op (octave_value::unary_op_as_string (op), type_name ());
+    }
+}
+
 // Current indentation.
 int octave_value::curr_print_indent_level = 0;
 
--- a/src/ov.h	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/ov.h	Fri Oct 30 20:26:31 1998 +0000
@@ -62,7 +62,13 @@
 
 // XXX FIXME XXX -- these should probably really be inside the scope
 // of the octave_value class, but the cygwin32 beta16 version of g++
-// can't handlt that.
+// can't handle that.
+
+typedef octave_value (*unary_op_fcn)
+  (const octave_value&);
+
+typedef void (*non_const_unary_op_fcn)
+  (octave_value&);
 
 typedef octave_value (*binary_op_fcn)
   (const octave_value&, const octave_value&);
@@ -77,6 +83,18 @@
 {
 public:
 
+  enum unary_op
+  {
+    not,
+    uminus,
+    transpose,
+    hermitian,
+    incr,
+    decr,
+    num_unary_ops,
+    unknown_unary_op
+  };
+
   enum binary_op
   {
     add,
@@ -121,6 +139,8 @@
     unknown_assign_op
   };
 
+  static string unary_op_as_string (unary_op);
+
   static string binary_op_as_string (binary_op);
 
   static string assign_op_as_string (assign_op);
@@ -409,28 +429,6 @@
   virtual boolMatrix bool_matrix_value (void) const
     { return rep->bool_matrix_value (); }
 
-  // Unary ops.
-
-  virtual octave_value not (void) const { return rep->not (); }
-
-  virtual octave_value uminus (void) const { return rep->uminus (); }
-
-  virtual octave_value transpose (void) const { return rep->transpose (); }
-
-  virtual octave_value hermitian (void) const { return rep->hermitian (); }
-
-  virtual void increment (void)
-    {
-      make_unique ();
-      rep->increment ();
-    }
-
-  virtual void decrement (void)
-    {
-      make_unique ();
-      rep->decrement ();
-    }
-
   ColumnVector vector_value (bool frc_str_conv = false,
 			     bool frc_vec_conv = false) const;
 
@@ -464,7 +462,12 @@
 
   virtual string type_name (void) const { return rep->type_name (); }
 
-  // Binary and unary operations.
+  // Unary and binary operations.
+
+  friend octave_value do_unary_op (octave_value::unary_op,
+				   const octave_value&);
+
+  void do_non_const_unary_op (octave_value::unary_op);
 
   friend octave_value do_binary_op (octave_value::binary_op,
 				    const octave_value&,
@@ -516,6 +519,79 @@
   static bool beginning_of_line;
 };
 
+#define OV_UNOP_FN(name) \
+  inline octave_value \
+  name (const octave_value& a) \
+  { \
+    return do_unary_op (octave_value::name, a); \
+  }
+
+#define OV_UNOP_OP(name, op) \
+  inline octave_value \
+  operator op (const octave_value& a) \
+  { \
+    return name (a); \
+  }
+
+#define OV_UNOP_FN_OP(name, op) \
+  OV_UNOP_FN (name) \
+  OV_UNOP_OP (name, op)
+
+OV_UNOP_FN_OP (not, !)
+OV_UNOP_FN_OP (uminus, -)
+
+OV_UNOP_FN (transpose)
+OV_UNOP_FN (hermitian)
+
+// No simple way to define these for prefix and suffix ops?
+//
+//   incr
+//   decr
+
+#define OV_BINOP_FN(name) \
+  inline octave_value \
+  name (const octave_value& a1, const octave_value& a2) \
+  { \
+    return do_binary_op (octave_value::name, a1, a2); \
+  }
+
+#define OV_BINOP_OP(name, op) \
+  inline octave_value \
+  operator op (const octave_value& a1, const octave_value& a2) \
+  { \
+    return name (a1, a2); \
+  }
+
+#define OV_BINOP_FN_OP(name, op) \
+  OV_BINOP_FN (name) \
+  OV_BINOP_OP (name, op)
+
+OV_BINOP_FN_OP (add, +)
+OV_BINOP_FN_OP (sub, -)
+OV_BINOP_FN_OP (mul, *)
+OV_BINOP_FN_OP (div, /)
+
+OV_BINOP_FN (pow)
+OV_BINOP_FN (ldiv)
+OV_BINOP_FN (lshift)
+OV_BINOP_FN (rshift)
+
+OV_BINOP_FN_OP (lt, <)
+OV_BINOP_FN_OP (le, <=)
+OV_BINOP_FN_OP (eq, ==)
+OV_BINOP_FN_OP (ge, >=)
+OV_BINOP_FN_OP (gt, >)
+OV_BINOP_FN_OP (ne, !=)
+
+OV_BINOP_FN (el_mul)
+OV_BINOP_FN (el_div)
+OV_BINOP_FN (el_pow)
+OV_BINOP_FN (el_ldiv)
+OV_BINOP_FN (el_and)
+OV_BINOP_FN (el_or)
+
+OV_BINOP_FN (struct_ref)
+
 // If TRUE, allow assignments like
 //
 //   octave> A(1) = 3; A(2) = 5
--- a/src/parse.y	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/parse.y	Fri Oct 30 20:26:31 1998 +0000
@@ -532,7 +532,10 @@
 		| '[' ';' ']'
 		  { $$ = new tree_constant (octave_value (Matrix ())); }
 		| '[' in_matrix_or_assign_lhs rows ']'
-		  { $$ = finish_matrix ($3); }
+		  {
+		    $$ = finish_matrix ($3);
+		    lexer_flags.looking_at_matrix_or_assign_lhs = false;
+		  }
 		;
 
 rows		: rows1
@@ -1842,24 +1845,24 @@
 static tree_expression *
 make_prefix_op (int op, tree_expression *op1, token *tok_val)
 {
-  tree_prefix_expression::type t;
+  octave_value::unary_op t = octave_value::unknown_unary_op;
 
   switch (op)
     {
     case EXPR_NOT:
-      t = tree_prefix_expression::unot;
+      t = octave_value::not;
       break;
 
     case '-':
-      t = tree_prefix_expression::uminus;
+      t = octave_value::uminus;
       break;
 
     case PLUS_PLUS:
-      t = tree_prefix_expression::increment;
+      t = octave_value::incr;
       break;
 
     case MINUS_MINUS:
-      t = tree_prefix_expression::decrement;
+      t = octave_value::decr;
       break;
 
     default:
@@ -1880,24 +1883,24 @@
 static tree_expression *
 make_postfix_op (int op, tree_expression *op1, token *tok_val)
 {
-  tree_postfix_expression::type t;
+  octave_value::unary_op t = octave_value::unknown_unary_op;
 
   switch (op)
     {
     case QUOTE:
-      t = tree_postfix_expression::hermitian;
+      t = octave_value::hermitian;
       break;
 
     case TRANSPOSE:
-      t = tree_postfix_expression::transpose;
+      t = octave_value::transpose;
       break;
 
     case PLUS_PLUS:
-      t = tree_postfix_expression::increment;
+      t = octave_value::incr;
       break;
 
     case MINUS_MINUS:
-      t = tree_postfix_expression::decrement;
+      t = octave_value::decr;
       break;
 
     default:
--- a/src/pt-unop.cc	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/pt-unop.cc	Fri Oct 30 20:26:31 1998 +0000
@@ -35,6 +35,14 @@
 #include "pt-unop.h"
 #include "pt-walk.h"
 
+// Unary expressions.
+
+string
+tree_unary_expression::oper (void) const
+{
+  return octave_value::unary_op_as_string (etype);
+}
+
 // Prefix expressions.
 
 octave_value_list
@@ -61,46 +69,40 @@
 
   if (op)
     {
-      if (etype == unot || etype == uminus)
+      if (etype == octave_value::incr || etype == octave_value::decr)
+	{
+	  octave_lvalue ref = op->lvalue ();
+
+	  if (error_state)
+	    eval_error ();
+	  else if (ref.is_defined ())
+	    {
+	      ref.do_unary_op (etype);
+
+	      retval = ref.value ();
+	    }
+	  else
+	    eval_error ();
+	}
+      else
 	{
 	  octave_value val = op->rvalue ();
 
-	  if (! error_state)
+	  if (error_state)
+	    eval_error ();
+	  else if (val.is_defined ())
 	    {
-	      if (val.is_defined ())
-		{
-		  if (etype == unot)
-		    retval = val.not ();
-		  else
-		    retval = val.uminus ();
-		}
-	      else
-		error ("argument to prefix operator `%s' undefined",
-		       oper () . c_str ());
-	    }
-	}
-      else if (etype == increment || etype == decrement)
-	{
-	  octave_lvalue ref = op->lvalue ();
+	      retval = ::do_unary_op (etype, val);
 
-	  if (! error_state)
-	    {
-	      if (ref.is_defined ())
+	      if (error_state)
 		{
-		  if (etype == increment)
-		    ref.increment ();
-		  else
-		    ref.decrement ();
-
-		  retval = ref.value ();
+		  retval = octave_value ();
+		  eval_error ();
 		}
-	      else
-		error ("argument to prefix operator `%s' undefined",
-		       oper () . c_str ());
 	    }
+	  else
+	    eval_error ();
 	}
-      else
-	error ("prefix operator %d not implemented", etype);
     }
 
   return retval;
@@ -114,36 +116,6 @@
 	     oper () . c_str (), line (), column ());
 }
 
-string
-tree_prefix_expression::oper (void) const
-{
-  string retval = "<unknown>";
-
-  switch (etype)
-    {
-    case unot:
-      retval = "!";
-      break;
-
-    case uminus:
-      retval = "-";
-      break;
-
-    case increment:
-      retval = "++";
-      break;
-
-    case decrement:
-      retval = "--";
-      break;
-
-    default:
-      break;
-    }
-
-  return retval;
-}
-
 void
 tree_prefix_expression::accept (tree_walker& tw)
 {
@@ -176,47 +148,43 @@
 
   if (op)
     {
-      if (etype == transpose || etype == hermitian)
+      if (etype == octave_value::incr || etype == octave_value::decr)
+	{
+	  octave_lvalue ref = op->lvalue ();
+
+	  if (error_state)
+	    eval_error ();
+	  else if (ref.is_defined ())
+	    {
+	      retval = ref.value ();
+
+	      ref.do_unary_op (etype);
+	    }
+	  else
+	    eval_error ();
+	}
+      else
 	{
 	  octave_value val = op->rvalue ();
 
-	  if (! error_state)
+	  if (error_state)
+	    eval_error ();
+	  else if (val.is_defined ())
 	    {
-	      if (val.is_defined ())
-		{
-		  if (etype == transpose)
-		    retval = val.transpose ();
-		  else
-		    retval = val.hermitian ();
-		}
-	      else
-		error ("argument to postfix operator `%s' undefined",
-		       oper () . c_str ());
-	    }
-	}
-      else if (etype == increment || etype == decrement)
-	{
-	  octave_lvalue ref = op->lvalue ();
+	      retval = ::do_unary_op (etype, val);
 
-	  if (! error_state)
-	    {
-	      if (ref.is_defined ())
+	      if (error_state)
 		{
-		  retval = ref.value ();
-
-		  if (etype == increment)
-		    ref.increment ();
-		  else
-		    ref.decrement ();
+		  retval = octave_value ();
+		  eval_error ();
 		}
-	      else
-		error ("argument to postfix operator `%s' undefined",
-		       oper () . c_str ());
 	    }
+	  else
+	    eval_error ();
 	}
-      else
-	error ("postfix operator %d not implemented", etype);
     }
+  else
+    eval_error ();
 
   return retval;
 }
@@ -229,36 +197,6 @@
 	     oper () . c_str (), line (), column ());
 }
 
-string
-tree_postfix_expression::oper (void) const
-{
-  string retval = "<unknown>";
-
-  switch (etype)
-    {
-    case transpose:
-      retval = ".'";
-      break;
-
-    case hermitian:
-      retval = "'";
-      break;
-
-    case increment:
-      retval = "++";
-      break;
-
-    case decrement:
-      retval = "--";
-      break;
-
-    default:
-      break;
-    }
-
-  return retval;
-}
-
 void
 tree_postfix_expression::accept (tree_walker& tw)
 {
--- a/src/pt-unop.h	Thu Oct 29 20:28:02 1998 +0000
+++ b/src/pt-unop.h	Fri Oct 30 20:26:31 1998 +0000
@@ -44,21 +44,32 @@
 {
 public:
 
-  tree_unary_expression (int l = -1, int c = -1)
-    : tree_expression (l, c), op (0)  { }
+  tree_unary_expression (int l = -1, int c = -1,
+			 octave_value::unary_op t
+			   = octave_value::unknown_unary_op)
+    : tree_expression (l, c), op (0), etype (t)  { }
 
-  tree_unary_expression (tree_expression *e, int l = -1, int c = -1)
-    : tree_expression (l, c), op (e) { }
+  tree_unary_expression (tree_expression *e, int l = -1, int c = -1,
+			 octave_value::unary_op t
+			   = octave_value::unknown_unary_op)
+    : tree_expression (l, c), op (e), etype (t) { }
 
   ~tree_unary_expression (void) { delete op; }
 
   tree_expression *operand (void) { return op; }
 
+  string oper (void) const;
+
 protected:
 
   // The operand for the expression.
   tree_expression *op;
 
+  // The type of the expression.
+  octave_value::unary_op etype;
+
+private:
+
   // No copying!
 
   tree_unary_expression (const tree_unary_expression&);
@@ -73,21 +84,13 @@
 {
 public:
 
-  enum type
-    {
-      unknown,
-      unot,
-      uminus,
-      increment,
-      decrement
-    };
-
   tree_prefix_expression (int l = -1, int c = -1)
-    : tree_unary_expression (l, c), etype (unknown) { }
+    : tree_unary_expression (l, c, octave_value::unknown_unary_op) { }
 
   tree_prefix_expression (tree_expression *e, int l = -1, int c = -1,
-			  type t = unknown)
-    : tree_unary_expression (e, l, c), etype (t) { }
+			  octave_value::unary_op t
+			    = octave_value::unknown_unary_op)
+    : tree_unary_expression (e, l, c, t) { }
 
   ~tree_prefix_expression (void) { }
 
@@ -100,15 +103,10 @@
 
   void eval_error (void);
 
-  string oper (void) const;
-
   void accept (tree_walker& tw);
 
 private:
 
-  // The type of the expression.
-  type etype;
-
   // No copying!
 
   tree_prefix_expression (const tree_prefix_expression&);
@@ -123,21 +121,13 @@
 {
 public:
 
-  enum type
-    {
-      unknown,
-      hermitian,
-      transpose,
-      increment,
-      decrement
-    };
-
   tree_postfix_expression (int l = -1, int c = -1)
-    : tree_unary_expression (l, c), etype (unknown) { }
+    : tree_unary_expression (l, c, octave_value::unknown_unary_op) { }
 
   tree_postfix_expression (tree_expression *e, int l = -1, int c = -1,
-			   type t = unknown)
-    : tree_unary_expression (e, l, c), etype (t) { }
+			   octave_value::unary_op t
+			     = octave_value::unknown_unary_op)
+    : tree_unary_expression (e, l, c, t) { }
 
   ~tree_postfix_expression (void) { }
 
@@ -150,15 +140,10 @@
 
   void eval_error (void);
 
-  string oper (void) const;
-
   void accept (tree_walker& tw);
 
 private:
 
-  // The type of the expression.
-  type etype;
-
   // No copying!
 
   tree_postfix_expression (const tree_postfix_expression&);