changeset 2879:4309724baab6

[project @ 1997-04-24 09:30:23 by jwe]
author jwe
date Thu, 24 Apr 1997 09:42:26 +0000
parents 55cca18e943a
children 0a076230ca87
files src/op-cm-cm.cc src/op-cm-cs.cc src/op-cm-m.cc src/op-cm-s.cc src/op-m-m.cc src/op-m-s.cc src/op-str-str.cc src/ops.h src/pt-cmd.cc src/pt-const.cc src/pt-const.h src/pt-exp.cc src/pt-exp.h src/pt-fcn.h src/pt-fvc-base.cc src/pt-fvc-base.h src/pt-fvc.cc src/pt-fvc.h
diffstat 18 files changed, 111 insertions(+), 613 deletions(-) [+]
line wrap: on
line diff
--- a/src/op-cm-cm.cc
+++ b/src/op-cm-cm.cc
@@ -220,7 +220,7 @@
   INSTALL_BINOP (el_and, octave_complex_matrix, octave_complex_matrix, el_and);
   INSTALL_BINOP (el_or, octave_complex_matrix, octave_complex_matrix, el_or);
 
-  INSTALL_ASSIGNOP (octave_complex_matrix, octave_complex_matrix, assign);
+  INSTALL_ASSIGNOP (asn_eq, octave_complex_matrix, octave_complex_matrix, assign);
 }
 
 /*
--- a/src/op-cm-cs.cc
+++ b/src/op-cm-cs.cc
@@ -225,7 +225,7 @@
   INSTALL_BINOP (el_and, octave_complex_matrix, octave_complex, el_and);
   INSTALL_BINOP (el_or, octave_complex_matrix, octave_complex, el_or);
 
-  INSTALL_ASSIGNOP (octave_complex_matrix, octave_complex, assign);
+  INSTALL_ASSIGNOP (asn_eq, octave_complex_matrix, octave_complex, assign);
 }
 
 /*
--- a/src/op-cm-m.cc
+++ b/src/op-cm-m.cc
@@ -218,7 +218,7 @@
   INSTALL_BINOP (el_and, octave_complex_matrix, octave_matrix, el_and);
   INSTALL_BINOP (el_or, octave_complex_matrix, octave_matrix, el_or);
 
-  INSTALL_ASSIGNOP (octave_complex_matrix, octave_matrix, assign);
+  INSTALL_ASSIGNOP (asn_eq, octave_complex_matrix, octave_matrix, assign);
 }
 
 /*
--- a/src/op-cm-s.cc
+++ b/src/op-cm-s.cc
@@ -227,7 +227,7 @@
   INSTALL_BINOP (el_and, octave_complex_matrix, octave_scalar, el_and);
   INSTALL_BINOP (el_or, octave_complex_matrix, octave_scalar, el_or);
 
-  INSTALL_ASSIGNOP (octave_complex_matrix, octave_scalar, assign);
+  INSTALL_ASSIGNOP (asn_eq, octave_complex_matrix, octave_scalar, assign);
 }
 
 /*
--- a/src/op-m-m.cc
+++ b/src/op-m-m.cc
@@ -214,7 +214,7 @@
   INSTALL_BINOP (el_and, octave_matrix, octave_matrix, el_and);
   INSTALL_BINOP (el_or, octave_matrix, octave_matrix, el_or);
 
-  INSTALL_ASSIGNOP (octave_matrix, octave_matrix, assign);
+  INSTALL_ASSIGNOP (asn_eq, octave_matrix, octave_matrix, assign);
 }
 
 /*
--- a/src/op-m-s.cc
+++ b/src/op-m-s.cc
@@ -225,7 +225,7 @@
   INSTALL_BINOP (el_and, octave_matrix, octave_scalar, el_and);
   INSTALL_BINOP (el_or, octave_matrix, octave_scalar, el_or);
 
-  INSTALL_ASSIGNOP (octave_matrix, octave_scalar, assign);
+  INSTALL_ASSIGNOP (asn_eq, octave_matrix, octave_scalar, assign);
 }
 
 /*
--- a/src/op-str-str.cc
+++ b/src/op-str-str.cc
@@ -111,7 +111,7 @@
   INSTALL_BINOP (eq, octave_char_matrix_str, octave_char_matrix_str, eq);
   INSTALL_BINOP (ne, octave_char_matrix_str, octave_char_matrix_str, ne);
 
-  INSTALL_ASSIGNOP (octave_char_matrix_str, octave_char_matrix_str, assign);
+  INSTALL_ASSIGNOP (asn_eq, octave_char_matrix_str, octave_char_matrix_str, assign);
 }
 
 /*
--- a/src/ops.h
+++ b/src/ops.h
@@ -25,17 +25,13 @@
 
 extern void install_ops (void);
 
-#define INSTALL_UNOP(op, t, f) \
-  octave_value_typeinfo::register_unary_op \
-    (octave_value::op, t::static_type_id (), 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);
 
-#define INSTALL_ASSIGNOP(t1, t2, f) \
+#define INSTALL_ASSIGNOP(op, t1, t2, f) \
   octave_value_typeinfo::register_assign_op \
-    (t1::static_type_id (), t2::static_type_id (), f);
+    (octave_value::op, t1::static_type_id (), t2::static_type_id (), f);
 
 #define INSTALL_ASSIGNCONV(t1, t2, tr) \
   octave_value_typeinfo::register_pref_assign_conv \
--- a/src/pt-cmd.cc
+++ b/src/pt-cmd.cc
@@ -311,7 +311,7 @@
       return;
     }
 
-  tmp.assign (rhs);
+  tmp.assign (octave_value::asn_eq, rhs);
 
   if (list)
     {
--- a/src/pt-const.cc
+++ b/src/pt-const.cc
@@ -28,54 +28,17 @@
 #include <config.h>
 #endif
 
-#include <cctype>
-#include <cstring>
-
-#include <string>
-
-#include <fstream.h>
 #include <iostream.h>
 
-#include <SLList.h>
-
-#include "Array-flags.h"
-
-#include "mx-base.h"
-#include "Range.h"
-#include "str-vec.h"
-
-#include "defun.h"
-#include "error.h"
-#include "gripes.h"
-#include "idx-vector.h"
-#include "mappers.h"
-#include "oct-map.h"
 #include "oct-obj.h"
-#include "pager.h"
-#include "pr-output.h"
-#include "sysdep.h"
 #include "pt-const.h"
 #include "pt-walk.h"
-#include "unwind-prot.h"
-#include "utils.h"
-#include "variables.h"
 
 // We are likely to have a lot of tree_constant objects to allocate,
 // so make the grow_size large.
 octave_allocator
 tree_constant::allocator (sizeof (tree_constant), 1024);
 
-Octave_map
-tree_constant::map_value (void) const
-{
-  return val.map_value ();
-}
-
-void
-tree_constant::print (void)
-{
-}
-
 void
 tree_constant::print (ostream& os, bool pr_as_read_syntax, bool pr_orig_text)
 {
@@ -97,42 +60,7 @@
 octave_value_list
 tree_constant::eval (bool, int, const octave_value_list& idx)
 {
-  octave_value_list retval;
-
-  if (idx.length () >  0)
-    retval (0) = index (idx);
-  else
-    retval (0) = val;
-
-  return retval;
-}
-
-octave_value
-tree_constant::lookup_map_element (const string&, bool, bool)
-{
-  octave_value retval;
-  error ("tree_constant::lookup_map_element() not implemented");
-  return retval;
-}
-
-octave_value
-tree_constant::lookup_map_element (SLList<string>&, bool, bool)
-{
-  octave_value retval;
-  error ("tree_constant::lookup_map_element() not implemented");
-  return retval;
-}
-
-void
-tree_constant::stash_original_text (const string& s)
-{
-  orig_text = s;
-}
-
-string
-tree_constant::original_text (void) const
-{
-  return orig_text;
+  return (idx.length () > 0) ? index (idx) : val;
 }
 
 void
--- a/src/pt-const.h
+++ b/src/pt-const.h
@@ -31,14 +31,10 @@
 
 class ostream;
 
-#include "Range.h"
-#include "mx-base.h"
 #include "oct-alloc.h"
-#include "str-vec.h"
 
 #include "pt-fvc.h"
 
-class Octave_map;
 class octave_value_list;
 
 class tree_walker;
@@ -50,94 +46,8 @@
 {
 public:
 
-  enum magic_colon { magic_colon_t };
-  enum all_va_args { all_va_args_t };
-
-  // Constructors.  It is possible to create the following types of
-  // constants:
-  //
-  // constant type    constructor arguments
-  // -------------    ---------------------
-  // unknown          none
-  // real scalar      double
-  // real matrix      Matrix
-  //                  DiagMatrix
-  //                  RowVector
-  //                  ColumnVector
-  // complex scalar   Complex
-  // complex matrix   ComplexMatrix
-  //                  ComplexDiagMatrix
-  //                  ComplexRowVector
-  //                  ComplexColumnVector
-  // char matrix      charMatrix
-  // string           char* (null terminated)
-  //                  string
-  //                  charMatrix
-  // range            double, double, double
-  //                  Range
-  // map              Octave_map
-  // magic colon      tree_constant::magic_colon
-  // all_va_args      tree_constant::all_va_args
-
-  tree_constant (void)
-    : tree_fvc (), val (), orig_text () { }
-
-  tree_constant (double d, int l = -1, int c = -1)
-    : tree_fvc (l, c), val (d), orig_text () { }
-
-  tree_constant (const Matrix& m)
-    : tree_fvc (), val (m), orig_text () { }
-
-  tree_constant (const DiagMatrix& d)
-    : tree_fvc (), val (d), orig_text () { }
-
-  tree_constant (const RowVector& v, int pcv = -1)
-    : tree_fvc (), val (v, pcv), orig_text () { }
-
-  tree_constant (const ColumnVector& v, int pcv = -1)
-    : tree_fvc (), val (v, pcv), orig_text () { }
-
-  tree_constant (const Complex& C, int l = -1, int c = -1)
-    : tree_fvc (l, c), val (C), orig_text () { }
-
-  tree_constant (const ComplexMatrix& m)
-    : tree_fvc (), val (m), orig_text () { }
-
-  tree_constant (const ComplexDiagMatrix& d)
-    : tree_fvc (), val (d), orig_text () { }
-
-  tree_constant (const ComplexRowVector& v, int pcv = -1)
-    : tree_fvc (), val (v, pcv), orig_text () { }
-
-  tree_constant (const ComplexColumnVector& v, int pcv = -1)
-    : tree_fvc (), val (v, pcv), orig_text () { }
-
-  tree_constant (const char *s, int l = -1, int c = -1)
-    : tree_fvc (l, c), val (s), orig_text () { }
-
-  tree_constant (const string& s, int l = -1, int c = -1)
-    : tree_fvc (l, c), val (s), orig_text () { }
-
-  tree_constant (const string_vector& s, int l = -1, int c = -1)
-    : tree_fvc (l, c), val (s), orig_text () { }
-
-  tree_constant (const charMatrix& chm, bool is_string = false)
-    : tree_fvc (), val (chm, is_string), orig_text () { }
-
-  tree_constant (double base, double limit, double inc)
-    : tree_fvc (), val (base, limit, inc), orig_text () { }
-
-  tree_constant (const Range& r)
-    : tree_fvc (), val (r), orig_text () { }
-
-  tree_constant (const Octave_map& m)
-    : tree_fvc (), val (m), orig_text () { }
-
-  tree_constant (tree_constant::magic_colon, int l = -1, int c = -1)
-    : tree_fvc (l, c), val (octave_value::magic_colon_t), orig_text () { }
-
-  tree_constant (tree_constant::all_va_args, int l = -1, int c = -1)
-    : tree_fvc (l, c), val (octave_value::all_va_args_t), orig_text () { }
+  tree_constant (int l = -1, int c = -1)
+    : tree_fvc (l, c), val (), orig_text () { }
 
   tree_constant (const octave_value& v, int l = -1, int c = -1)
     : tree_fvc (l, c), val (v), orig_text () { }
@@ -175,13 +85,13 @@
     }
 
   octave_value value (void) const
-    {
-      return val;
-    }
+    { return val; }
 
-  octave_value assign (const octave_value_list& idx, const octave_value& rhs)
+  octave_value assign (octave_value::assign_op op,
+		       const octave_value_list& idx,
+		       const octave_value& rhs)
     {
-      val.assign (idx, rhs);
+      val.assign (op, idx, rhs);
       return val;
     }
 
@@ -189,149 +99,12 @@
 
   bool is_constant (void) const { return true; }
 
-  // Size.
-
-  int rows (void) const { return val.rows (); }
-  int columns (void) const { return val.columns (); }
-
-  // Does this constant have a type?  Both of these are provided since
-  // it is sometimes more natural to write is_undefined() instead of
-  // ! is_defined().
-
-  bool is_defined (void) const { return val.is_defined (); }
-  bool is_undefined (void) const { return val.is_undefined (); }
-
-  // Is this constant a particular type, or does it belong to a
-  // particular class of types?
-
-  bool is_real_scalar (void) const { return val.is_real_scalar (); }
-  bool is_real_matrix (void) const { return val.is_real_matrix (); }
-  bool is_complex_scalar (void) const { return val.is_complex_scalar (); }
-  bool is_complex_matrix (void) const { return val.is_complex_matrix (); }
-  bool is_char_matrix (void) const { return val.is_char_matrix (); }
-  bool is_string (void) const { return val.is_string (); }
-  bool is_range (void) const { return val.is_range (); }
-  bool is_map (void) const { return val.is_map (); }
-  bool is_magic_colon (void) const { return val.is_magic_colon (); }
-  bool is_all_va_args (void) const { return val.is_all_va_args (); }
-
-  // Are any or all of the elements in this constant nonzero?
-
-  octave_value all (void) const { return val.all (); }
-  octave_value any (void) const { return val.any (); }
-
-  // Other type stuff.
-
-  bool is_real_type (void) const { return val.is_real_type (); }
-
-  bool is_complex_type (void) const { return val.is_complex_type (); }
-
-  bool is_scalar_type (void) const { return val.is_scalar_type (); }
-  bool is_matrix_type (void) const { return val.is_matrix_type (); }
-
-  bool is_numeric_type (void) const
-    { return val.is_numeric_type (); }
-
-  bool valid_as_scalar_index (void) const
-    { return val.valid_as_scalar_index (); }
-
-  bool valid_as_zero_index (void) const
-    { return val.valid_as_zero_index (); }
-
-  // Does this constant correspond to a truth value?
-
-  bool is_true (void) const { return val.is_true (); }
-
-  // Is at least one of the dimensions of this constant zero?
-
-  bool is_empty (void) const
-    { return val.is_empty (); }
-
-  // Are the dimensions of this constant zero by zero?
-
-  bool is_zero_by_zero (void) const
-    { return val.is_zero_by_zero (); }
-
-  // Values.
-
-  double double_value (bool frc_str_conv = false) const
-    { return val.double_value (frc_str_conv); }
-
-  Matrix matrix_value (bool frc_str_conv = false) const
-    { return val.matrix_value (frc_str_conv); }
-
-  Complex complex_value (bool frc_str_conv = false) const
-    { return val.complex_value (frc_str_conv); }
-
-  ComplexMatrix complex_matrix_value (bool frc_str_conv = false) const
-    { return val.complex_matrix_value (frc_str_conv); }
-
-  charMatrix char_matrix_value (bool frc_str_conv = false) const
-    { return val.char_matrix_value (frc_str_conv); }
-
-  charMatrix all_strings (void) const
-    { return val.all_strings (); }
-
-  string string_value (void) const
-    { return val.string_value (); }
-
-  Range range_value (void) const
-    { return val.range_value (); }
-
-  Octave_map map_value (void) const;
-
-  octave_value lookup_map_element (const string& ref,
-				   bool insert = false,
-				   bool silent = false);
-
-  octave_value lookup_map_element (SLList<string>& list,
-				   bool insert = false,
-				   bool silent = false);
-
-  ColumnVector vector_value (bool /* frc_str_conv */ = false,
-			     bool /* frc_vec_conv */ = false) const 
-    { return val.vector_value (); }
-
-  ComplexColumnVector
-  complex_vector_value (bool /* frc_str_conv */ = false,
-			bool /* frc_vec_conv */ = false) const
-    { return val.complex_vector_value (); }
-
-  // Binary and unary operations.
-
-  friend octave_value do_binary_op (octave_value& a, octave_value& b,
-				    tree_expression::type t);
-
-  friend octave_value do_unary_op (octave_value& a,
-				   tree_expression::type t);
-
-  // Conversions.  These should probably be private.  If a user of this
-  // class wants a certain kind of constant, he should simply ask for
-  // it, and we should convert it if possible.
-
-  octave_value convert_to_str (void) const
-    { return val.convert_to_str (); }
-
-  void convert_to_row_or_column_vector (void)
-    { val.convert_to_row_or_column_vector (); }
-
   void maybe_mutate (void)
     { val.maybe_mutate (); }
 
-  // Increment or decrement this constant.
-
-  void increment (void) { val.increment (); }
-
-  void decrement (void) { val.decrement (); }
-
-  void print (void);
   void print (ostream& os, bool pr_as_read_syntax = false,
 	      bool pr_orig_txt = true);
 
-  void print_with_name (const string& name, bool print_padding = true);
-  void print_with_name (ostream& os, const string& name,
-			bool print_padding = true);
-
   octave_value eval (bool print = false);
 
   octave_value_list eval (bool, int, const octave_value_list&);
@@ -339,14 +112,14 @@
   // Store the original text corresponding to this constant for later
   // pretty printing.
 
-  void stash_original_text (const string& s);
+  void stash_original_text (const string& s)
+    { orig_text = s; }
 
-  string original_text (void) const;
+  string original_text (void) const
+    { return orig_text; }
 
   void accept (tree_walker& tw);
 
-  string type_name (void) const { return val.type_name (); }
-
 private:
 
   // For custom memory management.
--- a/src/pt-exp.cc
+++ b/src/pt-exp.cc
@@ -46,6 +46,7 @@
 #include "pt-pr-code.h"
 #include "pt-walk.h"
 #include "utils.h"
+#include "variables.h"
 
 // Nonzero means we're returning from a function.
 extern int returning;
@@ -335,90 +336,9 @@
 	    eval_error ();
 	  else if (b.is_defined ())
 	    {
-	      octave_value::binary_op op = octave_value::unknown_binary_op;
-
-	      switch (etype)
-		{
-		case add:
-		  op = octave_value::add;
-		  break;
-
-		case subtract:
-		  op = octave_value::sub;
-		  break;
-
-		case multiply:
-		  op = octave_value::mul;
-		  break;
-
-		case el_mul:
-		  op = octave_value::el_mul;
-		  break;
-
-		case divide:
-		  op = octave_value::div;
-		  break;
-
-		case el_div:
-		  op = octave_value::el_div;
-		  break;
-
-		case leftdiv:
-		  op = octave_value::ldiv;
-		  break;
-
-		case el_leftdiv:
-		  op = octave_value::el_ldiv;
-		  break;
-
-		case power:
-		  op = octave_value::pow;
-		  break;
+	      retval = ::do_binary_op (etype, a, b);
 
-		case elem_pow:
-		  op = octave_value::el_pow;
-		  break;
-
-		case cmp_lt:
-		  op = octave_value::lt;
-		  break;
-
-		case cmp_le:
-		  op = octave_value::le;
-		  break;
-
-		case cmp_eq:
-		  op = octave_value::eq;
-		  break;
-
-		case cmp_ge:
-		  op = octave_value::ge;
-		  break;
-
-		case cmp_gt:
-		  op = octave_value::gt;
-		  break;
-
-		case cmp_ne:
-		  op = octave_value::ne;
-		  break;
-
-		case el_and:
-		  op = octave_value::el_and;
-		  break;
-
-		case el_or:
-		  op = octave_value::el_or;
-		  break;
-
-		default:
-		  ::error ("binary operator %d not implemented", etype);
-		  break;
-		}
-
-	      if (! error_state)
-		retval = ::do_binary_op (op, a, b);
-	      else
+	      if (error_state)
 		{
 		  retval = octave_value ();
 		  eval_error ();
@@ -439,86 +359,8 @@
 const char *
 tree_binary_expression::oper (void) const
 {
-  static const char *op;
-  switch (etype)
-    {
-    case add:
-      op = "+";
-      break;
-
-    case subtract:
-      op = "-";
-      break;
-
-    case multiply:
-      op = "*";
-      break;
-
-    case el_mul:
-      op = ".*";
-      break;
-
-    case divide:
-      op = "/";
-      break;
-
-    case el_div:
-      op = "./";
-      break;
-
-    case leftdiv:
-      op = "\\";
-      break;
-
-    case el_leftdiv:
-      op = ".\\";
-      break;
-
-    case power:
-      op = "^";
-      break;
-
-    case elem_pow:
-      op = ".^";
-      break;
-
-    case cmp_lt:
-      op = "<";
-      break;
-
-    case cmp_le:
-      op = "<=";
-      break;
-
-    case cmp_eq:
-      op = "==";
-      break;
-
-    case cmp_ge:
-      op = ">=";
-      break;
-
-    case cmp_gt:
-      op = ">";
-      break;
-
-    case cmp_ne:
-      op = "!=";
-      break;
-
-    case el_and:
-      op = "&";
-      break;
-
-    case el_or:
-      op = "|";
-      break;
-
-    default:
-      op = "<unknown>";
-      break;
-    }
-  return op;
+  // XXX FIXME XXX
+  return octave_value::binary_op_as_string (etype) . c_str ();
 }
 
 void
@@ -630,25 +472,17 @@
 
 tree_simple_assignment_expression::tree_simple_assignment_expression
   (tree_identifier *i, tree_expression *r, bool plhs, bool ans_assign,
-   int l, int c)
-    : tree_expression (l, c)
-      {
-	init (plhs, ans_assign);
-	lhs = new tree_indirect_ref (i);
-	rhs = r;
-      }
+   int l, int c, octave_value::assign_op t)
+    : tree_expression (l, c), lhs_idx_expr (0),
+      lhs (new tree_indirect_ref (i)), index (0), rhs (r),
+      preserve (plhs), ans_ass (ans_assign), etype (t) { }
 
 tree_simple_assignment_expression::tree_simple_assignment_expression
   (tree_index_expression *idx_expr, tree_expression *r, bool plhs,
-   bool ans_assign, int l, int c)
-    : tree_expression (l, c)
-      {
-	init (plhs, ans_assign);
-	lhs_idx_expr = idx_expr; // cache this -- we may need to delete it.
-	lhs = idx_expr->ident ();
-	index = idx_expr->arg_list ();
-	rhs = r;
-      }
+   bool ans_assign, int l, int c, octave_value::assign_op t)
+    : tree_expression (l, c), lhs_idx_expr (idx_expr),
+      lhs (idx_expr->ident ()), index (idx_expr->arg_list ()), rhs (r),
+      preserve (plhs), ans_ass (ans_assign), etype (t) { }
 
 tree_simple_assignment_expression::~tree_simple_assignment_expression (void)
 {
@@ -681,8 +515,6 @@
 octave_value
 tree_simple_assignment_expression::eval (bool print)
 {
-  assert (etype == tree_expression::assignment);
-
   octave_value retval;
 
   octave_value lhs_val;
@@ -725,7 +557,7 @@
 
 		      if (nargin > 0)
 			{
-			  ult.assign (args, rhs_val);
+			  ult.assign (etype, args, rhs_val);
 
 			  if (error_state)
 			    eval_error ();
@@ -742,7 +574,7 @@
 		}
 	      else
 		{
-		  ult.assign (rhs_val);
+		  ult.assign (etype, rhs_val);
 
 		  lhs_val = ult.value ();
 
@@ -776,6 +608,12 @@
     }
 }
 
+const char *
+tree_simple_assignment_expression::oper (void) const
+{
+  return octave_value::assign_op_as_string (etype) . c_str ();
+}
+
 void
 tree_simple_assignment_expression::accept (tree_walker& tw)
 {
--- a/src/pt-exp.h
+++ b/src/pt-exp.h
@@ -36,6 +36,10 @@
 
 class tree_walker;
 
+class octave_value;
+class octave_value_list;
+class octave_variable_reference;
+
 #include "pt-exp-base.h"
 
 // Prefix expressions.
@@ -179,34 +183,15 @@
 {
 public:
 
-  enum type
-    {
-      unknown,
-      add,
-      subtract,
-      multiply,
-      el_mul,
-      divide,
-      el_div,
-      leftdiv,
-      el_leftdiv,
-      power,
-      elem_pow,
-      cmp_lt,
-      cmp_le,
-      cmp_eq,
-      cmp_ge,
-      cmp_gt,
-      cmp_ne,
-      el_and,
-      el_or
-    };
-
-  tree_binary_expression (int l = -1, int c = -1, type t = unknown)
+  tree_binary_expression (int l = -1, int c = -1,
+			  octave_value::binary_op t
+			    = octave_value::unknown_binary_op)
     : tree_expression (l, c), op_lhs (0), op_rhs (0), etype (t) { }
 
   tree_binary_expression (tree_expression *a, tree_expression *b,
-			  int l = -1, int c = -1, type t = unknown)
+			  int l = -1, int c = -1,
+			  octave_value::binary_op t
+			    = octave_value::unknown_binary_op)
     : tree_expression (l, c), op_lhs (a), op_rhs (b), etype (t) { }
 
   ~tree_binary_expression (void)
@@ -235,7 +220,7 @@
 private:
 
   // The type of the expression.
-  type etype;
+  octave_value::binary_op etype;
 };
 
 // Boolean expressions.
@@ -252,7 +237,7 @@
       bool_or
     };
 
-  tree_boolean_expression (int l = -1, int c = -1, type t)
+  tree_boolean_expression (int l = -1, int c = -1, type t = unknown)
     : tree_binary_expression (l, c), etype (t) { }
 
   tree_boolean_expression (tree_expression *a, tree_expression *b,
@@ -278,35 +263,28 @@
 {
 public:
 
-  tree_simple_assignment_expression (bool plhs = false,
-				     bool ans_assign = false,
-				     int l = -1, int c = -1)
-    : tree_expression (l, c)
-      { init (plhs, ans_assign); }
+  tree_simple_assignment_expression
+    (bool plhs = false, bool ans_assign = false, int l = -1, int c = -1,
+     octave_value::assign_op t = octave_value::asn_eq)
+    : tree_expression (l, c), lhs_idx_expr (0), lhs (0), index (0),
+      rhs (0), preserve (plhs), ans_ass (ans_assign), etype (t) { }
 
-  tree_simple_assignment_expression (tree_identifier *i,
-				     tree_expression *r,
-				     bool plhs = false,
-				     bool ans_assign = false,
-				     int l = -1, int c = -1);
+  tree_simple_assignment_expression
+    (tree_identifier *i, tree_expression *r, bool plhs = false,
+     bool ans_assign = false, int l = -1, int c = -1,
+     octave_value::assign_op t = octave_value::asn_eq);
 
-  tree_simple_assignment_expression (tree_indirect_ref *i,
-				     tree_expression *r,
-				     bool plhs = false,
-				     bool ans_assign = false,
-				     int l = -1, int c = -1)
-    : tree_expression (l, c)
-      {
-	init (plhs, ans_assign);
-	lhs = i;
-	rhs = r;
-      }
+  tree_simple_assignment_expression
+    (tree_indirect_ref *i, tree_expression *r, bool plhs = false,
+     bool ans_assign = false, int l = -1, int c = -1,
+     octave_value::assign_op t = octave_value::asn_eq)
+    : tree_expression (l, c), lhs_idx_expr (0), lhs (i), index (0),
+      rhs (r), preserve (plhs), ans_ass (ans_assign), etype (t) { }
 
-  tree_simple_assignment_expression (tree_index_expression *idx_expr,
-				     tree_expression *r,
-				     bool plhs = false,
-				     bool ans_assign = false,
-				     int l = -1, int c = -1);
+  tree_simple_assignment_expression
+    (tree_index_expression *idx_expr, tree_expression *r,
+     bool plhs = false, bool ans_assign = false, int l = -1, int c = -1,
+     octave_value::assign_op t = octave_value::asn_eq);
 
   ~tree_simple_assignment_expression (void);
 
@@ -324,6 +302,8 @@
 
   void eval_error (void);
 
+  const char *oper (void) const;
+
   tree_indirect_ref *left_hand_side (void) { return lhs; }
 
   tree_argument_list *lhs_index (void) { return index; }
@@ -334,6 +314,13 @@
 
 private:
 
+  void do_assign (octave_variable_reference& ult,
+		  const octave_value_list& args,
+		  const octave_value& rhs_val);
+
+  void do_assign (octave_variable_reference& ult,
+		  const octave_value& rhs_val);
+
   // The left hand side of the assignment, as an index expression.  If
   // the assignment is constructed from an index expression, the index
   // expression is split into the its components in the constructor.
@@ -355,16 +342,8 @@
   // True if this is an assignment to the built-in variable ans.
   bool ans_ass;
 
-  void init (bool plhs, bool ans_assign)
-    {
-      etype = tree_expression::assignment;
-      lhs_idx_expr = 0;
-      lhs = 0;
-      index = 0;
-      rhs = 0;
-      preserve = plhs;
-      ans_ass = ans_assign;
-    }
+  // The type of the expression.
+  octave_value::assign_op etype;
 };
 
 // Colon expressions.
--- a/src/pt-fcn.h
+++ b/src/pt-fcn.h
@@ -33,6 +33,7 @@
 
 #include <string>
 
+class symbol_table;
 class tree_parameter_list;
 class tree_statement_list;
 class tree_va_return_list;
@@ -40,7 +41,6 @@
 class tree_walker;
 
 #include "oct-obj.h"
-#include "symtab.h"
 #include "pt-fvc.h"
 
 // User defined functions.
@@ -108,7 +108,8 @@
 
   octave_value eval (bool print = false);
 
-  octave_value_list eval (bool print, int nargout, const octave_value_list& args);
+  octave_value_list eval (bool print, int nargout,
+			  const octave_value_list& args);
 
   void traceback_error (void);
 
--- a/src/pt-fvc-base.cc
+++ b/src/pt-fvc-base.cc
@@ -47,18 +47,6 @@
   return retval;
 }
 
-void
-tree_fvc::increment (void)
-{
-  panic_impossible ();
-}
-
-void
-tree_fvc::decrement (void)
-{
-  panic_impossible ();
-}
-
 time_t
 tree_fvc::time_parsed (void)
 {
--- a/src/pt-fvc-base.h
+++ b/src/pt-fvc-base.h
@@ -54,10 +54,6 @@
 
   virtual string name (void) const;
 
-  virtual void increment (void);
-
-  virtual void decrement (void);
-
   virtual string fcn_file_name (void)
     { return string (); }
 
--- a/src/pt-fvc.cc
+++ b/src/pt-fvc.cc
@@ -124,7 +124,7 @@
 }
 
 octave_value
-tree_identifier::assign (const octave_value& rhs)
+tree_identifier::assign (octave_value::assign_op op, const octave_value& rhs)
 {
   octave_value retval;
 
@@ -143,6 +143,8 @@
 	  sym->clear ();
 	}
 
+      // XXX FIXME XXX -- make this work for ops other than `='.
+
       tree_constant *tmp = new tree_constant (rhs);
 
       if (sym->define (tmp))
@@ -155,7 +157,8 @@
 }
 
 octave_value
-tree_identifier::assign (const octave_value_list& args,
+tree_identifier::assign (octave_value::assign_op op,
+			 const octave_value_list& args,
 			 const octave_value& rhs)
 {
   octave_value retval;
@@ -178,7 +181,7 @@
       if (sym->is_variable () && sym->is_defined ())
 	{
 	  tree_constant *tmp = static_cast<tree_constant *> (sym->def ());
-	  retval = tmp->assign (args, rhs);
+	  retval = tmp->assign (op, args, rhs);
 	}
       else
 	{
@@ -192,7 +195,7 @@
 	  else
 	    {
 	      tree_constant *tmp = new tree_constant ();
-	      retval = tmp->assign (args, rhs);
+	      retval = tmp->assign (op, args, rhs);
 	      if (retval.is_defined ())
 		sym->define (tmp);
 	    }
@@ -214,16 +217,11 @@
   if (sym)
     {
       if (sym->is_read_only ())
-	{
-	  ::error ("can't redefined read-only variable `%s'",
-		   name ().c_str ());
-	}
+	::error ("can't redefined read-only variable `%s'", name ().c_str ());
+      else if (sym->is_defined () && sym->is_variable ())
+	reference () . increment ();
       else
-	{
-	  tree_fvc *tmp = sym->def ();
-	  if (tmp)
-	    tmp->increment ();
-	}
+	::error ("can only increment variables");
     }
 }
 
@@ -233,16 +231,11 @@
   if (sym)
     {
       if (sym->is_read_only ())
-	{
-	  ::error ("can't redefined read-only variable `%s'",
-		   name ().c_str ());
-	}
+	::error ("can't redefined read-only variable `%s'", name ().c_str ());
+      else if (sym->is_defined () && sym->is_variable ())
+	reference () . decrement ();
       else
-	{
-	  tree_fvc *tmp = sym->def ();
-	  if (tmp)
-	    tmp->decrement ();
-	}
+	::error ("can only decrement variables");
     }
 }
 
--- a/src/pt-fvc.h
+++ b/src/pt-fvc.h
@@ -29,6 +29,8 @@
 
 class ostream;
 
+#include <string>
+
 #include <SLList.h>
 
 class symbol_record;
@@ -68,8 +70,12 @@
 
   void document (const string& s);
 
-  octave_value assign (const octave_value& t);
-  octave_value assign (const octave_value_list& args, const octave_value& t);
+  octave_value assign (octave_value::assign_op op,
+		       const octave_value& t);
+
+  octave_value assign (octave_value::assign_op op,
+		       const octave_value_list& args,
+		       const octave_value& t);
 
   bool is_defined (void);