changeset 578:d169be9237fb

[project @ 1994-08-03 20:06:54 by jwe]
author jwe
date Wed, 03 Aug 1994 20:07:26 +0000
parents 91e2164fb1b2
children 606938d43402
files src/Makefile.in src/arith-ops.cc src/arith-ops.h src/defun-int.h src/lex.l src/octave.cc src/parse.y src/pt-base.h src/pt-cmd.cc src/pt-cmd.h src/pt-const.h src/pt-exp-base.cc src/pt-exp-base.h src/pt-plot.cc src/pt-plot.h src/tc-rep.cc src/tc-rep.h src/toplev.h src/utils.cc src/utils.h
diffstat 20 files changed, 1772 insertions(+), 2860 deletions(-) [+]
line wrap: on
line diff
--- a/src/Makefile.in	Wed Aug 03 20:06:54 1994 +0000
+++ b/src/Makefile.in	Wed Aug 03 20:07:26 1994 +0000
@@ -58,9 +58,9 @@
 	missing-math.h octave.h octave-hist.h \
 	oct-obj.h pager.h parse.h pr-output.h procstream.h \
 	sighandlers.h statdefs.h symtab.h sysdep.h token.h tree.h \
-	tree-base.h tree-cmd.h tree-const.h tree-expr.h tree-plot.h \
-	tc-rep.h unwind-prot.h user-prefs.h utils.h variables.h \
-	version.h xdiv.h xpow.h SLStack.h Stack.h
+	tree-base.h tree-cmd.h tree-const.h tree-expr.h tree-misc.h \
+	tree-plot.h tc-rep.h unwind-prot.h user-prefs.h utils.h \
+	variables.h version.h xdiv.h xpow.h SLStack.h Stack.h
 
 SOURCES = arith-ops.cc data.cc dirfns.cc dynamic-ld.cc \
 	error.cc file-io.cc fnmatch.c getopt.c getopt1.c gripes.cc \
@@ -68,9 +68,9 @@
 	oct-obj.cc octave-hist.cc pager.cc parse.y pr-output.cc \
 	procstream.cc sighandlers.cc strcasecmp.c strncase.c \
 	symtab.cc sysdep.cc tc-inlines.cc tc-rep.cc timefns.cc \
-	token.cc tree-cmd.cc tree-const.cc tree-expr.cc tree-plot.cc \
-	unwind-prot.cc user-prefs.cc utils.cc variables.cc xdiv.cc \
-	xpow.cc SLStack.cc \
+	token.cc tree-cmd.cc tree-const.cc tree-expr.cc tree-misc.cc \
+	tree-plot.cc unwind-prot.cc user-prefs.cc utils.cc \
+	variables.cc xdiv.cc xpow.cc SLStack.cc \
 	$(DLD_SRC)
 
 # Ugh.
@@ -95,8 +95,8 @@
 	oct-obj.o pager.o parse.o pr-output.o procstream.o sighandlers.o \
 	strcasecmp.o strncase.o symtab.o sysdep.o tc-rep.o timefns.o \
 	token.o tree-cmd.o tree-const.o tree-expr.o tree-plot.o \
-	unwind-prot.o user-prefs.o utils.o variables.o xdiv.o xpow.o \
-	SLStack.o \
+	tree-misc.o unwind-prot.o user-prefs.o utils.o variables.o \
+	xdiv.o xpow.o SLStack.o \
 	@DYNAMIC_LD_OBJ@
 
 OCTAVE_LIBS = @LIBOCTDLD@ ../liboctave.a ../libcruft.a ../libinfo.a \
--- a/src/arith-ops.cc	Wed Aug 03 20:06:54 1994 +0000
+++ b/src/arith-ops.cc	Wed Aug 03 20:07:26 1994 +0000
@@ -800,20 +800,20 @@
  */
 
 tree_constant
-do_unary_op (double d, tree::expression_type t)
+do_unary_op (double d, tree_expression::type t)
 {
   double result = 0.0;
 
   switch (t)
     {
-    case tree::not:
+    case tree_expression::not:
       result = (! d);
       break;
-    case tree::uminus:
+    case tree_expression::uminus:
       result = -d;
       break;
-    case tree::hermitian:
-    case tree::transpose:
+    case tree_expression::hermitian:
+    case tree_expression::transpose:
       result = d;
       break;
     default:
@@ -825,20 +825,20 @@
 }
 
 tree_constant
-do_unary_op (const Matrix& a, tree::expression_type t)
+do_unary_op (const Matrix& a, tree_expression::type t)
 {
   Matrix result;
 
   switch (t)
     {
-    case tree::not:
+    case tree_expression::not:
       result = (! a);
       break;
-    case tree::uminus:
+    case tree_expression::uminus:
       result = -a;
       break;
-    case tree::hermitian:
-    case tree::transpose:
+    case tree_expression::hermitian:
+    case tree_expression::transpose:
       result = a.transpose ();
       break;
     default:
@@ -850,22 +850,22 @@
 }
 
 tree_constant
-do_unary_op (const Complex& c, tree::expression_type t)
+do_unary_op (const Complex& c, tree_expression::type t)
 {
   Complex result = 0.0;
 
   switch (t)
     {
-    case tree::not:
+    case tree_expression::not:
       result = (c == 0.0);
       break;
-    case tree::uminus:
+    case tree_expression::uminus:
       result = -c;
       break;
-    case tree::hermitian:
+    case tree_expression::hermitian:
       result = conj (c);
       break;
-    case tree::transpose:
+    case tree_expression::transpose:
       result = c;
       break;
     default:
@@ -877,22 +877,22 @@
 }
 
 tree_constant
-do_unary_op (const ComplexMatrix& a, tree::expression_type t)
+do_unary_op (const ComplexMatrix& a, tree_expression::type t)
 {
   ComplexMatrix result;
 
   switch (t)
     {
-    case tree::not:
+    case tree_expression::not:
       result = (! a);
       break;
-    case tree::uminus:
+    case tree_expression::uminus:
       result = -a;
       break;
-    case tree::hermitian:
+    case tree_expression::hermitian:
       result = a.hermitian ();
       break;
-    case tree::transpose:
+    case tree_expression::transpose:
       result = a.transpose ();
       break;
     default:
@@ -921,60 +921,60 @@
 
 /* 1 */
 tree_constant
-do_binary_op (double a, double b, tree::expression_type t)
+do_binary_op (double a, double b, tree_expression::type t)
 {
   double result = 0.0;
 
   switch (t)
     {
-    case tree::add:
+    case tree_expression::add:
       result = a + b;
       break;
-    case tree::subtract:
+    case tree_expression::subtract:
       result = a - b;
       break;
-    case tree::multiply:
-    case tree::el_mul:
+    case tree_expression::multiply:
+    case tree_expression::el_mul:
       result = a * b;
       break;
-    case tree::divide:
-    case tree::el_div:
+    case tree_expression::divide:
+    case tree_expression::el_div:
       if (b == 0.0)
 	DIVIDE_BY_ZERO_ERROR;
       result = a / b;
       break;
-    case tree::leftdiv:
-    case tree::el_leftdiv:
+    case tree_expression::leftdiv:
+    case tree_expression::el_leftdiv:
       if (a == 0.0)
 	DIVIDE_BY_ZERO_ERROR;
       result = b / a;
       break;
-    case tree::power:
-    case tree::elem_pow:
+    case tree_expression::power:
+    case tree_expression::elem_pow:
       return xpow (a, b);
       break;
-    case tree::cmp_lt:
+    case tree_expression::cmp_lt:
       result = a < b;
       break;
-    case tree::cmp_le:
+    case tree_expression::cmp_le:
       result = a <= b;
       break;
-    case tree::cmp_eq:
+    case tree_expression::cmp_eq:
       result = a == b;
       break;
-    case tree::cmp_ge:
+    case tree_expression::cmp_ge:
       result = a >= b;
       break;
-    case tree::cmp_gt:
+    case tree_expression::cmp_gt:
       result = a > b;
       break;
-    case tree::cmp_ne:
+    case tree_expression::cmp_ne:
       result = a != b;
       break;
-    case tree::and:
+    case tree_expression::and:
       result = (a && b);
       break;
-    case tree::or:
+    case tree_expression::or:
       result = (a || b);
       break;
     default:
@@ -990,62 +990,62 @@
 
 /* 2 */
 tree_constant
-do_binary_op (double a, const Matrix& b, tree::expression_type t)
+do_binary_op (double a, const Matrix& b, tree_expression::type t)
 {
   Matrix result;
 
   switch (t)
     {
-    case tree::add:
+    case tree_expression::add:
       result = a + b;
       break;
-    case tree::subtract:
+    case tree_expression::subtract:
       result = a - b;
       break;
-    case tree::el_leftdiv:
-    case tree::leftdiv:
+    case tree_expression::el_leftdiv:
+    case tree_expression::leftdiv:
       if (a == 0.0)
 	DIVIDE_BY_ZERO_ERROR;
       a = 1.0 / a;
 // fall through...
-    case tree::multiply:
-    case tree::el_mul:
+    case tree_expression::multiply:
+    case tree_expression::el_mul:
       result = a * b;
       break;
-    case tree::el_div:
+    case tree_expression::el_div:
       return x_el_div (a, b);
       break;
-    case tree::divide:
+    case tree_expression::divide:
       gripe_nonconformant (1, 1, b.rows (), b.columns ());
       break;
-    case tree::power:
+    case tree_expression::power:
       return xpow (a, b);
       break;
-    case tree::elem_pow:
+    case tree_expression::elem_pow:
       return elem_xpow (a, b);
       break;
-    case tree::cmp_lt:
+    case tree_expression::cmp_lt:
       result = mx_stupid_bool_op (Matrix_LT, a, b);
       break;
-    case tree::cmp_le:
+    case tree_expression::cmp_le:
       result = mx_stupid_bool_op (Matrix_LE, a, b);
       break;
-    case tree::cmp_eq:
+    case tree_expression::cmp_eq:
       result = mx_stupid_bool_op (Matrix_EQ, a, b);
       break;
-    case tree::cmp_ge:
+    case tree_expression::cmp_ge:
       result = mx_stupid_bool_op (Matrix_GE, a, b);
       break;
-    case tree::cmp_gt:
+    case tree_expression::cmp_gt:
       result = mx_stupid_bool_op (Matrix_GT, a, b);
       break;
-    case tree::cmp_ne:
+    case tree_expression::cmp_ne:
       result = mx_stupid_bool_op (Matrix_NE, a, b);
       break;
-    case tree::and:
+    case tree_expression::and:
       result = mx_stupid_bool_op (Matrix_AND, a, b);
       break;
-    case tree::or:
+    case tree_expression::or:
       result = mx_stupid_bool_op (Matrix_OR, a, b);
       break;
     default:
@@ -1061,7 +1061,7 @@
 
 /* 3 */
 tree_constant
-do_binary_op (double a, const Complex& b, tree::expression_type t)
+do_binary_op (double a, const Complex& b, tree_expression::type t)
 {
   enum RT { RT_unknown, RT_real, RT_complex };
   RT result_type = RT_unknown;
@@ -1071,66 +1071,66 @@
 
   switch (t)
     {
-    case tree::add:
+    case tree_expression::add:
       result_type = RT_complex;
       complex_result = a + b;
       break;
-    case tree::subtract:
+    case tree_expression::subtract:
       result_type = RT_complex;
       complex_result = a - b;
       break;
-    case tree::multiply:
-    case tree::el_mul:
+    case tree_expression::multiply:
+    case tree_expression::el_mul:
       result_type = RT_complex;
       complex_result = a * b;
       break;
-    case tree::divide:
-    case tree::el_div:
+    case tree_expression::divide:
+    case tree_expression::el_div:
       result_type = RT_complex;
       if (b == 0.0)
 	DIVIDE_BY_ZERO_ERROR;
       complex_result = a / b;
       break;
-    case tree::leftdiv:
-    case tree::el_leftdiv:
+    case tree_expression::leftdiv:
+    case tree_expression::el_leftdiv:
       result_type = RT_complex;
       if (a == 0.0)
 	DIVIDE_BY_ZERO_ERROR;
       complex_result = b / a;
       break;
-    case tree::power:
-    case tree::elem_pow:
+    case tree_expression::power:
+    case tree_expression::elem_pow:
       return xpow (a, b);
       break;
-    case tree::cmp_lt:
+    case tree_expression::cmp_lt:
       result_type = RT_real;
       result = a < real (b);
       break;
-    case tree::cmp_le:
+    case tree_expression::cmp_le:
       result_type = RT_real;
       result = a <= real (b);
       break;
-    case tree::cmp_eq:
+    case tree_expression::cmp_eq:
       result_type = RT_real;
       result = a == b;
       break;
-    case tree::cmp_ge:
+    case tree_expression::cmp_ge:
       result_type = RT_real;
       result = a >= real (b);
       break;
-    case tree::cmp_gt:
+    case tree_expression::cmp_gt:
       result_type = RT_real;
       result = a > real (b);
       break;
-    case tree::cmp_ne:
+    case tree_expression::cmp_ne:
       result_type = RT_real;
       result = a != b;
       break;
-    case tree::and:
+    case tree_expression::and:
       result_type = RT_real;
       result = (a && (b != 0.0));
       break;
-    case tree::or:
+    case tree_expression::or:
       result_type = RT_real;
       result = (a || (b != 0.0));
       break;
@@ -1152,7 +1152,7 @@
 
 /* 4 */
 tree_constant
-do_binary_op (double a, const ComplexMatrix& b, tree::expression_type t)
+do_binary_op (double a, const ComplexMatrix& b, tree_expression::type t)
 {
   enum RT { RT_unknown, RT_real, RT_complex };
   RT result_type = RT_unknown;
@@ -1162,66 +1162,66 @@
 
   switch (t)
     {
-    case tree::add:
+    case tree_expression::add:
       result_type = RT_complex;
       complex_result = a + b;
       break;
-    case tree::subtract:
+    case tree_expression::subtract:
       result_type = RT_complex;
       complex_result = a - b;
       break;
-    case tree::el_leftdiv:
-    case tree::leftdiv:
+    case tree_expression::el_leftdiv:
+    case tree_expression::leftdiv:
       if (a == 0.0)
 	DIVIDE_BY_ZERO_ERROR;
       a = 1.0 / a;
 // fall through...
-    case tree::multiply:
-    case tree::el_mul:
+    case tree_expression::multiply:
+    case tree_expression::el_mul:
       result_type = RT_complex;
       complex_result = a * b;
       break;
-    case tree::el_div:
+    case tree_expression::el_div:
       return x_el_div (a, b);
       break;
-    case tree::divide:
+    case tree_expression::divide:
       gripe_nonconformant (1, 1, b.rows (), b.columns ());
       break;
-    case tree::power:
+    case tree_expression::power:
       return xpow (a, b);
       break;
-    case tree::elem_pow:
+    case tree_expression::elem_pow:
       return elem_xpow (a, b);
       break;
-    case tree::cmp_lt:
+    case tree_expression::cmp_lt:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_LT, a, b);
       break;
-    case tree::cmp_le:
+    case tree_expression::cmp_le:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_LE, a, b);
       break;
-    case tree::cmp_eq:
+    case tree_expression::cmp_eq:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_EQ, a, b);
       break;
-    case tree::cmp_ge:
+    case tree_expression::cmp_ge:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_GE, a, b);
       break;
-    case tree::cmp_gt:
+    case tree_expression::cmp_gt:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_GT, a, b);
       break;
-    case tree::cmp_ne:
+    case tree_expression::cmp_ne:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_NE, a, b);
       break;
-    case tree::and:
+    case tree_expression::and:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_AND, a, b);
       break;
-    case tree::or:
+    case tree_expression::or:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_OR, a, b);
       break;
@@ -1243,60 +1243,60 @@
 
 /* 5 */
 tree_constant
-do_binary_op (const Matrix& a, double b, tree::expression_type t)
+do_binary_op (const Matrix& a, double b, tree_expression::type t)
 {
   Matrix result;
 
   switch (t)
     {
-    case tree::add:
+    case tree_expression::add:
       result = a + b;
       break;
-    case tree::subtract:
+    case tree_expression::subtract:
       result = a - b;
       break;
-    case tree::multiply:
-    case tree::el_mul:
+    case tree_expression::multiply:
+    case tree_expression::el_mul:
       result = a * b;
       break;
-    case tree::divide:
-    case tree::el_div:
+    case tree_expression::divide:
+    case tree_expression::el_div:
       result = a / b;
       break;
-    case tree::el_leftdiv:
+    case tree_expression::el_leftdiv:
       return x_el_div (b, a);
       break;
-    case tree::leftdiv:
+    case tree_expression::leftdiv:
       gripe_nonconformant (a.rows (), a.columns (), 1, 1);
       break;
-    case tree::power:
+    case tree_expression::power:
       return xpow (a, b);
       break;
-    case tree::elem_pow:
+    case tree_expression::elem_pow:
       return elem_xpow (a, b);
       break;
-    case tree::cmp_lt:
+    case tree_expression::cmp_lt:
       result = mx_stupid_bool_op (Matrix_LT, a, b);
       break;
-    case tree::cmp_le:
+    case tree_expression::cmp_le:
       result = mx_stupid_bool_op (Matrix_LE, a, b);
       break;
-    case tree::cmp_eq:
+    case tree_expression::cmp_eq:
       result = mx_stupid_bool_op (Matrix_EQ, a, b);
       break;
-    case tree::cmp_ge:
+    case tree_expression::cmp_ge:
       result = mx_stupid_bool_op (Matrix_GE, a, b);
       break;
-    case tree::cmp_gt:
+    case tree_expression::cmp_gt:
       result = mx_stupid_bool_op (Matrix_GT, a, b);
       break;
-    case tree::cmp_ne:
+    case tree_expression::cmp_ne:
       result = mx_stupid_bool_op (Matrix_NE, a, b);
       break;
-    case tree::and:
+    case tree_expression::and:
       result = mx_stupid_bool_op (Matrix_AND, a, b);
       break;
-    case tree::or:
+    case tree_expression::or:
       result = mx_stupid_bool_op (Matrix_OR, a, b);
       break;
     default:
@@ -1312,78 +1312,78 @@
 
 /* 6 */
 tree_constant
-do_binary_op (const Matrix& a, const Matrix& b, tree::expression_type t)
+do_binary_op (const Matrix& a, const Matrix& b, tree_expression::type t)
 {
   Matrix result;
 
   switch (t)
     {
-    case tree::add:
+    case tree_expression::add:
       if (m_add_conform (a, b, 1))
 	result = a + b;
       break;
-    case tree::subtract:
+    case tree_expression::subtract:
       if (m_add_conform (a, b, 1))
 	result = a - b;
       break;
-    case tree::el_mul:
+    case tree_expression::el_mul:
       if (m_add_conform (a, b, 1))
 	result = product (a, b);
       break;
-    case tree::multiply:
+    case tree_expression::multiply:
       if (m_mul_conform (a, b, 1))
 	result = a * b;
       break;
-    case tree::el_div:
+    case tree_expression::el_div:
       if (m_add_conform (a, b, 1))
 	result = quotient (a, b);
       break;
-    case tree::el_leftdiv:
+    case tree_expression::el_leftdiv:
       if (m_add_conform (a, b, 1))
 	result = quotient (b, a);
       break;
-    case tree::leftdiv:
+    case tree_expression::leftdiv:
       return xleftdiv (a, b);
       break;
-    case tree::divide:
+    case tree_expression::divide:
       return xdiv (a, b);
       break;
-    case tree::power:
+    case tree_expression::power:
       error ("can't do A ^ B for A and B both matrices");
       break;
-    case tree::elem_pow:
+    case tree_expression::elem_pow:
       if (m_add_conform (a, b, 1))
 	return elem_xpow (a, b);
       break;
-    case tree::cmp_lt:
+    case tree_expression::cmp_lt:
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_LT, a, b);
       break;
-    case tree::cmp_le:
+    case tree_expression::cmp_le:
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_LE, a, b);
       break;
-    case tree::cmp_eq:
+    case tree_expression::cmp_eq:
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_EQ, a, b);
       break;
-    case tree::cmp_ge:
+    case tree_expression::cmp_ge:
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_GE, a, b);
       break;
-    case tree::cmp_gt:
+    case tree_expression::cmp_gt:
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_GT, a, b);
       break;
-    case tree::cmp_ne:
+    case tree_expression::cmp_ne:
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_NE, a, b);
       break;
-    case tree::and:
+    case tree_expression::and:
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_AND, a, b);
       break;
-    case tree::or:
+    case tree_expression::or:
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_OR, a, b);
       break;
@@ -1400,7 +1400,7 @@
 
 /* 7 */
 tree_constant
-do_binary_op (const Matrix& a, const Complex& b, tree::expression_type t)
+do_binary_op (const Matrix& a, const Complex& b, tree_expression::type t)
 {
   enum RT { RT_unknown, RT_real, RT_complex };
   RT result_type = RT_unknown;
@@ -1410,65 +1410,65 @@
 
   switch (t)
     {
-    case tree::add:
+    case tree_expression::add:
       result_type = RT_complex;
       complex_result = a + b;
       break;
-    case tree::subtract:
+    case tree_expression::subtract:
       result_type = RT_complex;
       complex_result = a - b;
       break;
-    case tree::multiply:
-    case tree::el_mul:
+    case tree_expression::multiply:
+    case tree_expression::el_mul:
       result_type = RT_complex;
       complex_result = a * b;
       break;
-    case tree::divide:
-    case tree::el_div:
+    case tree_expression::divide:
+    case tree_expression::el_div:
       result_type = RT_complex;
       complex_result = a / b;
       break;
-    case tree::el_leftdiv:
+    case tree_expression::el_leftdiv:
       return x_el_div (b, a);
       break;
-    case tree::leftdiv:
+    case tree_expression::leftdiv:
       gripe_nonconformant (a.rows (), a.columns (), 1, 1);
       break;
-    case tree::power:
+    case tree_expression::power:
       return xpow (a, b);
       break;
-    case tree::elem_pow:
+    case tree_expression::elem_pow:
       return elem_xpow (a, b);
       break;
-    case tree::cmp_lt:
+    case tree_expression::cmp_lt:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_LT, a, b);
       break;
-    case tree::cmp_le:
+    case tree_expression::cmp_le:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_LE, a, b);
       break;
-    case tree::cmp_eq:
+    case tree_expression::cmp_eq:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_EQ, a, b);
       break;
-    case tree::cmp_ge:
+    case tree_expression::cmp_ge:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_GE, a, b);
       break;
-    case tree::cmp_gt:
+    case tree_expression::cmp_gt:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_GT, a, b);
       break;
-    case tree::cmp_ne:
+    case tree_expression::cmp_ne:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_NE, a, b);
       break;
-    case tree::and:
+    case tree_expression::and:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_AND, a, b);
       break;
-    case tree::or:
+    case tree_expression::or:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_OR, a, b);
       break;
@@ -1490,7 +1490,7 @@
 
 /* 8 */
 tree_constant
-do_binary_op (const Matrix& a, const ComplexMatrix& b, tree::expression_type t)
+do_binary_op (const Matrix& a, const ComplexMatrix& b, tree_expression::type t)
 {
   enum RT { RT_unknown, RT_real, RT_complex };
   RT result_type = RT_unknown;
@@ -1500,85 +1500,85 @@
 
   switch (t)
     {
-    case tree::add:
+    case tree_expression::add:
       result_type = RT_complex;
       if (m_add_conform (a, b, 1))
 	complex_result = a + b;
       break;
-    case tree::subtract:
+    case tree_expression::subtract:
       result_type = RT_complex;
       if (m_add_conform (a, b, 1))
 	complex_result = a - b;
       break;
-    case tree::el_mul:
+    case tree_expression::el_mul:
       result_type = RT_complex;
       if (m_add_conform (a, b, 1))
 	complex_result = product (a, b);
       break;
-    case tree::multiply:
+    case tree_expression::multiply:
       result_type = RT_complex;
       if (m_mul_conform (a, b, 1))
 	complex_result = a * b;
       break;
-    case tree::el_div:
+    case tree_expression::el_div:
       result_type = RT_complex;
       if (m_add_conform (a, b, 1))
 	complex_result = quotient (a, b);
       break;
-    case tree::el_leftdiv:
+    case tree_expression::el_leftdiv:
       result_type = RT_complex;
       if (m_add_conform (a, b, 1))
 	complex_result = quotient (b, a);
       break;
-    case tree::leftdiv:
+    case tree_expression::leftdiv:
       return xleftdiv (a, b);
       break;
-    case tree::divide:
+    case tree_expression::divide:
       return xdiv (a, b);
       break;
-    case tree::power:
+    case tree_expression::power:
       error ("can't do A ^ B for A and B both matrices");
       break;
-    case tree::elem_pow:
+    case tree_expression::elem_pow:
       if (m_add_conform (a, b, 1))
 	return elem_xpow (a, b);
       break;
-    case tree::cmp_lt:
+    case tree_expression::cmp_lt:
       result_type = RT_real;
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_LT, a, b);
       break;
-    case tree::cmp_le:
+    case tree_expression::cmp_le:
       result_type = RT_real;
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_LE, a, b);
       break;
-    case tree::cmp_eq:
+    case tree_expression::cmp_eq:
       result_type = RT_real;
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_EQ, a, b);
       break;
-    case tree::cmp_ge:
+    case tree_expression::cmp_ge:
       result_type = RT_real;
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_GE, a, b);
       break;
-    case tree::cmp_gt:
+    case tree_expression::cmp_gt:
       result_type = RT_real;
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_GT, a, b);
       break;
-    case tree::cmp_ne:
+    case tree_expression::cmp_ne:
       result_type = RT_real;
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_NE, a, b);
       break;
-    case tree::and:
+    case tree_expression::and:
       result_type = RT_real;
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_AND, a, b);
       break;
-    case tree::or:
+    case tree_expression::or:
       result_type = RT_real;
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_OR, a, b);
@@ -1601,7 +1601,7 @@
 
 /* 9 */
 tree_constant
-do_binary_op (const Complex& a, double b, tree::expression_type t)
+do_binary_op (const Complex& a, double b, tree_expression::type t)
 {
   enum RT { RT_unknown, RT_real, RT_complex };
   RT result_type = RT_unknown;
@@ -1611,66 +1611,66 @@
 
   switch (t)
     {
-    case tree::add:
+    case tree_expression::add:
       result_type = RT_complex;
       complex_result = a + b;
       break;
-    case tree::subtract:
+    case tree_expression::subtract:
       result_type = RT_complex;
       complex_result = a - b;
       break;
-    case tree::multiply:
-    case tree::el_mul:
+    case tree_expression::multiply:
+    case tree_expression::el_mul:
       result_type = RT_complex;
       complex_result = a * b;
       break;
-    case tree::divide:
-    case tree::el_div:
+    case tree_expression::divide:
+    case tree_expression::el_div:
       result_type = RT_complex;
       if (b == 0.0)
 	DIVIDE_BY_ZERO_ERROR;
       complex_result = a / b;
       break;
-    case tree::leftdiv:
-    case tree::el_leftdiv:
+    case tree_expression::leftdiv:
+    case tree_expression::el_leftdiv:
       result_type = RT_complex;
       if (a == 0.0)
 	DIVIDE_BY_ZERO_ERROR;
       complex_result = b / a;
       break;
-    case tree::power:
-    case tree::elem_pow:
+    case tree_expression::power:
+    case tree_expression::elem_pow:
       return xpow (a, b);
       break;
-    case tree::cmp_lt:
+    case tree_expression::cmp_lt:
       result_type = RT_real;
       result = real (a) < b;
       break;
-    case tree::cmp_le:
+    case tree_expression::cmp_le:
       result_type = RT_real;
       result = real (a) <= b;
       break;
-    case tree::cmp_eq:
+    case tree_expression::cmp_eq:
       result_type = RT_real;
       result = a == b;
       break;
-    case tree::cmp_ge:
+    case tree_expression::cmp_ge:
       result_type = RT_real;
       result = real (a) >= b;
       break;
-    case tree::cmp_gt:
+    case tree_expression::cmp_gt:
       result_type = RT_real;
       result = real (a) > b;
       break;
-    case tree::cmp_ne:
+    case tree_expression::cmp_ne:
       result_type = RT_real;
       result = a != b;
       break;
-    case tree::and:
+    case tree_expression::and:
       result_type = RT_real;
       result = ((a != 0.0) && b);
       break;
-    case tree::or:
+    case tree_expression::or:
       result_type = RT_real;
       result = ((a != 0.0) || b);
       break;
@@ -1692,7 +1692,7 @@
 
 /* 10 */
 tree_constant
-do_binary_op (const Complex& a, const Matrix& b, tree::expression_type t)
+do_binary_op (const Complex& a, const Matrix& b, tree_expression::type t)
 {
   enum RT { RT_unknown, RT_real, RT_complex };
   RT result_type = RT_unknown;
@@ -1702,67 +1702,67 @@
 
   switch (t)
     {
-    case tree::add:
+    case tree_expression::add:
       result_type = RT_complex;
       complex_result = a + b;
       break;
-    case tree::subtract:
+    case tree_expression::subtract:
       result_type = RT_complex;
       complex_result = a - b;
       break;
-    case tree::el_leftdiv:
-    case tree::leftdiv:
+    case tree_expression::el_leftdiv:
+    case tree_expression::leftdiv:
       if (a == 0.0)
 	DIVIDE_BY_ZERO_ERROR;
       result_type = RT_complex;
       complex_result = b / a;
       break;
-    case tree::multiply:
-    case tree::el_mul:
+    case tree_expression::multiply:
+    case tree_expression::el_mul:
       result_type = RT_complex;
       complex_result = a * b;
       break;
-    case tree::el_div:
+    case tree_expression::el_div:
       return x_el_div (a, b);
       break;
-    case tree::divide:
+    case tree_expression::divide:
       gripe_nonconformant (1, 1, b.rows (), b.columns ());
       break;
-    case tree::power:
+    case tree_expression::power:
       return xpow (a, b);
       break;
-    case tree::elem_pow:
+    case tree_expression::elem_pow:
       return elem_xpow (a, b);
       break;
-    case tree::cmp_lt:
+    case tree_expression::cmp_lt:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_LT, a, b);
       break;
-    case tree::cmp_le:
+    case tree_expression::cmp_le:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_LE, a, b);
       break;
-    case tree::cmp_eq:
+    case tree_expression::cmp_eq:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_EQ, a, b);
       break;
-    case tree::cmp_ge:
+    case tree_expression::cmp_ge:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_GE, a, b);
       break;
-    case tree::cmp_gt:
+    case tree_expression::cmp_gt:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_GT, a, b);
       break;
-    case tree::cmp_ne:
+    case tree_expression::cmp_ne:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_NE, a, b);
       break;
-    case tree::and:
+    case tree_expression::and:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_AND, a, b);
       break;
-    case tree::or:
+    case tree_expression::or:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_OR, a, b);
       break;
@@ -1784,7 +1784,7 @@
 
 /* 11 */
 tree_constant
-do_binary_op (const Complex& a, const Complex& b, tree::expression_type t)
+do_binary_op (const Complex& a, const Complex& b, tree_expression::type t)
 {
   enum RT { RT_unknown, RT_real, RT_complex };
   RT result_type = RT_unknown;
@@ -1794,66 +1794,66 @@
 
   switch (t)
     {
-    case tree::add:
+    case tree_expression::add:
       result_type = RT_complex;
       complex_result = a + b;
       break;
-    case tree::subtract:
+    case tree_expression::subtract:
       result_type = RT_complex;
       complex_result = a - b;
       break;
-    case tree::multiply:
-    case tree::el_mul:
+    case tree_expression::multiply:
+    case tree_expression::el_mul:
       result_type = RT_complex;
       complex_result = a * b;
       break;
-    case tree::divide:
-    case tree::el_div:
+    case tree_expression::divide:
+    case tree_expression::el_div:
       result_type = RT_complex;
       if (b == 0.0)
 	DIVIDE_BY_ZERO_ERROR;
       complex_result = a / b;
       break;
-    case tree::leftdiv:
-    case tree::el_leftdiv:
+    case tree_expression::leftdiv:
+    case tree_expression::el_leftdiv:
       result_type = RT_complex;
       if (a == 0.0)
 	DIVIDE_BY_ZERO_ERROR;
       complex_result = b / a;
       break;
-    case tree::power:
-    case tree::elem_pow:
+    case tree_expression::power:
+    case tree_expression::elem_pow:
       return xpow (a, b);
       break;
-    case tree::cmp_lt:
+    case tree_expression::cmp_lt:
       result_type = RT_real;
       result = real (a) < real (b);
       break;
-    case tree::cmp_le:
+    case tree_expression::cmp_le:
       result_type = RT_real;
       result = real (a) <= real (b);
       break;
-    case tree::cmp_eq:
+    case tree_expression::cmp_eq:
       result_type = RT_real;
       result = a == b;
       break;
-    case tree::cmp_ge:
+    case tree_expression::cmp_ge:
       result_type = RT_real;
       result = real (a) >= real (b);
       break;
-    case tree::cmp_gt:
+    case tree_expression::cmp_gt:
       result_type = RT_real;
       result = real (a) > real (b);
       break;
-    case tree::cmp_ne:
+    case tree_expression::cmp_ne:
       result_type = RT_real;
       result = a != b;
       break;
-    case tree::and:
+    case tree_expression::and:
       result_type = RT_real;
       result = ((a != 0.0) && (b != 0.0));
       break;
-    case tree::or:
+    case tree_expression::or:
       result_type = RT_real;
       result = ((a != 0.0) || (b != 0.0));
       break;
@@ -1876,7 +1876,7 @@
 /* 12 */
 tree_constant
 do_binary_op (const Complex& a, const ComplexMatrix& b,
-	      tree::expression_type t)
+	      tree_expression::type t)
 {
   enum RT { RT_unknown, RT_real, RT_complex };
   RT result_type = RT_unknown;
@@ -1886,67 +1886,67 @@
 
   switch (t)
     {
-    case tree::add:
+    case tree_expression::add:
       result_type = RT_complex;
       complex_result = a + b;
       break;
-    case tree::subtract:
+    case tree_expression::subtract:
       result_type = RT_complex;
       complex_result = a - b;
       break;
-    case tree::el_leftdiv:
-    case tree::leftdiv:
+    case tree_expression::el_leftdiv:
+    case tree_expression::leftdiv:
       if (a == 0.0)
 	DIVIDE_BY_ZERO_ERROR;
       result_type = RT_complex;
       complex_result = b / a;
       break;
-    case tree::multiply:
-    case tree::el_mul:
+    case tree_expression::multiply:
+    case tree_expression::el_mul:
       result_type = RT_complex;
       complex_result = a * b;
       break;
-    case tree::el_div:
+    case tree_expression::el_div:
       return x_el_div (a, b);
       break;
-    case tree::divide:
+    case tree_expression::divide:
       gripe_nonconformant (1, 1, b.rows (), b.columns ());
       break;
-    case tree::power:
+    case tree_expression::power:
       return xpow (a, b);
       break;
-    case tree::elem_pow:
+    case tree_expression::elem_pow:
       return elem_xpow (a, b);
       break;
-    case tree::cmp_lt:
+    case tree_expression::cmp_lt:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_LT, a, b);
       break;
-    case tree::cmp_le:
+    case tree_expression::cmp_le:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_LE, a, b);
       break;
-    case tree::cmp_eq:
+    case tree_expression::cmp_eq:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_EQ, a, b);
       break;
-    case tree::cmp_ge:
+    case tree_expression::cmp_ge:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_GE, a, b);
       break;
-    case tree::cmp_gt:
+    case tree_expression::cmp_gt:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_GT, a, b);
       break;
-    case tree::cmp_ne:
+    case tree_expression::cmp_ne:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_NE, a, b);
       break;
-    case tree::and:
+    case tree_expression::and:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_AND, a, b);
       break;
-    case tree::or:
+    case tree_expression::or:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_OR, a, b);
       break;
@@ -1968,7 +1968,7 @@
 
 /* 13 */
 tree_constant
-do_binary_op (const ComplexMatrix& a, double b, tree::expression_type t)
+do_binary_op (const ComplexMatrix& a, double b, tree_expression::type t)
 {
   enum RT { RT_unknown, RT_real, RT_complex };
   RT result_type = RT_unknown;
@@ -1978,65 +1978,65 @@
 
   switch (t)
     {
-    case tree::add:
+    case tree_expression::add:
       result_type = RT_complex;
       complex_result = a + b;
       break;
-    case tree::subtract:
+    case tree_expression::subtract:
       result_type = RT_complex;
       complex_result = a - b;
       break;
-    case tree::multiply:
-    case tree::el_mul:
+    case tree_expression::multiply:
+    case tree_expression::el_mul:
       result_type = RT_complex;
       complex_result = a * b;
       break;
-    case tree::divide:
-    case tree::el_div:
+    case tree_expression::divide:
+    case tree_expression::el_div:
       result_type = RT_complex;
       complex_result = a / b;
       break;
-    case tree::el_leftdiv:
+    case tree_expression::el_leftdiv:
       return x_el_div (b, a);
       break;
-    case tree::leftdiv:
+    case tree_expression::leftdiv:
       gripe_nonconformant (a.rows (), a.columns (), 1, 1);
       break;
-    case tree::power:
+    case tree_expression::power:
       return xpow (a, b);
       break;
-    case tree::elem_pow:
+    case tree_expression::elem_pow:
       return elem_xpow (a, b);
       break;
-    case tree::cmp_lt:
+    case tree_expression::cmp_lt:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_LT, a, b);
       break;
-    case tree::cmp_le:
+    case tree_expression::cmp_le:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_LE, a, b);
       break;
-    case tree::cmp_eq:
+    case tree_expression::cmp_eq:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_EQ, a, b);
       break;
-    case tree::cmp_ge:
+    case tree_expression::cmp_ge:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_GE, a, b);
       break;
-    case tree::cmp_gt:
+    case tree_expression::cmp_gt:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_GT, a, b);
       break;
-    case tree::cmp_ne:
+    case tree_expression::cmp_ne:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_NE, a, b);
       break;
-    case tree::and:
+    case tree_expression::and:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_AND, a, b);
       break;
-    case tree::or:
+    case tree_expression::or:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_OR, a, b);
       break;
@@ -2058,7 +2058,7 @@
 
 /* 14 */
 tree_constant
-do_binary_op (const ComplexMatrix& a, const Matrix& b, tree::expression_type t)
+do_binary_op (const ComplexMatrix& a, const Matrix& b, tree_expression::type t)
 {
   enum RT { RT_unknown, RT_real, RT_complex };
   RT result_type = RT_unknown;
@@ -2068,85 +2068,85 @@
 
   switch (t)
     {
-    case tree::add:
+    case tree_expression::add:
       result_type = RT_complex;
       if (m_add_conform (a, b, 1))
 	complex_result = a + b;
       break;
-    case tree::subtract:
+    case tree_expression::subtract:
       result_type = RT_complex;
       if (m_add_conform (a, b, 1))
 	complex_result = a - b;
       break;
-    case tree::el_mul:
+    case tree_expression::el_mul:
       result_type = RT_complex;
       if (m_add_conform (a, b, 1))
 	complex_result = product (a, b);
       break;
-    case tree::multiply:
+    case tree_expression::multiply:
       result_type = RT_complex;
       if (m_mul_conform (a, b, 1))
 	complex_result = a * b;
       break;
-    case tree::el_div:
+    case tree_expression::el_div:
       result_type = RT_complex;
       if (m_add_conform (a, b, 1))
 	complex_result = quotient (a, b);
       break;
-    case tree::el_leftdiv:
+    case tree_expression::el_leftdiv:
       result_type = RT_complex;
       if (m_add_conform (a, b, 1))
 	complex_result = quotient (b, a);
       break;
-    case tree::leftdiv:
+    case tree_expression::leftdiv:
       return xleftdiv (a, b);
       break;
-    case tree::divide:
+    case tree_expression::divide:
       return xdiv (a, b);
       break;
-    case tree::power:
+    case tree_expression::power:
       error ("can't do A ^ B for A and B both matrices");
       break;
-    case tree::elem_pow:
+    case tree_expression::elem_pow:
       if (m_add_conform (a, b, 1))
 	return elem_xpow (a, b);
       break;
-    case tree::cmp_lt:
+    case tree_expression::cmp_lt:
       result_type = RT_real;
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_LT, a, b);
       break;
-    case tree::cmp_le:
+    case tree_expression::cmp_le:
       result_type = RT_real;
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_LE, a, b);
       break;
-    case tree::cmp_eq:
+    case tree_expression::cmp_eq:
       result_type = RT_real;
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_EQ, a, b);
       break;
-    case tree::cmp_ge:
+    case tree_expression::cmp_ge:
       result_type = RT_real;
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_GE, a, b);
       break;
-    case tree::cmp_gt:
+    case tree_expression::cmp_gt:
       result_type = RT_real;
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_GT, a, b);
       break;
-    case tree::cmp_ne:
+    case tree_expression::cmp_ne:
       result_type = RT_real;
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_NE, a, b);
       break;
-    case tree::and:
+    case tree_expression::and:
       result_type = RT_real;
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_AND, a, b);
       break;
-    case tree::or:
+    case tree_expression::or:
       result_type = RT_real;
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_OR, a, b);
@@ -2170,7 +2170,7 @@
 /* 15 */
 tree_constant
 do_binary_op (const ComplexMatrix& a, const Complex& b,
-	      tree::expression_type t)
+	      tree_expression::type t)
 {
   enum RT { RT_unknown, RT_real, RT_complex };
   RT result_type = RT_unknown;
@@ -2180,65 +2180,65 @@
 
   switch (t)
     {
-    case tree::add:
+    case tree_expression::add:
       result_type = RT_complex;
       complex_result = a + b;
       break;
-    case tree::subtract:
+    case tree_expression::subtract:
       result_type = RT_complex;
       complex_result = a - b;
       break;
-    case tree::multiply:
-    case tree::el_mul:
+    case tree_expression::multiply:
+    case tree_expression::el_mul:
       result_type = RT_complex;
       complex_result = a * b;
       break;
-    case tree::divide:
-    case tree::el_div:
+    case tree_expression::divide:
+    case tree_expression::el_div:
       result_type = RT_complex;
       complex_result = a / b;
       break;
-    case tree::el_leftdiv:
+    case tree_expression::el_leftdiv:
       return x_el_div (b, a);
       break;
-    case tree::leftdiv:
+    case tree_expression::leftdiv:
       gripe_nonconformant (a.rows (), a.columns (), 1, 1);
       break;
-    case tree::power:
+    case tree_expression::power:
       return xpow (a, b);
       break;
-    case tree::elem_pow:
+    case tree_expression::elem_pow:
       return elem_xpow (a, b);
       break;
-    case tree::cmp_lt:
+    case tree_expression::cmp_lt:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_LT, a, b);
       break;
-    case tree::cmp_le:
+    case tree_expression::cmp_le:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_LE, a, b);
       break;
-    case tree::cmp_eq:
+    case tree_expression::cmp_eq:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_EQ, a, b);
       break;
-    case tree::cmp_ge:
+    case tree_expression::cmp_ge:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_GE, a, b);
       break;
-    case tree::cmp_gt:
+    case tree_expression::cmp_gt:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_GT, a, b);
       break;
-    case tree::cmp_ne:
+    case tree_expression::cmp_ne:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_NE, a, b);
       break;
-    case tree::and:
+    case tree_expression::and:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_AND, a, b);
       break;
-    case tree::or:
+    case tree_expression::or:
       result_type = RT_real;
       result = mx_stupid_bool_op (Matrix_OR, a, b);
       break;
@@ -2261,7 +2261,7 @@
 /* 16 */
 tree_constant
 do_binary_op (const ComplexMatrix& a, const ComplexMatrix& b,
-	      tree::expression_type t)
+	      tree_expression::type t)
 {
   enum RT { RT_unknown, RT_real, RT_complex };
   RT result_type = RT_unknown;
@@ -2271,85 +2271,85 @@
 
   switch (t)
     {
-    case tree::add:
+    case tree_expression::add:
       result_type = RT_complex;
       if (m_add_conform (a, b, 1))
 	complex_result = a + b;
       break;
-    case tree::subtract:
+    case tree_expression::subtract:
       result_type = RT_complex;
       if (m_add_conform (a, b, 1))
 	complex_result = a - b;
       break;
-    case tree::el_mul:
+    case tree_expression::el_mul:
       result_type = RT_complex;
       if (m_add_conform (a, b, 1))
 	complex_result = product (a, b);
       break;
-    case tree::multiply:
+    case tree_expression::multiply:
       result_type = RT_complex;
       if (m_mul_conform (a, b, 1))
 	complex_result = a * b;
       break;
-    case tree::el_div:
+    case tree_expression::el_div:
       result_type = RT_complex;
       if (m_add_conform (a, b, 1))
 	complex_result = quotient (a, b);
       break;
-    case tree::el_leftdiv:
+    case tree_expression::el_leftdiv:
       result_type = RT_complex;
       if (m_add_conform (a, b, 1))
 	complex_result = quotient (b, a);
       break;
-    case tree::leftdiv:
+    case tree_expression::leftdiv:
       return xleftdiv (a, b);
       break;
-    case tree::divide:
+    case tree_expression::divide:
       return xdiv (a, b);
       break;
-    case tree::power:
+    case tree_expression::power:
       error ("can't do A ^ B for A and B both matrices");
       break;
-    case tree::elem_pow:
+    case tree_expression::elem_pow:
       if (m_add_conform (a, b, 1))
 	return elem_xpow (a, b);
       break;
-    case tree::cmp_lt:
+    case tree_expression::cmp_lt:
       result_type = RT_real;
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_LT, a, b);
       break;
-    case tree::cmp_le:
+    case tree_expression::cmp_le:
       result_type = RT_real;
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_LE, a, b);
       break;
-    case tree::cmp_eq:
+    case tree_expression::cmp_eq:
       result_type = RT_real;
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_EQ, a, b);
       break;
-    case tree::cmp_ge:
+    case tree_expression::cmp_ge:
       result_type = RT_real;
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_GE, a, b);
       break;
-    case tree::cmp_gt:
+    case tree_expression::cmp_gt:
       result_type = RT_real;
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_GT, a, b);
       break;
-    case tree::cmp_ne:
+    case tree_expression::cmp_ne:
       result_type = RT_real;
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_NE, a, b);
       break;
-    case tree::and:
+    case tree_expression::and:
       result_type = RT_real;
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_AND, a, b);
       break;
-    case tree::or:
+    case tree_expression::or:
       result_type = RT_real;
       if (m_add_conform (a, b, 1))
 	result = mx_stupid_bool_op (Matrix_OR, a, b);
--- a/src/arith-ops.h	Wed Aug 03 20:06:54 1994 +0000
+++ b/src/arith-ops.h	Wed Aug 03 20:07:26 1994 +0000
@@ -24,70 +24,70 @@
 #if !defined (octave_arith_ops_h)
 #define octave_arith_ops_h 1
 
-#include "tree-base.h"
+#include "tree-expr.h"
 
 class Complex;
 class Matrix;
 class ComplexMatrix;
 class tree_constant;
 
-extern tree_constant do_unary_op (double d, tree::expression_type t);
+extern tree_constant do_unary_op (double d, tree_expression::type t);
 
-extern tree_constant do_unary_op (const Matrix& a, tree::expression_type t);
+extern tree_constant do_unary_op (const Matrix& a, tree_expression::type t);
 
-extern tree_constant do_unary_op (const Complex& c, tree::expression_type t);
+extern tree_constant do_unary_op (const Complex& c, tree_expression::type t);
 
 extern tree_constant do_unary_op (const ComplexMatrix& a,
-				  tree::expression_type t);
+				  tree_expression::type t);
 
 extern tree_constant do_binary_op (double a, double b,
-				   tree::expression_type t);
+				   tree_expression::type t);
 
 extern tree_constant do_binary_op (double a, const Matrix& b,
-				   tree::expression_type t);
+				   tree_expression::type t);
 
 extern tree_constant do_binary_op (double a, const Complex& b,
-				   tree::expression_type t);
+				   tree_expression::type t);
 
 extern tree_constant do_binary_op (double a, const ComplexMatrix& b,
-				   tree::expression_type t);
+				   tree_expression::type t);
 
 extern tree_constant do_binary_op (const Matrix& a, double b,
-				   tree::expression_type t);
+				   tree_expression::type t);
 
 extern tree_constant do_binary_op (const Matrix& a, const Matrix& b,
-				   tree::expression_type t);
+				   tree_expression::type t);
 
 extern tree_constant do_binary_op (const Matrix& a, const Complex& b,
-				   tree::expression_type t);
+				   tree_expression::type t);
 
 extern tree_constant do_binary_op (const Matrix& a, const ComplexMatrix& b,
-				   tree::expression_type t);
+				   tree_expression::type t);
 
 extern tree_constant do_binary_op (const Complex& a, double b,
-				   tree::expression_type t);
+				   tree_expression::type t);
 
 extern tree_constant do_binary_op (const Complex& a, const Matrix& b,
-				   tree::expression_type t);
+				   tree_expression::type t);
 
 extern tree_constant do_binary_op (const Complex& a, const Complex& b,
-				   tree::expression_type t);
+				   tree_expression::type t);
 
 extern tree_constant do_binary_op (const Complex& a, const ComplexMatrix& b,
-				   tree::expression_type t);
+				   tree_expression::type t);
 
 extern tree_constant do_binary_op (const ComplexMatrix& a, double b,
-				   tree::expression_type t);
+				   tree_expression::type t);
 
 extern tree_constant do_binary_op (const ComplexMatrix& a, const Matrix& b,
-				   tree::expression_type t); 
+				   tree_expression::type t); 
 
 extern tree_constant do_binary_op (const ComplexMatrix& a, const Complex& b,
-				   tree::expression_type t); 
+				   tree_expression::type t); 
 
 extern tree_constant do_binary_op (const ComplexMatrix& a,
 				   const ComplexMatrix& b,
-				   tree::expression_type t); 
+				   tree_expression::type t); 
 
 #endif
 
--- a/src/defun-int.h	Wed Aug 03 20:06:54 1994 +0000
+++ b/src/defun-int.h	Wed Aug 03 20:07:26 1994 +0000
@@ -76,10 +76,10 @@
 // XXX FIXME XXX -- eliminate the need for these in the functions that
 // use them?
 
-#define DEFINE_ARGV(warnfor) \
+#define DEFINE_ARGV(fcn_name) \
   int argc = args.length (); \
   int save_argc = argc; \
-  char **argv = make_argv (args, warnfor); \
+  char **argv = make_argv (args, fcn_name); \
   char **save_argv = argv; \
   if (error_state) \
     return retval
--- a/src/lex.l	Wed Aug 03 20:06:54 1994 +0000
+++ b/src/lex.l	Wed Aug 03 20:07:26 1994 +0000
@@ -1056,6 +1056,8 @@
     }
   else if (strcmp ("global", s) == 0)
     {
+      yylval.tok_val = new token (l, c);
+      token_stack.push (yylval.tok_val);
       return GLOBAL;
     }
   else if (strcmp ("gplot", s) == 0)
--- a/src/octave.cc	Wed Aug 03 20:06:54 1994 +0000
+++ b/src/octave.cc	Wed Aug 03 20:07:26 1994 +0000
@@ -50,6 +50,7 @@
 #include "sighandlers.h"
 #include "variables.h"
 #include "error.h"
+#include "tree-misc.h"
 #include "tree-const.h"
 #include "tree-plot.h"
 #include "utils.h"
@@ -110,7 +111,7 @@
 int quitting_gracefully = 0;
 
 // Current command to execute.
-tree *global_command = 0;
+tree_statement_list *global_command = 0;
 
 // Pointer to function that is currently being evaluated.
 tree_function *curr_function = 0;
@@ -138,6 +139,9 @@
 // Nonzero means we read ~/.octaverc and ./.octaverc.
 static int read_init_files = 1;
 
+// Nonzero means we printed messages about reading startup files.
+static int reading_startup_message_printed = 0;
+
 // Nonzero means we don\'t print the usual startup message.
 static int inhibit_startup_message = 0;
 
@@ -242,7 +246,7 @@
 }
 
 void
-parse_and_execute (char *s, int print)
+parse_and_execute (char *s, int print, int verbose)
 {
   begin_unwind_frame ("parse_and_execute_2");
 
@@ -261,7 +265,17 @@
       current_input_column = 1;
       echo_input = 0;
 
+      if (verbose)
+	{
+	  cout << "Reading commands from " << s << " ... ";
+	  reading_startup_message_printed = 1;
+	  cout.flush ();
+	}
+
       parse_and_execute (f, print);
+
+      if (verbose)
+	cout << "done." << endl;
     }
 
   run_unwind_frame ("parse_and_execute_2");
@@ -278,11 +292,13 @@
   unwind_protect_int (input_from_startup_file);
   input_from_startup_file = 1;
 
+  int verbose = ! inhibit_startup_message;
+
 // Execute commands from the site-wide configuration file.
 
   char *sd = get_site_defaults ();
 
-  parse_and_execute (sd, 0);
+  parse_and_execute (sd, 0, verbose);
 
 // Try to execute commands from $HOME/.octaverc and ./.octaverc.
 
@@ -290,7 +306,7 @@
   if (home_directory)
     {
       home_rc = strconcat (home_directory, "/.octaverc");
-      parse_and_execute (home_rc, 0);
+      parse_and_execute (home_rc, 0, verbose);
     }
 
 // Names alone are not enough.
@@ -303,7 +319,7 @@
   stat ("./.octaverc", &dot_rc_statbuf);
 
   if (home_rc_statbuf.st_ino != dot_rc_statbuf.st_ino)
-    parse_and_execute ("./.octaverc", 0);
+    parse_and_execute ("./.octaverc", 0, verbose);
 
   run_unwind_frame ("execute_startup_files");
 }
@@ -464,6 +480,12 @@
 
   install_signal_handlers ();
 
+  if (! inhibit_startup_message)
+    cout << "Octave, version " << version_string
+	 << ".  Copyright (C) 1992, 1993, 1994 John W. Eaton.\n"
+	 << "This is free software with ABSOLUTELY NO WARRANTY.\n"
+	 << "For details, type `warranty'.\n" << endl;
+
   if (read_init_files)
     {
       saving_history = 0;
@@ -471,6 +493,9 @@
       saving_history = 1;
     }
 
+  if (! inhibit_startup_message && reading_startup_message_printed)
+    cout << endl;
+
 // Avoid counting commands executed from startup files.
   current_command_number = 1;
 
@@ -514,15 +539,6 @@
   if (! (interactive || forced_interactive))
     using_readline = 0;
 
-  if (! inhibit_startup_message)
-    {
-      cout << "Octave, version " << version_string
-	   << ".  Copyright (C) 1992, 1993, 1994 John W. Eaton.\n"
-	   << "This is free software with ABSOLUTELY NO WARRANTY.\n"
-	   << "For details, type `warranty'.\n"
-	   << endl;
-    }
-
 // Allow the user to interrupt us without exiting.
 
   volatile sig_handler *saved_sigint_handler = signal (SIGINT, SIG_IGN);
@@ -703,7 +719,7 @@
 // trying to eval the command we just parsed -- it might contain the
 // name of an function file that still needs to be parsed!
 
-  tree *command = global_command;
+  tree_statement_list *command = global_command;
 
   run_unwind_frame ("eval_string");
 
--- a/src/parse.y	Wed Aug 03 20:06:54 1994 +0000
+++ b/src/parse.y	Wed Aug 03 20:07:26 1994 +0000
@@ -44,6 +44,7 @@
 #include "input.h"
 #include "utils.h"
 #include "tree.h"
+#include "tree-misc.h"
 #include "tree-plot.h"
 #include "tree-const.h"
 #include "symtab.h"
@@ -111,10 +112,10 @@
 // Generic error messages.
 static void yyerror (char *s);
 
-// Error mesages for mismatched end statements.
+// Error mesages for mismatched end tokens.
 static void end_error (char *type, token::end_tok_type ettype, int l, int c);
 
-// Check to see that end statements are properly matched.
+// Check to see that end tokens are properly matched.
 static int check_end (token *tok, token::end_tok_type expected);
 
 // Try to figure out early if an expression should become an
@@ -125,6 +126,23 @@
 // test in a logical expression.
 static void maybe_warn_assign_as_truth_value (tree_expression *expr);
 
+// Build a binary expression.
+static tree_expression *make_binary_op (int op, tree_expression *op1,
+				    	token *tok_val,
+					tree_expression *op2);
+
+// Build a prefix expression.
+static tree_expression *make_prefix_op (int op, tree_identifier *op1,
+					token *tok_val);
+
+// Build a postfix expression.
+static tree_expression *make_postfix_op (int op, tree_identifier *op1,
+					 token *tok_val);
+
+// Build a binary expression.
+static tree_expression *make_unary_op (int op, tree_expression *op1,
+				       token *tok_val);
+
 #define ABORT_PARSE \
   do \
     { \
@@ -161,14 +179,20 @@
   tree_parameter_list *tree_parameter_list_type;
   tree_command *tree_command_type;
   tree_if_command *tree_if_command_type;
+  tree_if_clause *tree_if_clause_type;
+  tree_if_command_list *tree_if_command_list_type;
+  tree_global *tree_global_type;
+  tree_global_init_list *tree_global_init_list_type;
   tree_global_command *tree_global_command_type;
-  tree_command_list *tree_command_list_type;
+  tree_statement *tree_statement_type;
+  tree_statement_list *tree_statement_list_type;
   tree_plot_command *tree_plot_command_type;
-  tree_subplot_list *tree_subplot_list_type;
-  tree_plot_limits *tree_plot_limits_type;
-  tree_plot_range *tree_plot_range_type;
-  tree_subplot_using *tree_subplot_using_type;
-  tree_subplot_style *tree_subplot_style_type;
+  subplot *subplot_type;
+  subplot_list *subplot_list_type;
+  plot_limits *plot_limits_type;
+  plot_range *plot_range_type;
+  subplot_using *subplot_using_type;
+  subplot_style *subplot_style_type;
 }
 
 // Tokens with line and column information.
@@ -184,35 +208,41 @@
 %token <tok_val> PLOT
 %token <tok_val> TEXT STYLE
 %token <tok_val> FOR WHILE IF ELSEIF ELSE BREAK CONTINUE FUNC_RET
+%token <tok_val> GLOBAL
 
 // Other tokens.
 %token FCN SCREW_TWO
-%token GLOBAL
 %token ELLIPSIS
 %token END_OF_INPUT
 %token USING TITLE WITH COLON OPEN_BRACE CLOSE_BRACE
 
 // Nonterminals we construct.
-%type <tree_type> input command 
+%type <tree_type> input
 %type <tree_expression_type> expression simple_expr simple_expr1
 %type <tree_expression_type> ans_expression title
 %type <tree_matrix_type> matrix
 %type <tree_identifier_type> identifier
-%type <tree_function_type> func_def func_def1 func_def2 func_def3
+%type <tree_function_type> func_def1 func_def2 func_def3
 %type <tree_index_expression_type> variable word_list_cmd
 %type <tree_colon_expression_type> colon_expr
-%type <tree_argument_list_type> arg_list arg_list1 word_list word_list1
+%type <tree_argument_list_type> arg_list word_list
 %type <tree_parameter_list_type> param_list param_list1 func_def1a 
-%type <tree_command_type> statement
-%type <tree_if_command_type> elseif
-%type <tree_global_command_type> global_decl global_decl1
-%type <tree_command_list_type> simple_list simple_list1 list list1 opt_list
+%type <tree_command_type> command func_def
+%type <tree_if_command_type> if_command
+%type <tree_if_clause_type> elseif_clause else_clause
+%type <tree_if_command_list_type> if_cmd_list1 if_cmd_list
+%type <tree_global_type> global_decl2
+%type <tree_global_init_list_type> global_decl1
+%type <tree_global_command_type> global_decl
+%type <tree_statement_type> statement
+%type <tree_statement_list_type> simple_list simple_list1 list list1 opt_list
 %type <tree_plot_command_type> plot_command 
-%type <tree_subplot_list_type> plot_command1 plot_command2 plot_options
-%type <tree_plot_limits_type> ranges
-%type <tree_plot_range_type> ranges1 
-%type <tree_subplot_using_type> using using1 
-%type <tree_subplot_style_type> style
+%type <subplot_type> plot_command2 plot_options
+%type <subplot_list_type> plot_command1
+%type <plot_limits_type> ranges
+%type <plot_range_type> ranges1 
+%type <subplot_using_type> using using1 
+%type <subplot_style_type> style
 
 // Precedence and associativity.
 %left ';' ',' '\n'
@@ -287,29 +317,30 @@
 		| comma_semi
 		  { $$ = 0; }
 		| simple_list1
-		  { $$ = $1->reverse (); }
+		  { $$ = $1; }
 		| simple_list1 semi_comma
 		  {
-		    $1->set_print_flag (0);
-		    $$ = $1->reverse ();
+		    tree_statement *tmp = $1->rear ();
+		    tmp->set_print_flag (0);
 		  }
 		| simple_list1 comma_semi
-		  { $$ = $1->reverse (); }
+		  { $$ = $1; }
 		;
 
-simple_list1	: command
-		  { $$ = new tree_command_list ($1); }
-		| semi_comma command
-		  { $$ = new tree_command_list ($2); }
-		| comma_semi command
-		  { $$ = new tree_command_list ($2); }
-		| simple_list1 semi_comma command
+simple_list1	: statement
+		  { $$ = new tree_statement_list ($1); }
+		| semi_comma statement
+		  { $$ = new tree_statement_list ($2); }
+		| comma_semi statement
+		  { $$ = new tree_statement_list ($2); }
+		| simple_list1 semi_comma statement
 		  {
-		    $1->set_print_flag (0);
-		    $$ = $1->chain ($3);
+		    tree_statement *tmp = $1->rear ();
+		    tmp->set_print_flag (0);
+		    $1->append ($3);
 		  }
-		| simple_list1 comma_semi command
-		  { $$ = $1->chain ($3); }
+		| simple_list1 comma_semi statement
+		  { $1->append ($3); }
 		;
 
 semi_comma	: ';'
@@ -332,62 +363,53 @@
 		;
 
 opt_list	: // empty
-		  { $$ = new tree_command_list (); }
+		  { $$ = new tree_statement_list (); }
 		| list
 		  { $$ = $1; }
 		;
 
 list		: list1
-		  { $$ = $1->reverse (); }
+		  { $$ = $1; }
 		| list1 comma_nl_sep
-		  { $$ = $1->reverse (); }
+		  { $$ = $1; }
 		| list1 semi_sep
 		  {
-		    $1->set_print_flag (0);
-		    $$ = $1->reverse ();
+		    tree_statement *tmp = $1->rear ();
+		    tmp->set_print_flag (0);
 		  }
 		;
 
-list1		: command
+list1		: statement
 		  {
 		    beginning_of_function = 0;
-		    $$ = new tree_command_list ($1);
+		    $$ = new tree_statement_list ($1);
 		  }
-		| list1 comma_nl_sep command
-		  { $$ = $1->chain ($3); }
-		| list1 semi_sep command
+		| list1 comma_nl_sep statement
+		  { $1->append ($3); }
+		| list1 semi_sep statement
 		  {
-		    $1->set_print_flag (0);
-		    $$ = $1->chain ($3);
+		    tree_statement *tmp = $1->rear ();
+		    tmp->set_print_flag (0);
+		    $1->append ($3);
 		  }
 		;
 
-command		: plot_command
-		  { $$ = $1; }
-		| statement
-		  { $$ = $1; }
+statement	: command
+		  { $$ = new tree_statement ($1); }
 		| ans_expression
-		  { $$ = $1; }
-		| func_def
-		  { $$ = $1; }
-		| global_decl
-		  { $$ = $1; }
+		  { $$ = new tree_statement ($1); }
 		;
 
 plot_command	: PLOT plot_command1
 		  {
-		    tree_subplot_list *tmp = 0;
-		    if ($2)
-		      tmp = $2->reverse ();
-
-		    if (! tmp && $1->pttype () != token::replot)
+		    if (! $2 && $1->pttype () != token::replot)
 		      {
 			yyerror ("must have something to plot");
 			ABORT_PARSE;
 		      }
 		    else
 		      {
-			$$ = new tree_plot_command (tmp, $1->pttype ());
+			$$ = new tree_plot_command ($2, $1->pttype ());
 			plotting = 0;
 			past_plot_range = 0;
 			in_plot_range = 0;
@@ -404,8 +426,7 @@
 		      }
 		    else
 		      {
-			tree_subplot_list *tmp = $3->reverse ();
-			$$ = new tree_plot_command (tmp, $2, $1->pttype ());
+			$$ = new tree_plot_command ($3, $2, $1->pttype ());
 			plotting = 0;
 			past_plot_range = 0;
 			in_plot_range = 0;
@@ -416,69 +437,72 @@
 		;
 
 ranges		: ranges1
-		  { $$ = new tree_plot_limits ($1); }
+		  { $$ = new plot_limits ($1); }
 		| ranges1 ranges1
-		  { $$ = new tree_plot_limits ($1, $2); }
+		  { $$ = new plot_limits ($1, $2); }
 		| ranges1 ranges1 ranges1
-		  { $$ = new tree_plot_limits ($1, $2, $3); }
+		  { $$ = new plot_limits ($1, $2, $3); }
 		;
 
 ranges1		: OPEN_BRACE expression COLON expression CLOSE_BRACE
-		  { $$ = new tree_plot_range ($2, $4); }
+		  { $$ = new plot_range ($2, $4); }
 		| OPEN_BRACE COLON expression CLOSE_BRACE
-		  { $$ = new tree_plot_range (0, $3); }
+		  { $$ = new plot_range (0, $3); }
 		| OPEN_BRACE expression COLON CLOSE_BRACE
-		  { $$ = new tree_plot_range ($2, 0); }
+		  { $$ = new plot_range ($2, 0); }
 		| OPEN_BRACE COLON CLOSE_BRACE
-		  { $$ = new tree_plot_range (); }
+		  { $$ = new plot_range (); }
 		| OPEN_BRACE CLOSE_BRACE
-		  { $$ = new tree_plot_range (); }
+		  { $$ = new plot_range (); }
 		;
 
 plot_command1	: // empty
 		  { $$ = 0; }
 		| plot_command2
-		  { $$ = $1; }
+		  { $$ = new subplot_list ($1); }
 		| plot_command1 ',' plot_command2
-		  { $$ = $1->chain ($3); }
+		  { $1->append ($3); }
 		;
 
 plot_command2	: expression
-		  { $$ = new tree_subplot_list ($1); }
+		  { $$ = new subplot ($1); }
 		| expression plot_options
-		  { $$ = $2->set_data ($1); }
+		  {
+		    $2->set_data ($1);
+		    $$ = $2;
+		  }
 		;
 
 plot_options	: using
-		  { $$ = new tree_subplot_list ($1, 0, 0); }
+		  { $$ = new subplot ($1, 0, 0); }
 		| title
-		  { $$ = new tree_subplot_list (0, $1, 0); }
+		  { $$ = new subplot (0, $1, 0); }
 		| style
-		  { $$ = new tree_subplot_list (0, 0, $1); }
+		  { $$ = new subplot (0, 0, $1); }
 		| using title
-		  { $$ = new tree_subplot_list ($1, $2, 0); }
-		| title using
-		  { $$ = new tree_subplot_list ($2, $1, 0); }
-		| using style
-		  { $$ = new tree_subplot_list ($1, 0, $2); }
-		| style using
-		  { $$ = new tree_subplot_list ($2, 0, $1); }
-		| title style
-		  { $$ = new tree_subplot_list (0, $1, $2); }
-		| style title
-		  { $$ = new tree_subplot_list (0, $2, $1); }
-		| using title style
-		  { $$ = new tree_subplot_list ($1, $2, $3); }
-		| using style title
-		  { $$ = new tree_subplot_list ($1, $3, $2); }
-		| title using style
-		  { $$ = new tree_subplot_list ($2, $1, $3); }
-		| title style using
-		  { $$ = new tree_subplot_list ($3, $1, $2); }
-		| style using title
-		  { $$ = new tree_subplot_list ($2, $3, $1); }
-		| style title using
-		  { $$ = new tree_subplot_list ($3, $2, $1); }
+		  { $$ = new subplot ($1, $2, 0); }
+		| title using		 
+		  { $$ = new subplot ($2, $1, 0); }
+		| using style		 
+		  { $$ = new subplot ($1, 0, $2); }
+		| style using		 
+		  { $$ = new subplot ($2, 0, $1); }
+		| title style		 
+		  { $$ = new subplot (0, $1, $2); }
+		| style title		 
+		  { $$ = new subplot (0, $2, $1); }
+		| using title style	 
+		  { $$ = new subplot ($1, $2, $3); }
+		| using style title	 
+		  { $$ = new subplot ($1, $3, $2); }
+		| title using style	 
+		  { $$ = new subplot ($2, $1, $3); }
+		| title style using	 
+		  { $$ = new subplot ($3, $1, $2); }
+		| style using title	 
+		  { $$ = new subplot ($2, $3, $1); }
+		| style title using	 
+		  { $$ = new subplot ($3, $2, $1); }
 		;
 
 using		: using1
@@ -495,7 +519,7 @@
 
 using1		: USING expression
 		  {
-		    tree_subplot_using *tmp = new tree_subplot_using ();
+		    subplot_using *tmp = new subplot_using ();
 		    $$ = tmp->add_qualifier ($2);
 		  }
 		| using1 COLON expression
@@ -507,11 +531,11 @@
 		;
 
 style		: WITH STYLE
-		  { $$ = new tree_subplot_style ($2->string ()); }
+		  { $$ = new subplot_style ($2->string ()); }
 		| WITH STYLE expression
-		  { $$ = new tree_subplot_style ($2->string (), $3); }
+		  { $$ = new subplot_style ($2->string (), $3); }
 		| WITH STYLE expression bogus_syntax expression
-		  { $$ = new tree_subplot_style ($2->string (), $3, $5); }
+		  { $$ = new subplot_style ($2->string (), $3, $5); }
 		;
 
 bogus_syntax	: // empty
@@ -522,30 +546,25 @@
 		;
 
 global_decl	: GLOBAL global_decl1
-		  { $$ = $2->reverse (); }
-		| GLOBAL global_decl1 ','
-		  { $$ = $2->reverse (); }
+		  {
+		    $$ = new tree_global_command ($2, $1->line (),
+						  $1->column ());
+		  }
 		;
 
-global_decl1	: NAME
-		  {
-		    $$ = new tree_global_command
-			   ($1->sym_rec (), $1->line (), $1->column ());
-		  }
-		| NAME '=' expression
+global_decl1	: global_decl2
+		  { $$ = new tree_global_init_list ($1); }
+		| global_decl1 optcomma global_decl2
+		  { $1->append ($3); }
+
+global_decl2	: identifier
+		  { $$ = new tree_global ($1); }
+		| identifier '=' expression
 		  {
-		    $$ = new tree_global_command
-			   ($1->sym_rec (), $3, $1->line (), $1->column ());
-		  }
-		| global_decl1 optcomma NAME
-		  {
-		    $$ = $1->chain ($3->sym_rec (), $3->line (),
-				    $3->column ());
-		  }
-		| global_decl1 optcomma NAME '=' expression
-		  {
-		    $$ = $1->chain ($3->sym_rec (), $5, $3->line (),
-				    $3->column ());
+		    tree_simple_assignment_expression *tmp_ass;
+		    tmp_ass = new tree_simple_assignment_expression
+		      ($1, $3, 0, $2->line (), $2->column ());
+		    $$ = new tree_global (tmp_ass);
 		  }
 		;
 
@@ -558,7 +577,18 @@
 		  }
 		;
 
-statement	: WHILE expression optsep opt_list END
+command		: plot_command
+		  { $$ = $1; }
+		| func_def
+		  { $$ = $1; }
+		| global_decl
+		  { $$ = $1; }
+		| if_command
+		  {
+		    iffing--;
+		    $$ = $1;
+		  }
+		| WHILE expression optsep opt_list END
 		  {
 		    maybe_warn_assign_as_truth_value ($2);
 		    if (check_end ($5, token::while_end))
@@ -575,51 +605,6 @@
 		    $$ = new tree_for_command ($2, $4, $6,
 					       $1->line (), $1->column ());
 		  }
-		| IF expression optsep opt_list END
-		  {
-		    maybe_warn_assign_as_truth_value ($2);
-		    if (check_end ($5, token::if_end))
-		      ABORT_PARSE;
-		    iffing--;
-		    $$ = new tree_if_command ($2, $4,
-					      $1->line (), $1->column ());
-		  }
-		| IF expression optsep opt_list ELSE optsep opt_list END
-		  {
-		    maybe_warn_assign_as_truth_value ($2);
-		    if (check_end ($8, token::if_end))
-		      ABORT_PARSE;
-		    iffing--;
-		    tree_if_command *t1 = new tree_if_command
-					    ($7, $5->line (), $5->column ());
-		    $$ = t1->chain ($2, $4, $1->line (), $1->column ());
-		  }
-		| IF expression optsep opt_list elseif END
-		  {
-		    maybe_warn_assign_as_truth_value ($2);
-		    if (check_end ($6, token::if_end))
-		      ABORT_PARSE;
-		    iffing--;
-		    tree_if_command *t1 = $5->reverse ();
-		    // Add the if list to the new head of the elseif
-		    // list, and return the list.
-		    $$ = t1->chain ($2, $4, $1->line (), $1->column ());
-		  }
-		| IF expression optsep opt_list elseif ELSE optsep opt_list END
-		  {
-		    maybe_warn_assign_as_truth_value ($2);
-		    if (check_end ($9, token::if_end))
-		      ABORT_PARSE;
-		    iffing--;
-		    // Add the else list to the head of the elseif list,
-		    // then reverse the list.
-		    tree_if_command *t1 = $5->chain ($8, $6->line (),
-						     $6->column ());
-		    t1 = t1->reverse ();
-		    // Add the if list to the new head of the elseif
-		    // list, and return the list.
-		    $$ = t1->chain ($2, $4, $1->line (), $1->column ());
-		  }
 		| BREAK
 		  {
 		    if (!looping)
@@ -655,17 +640,39 @@
 		  }
 		;
 
-elseif		: ELSEIF optsep expression optsep opt_list
+if_command	: IF if_cmd_list END
+		  {
+		    if (check_end ($3, token::if_end))
+		      ABORT_PARSE;
+		    $$ = new tree_if_command ($2, $1->line (), $1->column ());
+		  }
+		;
+
+if_cmd_list	: if_cmd_list1
+		  { $$ = $1 }
+		| if_cmd_list1 else_clause
+		  { $1->append ($2); }
+		;
+
+if_cmd_list1	: expression optsep opt_list
+		  {
+		    maybe_warn_assign_as_truth_value ($1);
+		    tree_if_clause *t = new tree_if_clause ($1, $3);
+		    $$ = new tree_if_command_list (t);
+		  }
+		| if_cmd_list1 elseif_clause
+		  { $1->append ($2); }
+		;
+
+elseif_clause	: ELSEIF optsep expression optsep opt_list
 		  {
 		    maybe_warn_assign_as_truth_value ($3);
-		    $$ = new tree_if_command ($3, $5, $1->line (),
-					      $1->column ());
+		    $$ = new tree_if_clause ($3, $5);
 		  }
-		| elseif ELSEIF optsep expression optsep opt_list
-		  {
-		    maybe_warn_assign_as_truth_value ($4);
-		    $$ = $1->chain ($4, $6, $2->line (), $2->column ());
-		  }
+		;
+
+else_clause	: ELSE optsep opt_list
+		  { $$ = new tree_if_clause ($3); }
 		;
 
 optsep		: // empty
@@ -686,7 +693,7 @@
 
 expression	: variable '=' expression
 		  { $$ = new tree_simple_assignment_expression
-		      ($1, $3, $2->line (), $2->column ()); }
+		      ($1, $3, 0, $2->line (), $2->column ()); }
 		| '[' screwed_again matrix_row SCREW_TWO '=' expression
 		  {
 
@@ -727,77 +734,53 @@
 simple_expr	: simple_expr1
 		  { $$ = $1; }
 		| identifier PLUS_PLUS
-		  { $$ = new tree_postfix_expression
-		      ($1, tree::increment, $2->line (), $2->column ()); }
+		  { $$ = make_postfix_op (PLUS_PLUS, $1, $2); }
 		| identifier MINUS_MINUS
-		  { $$ = new tree_postfix_expression
-		      ($1, tree::decrement, $2->line (), $2->column ()); }
+		  { $$ = make_postfix_op (MINUS_MINUS, $1, $2); }
 		| simple_expr QUOTE
-		  { $$ = new tree_unary_expression
-		      ($1, tree::hermitian, $2->line (), $2->column ()); }
+		  { $$ = make_unary_op (QUOTE, $1, $2); }
 		| simple_expr TRANSPOSE
-		  { $$ = new tree_unary_expression
-		      ($1, tree::transpose, $2->line (), $2->column ()); }
+		  { $$ = make_unary_op (TRANSPOSE, $1, $2); }
 		| simple_expr POW simple_expr
-		  { $$ = new tree_binary_expression
-		      ($1, $3, tree::power, $2->line (), $2->column ()); }
+		  { $$ = make_binary_op (POW, $1, $2, $3); }
 		| simple_expr EPOW simple_expr
-		  { $$ = new tree_binary_expression
-		      ($1, $3, tree::elem_pow, $2->line (), $2->column ()); }
+		  { $$ = make_binary_op (EPOW, $1, $2, $3); }
 		| simple_expr '+' simple_expr
-		  { $$ = new tree_binary_expression
-		      ($1, $3, tree::add, $2->line (), $2->column ()); }
+		  { $$ = make_binary_op ('+', $1, $2, $3); }
 		| simple_expr '-' simple_expr
-		  { $$ = new tree_binary_expression
-		      ($1, $3, tree::subtract, $2->line (), $2->column ()); }
+		  { $$ = make_binary_op ('-', $1, $2, $3); }
 		| simple_expr '*' simple_expr
-		  { $$ = new tree_binary_expression
-		      ($1, $3, tree::multiply, $2->line (), $2->column ()); }
+		  { $$ = make_binary_op ('*', $1, $2, $3); }
 		| simple_expr '/' simple_expr
-		  { $$ = new tree_binary_expression
-		      ($1, $3, tree::divide, $2->line (), $2->column ()); }
+		  { $$ = make_binary_op ('/', $1, $2, $3); }
 		| simple_expr EMUL simple_expr
-		  { $$ = new tree_binary_expression
-		      ($1, $3, tree::el_mul, $2->line (), $2->column ()); }
+		  { $$ = make_binary_op (EMUL, $1, $2, $3); }
 		| simple_expr EDIV simple_expr
-		  { $$ = new tree_binary_expression
-		      ($1, $3, tree::el_div, $2->line (), $2->column ()); }
+		  { $$ = make_binary_op (EDIV, $1, $2, $3); }
 		| simple_expr LEFTDIV simple_expr
-		  { $$ = new tree_binary_expression
-		      ($1, $3, tree::leftdiv, $2->line (), $2->column ()); }
+		  { $$ = make_binary_op (LEFTDIV, $1, $2, $3); }
 		| simple_expr ELEFTDIV simple_expr
-		  { $$ = new tree_binary_expression
-		      ($1, $3, tree::el_leftdiv, $2->line (), $2->column ()); }
+		  { $$ = make_binary_op (ELEFTDIV, $1, $2, $3); }
 		| simple_expr EXPR_LT simple_expr
-		  { $$ = new tree_binary_expression
-		      ($1, $3, tree::cmp_lt, $2->line (), $2->column ()); }
+		  { $$ = make_binary_op (EXPR_LT, $1, $2, $3); }
 		| simple_expr EXPR_LE simple_expr
-		  { $$ = new tree_binary_expression
-		      ($1, $3, tree::cmp_le, $2->line (), $2->column ()); }
+		  { $$ = make_binary_op (EXPR_LE, $1, $2, $3); }
 		| simple_expr EXPR_EQ simple_expr
-		  { $$ = new tree_binary_expression
-		      ($1, $3, tree::cmp_eq, $2->line (), $2->column ()); }
+		  { $$ = make_binary_op (EXPR_EQ, $1, $2, $3); }
 		| simple_expr EXPR_GE simple_expr
-		  { $$ = new tree_binary_expression
-		      ($1, $3, tree::cmp_ge, $2->line (), $2->column ()); }
+		  { $$ = make_binary_op (EXPR_GE, $1, $2, $3); }
 		| simple_expr EXPR_GT simple_expr
-		  { $$ = new tree_binary_expression
-		      ($1, $3, tree::cmp_gt, $2->line (), $2->column ()); }
+		  { $$ = make_binary_op (EXPR_GT, $1, $2, $3); }
 		| simple_expr EXPR_NE simple_expr
-		  { $$ = new tree_binary_expression
-		      ($1, $3, tree::cmp_ne, $2->line (), $2->column ()); }
+		  { $$ = make_binary_op (EXPR_NE, $1, $2, $3); }
 		| simple_expr EXPR_AND_AND simple_expr
-		  { $$ = new tree_binary_expression
-		      ($1, $3, tree::and_and, $2->line (), $2->column ()); }
+		  { $$ = make_binary_op (EXPR_AND_AND, $1, $2, $3); }
 		| simple_expr EXPR_OR_OR simple_expr
-		  { $$ = new tree_binary_expression
-		      ($1, $3, tree::or_or, $2->line (), $2->column ()); }
+		  { $$ = make_binary_op (EXPR_OR_OR, $1, $2, $3); }
 		| simple_expr EXPR_AND simple_expr
-		  { $$ = new tree_binary_expression
-		      ($1, $3, tree::and, $2->line (), $2->column ()); }
+		  { $$ = make_binary_op (EXPR_AND, $1, $2, $3); }
 		| simple_expr EXPR_OR simple_expr
-		  { $$ = new tree_binary_expression
-		      ($1, $3, tree::or, $2->line (), $2->column ()); }
+		  { $$ = make_binary_op (EXPR_OR, $1, $2, $3); }
 		;
 
 simple_expr1	: NUM
@@ -831,19 +814,15 @@
 		| colon_expr
 		  { $$ = $1; }
 		| PLUS_PLUS identifier %prec UNARY
-		  { $$ = new tree_prefix_expression
-		      ($2, tree::increment, $1->line (), $1->column ()); }
+		  { $$ = make_prefix_op (PLUS_PLUS, $2, $1); }
 		| MINUS_MINUS identifier %prec UNARY
-		  { $$ = new tree_prefix_expression
-		      ($2, tree::decrement, $1->line (), $1->column ()); }
+		  { $$ = make_prefix_op (MINUS_MINUS, $2, $1); }
 		| EXPR_NOT simple_expr
-		  { $$ = new tree_unary_expression
-		      ($2, tree::not, $1->line (), $1->column ()); }
+		  { $$ = make_unary_op (EXPR_NOT, $2, $1); }
 		| '+' simple_expr %prec UNARY
 		  { $$ = $2; }
 		| '-' simple_expr %prec UNARY
-		  { $$ = new tree_unary_expression
-		      ($2, tree::uminus, $1->line (), $1->column ()); }
+		  { $$ = make_unary_op ('-', $2, $1); }
 		;
 
 colon_expr	: simple_expr ':' simple_expr
@@ -867,19 +846,15 @@
 		  }
 		;
 
-word_list	: word_list1
-		  { $$ = $1->reverse (); }
-		;
-
-word_list1	: TEXT
+word_list	: TEXT
 		  {
 		    tree_constant *tmp = new tree_constant ($1->string ());
 		    $$ = new tree_argument_list (tmp);
 		  }
-		| word_list1 TEXT
+		| word_list TEXT
 		  {
 		    tree_constant *tmp = new tree_constant ($2->string ());
-		    $$ = $1->chain (tmp);
+		    $1->append (tmp);
 		  }
 		;
 
@@ -920,22 +895,20 @@
 		    tree_identifier *tmp = new tree_identifier
 		      ($1->sym_rec (), $1->line (), $1->column ());
 		    tree_parameter_list *tpl = new tree_parameter_list (tmp);
-		    tpl = tpl->reverse ();
 		    tpl->mark_as_formal_parameters ();
 		    $$ = $5->define_ret_list (tpl);
 		  }
 		| func_def1a ']' g_symtab '=' func_def2
 		  {
-		    tree_parameter_list *tpl = $1->reverse ();
-		    tpl->mark_as_formal_parameters ();
-		    $$ = $5->define_ret_list (tpl);
+		    $1->mark_as_formal_parameters ();
+		    $$ = $5->define_ret_list ($1);
 		  }
 		;
 
 func_def1a	: '[' safe local_symtab identifier
 		  { $$ = new tree_parameter_list ($4); }
 		| func_def1a ',' identifier
-		  { $$ = $1->chain ($3); }
+		  { $1->append ($3); }
 		;
 
 func_def2	: identifier safe local_symtab func_def3
@@ -1053,24 +1026,20 @@
 		| param_list1 ')'
 		  {
 		    quote_is_transpose = 0;
-		    tree_parameter_list *tmp = $1->reverse ();
-		    tmp->mark_as_formal_parameters ();
-		    $$ = tmp;
+		    $1->mark_as_formal_parameters ();
 		  }
 		| param_list1 ',' ELLIPSIS ')'
 		  {
 		    quote_is_transpose = 0;
-		    tree_parameter_list *tmp = $1->reverse ();
-		    tmp->mark_as_formal_parameters ();
-		    tmp->mark_varargs ();
-		    $$ = tmp;
+		    $1->mark_as_formal_parameters ();
+		    $1->mark_varargs ();
 		  }
 		;
 
 param_list1	: '(' identifier
 		  { $$ = new tree_parameter_list ($2); }
 		| param_list1 ',' identifier
-		  { $$ = $1->chain ($3); }
+		  { $1->append ($3); }
 		| '(' error
 		  {
 		    yyerror ("parse error");
@@ -1092,38 +1061,22 @@
 		  }
 		;
 
-arg_list	: arg_list1
-		  { $$ = $1->reverse (); }
-		;
-
-arg_list1	: ':'
+arg_list	: ':'
 		  {
 		    tree_constant *colon;
 		    colon = new tree_constant (tree_constant_rep::magic_colon);
 		    $$ = new tree_argument_list (colon);
 		  }
-		| arg_list1 ',' ':'
+		| arg_list ',' ':'
 		  {
 		    tree_constant *colon;
 		    colon = new tree_constant (tree_constant_rep::magic_colon);
-		    $$ = $1->chain (colon);
-		    if (! $$)
-		      {
-			yyerror ("parse error");
-			ABORT_PARSE;
-		      }
+		    $1->append (colon);
 		  }
 		| expression
 		  { $$ = new tree_argument_list ($1); }
-		| arg_list1 ',' expression
-		  {
-		    $$ = $1->chain ($3);
-		    if (! $$)
-		      {
-			yyerror ("parse error");
-			ABORT_PARSE;
-		      }
-		  }
+		| arg_list ',' expression
+		  { $1->append ($3); }
 		;
 
 matrix		: '[' screwed_again rows ']'
@@ -1146,13 +1099,14 @@
 		      {
 			mlnm.pop ();
 			mlnm.push (0);
-			tree_matrix *tmp = new tree_matrix ($1, tree::md_none);
+			tree_matrix *tmp = new tree_matrix
+			  ($1, tree_matrix::md_none);
 			ml.push (tmp);
 		      }
 		    else
 		      {
 			tree_matrix *tmp = ml.pop ();
-			tmp = tmp->chain ($1, tree::md_down);
+			tmp = tmp->chain ($1, tree_matrix::md_down);
 			ml.push (tmp);
 		      }
 		  }
@@ -1160,7 +1114,7 @@
 		| matrix_row ',' expression
 		  {
 		    tree_matrix *tmp = ml.pop ();
-		    tmp = tmp->chain ($3, tree::md_right);
+		    tmp = tmp->chain ($3, tree_matrix::md_right);
 		    ml.push (tmp);
 		  }
 		;
@@ -1312,3 +1266,156 @@
       warning ("suggest parenthesis around assignment used as truth value");
     }
 }
+
+static tree_expression *
+make_binary_op (int op, tree_expression *op1, token *tok_val,
+		tree_expression *op2)
+{
+  tree_expression::type t;
+  switch (op)
+    {
+    case POW:
+      t = tree_expression::power;
+      break;
+    case EPOW:
+      t = tree_expression::elem_pow;
+      break;
+    case '+':
+      t = tree_expression::add;
+      break;
+    case '-':
+      t = tree_expression::subtract;
+      break;
+    case '*':
+      t = tree_expression::multiply;
+      break;
+    case '/':
+      t = tree_expression::divide;
+      break;
+    case EMUL:
+      t = tree_expression::el_mul;
+      break;
+    case EDIV:
+      t = tree_expression::el_div;
+      break;
+    case LEFTDIV:
+      t = tree_expression::leftdiv;
+      break;
+    case ELEFTDIV:
+      t = tree_expression::el_leftdiv;
+      break;
+    case EXPR_LT:
+      t = tree_expression::cmp_lt;
+      break;
+    case EXPR_LE:
+      t = tree_expression::cmp_le;
+      break;
+    case EXPR_EQ:
+      t = tree_expression::cmp_eq;
+      break;
+    case EXPR_GE:
+      t = tree_expression::cmp_ge;
+      break;
+    case EXPR_GT:
+      t = tree_expression::cmp_gt;
+      break;
+    case EXPR_NE:
+      t = tree_expression::cmp_ne;
+      break;
+    case EXPR_AND_AND:
+      t = tree_expression::and_and;
+      break;
+    case EXPR_OR_OR:
+      t = tree_expression::or_or;
+      break;
+    case EXPR_AND:
+      t = tree_expression::and;
+      break;
+    case EXPR_OR:
+      t = tree_expression::or;
+      break;
+    default:
+      panic_impossible ();
+      break;
+    }
+
+  int l = tok_val->line ();
+  int c = tok_val->column ();
+
+  return new tree_binary_expression (op1, op2, t, l, c);
+}
+
+static tree_expression *
+make_prefix_op (int op, tree_identifier *op1, token *tok_val)
+{
+  tree_expression::type t;
+  switch (op)
+    {
+    case PLUS_PLUS:
+      t = tree_expression::increment;
+      break;
+    case MINUS_MINUS:
+      t = tree_expression::decrement;
+      break;
+    default:
+      panic_impossible ();
+      break;
+    }
+
+  int l = tok_val->line ();
+  int c = tok_val->column ();
+
+  return new tree_prefix_expression (op1, t, l, c);
+}
+
+static tree_expression *
+make_postfix_op (int op, tree_identifier *op1, token *tok_val)
+{
+  tree_expression::type t;
+  switch (op)
+    {
+    case PLUS_PLUS:
+      t = tree_expression::increment;
+      break;
+    case MINUS_MINUS:
+      t = tree_expression::decrement;
+      break;
+    default:
+      panic_impossible ();
+      break;
+    }
+
+  int l = tok_val->line ();
+  int c = tok_val->column ();
+
+  return new tree_postfix_expression (op1, t, l, c);
+}
+
+static tree_expression *
+make_unary_op (int op, tree_expression *op1, token *tok_val)
+{
+  tree_expression::type t;
+  switch (op)
+    {
+    case QUOTE:
+      t = tree_expression::hermitian;
+      break;
+    case TRANSPOSE:
+      t = tree_expression::transpose;
+      break;
+    case EXPR_NOT:
+      t = tree_expression::not;
+      break;
+    case '-':
+      t = tree_expression::uminus;
+      break;
+    default:
+      panic_impossible ();
+      break;
+    }
+
+  int l = tok_val->line ();
+  int c = tok_val->column ();
+
+  return new tree_unary_expression (op1, t, l, c);
+}
--- a/src/pt-base.h	Wed Aug 03 20:06:54 1994 +0000
+++ b/src/pt-base.h	Wed Aug 03 20:07:26 1994 +0000
@@ -33,58 +33,19 @@
 tree
 {
 public:
-  enum matrix_dir
-    {
-      md_none,
-      md_right,
-      md_down,
-    };
-
-  enum expression_type
+  tree (int l = -1, int c = -1)
     {
-      unknown,
-      assignment,
-      simple_assignment,
-      multi_assignment,
-      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,
-      and_and,
-      or_or,
-      and,
-      or,
-      not,
-      unot,
-      uminus,
-      hermitian,
-      transpose,
-      colon,
-      index,
-      increment,
-      decrement,
-   };
+      line_num = l;
+      column_num = c;
+    }
 
   virtual ~tree (void) { }
 
-  virtual tree_constant eval (int print) = 0;
+  virtual int line (void) const { return line_num; }
 
-  virtual int line (void) const { return line_num; }
   virtual int column (void) const { return column_num; }
 
-protected:
+private:
   int line_num;
   int column_num;
 };
--- a/src/pt-cmd.cc	Wed Aug 03 20:06:54 1994 +0000
+++ b/src/pt-cmd.cc	Wed Aug 03 20:07:26 1994 +0000
@@ -31,25 +31,27 @@
 
 #include <iostream.h>
 
+// Nonzero means we're breaking out of a loop.
+int breaking = 0;
+
+// Nonzero means we're jumping to the end of a loop.
+int continuing = 0;
+
+// Nonzero means we're returning from a function.  Global because it
+// is also needed in tree-expr.cc.
+int returning = 0;
+
 #include "user-prefs.h"
 #include "variables.h"
 #include "symtab.h"
 #include "error.h"
 #include "gripes.h"
 #include "tree.h"
+#include "tree-expr.h"
 #include "tree-cmd.h"
+#include "tree-misc.h"
 #include "tree-const.h"
 
-// Nonzero means we're breaking out of a loop.
-static int breaking = 0;
-
-// Nonzero means we're jumping to the end of a loop.
-static int continuing = 0;
-
-// Nonzero means we're returning from a function.  Global because it
-// is also needed in tree-expr.cc.
-int returning = 0;
-
 // Decide if it's time to quit a for or while loop.
 static int
 quit_loop_now (void)
@@ -72,9 +74,9 @@
 // We seem to have no use for this now.  Maybe it will be needed at
 // some future date, so here it is.
 #if 0
-/*
- * Convert a linked list of trees to a vector of pointers to trees.
- */
+
+// Convert a linked list of trees to a vector of pointers to trees.
+
 static tree **
 list_to_vector (tree *list, int& len)
 {
@@ -94,243 +96,25 @@
 }
 #endif
 
-/*
- * A command or two to be executed.
- */
-tree_command_list::tree_command_list (void)
-{
-  command = 0;
-  print_flag = 1;
-  next = 0;
-}
+// Global.
 
-tree_command_list::tree_command_list (tree *t)
+tree_global_command::~tree_global_command (void)
 {
-  command = t;
-  print_flag = 1;
-  next = 0;
-}
-
-tree_command_list::~tree_command_list (void)
-{
-  delete command;
-  delete next;
+  delete init_list;
 }
 
 void
-tree_command_list::set_print_flag (int flag)
-{
-  print_flag = flag;
-}
-
-tree_command_list *
-tree_command_list::chain (tree *t)
-{
-  tree_command_list *tmp = new tree_command_list (t);
-  tmp->next = this;
-  return tmp;
-}
-
-tree_command_list *
-tree_command_list::reverse (void)
-{
-  tree_command_list *list = this;
-  tree_command_list *next;
-  tree_command_list *prev = 0;
-
-  while (list)
-    {
-      next = list->next;
-      list->next = prev;
-      prev = list;
-      list = next;
-    }
-  return prev;
-}
-
-tree_constant
-tree_command_list::eval (int print)
-{
-  int pf;
-  tree_constant retval;
-
-  if (error_state)
-    return retval;
-
-  for (tree_command_list *list = this; list; list = list->next)
-    {
-      if (print == 0)
-	pf = 0;
-      else
-	pf = list->print_flag;
-
-      tree *cmd = list->command;
-      if (! cmd)
-	retval = tree_constant ();
-      else
-	{
-	  retval = cmd->eval (pf);
-
-	  if (error_state)
-	    return tree_constant ();
-
-	  if (breaking || continuing)
-	    break;
-
-	  if (returning)
-	    break;
-	}
-    }
-  return retval;
-}
-
-/*
- * Global.
- */
-tree_global_command::tree_global_command (int l, int c)
-{
-  line_num = l;
-  column_num = c;
-  sr = 0;
-  rhs = 0;
-  next = 0;
-}
-
-tree_global_command::tree_global_command (symbol_record *s, int l, int c)
-{
-  line_num = l;
-  column_num = c;
-  sr = s;
-  rhs = 0;
-  next = 0;
-}
-
-tree_global_command::tree_global_command (symbol_record *s,
-					  tree_expression *e,
-					  int l, int c) 
+tree_global_command::eval (void)
 {
-  line_num = l;
-  column_num = c;
-  sr = s;
-  rhs = e;
-  next = 0;
-}
-
-tree_global_command::~tree_global_command (void)
-{
-  delete next;
-}
-
-tree_global_command *
-tree_global_command::chain (symbol_record *s, int l, int c)
-{
-  tree_global_command *tmp = new tree_global_command (s, l, c);
-  tmp->next = this;
-  return tmp;
-}
-
-tree_global_command *
-tree_global_command::chain (symbol_record *s, tree_expression *e,
-			    int l, int c)
-{
-  tree_global_command *tmp = new tree_global_command (s, e, l, c);
-  tmp->next = this;
-  return tmp;
-}
-
-tree_global_command *
-tree_global_command::reverse (void)
-{
-  tree_global_command *list = this;
-  tree_global_command *next;
-  tree_global_command *prev = 0;
+  if (init_list)
+    init_list->eval ();
 
-  while (list)
-    {
-      next = list->next;
-      list->next = prev;
-      prev = list;
-      list = next;
-    }
-  return prev;
-}
-
-tree_constant
-tree_global_command::eval (int print)
-{
-  tree_constant retval;
-
-  link_to_global_variable (sr);
-
-  if (rhs)
-    {
-      tree_identifier *id = new tree_identifier (sr);
-      tree_constant tmp_rhs = rhs->eval (0);
-      if (error_state)
-	{
-	  delete id;
-	  eval_error ();
-	  return retval;
-	}
-      else
-	{
-	  tree_constant *tmp_val = new tree_constant (tmp_rhs);
-
-	  tree_simple_assignment_expression tmp_ass (id, tmp_val);
-
-	  tmp_ass.eval (0);
-
-	  delete id; // XXX FIXME XXX
-
-	  if (error_state)
-	    {
-	      eval_error ();
-	      return retval;
-	    }
-	}
-    }
-
-  if (next)
-    next->eval (print);
-
-  return retval;
-}
-
-void
-tree_global_command::eval_error (void)
-{
   if (error_state > 0)
     ::error ("evaluating global command near line %d, column %d",
 	     line (), column ());
 }
 
-/*
- * While.
- */
-tree_while_command::tree_while_command (int l, int c)
-{
-  line_num = l;
-  column_num = c;
-  expr = 0;
-  list = 0;
-}
-
-tree_while_command::tree_while_command (tree_expression *e, int l, int c) 
-{
-  line_num = l;
-  column_num = c;
-  expr = e;
-  list = 0;
-}
-
-tree_while_command::tree_while_command (tree_expression *e, tree *lst,
-					int l, int c)
-{
-  line_num = l;
-  column_num = c;
-  expr = e;
-  list = lst;
-}
+// While.
 
 tree_while_command::~tree_while_command (void)
 {
@@ -338,25 +122,23 @@
   delete list;
 }
 
-tree_constant
-tree_while_command::eval (int print)
+void
+tree_while_command::eval (void)
 {
-  tree_constant retval;
-
   if (error_state)
-    return retval;
+    return;
 
   for (;;)
     {
       int expr_value = 0;
       if (! expr)
-	return tree_constant ();
+	return;
       tree_constant t1 = expr->eval (0);
 
       if (error_state)
 	{
 	  eval_error ();
-	  return tree_constant ();
+	  return;
 	}
 
       if (t1.rows () == 0 || t1.columns () == 0)
@@ -367,7 +149,7 @@
 	  else if (flag == 0)
 	    {
 	      ::error ("while: empty matrix used in conditional");
-	      return tree_constant ();
+	      return;
 	    }
 	  t1 = tree_constant (0.0);
 	}
@@ -389,11 +171,11 @@
 	{
 	  if (list)
 	    {
-	      retval = list->eval (1);
+	      list->eval (1);
 	      if (error_state)
 		{
 		  eval_error ();
-		  return tree_constant ();
+		  return;
 		}
 	    }
 
@@ -403,7 +185,6 @@
       else
 	break;
     }
-  return retval;
 }
 
 void
@@ -414,28 +195,7 @@
 	     line (), column ());
 }
 
-/*
- * For.
- */
-tree_for_command::tree_for_command (int l, int c)
-{
-  line_num = l;
-  column_num = c;
-  id = 0;
-  expr = 0;
-  list = 0;
-}
-
-tree_for_command::tree_for_command (tree_index_expression *ident,
-				    tree_expression *e, tree *lst,
-				    int l, int c)
-{
-  line_num = l;
-  column_num = c;
-  id = ident;
-  expr = e;
-  list = lst;
-}
+// For.
 
 tree_for_command::~tree_for_command (void)
 {
@@ -444,20 +204,18 @@
   delete list;
 }
 
-tree_constant
-tree_for_command::eval (int print)
+void
+tree_for_command::eval (void)
 {
-  tree_constant retval;
-
   if (error_state || ! expr)
-    return retval;
+    return;
 
   tree_constant tmp_expr = expr->eval (0);
 
   if (error_state || tmp_expr.is_undefined ())
     {
       eval_error ();
-      return retval;
+      return;
     }
 
   tree_constant_rep::constant_type expr_type = tmp_expr.const_type ();
@@ -468,7 +226,7 @@
       {
 	tree_constant *rhs = new tree_constant (tmp_expr);
 	int quit = 0;
-	retval = do_for_loop_once (rhs, quit);
+	do_for_loop_once (rhs, quit);
       }
       break;
     case tree_constant_rep::complex_matrix_constant:
@@ -511,7 +269,7 @@
 	      }
 
 	    int quit = 0;
-	    retval = do_for_loop_once (rhs, quit);
+	    do_for_loop_once (rhs, quit);
 	    if (quit)
 	      break;
 	  }
@@ -535,7 +293,7 @@
 	    tree_constant *rhs = new tree_constant (tmp_val);
 
 	    int quit = 0;
-	    retval = do_for_loop_once (rhs, quit);
+	    do_for_loop_once (rhs, quit);
 	    if (quit)
 	      break;
 	  }
@@ -545,8 +303,6 @@
       panic_impossible ();
       break;
     }
-  
-  return retval;
 }
 
 void
@@ -557,260 +313,78 @@
 	     line (), column ());
 }
 
-tree_constant
+void
 tree_for_command::do_for_loop_once (tree_constant *rhs, int& quit)
 {
-  tree_constant retval;
-
   quit = 0;
 
-  tree_simple_assignment_expression tmp_ass (id, rhs);
+  tree_simple_assignment_expression tmp_ass (id, rhs, 1);
 
   tmp_ass.eval (0);
 
   if (error_state)
     {
       eval_error ();
-      return tree_constant ();
+      return;
     }
 
   if (list)
     {
-      retval = list->eval (1);
+      list->eval (1);
       if (error_state)
 	{
 	  eval_error ();
 	  quit = 1;
-	  return tree_constant ();
+	  return;
 	}
     }
 
   quit = quit_loop_now ();
-
-  return retval;
-}
-
-/*
- * If.
- */
-tree_if_command::tree_if_command (int l, int c)
-{
-  line_num = l;
-  column_num = c;
-  expr = 0;
-  list = 0;
-  next = 0;
 }
 
-tree_if_command::tree_if_command (tree *lst, int l, int c)
-{
-  line_num = l;
-  column_num = c;
-  expr = 0;
-  list = lst;
-  next = 0;
-}
-
-tree_if_command::tree_if_command (tree_expression *e, tree *lst,
-				  int l, int c)
-{
-  line_num = l;
-  column_num = c;
-  expr = e;
-  list = lst;
-  next = 0;
-}
+// If.
 
 tree_if_command::~tree_if_command (void)
 {
-  delete expr;
   delete list;
-  delete next;
-}
-
-tree_if_command *
-tree_if_command::chain (tree *lst, int l, int c)
-{
-  tree_if_command *tmp = new tree_if_command (lst, l, c);
-  tmp->next = this;
-  return tmp;
-}
-
-tree_if_command *
-tree_if_command::chain (tree_expression *e, tree *lst, int l, int c)
-{
-  tree_if_command *tmp = new tree_if_command (e, lst, l, c);
-  tmp->next = this;
-  return tmp;
-}
-
-tree_if_command *
-tree_if_command::reverse (void)
-{
-  tree_if_command *list = this;
-  tree_if_command *next;
-  tree_if_command *prev = 0;
-
-  while (list)
-    {
-      next = list->next;
-      list->next = prev;
-      prev = list;
-      list = next;
-    }
-  return prev;
-}
-
-tree_constant
-tree_if_command::eval (int print)
-{
-  int expr_value = 0;
-  tree_constant retval;
-
-  if (error_state)
-    return retval;
-
-  
-  for (tree_if_command *lst = this; lst; lst = lst->next)
-    {
-      if (lst->expr)
-	{
-	  tree_expression *tmp = lst->expr;
-	  if (! tmp)
-	    return tree_constant ();
-	  tree_constant t1 = tmp->eval (0);
-	  if (error_state || t1.is_undefined ())
-	    {
-	      lst->eval_error ();
-	      break;
-	    }
-
-	  if (t1.rows () == 0 || t1.columns () == 0)
-	    {
-	      int flag = user_pref.propagate_empty_matrices;
-	      if (flag < 0)
-		warning ("if: empty matrix used in conditional");
-	      else if (flag == 0)
-		{
-		  ::error ("if: empty matrix used in conditional");
-		  lst->eval_error ();
-		  return tree_constant ();
-		}
-	      t1 = tree_constant (0.0);
-	    }
-	  else if (! t1.is_scalar_type ())
-	    {
-	      tree_constant t2 = t1.all ();
-	      t1 = t2.all ();
-	    }
-
-	  tree_constant_rep::constant_type t = t1.const_type ();
-	  if (t == tree_constant_rep::scalar_constant)
-	    expr_value = (int) t1.double_value ();
-	  else if (t == tree_constant_rep::complex_scalar_constant)
-	    expr_value = t1.complex_value () != 0.0;
-	  else
-	    panic_impossible ();
-
-	  if (expr_value)
-	    {
-	      if (lst->list)
-		retval = lst->list->eval (1);
-	      else
-		::error ("if: empty command list");
-
-	      if (error_state)
-		lst->eval_error ();
-
-	      break;
-	    }
-	}
-      else
-	{
-	  if (lst->list)
-	    retval = lst->list->eval (1);
-	  else
-	    ::error ("if: empty command list");
-
-	  if (error_state)
-	    lst->eval_error ();
-
-	  break;
-	}
-    }
-
-  return retval;
 }
 
 void
-tree_if_command::eval_error (void)
+tree_if_command::eval (void)
 {
+  if (list)
+    list->eval ();
+
   if (error_state > 0)
     ::error ("evaluating if command near line %d, column %d",
 	     line (), column ());
 }
 
-/*
- * Break.  Is this overkill, or what?
- */
-tree_break_command::tree_break_command (int l, int c)
-{
-  line_num = l;
-  column_num = c;
-}
+// Break.
 
-tree_break_command::~tree_break_command (void)
-{
-}
-
-tree_constant
-tree_break_command::eval (int print)
+void
+tree_break_command::eval (void)
 {
   if (! error_state)
     breaking = 1;
-  return tree_constant ();
 }
 
-/*
- * Continue.
- */
-tree_continue_command::tree_continue_command (int l, int c)
-{
-  line_num = l;
-  column_num = c;
-}
+// Continue.
 
-tree_continue_command::~tree_continue_command (void)
-{
-}
-
-tree_constant
-tree_continue_command::eval (int print)
+void
+tree_continue_command::eval (void)
 {
   if (! error_state)
     continuing = 1;
-  return tree_constant ();
 }
 
-/*
- * Return.
- */
-tree_return_command::tree_return_command (int l, int c)
-{
-  line_num = l;
-  column_num = c;
-}
+// Return.
 
-tree_return_command::~tree_return_command (void)
-{
-}
-
-tree_constant
-tree_return_command::eval (int print)
+void
+tree_return_command::eval (void)
 {
   if (! error_state)
     returning = 1;
-  return tree_constant ();
 }
 
 /*
--- a/src/pt-cmd.h	Wed Aug 03 20:06:54 1994 +0000
+++ b/src/pt-cmd.h	Wed Aug 03 20:07:26 1994 +0000
@@ -28,13 +28,15 @@
 #pragma interface
 #endif
 
+class tree_statement_list;
+class tree_global_init_list;
+class tree_if_command_list;
 class tree_expression;
 class tree_index_expression;
 class tree_constant;
 class symbol_record;
 
 class tree_command;
-class tree_command_list;
 class tree_global_command;
 class tree_while_command;
 class tree_for_command;
@@ -43,183 +45,172 @@
 class tree_continue_command;
 class tree_return_command;
 
-/*
- * A base class for commands.
- */
+#include "tree-base.h"
+
+// A base class for commands.
+
 class
 tree_command : public tree
 {
+public:
+  tree_command (int l = -1, int c = -1) : tree (l, c) { }
+
+  virtual void eval (void) = 0;
 };
 
-/*
- * A command or two to be executed.
- */
-class
-tree_command_list : public tree_command
-{
- public:
-  tree_command_list (void);
-  tree_command_list (tree *t);
-
-  ~tree_command_list (void);
-
-  tree_command_list *chain (tree *t);
-  tree_command_list *reverse (void);
-
-  void set_print_flag (int print);
-
-  tree_constant eval (int print);
-
- private:
-  tree *command;		// Command to execute.
-  int print_flag;		// Print result of eval for this command?
-  tree_command_list *next;	// Next command in list.
-};
-
-/*
- * Global.
- */
 class
 tree_global_command : public tree_command
 {
  public:
-  tree_global_command (int l = -1, int c = -1);
-  tree_global_command (symbol_record *s, int l = -1, int c = -1);
-  tree_global_command (symbol_record *s, tree_expression *e,
-		       int l = -1, int c = -1); 
+  tree_global_command (int l = -1, int c = -1) : tree_command (l, c)
+    { init_list = 0; }
+
+  tree_global_command (tree_global_init_list *t, int l = -1, int c = -1)
+    : tree_command (l, c)
+      { init_list = t; }
 
   ~tree_global_command (void);
 
-  tree_global_command *chain (symbol_record *s, int l = -1, int c = -1);
-  tree_global_command *chain (symbol_record *s, tree_expression *e,
-			      int l = -1, int c = -1);
-  tree_global_command *reverse (void);
-
-  tree_constant eval (int print);
+  void eval (void);
 
-  void eval_error (void);
-
- private:
-  symbol_record *sr;		// Symbol record from local symbol table.
-  tree_expression *rhs;		// RHS of assignment.
-  tree_global_command *next;	// Next global command.
+private:
+  tree_global_init_list *init_list;
 };
 
-/*
- * While.
- */
+// While.
+
 class
 tree_while_command : public tree_command
 {
  public:
-  tree_while_command (int l = -1, int c = -1);
-  tree_while_command (tree_expression *e, int l = -1, int c = -1);
-  tree_while_command (tree_expression *e, tree *lst, int l = -1, int c = -1);
+  tree_while_command (int l = -1, int c = -1) : tree_command (l, c)
+    {
+      expr = 0;
+      list = 0;
+    }
+
+  tree_while_command (tree_expression *e, int l = -1, int c = -1)
+    : tree_command (l, c)
+      {
+	expr = e;
+	list = 0;
+      }
+
+  tree_while_command (tree_expression *e, tree_statement_list *lst,
+		      int l = -1, int c = -1)
+    : tree_command (l, c)
+      {
+	expr = e;
+	list = lst;
+      }
 
   ~tree_while_command (void);
 
-  tree_constant eval (int print);
+  void eval (void);
 
   void eval_error (void);
 
  private:
   tree_expression *expr;	// Expression to test.
-  tree *list;			// List of commands to execute.
+  tree_statement_list *list;	// List of commands to execute.
 };
 
-/*
- * For.
- */
+// For.
+
 class
 tree_for_command : public tree_command
 {
  public:
-  tree_for_command (int l = -1, int c = -1);
-  tree_for_command (tree_index_expression *id, tree_expression *e, tree *lst,
-		    int l = -1, int c = -1);
+  tree_for_command (int l = -1, int c = -1) : tree_command (l, c)
+    {
+      id = 0;
+      expr = 0;
+      list = 0;
+    }
+
+  tree_for_command (tree_index_expression *ident, tree_expression *e,
+		    tree_statement_list *lst, int l = -1, int c = -1)
+    : tree_command (l, c)
+      {
+	id = ident;
+	expr = e;
+	list = lst;
+      }
 
   ~tree_for_command (void);
 
-  tree_constant eval (int print);
+  void eval (void);
 
   void eval_error (void);
 
  private:
-  tree_constant do_for_loop_once (tree_constant *rhs, int& quit);
+  void do_for_loop_once (tree_constant *rhs, int& quit);
 
   tree_index_expression *id;	// Identifier to modify.
   tree_expression *expr;	// Expression to evaluate.
-  tree *list;			// List of commands to execute.
+  tree_statement_list *list;	// List of commands to execute.
 };
 
-/*
- * Simple if.
- */
+// If.
+
 class
 tree_if_command : public tree_command
 {
  public:
-  tree_if_command (int l = -1, int c = -1);
-  tree_if_command (tree *lst, int l = -1, int c = -1);
-  tree_if_command (tree_expression *e, tree *lst, int l = -1, int c = -1);
+  tree_if_command (int l = -1, int c = -1) : tree_command (l, c)
+    { list = 0; }
+
+  tree_if_command (tree_if_command_list *lst, int l = -1, int c = -1)
+    : tree_command (l, c)
+      { list = lst; }
 
   ~tree_if_command (void);
 
-  tree_if_command *chain (tree *lst, int l = -1, int c = -1);
-  tree_if_command *chain (tree_expression *e, tree *lst, int l = -1,
-			  int c = -1);
-  tree_if_command *reverse (void);
-
-  tree_constant eval (int print);
+  void eval (void);
 
   void eval_error (void);
 
  private:
-  tree_expression *expr;	// Expression to test.
-  tree *list;			// Commands to execute.
-  tree_if_command *next;	// Next if command.
+  tree_if_command_list *list;
 };
 
-/*
- * Break.
- */
+// Break.
+
 class
 tree_break_command : public tree_command
 {
  public:
-  tree_break_command (int l = -1, int c = -1);
+  tree_break_command (int l = -1, int c = -1) : tree_command (l, c) { }
 
-  ~tree_break_command (void);
+  ~tree_break_command (void) { }
 
-  tree_constant eval (int print);
+  void eval (void);
 };
 
-/*
- * Continue.
- */
+// Continue.
+
 class
 tree_continue_command : public tree_command
 {
  public:
-  tree_continue_command (int l = -1, int c = -1);
+  tree_continue_command (int l = -1, int c = -1) : tree_command (l, c) { }
 
-  ~tree_continue_command (void);
+  ~tree_continue_command (void) { }
 
-  tree_constant eval (int print);
+  void eval (void);
 };
 
-/*
- * Return.
- */
+// Return.
+
 class
 tree_return_command : public tree_command
 {
- public:
-  tree_return_command (int l = -1, int c = -1);
+public:
+  tree_return_command (int l = -1, int c = -1) : tree_command (l, c) { }
 
-  ~tree_return_command (void);
+  ~tree_return_command (void) { }
 
-  tree_constant eval (int print);
+  void eval (void);
 };
 
 #endif
--- a/src/pt-const.h	Wed Aug 03 20:06:54 1994 +0000
+++ b/src/pt-const.h	Wed Aug 03 20:07:26 1994 +0000
@@ -248,7 +248,7 @@
   tree_constant mapper (Mapper_fcn& m_fcn, int print) const
     { return rep->mapper (m_fcn, print); }
 
-  void bump_value (tree::expression_type et)
+  void bump_value (tree_expression::type et)
     {
       if (rep->count > 1)
 	{
--- a/src/pt-exp-base.cc	Wed Aug 03 20:06:54 1994 +0000
+++ b/src/pt-exp-base.cc	Wed Aug 03 20:07:26 1994 +0000
@@ -47,6 +47,7 @@
 #include "pager.h"
 #include "tree.h"
 #include "tree-expr.h"
+#include "tree-misc.h"
 #include "tree-const.h"
 #include "input.h"
 #include "symtab.h"
@@ -71,9 +72,8 @@
 // We seem to have no use for this now.  Maybe it will be needed at
 // some future date, so here it is.
 #if 0
-/*
- * Convert a linked list of trees to a vector of pointers to trees.
- */
+// Convert a linked list of trees to a vector of pointers to trees.
+
 static tree **
 list_to_vector (tree *list, int& len)
 {
@@ -106,9 +106,8 @@
 		  || nc == 0)));
 }
 
-/*
- * Make sure that all arguments have values.
- */
+// Make sure that all arguments have values.
+
 static int
 all_args_defined (const Octave_object& args)
 {
@@ -122,9 +121,8 @@
   return 1;
 }
 
-/*
- * Are any of the arguments `:'?
- */
+// Are any of the arguments `:'?
+
 static int
 any_arg_is_magic_colon (const Octave_object& args)
 {
@@ -142,24 +140,9 @@
 // are now defined in tree-const.cc.  This should help speed up
 // compilation when working only on the tree_constant class.
 
-/*
- * General matrices.  This list type is much more work to handle than
- * constant matrices, but it allows us to construct matrices from
- * other matrices, variables, and functions.
- */
-tree_matrix::tree_matrix (void)
-{
-  dir = tree::md_none;
-  element = 0;
-  next = 0;
-}
-
-tree_matrix::tree_matrix (tree_expression *e, tree::matrix_dir d)
-{
-  dir = d;
-  element = e;
-  next = 0;
-}
+// General matrices.  This list type is much more work to handle than
+// constant matrices, but it allows us to construct matrices from
+// other matrices, variables, and functions.
 
 tree_matrix::~tree_matrix (void)
 {
@@ -168,7 +151,7 @@
 }
 
 tree_matrix *
-tree_matrix::chain (tree_expression *t, tree::matrix_dir d)
+tree_matrix::chain (tree_expression *t, tree_matrix::dir d)
 {
   tree_matrix *tmp = new tree_matrix (t, d);
   tmp->next = this;
@@ -209,26 +192,32 @@
 tree_matrix::to_return_list (void)
 {
   tree_return_list *retval = 0;
+
   tree_matrix *list;
+
   for (list = this; list; list = list->next)
     {
       tree_expression *elem = list->element;
-      if (elem->is_identifier ())
+
+      int is_id = elem->is_identifier ();
+
+      int is_idx_expr = elem->is_index_expression ();
+
+      if (is_id || is_idx_expr)
 	{
-	  tree_identifier *id = (tree_identifier *) elem;
-	  if (list == this)
-	    retval = new tree_return_list (id);
+	  tree_index_expression *idx_expr;
+	  if (is_id)
+	    {
+	      tree_identifier *id = (tree_identifier *) elem;
+	      idx_expr = new tree_index_expression (id);
+	    }
 	  else
-	    retval = retval->chain (id);
-	}
-      else if (elem->is_index_expression ())
-//	       && ! ((tree_index_expression *) elem) -> arg_list ())
-	{
-	  tree_index_expression *idx_expr = (tree_index_expression *) elem;
+	    idx_expr = (tree_index_expression *) elem;
+
 	  if (list == this)
 	    retval = new tree_return_list (idx_expr);
 	  else
-	    retval = retval->chain (idx_expr);
+	    retval->append (idx_expr);
 	}
       else
 	{
@@ -238,8 +227,6 @@
 	}
     }
 
-  if (retval)
-    retval = retval->reverse ();
   return retval;
 }
 
@@ -247,7 +234,7 @@
 
 struct const_matrix_list
 {
-  tree::matrix_dir dir;
+  tree_matrix::dir dir_next;
   tree_constant elem;
   int nr;
   int nc;
@@ -330,7 +317,7 @@
       int nr = tmp.rows ();
       int nc = tmp.columns ();
 
-      matrix_dir direct = ptr->dir;
+      dir direct = ptr->dir_next;
 
       if (nr == 0 || nc == 0)
 	{
@@ -352,10 +339,10 @@
       if (found_new_row_in_empties)
 	{
 	  found_new_row_in_empties = 0;
-	  list[len].dir = md_down;
+	  list[len].dir_next = md_down;
 	}
       else
-	list[len].dir = direct;
+	list[len].dir_next = direct;
 
       list[len].elem = tmp;
       list[len].nr = nr;
@@ -382,7 +369,8 @@
 
   for (i = 0; i < len; i++)
     {
-      matrix_dir direct = list[i].dir;
+      dir direct = list[i].dir_next;
+
       int nr = list[i].nr;
       int nc = list[i].nc;
 
@@ -472,7 +460,7 @@
 	}
       else
 	{
-	  switch (list[i].dir)
+	  switch (list[i].dir_next)
 	    {
 	    case md_right:
 	      put_col += prev_nc;
@@ -584,9 +572,8 @@
   return tree_constant ();
 }
 
-/*
- * Builtin functions.
- */
+// Builtin functions.
+
 tree_builtin::tree_builtin (const char *nm)
 {
   nargin_max = -1;
@@ -620,23 +607,6 @@
     my_name = strsave (nm);
 }
 
-tree_builtin::~tree_builtin (void)
-{
-}
-
-#if 0
-int
-tree_builtin::is_builtin (void) const
-{
-  return 1;
-}
-#endif
-
-int
-tree_builtin::is_mapper_function (void) const
-{
-  return is_mapper;
-}
 
 tree_constant
 tree_builtin::eval (int print)
@@ -694,12 +664,6 @@
   return retval;
 }
 
-char *
-tree_builtin::name (void) const
-{
-  return my_name;
-}
-
 int
 tree_builtin::max_expected_args (void)
 {
@@ -711,34 +675,7 @@
   return ea;
 }
 
-/*
- * Symbols from the symbol table.
- */
-tree_identifier::tree_identifier (int l, int c)
-{
-  sym = 0;
-  line_num = l;
-  column_num = c;
-  maybe_do_ans_assign = 0;
-}
-
-tree_identifier::tree_identifier (symbol_record *s, int l, int c)
-{
-  sym = s;
-  line_num = l;
-  column_num = c;
-  maybe_do_ans_assign = 0;
-}
-
-tree_identifier::~tree_identifier (void)
-{
-}
-
-int
-tree_identifier::is_identifier (void) const
-{
-  return 1;
-}
+// Symbols from the symbol table.
 
 char *
 tree_identifier::name (void) const
@@ -859,7 +796,7 @@
 }
 
 void
-tree_identifier::bump_value (tree::expression_type etype)
+tree_identifier::bump_value (tree_expression::type etype)
 {
   if (sym)
     {
@@ -1055,22 +992,21 @@
     ::error ("`%s' undefined near line %d column %d", nm, l, c);
 }
 
-/*
- * Try to find a definition for an identifier.  Here's how:
- *
- *   * If the identifier is already defined and is a function defined
- *     in an function file that has been modified since the last time 
- *     we parsed it, parse it again.
- *
- *   * If the identifier is not defined, try to find a builtin
- *     variable or an already compiled function with the same name.
- *
- *   * If the identifier is still undefined, try looking for an
- *     function file to parse.
- *
- *   * On systems that support dynamic linking, we prefer .oct files
- *     over .m files.
- */
+// Try to find a definition for an identifier.  Here's how:
+//
+//   * If the identifier is already defined and is a function defined
+//     in an function file that has been modified since the last time 
+//     we parsed it, parse it again.
+//
+//   * If the identifier is not defined, try to find a builtin
+//     variable or an already compiled function with the same name.
+//
+//   * If the identifier is still undefined, try looking for an
+//     function file to parse.
+//
+//   * On systems that support dynamic linking, we prefer .oct files
+//     over .m files.
+
 tree_fvc *
 tree_identifier::do_lookup (int& script_file_executed)
 {
@@ -1115,12 +1051,6 @@
     sym->mark_as_formal_parameter ();
 }
 
-void
-tree_identifier::mark_for_possible_ans_assign (void)
-{
-  maybe_do_ans_assign = 1;
-}
-
 tree_constant
 tree_identifier::eval (int print)
 {
@@ -1259,51 +1189,16 @@
   return retval;
 }
 
-/*
- * User defined functions.
- */
-tree_function::tree_function (void)
-{
-  call_depth = 0;
-  param_list = 0;
-  ret_list = 0;
-  sym_tab = 0;
-  cmd_list = 0;
-  file_name = 0;
-  fcn_name = 0;
-  t_parsed = 0;
-  system_fcn_file = 0;
-  num_named_args = 0;
-  num_args_passed = 0;
-  curr_va_arg_number = 0;
-}
+// User defined functions.
 
-tree_function::tree_function (tree *cl, symbol_table *st)
-{
-  call_depth = 0;
-  param_list = 0;
-  ret_list = 0;
-  sym_tab = st;
-  cmd_list = cl;
-  file_name = 0;
-  fcn_name = 0;
-  t_parsed = 0;
-  system_fcn_file = 0;
-  num_named_args = 0;
-  num_args_passed = 0;
-  curr_va_arg_number = 0;
-}
-
-tree_function::~tree_function (void)
-{
-}
-
+#if 0
 tree_function *
-tree_function::define (tree *t)
+tree_function::define (tree statement_list *t)
 {
   cmd_list = t;
   return this;
 }
+#endif
 
 tree_function *
 tree_function::define_param_list (tree_parameter_list *t)
@@ -1336,24 +1231,6 @@
 }
 
 void
-tree_function::stash_fcn_file_time (time_t t)
-{
-  t_parsed = t;
-}
-
-char *
-tree_function::fcn_file_name (void)
-{
-  return file_name;
-}
-
-time_t
-tree_function::time_parsed (void)
-{
-  return t_parsed;
-}
-
-void
 tree_function::mark_as_system_fcn_file (void)
 {
   if (file_name)
@@ -1380,23 +1257,11 @@
 }
 
 int
-tree_function::is_system_fcn_file (void) const
-{
-  return system_fcn_file;
-}
-
-int
 tree_function::takes_varargs (void) const
 {
   return (param_list && param_list->takes_varargs ());
 }
 
-void
-tree_function::octave_va_start (void)
-{
-  curr_va_arg_number = num_named_args;
-}
-
 tree_constant
 tree_function::octave_va_arg (void)
 {
@@ -1418,12 +1283,6 @@
   fcn_name = strsave (s);
 }
 
-char *
-tree_function::function_name (void)
-{
-  return fcn_name;
-}
-
 tree_constant
 tree_function::eval (int print)
 {
@@ -1646,17 +1505,7 @@
   return retval;
 }
 
-/*
- * Expressions.
- */
-tree_expression::tree_expression (void)
-{
-  etype = tree::unknown;
-}
-
-tree_expression::~tree_expression (void)
-{
-}
+// Expressions.
 
 tree_constant
 tree_expression::eval (int print)
@@ -1668,35 +1517,11 @@
 Octave_object
 tree_expression::eval (int print, int nargout, const Octave_object& args)
 {
-  panic_impossible ();
+  panic ("invalid evaluation of generic expression");
   return Octave_object ();
 }
 
-/*
- * Prefix expressions.
- */
-tree_prefix_expression::tree_prefix_expression (int l, int c)
-{
-  id = 0;
-  etype = unknown;
-  line_num = l;
-  column_num = c;
-}
-
-tree_prefix_expression::tree_prefix_expression (tree_identifier *t,
-						tree::expression_type et,
-						int l, int c)
-{
-  id = t;
-  etype = et;
-  line_num = l;
-  column_num = c;
-}
-
-tree_prefix_expression::~tree_prefix_expression (void)
-{
-  delete id;
-}
+// Prefix expressions.
 
 tree_constant
 tree_prefix_expression::eval (int print)
@@ -1728,9 +1553,9 @@
       char *op;
       switch (etype)
 	{
-	case tree::increment: op = "++";      break;
-	case tree::decrement: op = "--";      break;
-	default:              op = "unknown"; break;
+	case tree_expression::increment: op = "++";      break;
+	case tree_expression::decrement: op = "--";      break;
+	default:                         op = "unknown"; break;
 	}
 
       ::error ("evaluating prefix operator `%s' near line %d, column %d",
@@ -1738,37 +1563,7 @@
     }
 }
 
-int
-tree_prefix_expression::is_prefix_expression (void) const
-{
-  return 1;
-}
-
-/*
- * Postfix expressions.
- */
-tree_postfix_expression::tree_postfix_expression (int l, int c)
-{
-  id = 0;
-  etype = unknown;
-  line_num = l;
-  column_num = c;
-}
-
-tree_postfix_expression::tree_postfix_expression (tree_identifier *t,
-						  tree::expression_type et,
-						  int l, int c)
-{
-  id = t;
-  etype = et;
-  line_num = l;
-  column_num = c;
-}
-
-tree_postfix_expression::~tree_postfix_expression (void)
-{
-  delete id;
-}
+// Postfix expressions.
 
 tree_constant
 tree_postfix_expression::eval (int print)
@@ -1800,9 +1595,9 @@
       char *op;
       switch (etype)
 	{
-	case tree::increment: op = "++";      break;
-	case tree::decrement: op = "--";      break;
-	default:              op = "unknown"; break;
+	case tree_expression::increment: op = "++";      break;
+	case tree_expression::decrement: op = "--";      break;
+	default:                         op = "unknown"; break;
 	}
 
       ::error ("evaluating postfix operator `%s' near line %d, column %d",
@@ -1810,31 +1605,7 @@
     }
 }
 
-/*
- * Unary expressions.
- */
-tree_unary_expression::tree_unary_expression (int l, int c)
-{
-  etype = tree::unknown;
-  op = 0;
-  line_num = l;
-  column_num = c;
-}
-
-tree_unary_expression::tree_unary_expression (tree_expression *a,
-					      tree::expression_type t,
-					      int l, int c)
-{
-  etype = t;
-  op = a;
-  line_num = l;
-  column_num = c;
-}
-
-tree_unary_expression::~tree_unary_expression (void)
-{
-  delete op;
-}
+// Unary expressions.
 
 tree_constant
 tree_unary_expression::eval (int print)
@@ -1846,10 +1617,10 @@
 
   switch (etype)
     {
-    case tree::not:
-    case tree::uminus:
-    case tree::hermitian:
-    case tree::transpose:
+    case tree_expression::not:
+    case tree_expression::uminus:
+    case tree_expression::hermitian:
+    case tree_expression::transpose:
       if (op)
 	{
 	  tree_constant u = op->eval (0);
@@ -1883,11 +1654,11 @@
       char *op;
       switch (etype)
 	{
-	case tree::not:        op = "!";       break;
-	case tree::uminus:     op = "-";       break;
-	case tree::hermitian:  op = "'";       break;
-	case tree::transpose:  op = ".'";      break;
-	default:               op = "unknown"; break;
+	case tree_expression::not:        op = "!";       break;
+	case tree_expression::uminus:     op = "-";       break;
+	case tree_expression::hermitian:  op = "'";       break;
+	case tree_expression::transpose:  op = ".'";      break;
+	default:                          op = "unknown"; break;
 	}
 
       ::error ("evaluating unary operator `%s' near line %d, column %d",
@@ -1895,36 +1666,8 @@
     }
 }
 
-/*
- * Binary expressions.
- */
-tree_binary_expression::tree_binary_expression (int l, int c)
-{
-  etype = tree::unknown;
-  op1 = 0;
-  op2 = 0;
-  line_num = l;
-  column_num = c;
-}
-
-tree_binary_expression::tree_binary_expression (tree_expression *a,
-						tree_expression *b,
-						tree::expression_type t,
-						int l, int c)
-{
-  etype = t;
-  op1 = a;
-  op2 = b;
-  line_num = l;
-  column_num = c;
-}
-
-tree_binary_expression::~tree_binary_expression (void)
-{
-  delete op1;
-  delete op2;
-}
-
+// Binary expressions.
+ 
 tree_constant
 tree_binary_expression::eval (int print)
 {
@@ -1934,24 +1677,24 @@
   tree_constant ans;
   switch (etype)
     {
-    case tree::add:
-    case tree::subtract:
-    case tree::multiply:
-    case tree::el_mul:
-    case tree::divide:
-    case tree::el_div:
-    case tree::leftdiv:
-    case tree::el_leftdiv:
-    case tree::power:
-    case tree::elem_pow:
-    case tree::cmp_lt:
-    case tree::cmp_le:
-    case tree::cmp_eq:
-    case tree::cmp_ge:
-    case tree::cmp_gt:
-    case tree::cmp_ne:
-    case tree::and:
-    case tree::or:
+    case tree_expression::add:
+    case tree_expression::subtract:
+    case tree_expression::multiply:
+    case tree_expression::el_mul:
+    case tree_expression::divide:
+    case tree_expression::el_div:
+    case tree_expression::leftdiv:
+    case tree_expression::el_leftdiv:
+    case tree_expression::power:
+    case tree_expression::elem_pow:
+    case tree_expression::cmp_lt:
+    case tree_expression::cmp_le:
+    case tree_expression::cmp_eq:
+    case tree_expression::cmp_ge:
+    case tree_expression::cmp_gt:
+    case tree_expression::cmp_ne:
+    case tree_expression::and:
+    case tree_expression::or:
       if (op1)
 	{
 	  tree_constant a = op1->eval (0);
@@ -1975,8 +1718,8 @@
 	    }
 	}
       break;
-    case tree::and_and:
-    case tree::or_or:
+    case tree_expression::and_and:
+    case tree_expression::or_or:
       {
 	int result = 0;
 	if (op1)
@@ -1997,7 +1740,7 @@
 
 	    if (a_true)
 	      {
-		if (etype == tree::or_or)
+		if (etype == tree_expression::or_or)
 		  {
 		    result = 1;
 		    goto done;
@@ -2005,7 +1748,7 @@
 	      }
 	    else
 	      {
-		if (etype == tree::and_and)
+		if (etype == tree_expression::and_and)
 		  {
 		    result = 0;
 		    goto done;
@@ -2049,27 +1792,27 @@
       char *op;
       switch (etype)
 	{
-	case tree::add:        op = "+";       break;
-	case tree::subtract:   op = "-";       break;
-	case tree::multiply:   op = "*";       break;
-	case tree::el_mul:     op = ".*";      break;
-	case tree::divide:     op = "/";       break;
-	case tree::el_div:     op = "./";      break;
-	case tree::leftdiv:    op = "\\";      break;
-	case tree::el_leftdiv: op = ".\\";     break;
-	case tree::power:      op = "^";       break;
-	case tree::elem_pow:   op = ".^";      break;
-	case tree::cmp_lt:     op = "<";       break;
-	case tree::cmp_le:     op = "<=";      break;
-	case tree::cmp_eq:     op = "==";      break;
-	case tree::cmp_ge:     op = ">=";      break;
-	case tree::cmp_gt:     op = ">";       break;
-	case tree::cmp_ne:     op = "!=";      break;
-	case tree::and_and:    op = "&&";      break;
-	case tree::or_or:      op = "||";      break;
-	case tree::and:        op = "&";       break;
-	case tree::or:         op = "|";       break;
-	default:               op = "unknown"; break;
+	case tree_expression::add:        op = "+";       break;
+	case tree_expression::subtract:   op = "-";       break;
+	case tree_expression::multiply:   op = "*";       break;
+	case tree_expression::el_mul:     op = ".*";      break;
+	case tree_expression::divide:     op = "/";       break;
+	case tree_expression::el_div:     op = "./";      break;
+	case tree_expression::leftdiv:    op = "\\";      break;
+	case tree_expression::el_leftdiv: op = ".\\";     break;
+	case tree_expression::power:      op = "^";       break;
+	case tree_expression::elem_pow:   op = ".^";      break;
+	case tree_expression::cmp_lt:     op = "<";       break;
+	case tree_expression::cmp_le:     op = "<=";      break;
+	case tree_expression::cmp_eq:     op = "==";      break;
+	case tree_expression::cmp_ge:     op = ">=";      break;
+	case tree_expression::cmp_gt:     op = ">";       break;
+	case tree_expression::cmp_ne:     op = "!=";      break;
+	case tree_expression::and_and:    op = "&&";      break;
+	case tree_expression::or_or:      op = "||";      break;
+	case tree_expression::and:        op = "&";       break;
+	case tree_expression::or:         op = "|";       break;
+	default:                          op = "unknown"; break;
 	}
 
       ::error ("evaluating binary operator `%s' near line %d, column %d",
@@ -2077,18 +1820,7 @@
     }
 }
 
-/*
- * Assignment expressions.
- */
-tree_assignment_expression::tree_assignment_expression (void)
-{
-  in_parens = 0;
-  etype = tree::assignment;
-}
-
-tree_assignment_expression::~tree_assignment_expression (void)
-{
-}
+// Assignment expressions.
 
 tree_constant
 tree_assignment_expression::eval (int print)
@@ -2097,59 +1829,22 @@
   return tree_constant ();
 }
 
-int
-tree_assignment_expression::is_assignment_expression (void) const
-{
-  return 1;
-}
-
-/*
- * Simple assignment expressions.
- */
-tree_simple_assignment_expression::tree_simple_assignment_expression
-  (int l, int c)
-{
-  etype = tree::assignment;
-  lhs = 0;
-  index = 0;
-  rhs = 0;
-  line_num = l;
-  column_num = c;
-}
-
-tree_simple_assignment_expression::tree_simple_assignment_expression
-  (tree_identifier *i, tree_expression *r, int l, int c)
-{
-  etype = tree::assignment;
-  lhs = i;
-  index = 0;
-  rhs = r;
-  line_num = l;
-  column_num = c;
-}
-
-tree_simple_assignment_expression::tree_simple_assignment_expression
-  (tree_index_expression *idx_expr, tree_expression *r, int l, int c)
-{
-  etype = tree::assignment;
-  lhs = idx_expr->ident ();
-  index = idx_expr->arg_list ();
-  rhs = r;
-  line_num = l;
-  column_num = c;
-}
+// Simple assignment expressions.
 
 tree_simple_assignment_expression::~tree_simple_assignment_expression (void)
 {
-//  delete lhs;
-//  delete index; 
+  if (! preserve)
+    {
+      delete lhs;
+      delete index;
+    }
   delete rhs;
 }
 
 tree_constant
 tree_simple_assignment_expression::eval (int print)
 {
-  assert (etype == tree::assignment);
+  assert (etype == tree_expression::assignment);
 
   tree_constant ans;
   tree_constant retval;
@@ -2237,28 +1932,7 @@
     }
 }
 
-/*
- * Multi-valued assignmnt expressions.
- */
-tree_multi_assignment_expression::tree_multi_assignment_expression
-  (int l, int c)
-{
-  etype = tree::multi_assignment;
-  lhs = 0;
-  rhs = 0;
-  line_num = l;
-  column_num = c;
-}
-
-tree_multi_assignment_expression::tree_multi_assignment_expression
-  (tree_return_list *lst, tree_expression *r, int l, int c)
-{
-  etype = tree::multi_assignment;
-  lhs = lst;
-  rhs = r;
-  line_num = l;
-  column_num = c;
-}
+// Multi-valued assignmnt expressions.
 
 tree_multi_assignment_expression::~tree_multi_assignment_expression (void)
 {
@@ -2287,7 +1961,7 @@
 tree_multi_assignment_expression::eval (int print, int nargout,
 					const Octave_object& args)
 {
-  assert (etype == tree::multi_assignment);
+  assert (etype == tree_expression::multi_assignment);
 
   if (error_state || ! rhs)
     return Octave_object ();
@@ -2304,13 +1978,13 @@
 
   if (results.length () > 0)
     {
-      tree_return_list *elem;
       int i = 0;
       int pad_after = 0;
       int last_was_scalar_type = 0;
-      for (elem = lhs; elem; elem = elem->next_elem ())
+      for (Pix p = lhs->first (); p != 0; lhs->next (p))
 	{
-	  tree_index_expression *lhs_expr = elem->idx_expr ();
+	  tree_index_expression *lhs_expr = (*lhs) (p);
+
 	  if (i < nargout)
 	    {
 // XXX FIXME? XXX -- this is apparently the way Matlab works, but
@@ -2326,7 +2000,7 @@
 		tmp = new tree_constant (results(i));
 
 	      tree_simple_assignment_expression tmp_expr
-		(lhs_expr, tmp, ma_line, ma_column);
+		(lhs_expr, tmp, 1, ma_line, ma_column);
 
 	      results(i) = tmp_expr.eval (0); // May change
 
@@ -2369,7 +2043,7 @@
 	  else
 	    {
 	      tree_simple_assignment_expression tmp_expr
-		(lhs_expr, 0, ma_line, ma_column);
+		(lhs_expr, 0, 1, ma_line, ma_column);
 
 	      tmp_expr.eval (0);
 
@@ -2402,36 +2076,7 @@
 	     line (), column ());
 }
 
-/*
- * Colon expressions.
- */
-tree_colon_expression::tree_colon_expression (int l, int c)
-{
-  etype = tree::colon;
-  op1 = 0;
-  op2 = 0;
-  op3 = 0;
-  line_num = l;
-  column_num = c;
-}
-
-tree_colon_expression::tree_colon_expression (tree_expression *a, tree_expression *b,
-					      int l, int c)
-{
-  etype = tree::colon;
-  op1 = a;	// base
-  op2 = b;	// limit
-  op3 = 0;	// increment if not empty.
-  line_num = l;
-  column_num = c;
-}
-
-tree_colon_expression::~tree_colon_expression (void)
-{
-  delete op1;
-  delete op2;
-  delete op3;
-}
+// Colon expressions.
 
 tree_colon_expression *
 tree_colon_expression::chain (tree_expression *t)
@@ -2534,35 +2179,7 @@
     ::error ("%s near line %d column %d", s, line (), column ());
 }
 
-/*
- * Index expressions.
- */
-tree_index_expression::tree_index_expression (int l, int c)
-{
-  id = 0;
-  list = 0;
-  line_num = l;
-  column_num = c;
-}
-
-tree_index_expression::tree_index_expression (tree_identifier *i,
-					      tree_argument_list *lst,
-					      int l, int c)
-{
-  id = i;
-  list = lst;
-  line_num = l;
-  column_num = c;
-}
-
-tree_index_expression::tree_index_expression (tree_identifier *i,
-					      int l, int c)
-{
-  id = i;
-  list = 0;
-  line_num = l;
-  column_num = c;
-}
+// Index expressions.
 
 tree_index_expression::~tree_index_expression (void)
 {
@@ -2570,31 +2187,6 @@
   delete list;
 }
 
-int
-tree_index_expression::is_index_expression (void) const
-{
-  return 1;
-}
-
-tree_identifier *
-tree_index_expression::ident (void)
-{
-  return id;
-}
-
-tree_argument_list *
-tree_index_expression::arg_list (void)
-{
-  return list;
-}
-
-void
-tree_index_expression::mark_for_possible_ans_assign (void)
-{
-  id->mark_for_possible_ans_assign ();
-}
-
-
 tree_constant
 tree_index_expression::eval (int print)
 {
@@ -2693,386 +2285,6 @@
 }
 
 /*
- * Argument lists.
- */
-tree_argument_list::tree_argument_list (void)
-{
-  arg = 0;
-  next = 0;
-}
-
-tree_argument_list::tree_argument_list (tree *t)
-{
-  arg = t;
-  next = 0;
-}
-
-tree_argument_list::~tree_argument_list (void)
-{
-  delete arg;
-  delete next;
-}
-
-tree_argument_list *
-tree_argument_list::chain (tree *t)
-{
-  tree_argument_list *tmp = new tree_argument_list (t);
-  tmp->next = this;
-  return tmp;
-}
-
-tree_argument_list *
-tree_argument_list::reverse (void)
-{
-  tree_argument_list *list = this;
-  tree_argument_list *next;
-  tree_argument_list *prev = 0;
-
-  while (list)
-    {
-      next = list->next;
-      list->next = prev;
-      prev = list;
-      list = next;
-    }
-  return prev;
-}
-
-int
-tree_argument_list::length (void)
-{
-  tree_argument_list *list = this;
-  int len = 0;
-  while (list)
-    {
-      len++;
-      list = list->next;
-    }
-  return len;
-}
-
-tree_argument_list *
-tree_argument_list::next_elem (void)
-{
-  return next;
-}
-
-/*
- * Convert a linked list of trees to a vector of pointers to trees,
- * evaluating them along the way.
- */
-Octave_object
-tree_argument_list::convert_to_const_vector (void)
-{
-  int len = length () + 1;
-
-  Octave_object args;
-  args.resize (len);
-
-// args[0] may eventually hold something useful, like the function
-// name.
-  tree_argument_list *tmp_list = this;
-  for (int k = 1; k < len; k++)
-    {
-      if (tmp_list)
-	{
-	  args(k) = tmp_list->eval (0);
-	  if (error_state)
-	    {
-	      ::error ("evaluating argument list element number %d", k);
-	      break;
-	    }
-	  tmp_list = tmp_list->next;
-	}
-      else
-	{
-	  args(k) = tree_constant ();
-	  break;
-	}
-    }
-  return args;
-}
-
-tree_constant
-tree_argument_list::eval (int print)
-{
-  if (error_state || ! arg)
-    return tree_constant ();
-  else
-    return arg->eval (print);
-}
-
-/*
- * Parameter lists.
- */
-tree_parameter_list::tree_parameter_list (void)
-{
-  marked_for_varargs = 0;
-  param = 0;
-  next = 0;
-}
-
-tree_parameter_list::tree_parameter_list (tree_identifier *t)
-{
-  marked_for_varargs = 0;
-  param = t;
-  next = 0;
-}
-
-tree_parameter_list::~tree_parameter_list (void)
-{
-  delete param;
-  delete next;
-}
-
-tree_parameter_list *
-tree_parameter_list::chain (tree_identifier *t)
-{
-  tree_parameter_list *tmp = new tree_parameter_list (t);
-  tmp->next = this;
-  return tmp;
-}
-
-tree_parameter_list *
-tree_parameter_list::reverse (void)
-{
-  tree_parameter_list *list = this;
-  tree_parameter_list *next;
-  tree_parameter_list *prev = 0;
-
-  while (list)
-    {
-      next = list->next;
-      list->next = prev;
-      prev = list;
-      list = next;
-    }
-  return prev;
-}
-
-int
-tree_parameter_list::length (void)
-{
-  tree_parameter_list *list = this;
-  int len = 0;
-  while (list)
-    {
-      len++;
-      list = list->next;
-    }
-  return len;
-}
-
-char *
-tree_parameter_list::name (void) const
-{
-  return param->name ();
-}
-
-void
-tree_parameter_list::mark_as_formal_parameters (void)
-{
-  param->mark_as_formal_parameter ();
-  if (next)
-    next->mark_as_formal_parameters ();
-}
-
-void
-tree_parameter_list::mark_varargs (void)
-{
-  marked_for_varargs = 1;
-}
-
-int
-tree_parameter_list::takes_varargs (void) const
-{
-  return marked_for_varargs;
-}
-
-void
-tree_parameter_list::mark_varargs_only (void)
-{
-  marked_for_varargs = -1;
-}
-
-int
-tree_parameter_list::varargs_only (void)
-{
-  return (marked_for_varargs < 0);
-}
-
-tree_identifier *
-tree_parameter_list::define (tree_constant *t)
-{
-  return param->define (t);
-}
-
-void
-tree_parameter_list::define_from_arg_vector (const Octave_object& args)
-{
-  if (args.length () <= 0)
-    return;
-
-  int nargin = args.length ();
-
-  int expected_nargin = length () + 1;
-
-  tree_parameter_list *ptr = this;
-
-  for (int i = 1; i < expected_nargin; i++)
-    {
-      tree_constant *tmp = 0;
-
-      if (i < nargin)
-	{
-	  if (args(i).is_defined ()
-	      && (args(i).const_type () == tree_constant_rep::magic_colon))
-	    {
-	      ::error ("invalid use of colon in function argument list");
-	      return;
-	    }
-	  tmp = new tree_constant (args(i));
-	}
-
-      ptr->define (tmp);
-      ptr = ptr->next;
-    }
-}
-
-Octave_object
-tree_parameter_list::convert_to_const_vector (void)
-{
-  int nout = length ();
-
-  Octave_object retval;
-  retval.resize (nout);
-
-  int i = 0;
-  
-  for (tree_parameter_list *elem = this; elem; elem = elem->next)
-    {
-      if (elem->is_defined ())
-	retval(i) = elem->eval (0);
-      i++;
-    }
-
-  return retval;
-}
-
-int
-tree_parameter_list::is_defined (void)
-{
-  return (param && param->is_defined ());
-}
-
-tree_parameter_list *
-tree_parameter_list::next_elem (void)
-{
-  return next;
-}
-
-tree_constant
-tree_parameter_list::eval (int print)
-{
-  if (error_state || ! param)
-    return tree_constant ();
-  else
-    return param->eval (print);
-}
-
-/*
- * Return lists.
- */
-tree_return_list::tree_return_list (void)
-{
-  retval = 0;
-  next = 0;
-}
-
-tree_return_list::tree_return_list (tree_identifier *t)
-{
-  retval = new tree_index_expression (t);
-  next = 0;
-}
-
-tree_return_list::tree_return_list (tree_index_expression *t)
-{
-  retval = t;
-  next = 0;
-}
-
-tree_return_list::~tree_return_list (void)
-{
-  delete retval;
-  delete next;
-}
-
-tree_return_list *
-tree_return_list::chain (tree_identifier *t)
-{
-  tree_return_list *tmp = new tree_return_list (t);
-  tmp->next = this;
-  return tmp;
-}
-
-tree_return_list *
-tree_return_list::chain (tree_index_expression *t)
-{
-  tree_return_list *tmp = new tree_return_list (t);
-  tmp->next = this;
-  return tmp;
-}
-
-tree_return_list *
-tree_return_list::reverse (void)
-{
-  tree_return_list *list = this;
-  tree_return_list *next;
-  tree_return_list *prev = 0;
-
-  while (list)
-    {
-      next = list->next;
-      list->next = prev;
-      prev = list;
-      list = next;
-    }
-  return prev;
-}
-
-int
-tree_return_list::length (void)
-{
-  tree_return_list *list = this;
-  int len = 0;
-  while (list)
-    {
-      len++;
-      list = list->next;
-    }
-  return len;
-}
-
-tree_index_expression *
-tree_return_list::idx_expr (void)
-{
-  return retval;
-}
-
-tree_return_list *
-tree_return_list::next_elem (void)
-{
-  return next;
-}
-
-tree_constant
-tree_return_list::eval (int print)
-{
-  panic ("invalid evaluation of return list");
-  return tree_constant ();
-}
-
-/*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
 ;;; page-delimiter: "^/\\*" ***
--- a/src/pt-exp-base.h	Wed Aug 03 20:06:54 1994 +0000
+++ b/src/pt-exp-base.h	Wed Aug 03 20:07:26 1994 +0000
@@ -37,6 +37,10 @@
 #include "oct-obj.h"
 
 class tree_constant;
+class tree_statement_list;
+class tree_argument_list;
+class tree_parameter_list;
+class tree_return_list;
 class symbol_record;
 class symbol_table;
 
@@ -54,22 +58,56 @@
 class tree_multi_assignment_expression;
 class tree_colon_expression;
 class tree_index_expression;
-class tree_argument_list;
-class tree_parameter_list;
-class tree_return_list;
+
+#include "tree-base.h"
 
-/*
- * A base class for expressions.
- */
+// A base class for expressions.
+
 class
 tree_expression : public tree
 {
 public:
-  tree_expression (void);
+  enum type
+    {
+      unknown,
+      assignment,
+      simple_assignment,
+      multi_assignment,
+      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,
+      and_and,
+      or_or,
+      and,
+      or,
+      not,
+      unot,
+      uminus,
+      hermitian,
+      transpose,
+      colon,
+      index,
+      increment,
+      decrement,
+   };
 
-  ~tree_expression (void);
+  tree_expression (int l = -1, int c = -1) : tree (l, c)
+    { etype = unknown; }
 
-  tree_constant eval (int print);
+  ~tree_expression (void) { }
 
   virtual int is_identifier (void) const
     { return 0; }
@@ -86,27 +124,46 @@
   virtual void mark_for_possible_ans_assign (void)
     { panic_impossible (); }
 
+  virtual tree_constant eval (int print) = 0;
+
   virtual Octave_object eval (int print, int nargout,
 			      const Octave_object& args);
 
 protected:
-  expression_type etype;
+  type etype;
 };
 
-/*
- * General matrices.  This allows us to construct matrices from
- * other matrices, variables, and functions.
- */
+// General matrices.  This allows us to construct matrices from
+// other matrices, variables, and functions.
+
 class
 tree_matrix : public tree_expression
 {
 public:
-  tree_matrix (void);
-  tree_matrix (tree_expression *e, tree::matrix_dir d);
+  enum dir
+    {
+      md_none,
+      md_right,
+      md_down,
+    };
+
+  tree_matrix (void)
+    {
+      dir_next = tree_matrix::md_none;
+      element = 0;
+      next = 0;
+    }
+
+  tree_matrix (tree_expression *e, tree_matrix::dir d)
+    {
+      dir_next = d;
+      element = e;
+      next = 0;
+    }
 
   ~tree_matrix (void);
 
-  tree_matrix *chain (tree_expression *e, tree::matrix_dir d);
+  tree_matrix *chain (tree_expression *e, tree_matrix::dir d);
   tree_matrix *reverse (void);
   int length (void);
 
@@ -115,232 +172,19 @@
   tree_constant eval (int print);
 
 private:
-  tree::matrix_dir dir; // Direction to the next element.
+  tree_matrix::dir dir_next; // Direction to the next element.
   tree_expression *element;
   tree_matrix *next;
 };
 
-/*
- * Prefix expressions.
- */
-class
-tree_prefix_expression : public tree_expression
-{
- public:
-  tree_prefix_expression (int l = -1, int c = -1);
-  tree_prefix_expression (tree_identifier *t, tree::expression_type et,
-			  int l = -1, int c = -1);
-
-  ~tree_prefix_expression (void);
-
-  tree_constant eval (int print);
-
-  void eval_error (void);
-
-  int is_prefix_expression (void) const;
-
- private:
-  tree_identifier *id;
-};
-
-/*
- * Postfix expressions.
- */
-class
-tree_postfix_expression : public tree_expression
-{
- public:
-  tree_postfix_expression (int l = -1, int c = -1);
-  tree_postfix_expression (tree_identifier *t, tree::expression_type et,
-			   int l = -1, int c = -1);
-
-  ~tree_postfix_expression (void);
-
-  tree_constant eval (int print);
-
-  void eval_error (void);
-
- private:
-  tree_identifier *id;
-};
-
-/*
- * Unary expressions.
- */
-class
-tree_unary_expression : public tree_expression
-{
- public:
-  tree_unary_expression (int l = -1, int c = -1);
-  tree_unary_expression (tree_expression *a, tree::expression_type t,
-			 int l = -1, int c = -1);
-
-  ~tree_unary_expression (void);
-
-  tree_constant eval (int print);
-
-  void eval_error (void);
-
- private:
-  tree_expression *op;
-};
-
-/*
- * Binary expressions.
- */
-class
-tree_binary_expression : public tree_expression
-{
- public:
-  tree_binary_expression (int l = -1, int c = -1);
-  tree_binary_expression (tree_expression *a, tree_expression *b,
-			  tree::expression_type t, int l = -1, int c = -1);
-
-  ~tree_binary_expression (void);
-
-  tree_constant eval (int print);
-
-  void eval_error (void);
-
- private:
-  tree_expression *op1;
-  tree_expression *op2;
-};
-
-/*
- * Assignment expressions.
- */
-class
-tree_assignment_expression : public tree_expression
-{
-public:
-  int in_parens;
-
-  tree_assignment_expression (void);
-
-  ~tree_assignment_expression (void);
-
-  tree_constant eval (int print);
-
-  int is_assignment_expression (void) const;
-};
+// A base class for objects that can be evaluated with argument lists.
 
-/*
- * Simple assignment expressions.
- */
-class
-tree_simple_assignment_expression : public tree_assignment_expression
-{
- public:
-  tree_simple_assignment_expression (int l = -1, int c = -1);
-  tree_simple_assignment_expression (tree_identifier *i,
-				     tree_expression *r,
-				     int l = -1, int c = -1);
-  tree_simple_assignment_expression (tree_index_expression *idx_expr,
-				     tree_expression *r, int l = -1, int c = -1);
-
-  ~tree_simple_assignment_expression (void);
-
-  tree_constant eval (int print);
-
-  void eval_error (void);
-
- private:
-  tree_identifier *lhs;
-  tree_argument_list *index;
-  tree_expression *rhs;
-};
-
-/*
- * Multi-valued assignment expressions.
- */
-class
-tree_multi_assignment_expression : public tree_assignment_expression
-{
- public:
-  tree_multi_assignment_expression (int l = -1, int c = -1);
-  tree_multi_assignment_expression (tree_return_list *lst,
-				    tree_expression *r,
-				    int l = -1, int c = -1);
-
-  ~tree_multi_assignment_expression (void);
-
-  tree_constant eval (int print);
-
-  Octave_object eval (int print, int nargout, const Octave_object& args);
-
-  void eval_error (void);
-
- private:
-  tree_return_list *lhs;
-  tree_expression *rhs;
-};
-
-/*
- * Colon expressions.
- */
-class
-tree_colon_expression : public tree_expression
-{
- public:
-  tree_colon_expression (int l = -1, int c = -1);
-  tree_colon_expression (tree_expression *a, tree_expression *b,
-			 int l = -1, int c = -1);
-
-  ~tree_colon_expression (void);
-
-  tree_colon_expression *chain (tree_expression *t);
-
-  tree_constant eval (int print);
-
-  void eval_error (const char *s);
-
- private:
-  tree_expression *op1;
-  tree_expression *op2;
-  tree_expression *op3;
-};
-
-/*
- * Index expressions.
- */
-class
-tree_index_expression : public tree_expression
-{
- public:
-  tree_index_expression (int l = -1, int c = -1);
-  tree_index_expression (tree_identifier *i, int l = -1, int c = -1);
-  tree_index_expression (tree_identifier *i, tree_argument_list *lst,
-			 int l = -1, int c = -1);
-
-  ~tree_index_expression (void);
-
-  int is_index_expression (void) const;
-
-  tree_identifier *ident (void);
-
-  tree_argument_list *arg_list (void);
-
-  void mark_for_possible_ans_assign (void);
-
-  tree_constant eval (int print);
-
-  Octave_object eval (int print, int nargout, const Octave_object& args);
-
-  void eval_error (void);
-
- private:
-  tree_identifier *id;
-  tree_argument_list *list;
-};
-
-/*
- * A base class for objects that can be evaluated with argument lists.
- */
 class
 tree_fvc : public tree_expression
 {
 public:
+  tree_fvc (int l = -1, int c = -1) : tree_expression (l, c) { }
+
   virtual int is_constant (void) const
     { return 0; }
 
@@ -352,7 +196,7 @@
   virtual char *name (void) const
     { panic_impossible (); return 0; }
 
-  virtual void bump_value (tree::expression_type)
+  virtual void bump_value (tree_expression::type)
     { panic_impossible (); }
 
   virtual int max_expected_args (void)
@@ -372,59 +216,30 @@
     { panic_impossible (); return 0; }
 };
 
-/*
- * Builtin functions.
- */
-class
-tree_builtin : public tree_fvc
-{
-public:
-  tree_builtin (const char *nm = 0);
-
-  tree_builtin (int i_max, int o_max, Mapper_fcn& m_fcn,
-		const char *nm = 0);
-
-  tree_builtin (int i_max, int o_max, Octave_builtin_fcn f,
-		const char *nm = 0);
-
-  ~tree_builtin (void);
-
-//  int is_builtin (void) const;
-
-  int is_mapper_function (void) const;
+// Symbols from the symbol table.
 
-  tree_constant eval (int print);
-
-  Octave_object eval (int print, int nargout, const Octave_object& args);
-
-  char *name (void) const;
-
-  int max_expected_args (void);
-
-private:
-  int nargin_max;
-  int nargout_max;
-  int is_mapper;
-  Mapper_fcn mapper_fcn;
-  Octave_builtin_fcn fcn;
-  char *my_name;
-};
-
-/*
- * Symbols from the symbol table.
- */
 class
 tree_identifier : public tree_fvc
 {
   friend class tree_index_expression;
 
 public:
-  tree_identifier (int l = -1, int c = -1);
-  tree_identifier (symbol_record *s, int l = -1, int c = -1);
+  tree_identifier (int l = -1, int c = -1)
+    {
+      sym = 0;
+      maybe_do_ans_assign = 0;
+    }
 
-  ~tree_identifier (void);
+  tree_identifier (symbol_record *s, int l = -1, int c = -1)
+    {
+      sym = s;
+      maybe_do_ans_assign = 0;
+    }
 
-  int is_identifier (void) const;
+  ~tree_identifier (void) { }
+
+  int is_identifier (void) const
+    { return 1; }
 
   char *name (void) const;
 
@@ -438,7 +253,7 @@
 
   int is_defined (void);
 
-  void bump_value (tree::expression_type);
+  void bump_value (tree_expression::type);
 
   int load_fcn_from_file (int exec_script = 1);
 
@@ -446,9 +261,16 @@
 
   tree_fvc *do_lookup (int& script_file_executed);
 
+  void link_to_global (void)
+    {
+      if (sym)
+	::link_to_global_variable (sym);
+    }
+
   void mark_as_formal_parameter (void);
 
-  void mark_for_possible_ans_assign (void);
+  void mark_for_possible_ans_assign (void)
+    { maybe_do_ans_assign = 1; }
 
   tree_constant eval (int print);
 
@@ -461,37 +283,459 @@
   int maybe_do_ans_assign;
 };
 
-/*
- * User defined functions.
- */
+// Index expressions.
+
+class
+tree_index_expression : public tree_expression
+{
+ public:
+  tree_index_expression (int l = -1, int c = -1) : tree_expression (l, c)
+    {
+      id = 0;
+      list = 0;
+    }
+
+  tree_index_expression (tree_identifier *i, int l = -1, int c = -1)
+    : tree_expression (l, c)
+      {
+	id = i;
+	list = 0;
+      }
+
+  tree_index_expression (tree_identifier *i, tree_argument_list *lst,
+			 int l = -1, int c = -1)
+    : tree_expression (l, c)
+      {
+	id = i;
+	list = lst;
+      }
+
+  ~tree_index_expression (void);
+
+  int is_index_expression (void) const
+    { return 1; }
+
+  tree_identifier *ident (void)
+    { return id; }
+
+  tree_argument_list *arg_list (void)
+    { return list; }
+
+  void mark_for_possible_ans_assign (void)
+    {
+      if (id)
+	id->mark_for_possible_ans_assign ();
+    }
+
+  tree_constant eval (int print);
+
+  Octave_object eval (int print, int nargout, const Octave_object& args);
+
+  void eval_error (void);
+
+ private:
+  tree_identifier *id;
+  tree_argument_list *list;
+};
+
+// Prefix expressions.
+
+class
+tree_prefix_expression : public tree_expression
+{
+ public:
+  tree_prefix_expression (int l = -1, int c = -1) : tree_expression (l, c)
+    {
+      id = 0;
+      etype = unknown;
+    }
+
+  tree_prefix_expression (tree_identifier *t, tree_expression::type et,
+			  int l = -1, int c = -1)
+    : tree_expression (l, c)
+      {
+	id = t;
+	etype = et;
+      }
+
+  ~tree_prefix_expression (void)
+    { delete id; }
+
+  tree_constant eval (int print);
+
+  void eval_error (void);
+
+  int is_prefix_expression (void) const
+    { return 1; }
+
+ private:
+  tree_identifier *id;
+};
+
+// Postfix expressions.
+
+class
+tree_postfix_expression : public tree_expression
+{
+ public:
+  tree_postfix_expression (int l = -1, int c = -1) : tree_expression (l, c)
+    {
+      id = 0;
+      etype = unknown;
+    }
+
+  tree_postfix_expression (tree_identifier *t, tree_expression::type et,
+			   int l = -1, int c = -1)
+    : tree_expression (l, c)
+      {
+	id = t;
+	etype = et;
+      }
+
+  ~tree_postfix_expression (void)
+    { delete id; }
+
+  tree_constant eval (int print);
+
+  void eval_error (void);
+
+ private:
+  tree_identifier *id;
+};
+
+// Unary expressions.
+
+class
+tree_unary_expression : public tree_expression
+{
+ public:
+  tree_unary_expression (int l = -1, int c = -1) : tree_expression (l, c)
+    {
+      etype = tree_expression::unknown;
+      op = 0;
+    }
+
+  tree_unary_expression (tree_expression *a, tree_expression::type t,
+			 int l = -1, int c = -1)
+    : tree_expression (l, c)
+      {
+	etype = t;
+	op = a;
+      }
+
+  ~tree_unary_expression (void)
+    { delete op; }
+
+  tree_constant eval (int print);
+
+  void eval_error (void);
+
+ private:
+  tree_expression *op;
+};
+
+// Binary expressions.
+
+class
+tree_binary_expression : public tree_expression
+{
+ public:
+  tree_binary_expression (int l = -1, int c = -1) : tree_expression (l, c)
+    {
+      etype = tree_expression::unknown;
+      op1 = 0;
+      op2 = 0;
+    }
+
+  tree_binary_expression (tree_expression *a, tree_expression *b,
+			  tree_expression::type t, int l = -1, int c = -1)
+    : tree_expression (l, c)
+      {
+	etype = t;
+	op1 = a;
+	op2 = b;
+      }
+
+  ~tree_binary_expression (void)
+    {
+      delete op1;
+      delete op2;
+    }
+
+  tree_constant eval (int print);
+
+  void eval_error (void);
+
+ private:
+  tree_expression *op1;
+  tree_expression *op2;
+};
+
+// Assignment expressions.
+
+class
+tree_assignment_expression : public tree_expression
+{
+public:
+  int in_parens;
+
+  tree_assignment_expression (int l = -1, int c = -1)
+    : tree_expression (l, c)
+    {
+      in_parens = 0;
+      etype = tree_expression::assignment;
+    }
+
+  ~tree_assignment_expression (void) { }
+
+  tree_constant eval (int print);
+
+  int is_assignment_expression (void) const
+    { return 1; }
+};
+
+// Simple assignment expressions.
+
+class
+tree_simple_assignment_expression : public tree_assignment_expression
+{
+ public:
+  tree_simple_assignment_expression (int plhs = 0, int l = -1, int c = -1)
+    : tree_assignment_expression (l, c)
+      {
+	etype = tree_expression::assignment;
+	lhs = 0;
+	index = 0;
+	rhs = 0;
+	preserve = plhs;
+      }
+
+  tree_simple_assignment_expression (tree_identifier *i,
+				     tree_expression *r,
+				     int plhs = 0, int l = -1, int c = -1)
+    : tree_assignment_expression (l, c)
+      {
+	etype = tree_expression::assignment;
+	lhs = i;
+	index = 0;
+	rhs = r;
+	preserve = plhs;
+      }
+
+  tree_simple_assignment_expression (tree_index_expression *idx_expr,
+				     tree_expression *r,
+				     int plhs = 0, int l = -1, int c = -1)
+    : tree_assignment_expression (l, c)
+      {
+	etype = tree_expression::assignment;
+	lhs = idx_expr->ident ();
+	index = idx_expr->arg_list ();
+	rhs = r;
+	preserve = plhs;
+      }
+
+  ~tree_simple_assignment_expression (void);
+
+  tree_identifier *left_hand_side (void)
+    { return lhs; }
+
+  tree_constant eval (int print);
+
+  void eval_error (void);
+
+ private:
+  tree_identifier *lhs;
+  tree_argument_list *index;
+  tree_expression *rhs;
+  int preserve;
+};
+
+// Multi-valued assignment expressions.
+
+class
+tree_multi_assignment_expression : public tree_assignment_expression
+{
+ public:
+  tree_multi_assignment_expression (int l = -1, int c = -1)
+    : tree_assignment_expression (l, c)
+      {
+	etype = tree_expression::multi_assignment;
+	lhs = 0;
+	rhs = 0;
+      }
+
+  tree_multi_assignment_expression (tree_return_list *lst,
+				    tree_expression *r,
+				    int l = -1, int c = -1)
+    : tree_assignment_expression (l, c)
+      {
+	etype = tree_expression::multi_assignment;
+	lhs = lst;
+	rhs = r;
+      }
+
+  ~tree_multi_assignment_expression (void);
+
+  tree_constant eval (int print);
+
+  Octave_object eval (int print, int nargout, const Octave_object& args);
+
+  void eval_error (void);
+
+ private:
+  tree_return_list *lhs;
+  tree_expression *rhs;
+};
+
+// Colon expressions.
+
+class
+tree_colon_expression : public tree_expression
+{
+ public:
+  tree_colon_expression (int l = -1, int c = -1) : tree_expression (l, c)
+    {
+      etype = tree_expression::colon;
+      op1 = 0;
+      op2 = 0;
+      op3 = 0;
+    }
+
+  tree_colon_expression (tree_expression *a, tree_expression *b,
+			 int l = -1, int c = -1)
+    : tree_expression (l, c)
+      {
+	etype = tree_expression::colon;
+	op1 = a;
+	op2 = b;
+	op3 = 0;
+      }
+
+  ~tree_colon_expression (void)
+    {
+      delete op1;
+      delete op2;
+      delete op3;
+    }
+
+  tree_colon_expression *chain (tree_expression *t);
+
+  tree_constant eval (int print);
+
+  void eval_error (const char *s);
+
+ private:
+  tree_expression *op1;
+  tree_expression *op2;
+  tree_expression *op3;
+};
+
+// Builtin functions.
+
+class
+tree_builtin : public tree_fvc
+{
+public:
+  tree_builtin (const char *nm = 0);
+
+  tree_builtin (int i_max, int o_max, Mapper_fcn& m_fcn,
+		const char *nm = 0);
+
+  tree_builtin (int i_max, int o_max, Octave_builtin_fcn f,
+		const char *nm = 0);
+
+  ~tree_builtin (void) { }
+
+//  int is_builtin (void) const;
+
+  int is_mapper_function (void) const
+    { return is_mapper; }
+
+  tree_constant eval (int print);
+
+  Octave_object eval (int print, int nargout, const Octave_object& args);
+
+  char *name (void) const
+    { return my_name; }
+
+  int max_expected_args (void);
+
+private:
+  int nargin_max;
+  int nargout_max;
+  int is_mapper;
+  Mapper_fcn mapper_fcn;
+  Octave_builtin_fcn fcn;
+  char *my_name;
+};
+
+// User defined functions.
+
 class
 tree_function : public tree_fvc
 {
 public:
-  tree_function (void);
-  tree_function (tree *cl, symbol_table *st);
+  void init (void)
+    {
+      call_depth = 0;
+      param_list = 0;
+      ret_list = 0;
+      sym_tab = 0;
+      cmd_list = 0;
+      file_name = 0;
+      fcn_name = 0;
+      t_parsed = 0;
+      system_fcn_file = 0;
+      num_named_args = 0;
+      num_args_passed = 0;
+      curr_va_arg_number = 0;
+    }
 
-  ~tree_function (void);
+  tree_function (int l = -1, int c = -1) : tree_fvc (l, c)
+    { init (); }
 
-  tree_function *define (tree *t);
+  tree_function (tree_statement_list *cl, symbol_table *st,
+		 int l = -1, int c = -1)
+     : tree_fvc (l, c)
+       {
+	 init ();
+	 sym_tab = st;
+	 cmd_list = cl;
+       }
+
+  ~tree_function (void) { }
+
+//  tree_function *define (tree_statement_list *t);
   tree_function *define_param_list (tree_parameter_list *t);
   tree_function *define_ret_list (tree_parameter_list *t);
 
   void stash_fcn_file_name (char * s);
-  void stash_fcn_file_time (time_t t);
+
+  void stash_fcn_file_time (time_t t)
+    { t_parsed = t; }
 
-  char *fcn_file_name (void);
-  time_t time_parsed (void);
+  char *fcn_file_name (void)
+    { return file_name; }
+
+  time_t time_parsed (void)
+    { return t_parsed; }
 
   void mark_as_system_fcn_file (void);
-  int is_system_fcn_file (void) const;
+
+  int is_system_fcn_file (void) const
+    { return system_fcn_file; }
 
   int takes_varargs (void) const;
-  void octave_va_start (void);
+
+  void octave_va_start (void)
+    { curr_va_arg_number = num_named_args; }
+
   tree_constant octave_va_arg (void);
 
   void stash_function_name (char *s);
-  char *function_name (void);
+
+  char *function_name (void)
+    { return fcn_name; }
 
   tree_constant eval (int print);
 
@@ -506,7 +750,7 @@
   tree_parameter_list *param_list;
   tree_parameter_list *ret_list;
   symbol_table *sym_tab;
-  tree *cmd_list;
+  tree_statement_list *cmd_list;
   char *file_name;
   char *fcn_name;
   time_t t_parsed;
@@ -517,109 +761,6 @@
   int curr_va_arg_number;
 };
 
-/*
- * Argument lists.
- */
-class
-tree_argument_list : public tree
-{
- public:
-  tree_argument_list (void);
-  tree_argument_list (tree *t);
-
-  ~tree_argument_list (void);
-
-  tree_argument_list *chain (tree *t);
-  tree_argument_list *reverse (void);
-  int length (void);
-
-  tree_argument_list *next_elem (void);
-
-  Octave_object convert_to_const_vector (void);
-
-  tree_constant eval (int print);
-
- private:
-  tree *arg;
-  tree_argument_list *next;
-};
-
-/*
- * Parameter lists.  Almost like argument lists, except that the
- * elements are only supposed to be identifiers, never constants or
- * expressions.
- */
-class
-tree_parameter_list : public tree
-{
- public:
-  tree_parameter_list (void);
-  tree_parameter_list (tree_identifier *t);
-
-  ~tree_parameter_list (void);
-
-  tree_parameter_list *chain (tree_identifier *t);
-  tree_parameter_list *reverse (void);
-  int length (void);
-
-  char *name (void) const;
-
-  void mark_as_formal_parameters (void);
-
-  void mark_varargs (void);
-  int takes_varargs (void) const;
-
-  void mark_varargs_only (void);
-  int varargs_only (void);
-
-  tree_identifier *define (tree_constant *t);
-
-  void define_from_arg_vector (const Octave_object& args);
-
-  int is_defined (void);
-
-  Octave_object convert_to_const_vector (void);
-
-  tree_parameter_list *next_elem (void);
-
-  tree_constant eval (int print);
-
- private:
-  int marked_for_varargs;
-  tree_identifier *param;
-  tree_parameter_list *next;
-};
-
-/*
- * Return lists.  Almost like parameter lists, except that the
- * elements may also be index expressions.
- */
-class
-tree_return_list : public tree
-{
- public:
-  tree_return_list (void);
-  tree_return_list (tree_identifier *t);
-  tree_return_list (tree_index_expression *t);
-
-  ~tree_return_list (void);
-
-  tree_return_list *chain (tree_identifier *t);
-  tree_return_list *chain (tree_index_expression *t);
-  tree_return_list *reverse (void);
-  int length (void);
-
-  tree_index_expression *idx_expr (void);
-
-  tree_return_list *next_elem (void);
-
-  tree_constant eval (int print);
-
- private:
-  tree_index_expression *retval;
-  tree_return_list *next;
-};
-
 #endif
 
 /*
--- a/src/pt-plot.cc	Wed Aug 03 20:06:54 1994 +0000
+++ b/src/pt-plot.cc	Wed Aug 03 20:07:26 1994 +0000
@@ -80,15 +80,15 @@
   ndim = 0;
 }
 
-tree_plot_command::tree_plot_command (tree_subplot_list *plt, int nd)
+tree_plot_command::tree_plot_command (subplot_list *plt, int nd)
 {
   range = 0;
   plot_list = plt;
   ndim = nd;
 }
 
-tree_plot_command::tree_plot_command (tree_subplot_list *plt,
-				      tree_plot_limits *rng, int nd)
+tree_plot_command::tree_plot_command (subplot_list *plt,
+				      plot_limits *rng, int nd)
 {
   range = rng;
   plot_list = plt;
@@ -101,13 +101,11 @@
   delete plot_list;
 }
 
-tree_constant
-tree_plot_command::eval (int print)
+void
+tree_plot_command::eval (void)
 {
-  tree_constant retval;
-
   if (error_state)
-    return retval;
+    return;
 
   ostrstream plot_buf;
 
@@ -121,7 +119,7 @@
 	  else
 	    {
 	      ::error ("replot: must have something to plot");
-	      return retval;
+	      return;
 	    }
 	}
       else
@@ -157,18 +155,20 @@
     }
 
   if (error_state)
-    return retval;
+    return;
 
-  for (tree_subplot_list *ptr = plot_list; ptr; ptr = ptr->next_elem ())
+  for (Pix p = plot_list->first () ; p != 0; plot_list->next (p))
     {
+      subplot *ptr = plot_list->operator () (p);
+
       plot_line_count++;
 
-      if (ptr != plot_list)
+      if (p != plot_list->first ())
 	plot_buf << ",\\\n  ";
 
       int status = ptr->print (ndim, plot_buf);
       if (status < 0)
-	return retval;
+	return;
     }
 
   plot_buf << "\n" << ends;
@@ -192,103 +192,10 @@
       send_to_plot_stream (message);
       delete [] message;
     }
-
-  return retval;
-}
-
-tree_subplot_list::tree_subplot_list (void)
-{
-  plot_data = 0;
-  using = 0;
-  title = 0;
-  style = 0;
-  next = 0;
-}
-
-tree_subplot_list::tree_subplot_list (tree_expression *data)
-{
-  plot_data = data;
-  using = 0;
-  title = 0;
-  style = 0;
-  next = 0;
-}
-
-tree_subplot_list::tree_subplot_list (tree_subplot_list *t)
-{
-  plot_data = t->plot_data;
-  using = t->using;
-  title = t->title;
-  style = t->style;
-  next = t->next;
-}
-
-tree_subplot_list::tree_subplot_list (tree_subplot_using *u,
-				      tree_expression *t,
-				      tree_subplot_style *s)
-{
-  plot_data = 0;
-  using = u;
-  title = t;
-  style = s;
-  next = 0;
-}
-
-tree_subplot_list::~tree_subplot_list (void)
-{
-  delete plot_data;
-  delete using;
-  delete title;
-  delete style;
-  delete next;
-}
-
-tree_subplot_list *
-tree_subplot_list::set_data (tree_expression *data)
-{
-  plot_data = data;
-  return this;
-}
-
-tree_subplot_list *
-tree_subplot_list::chain (tree_subplot_list *t)
-{
-  tree_subplot_list *tmp = new tree_subplot_list (t);
-  tmp->next = this;
-  return tmp;
-}
-
-tree_subplot_list *
-tree_subplot_list::reverse (void)
-{
-  tree_subplot_list *list = this;
-  tree_subplot_list *next;
-  tree_subplot_list *prev = 0;
-
-  while (list)
-    {
-      next = list->next;
-      list->next = prev;
-      prev = list;
-      list = next;
-    }
-  return prev;
-}
-
-tree_subplot_list *
-tree_subplot_list::next_elem (void)
-{
-  return next;
-}
-
-tree_constant
-tree_subplot_list::eval (int print)
-{
-  return plot_data->eval (0);
 }
 
 int
-tree_subplot_list::print (int ndim, ostrstream& plot_buf)
+subplot::print (int ndim, ostrstream& plot_buf)
 {
   int nc = 0;
   if (plot_data)
@@ -378,53 +285,46 @@
   return 0;
 }
 
-tree_plot_limits::tree_plot_limits (void)
+plot_limits::plot_limits (void)
 {
   x_range = 0;
   y_range = 0;
   z_range = 0;
 }
 
-tree_plot_limits::tree_plot_limits (tree_plot_range *xlim)
+plot_limits::plot_limits (plot_range *xlim)
 {
   x_range = xlim;
   y_range = 0;
   z_range = 0;
 }
 
-tree_plot_limits::tree_plot_limits (tree_plot_range *xlim,
-				    tree_plot_range *ylim)
+plot_limits::plot_limits (plot_range *xlim,
+				    plot_range *ylim)
 {
   x_range = xlim;
   y_range = ylim;
   z_range = 0;
 }
 
-tree_plot_limits::tree_plot_limits (tree_plot_range *xlim,
-				    tree_plot_range *ylim,
-				    tree_plot_range *zlim)
+plot_limits::plot_limits (plot_range *xlim,
+				    plot_range *ylim,
+				    plot_range *zlim)
 {
   x_range = xlim;
   y_range = ylim;
   z_range = zlim;
 }
 
-tree_plot_limits::~tree_plot_limits (void)
+plot_limits::~plot_limits (void)
 {
   delete x_range;
   delete y_range;
   delete z_range;
 }
 
-tree_constant
-tree_plot_limits::eval (int print)
-{
-  tree_constant retval;
-  return retval;
-}
-
 void
-tree_plot_limits::print (int ndim, ostrstream& plot_buf)
+plot_limits::print (int ndim, ostrstream& plot_buf)
 {
   if (ndim  == 2 || ndim == 3)
     {
@@ -443,33 +343,26 @@
     z_range->print (plot_buf);
 }
 
-tree_plot_range::tree_plot_range (void)
+plot_range::plot_range (void)
 {
   lower = 0;
   upper = 0;
 }
 
-tree_plot_range::tree_plot_range (tree_expression *l, tree_expression *u)
+plot_range::plot_range (tree_expression *l, tree_expression *u)
 {
   lower = l;
   upper = u;
 }
 
-tree_plot_range::~tree_plot_range (void)
+plot_range::~plot_range (void)
 {
   delete lower;
   delete upper;
 }
 
-tree_constant
-tree_plot_range::eval (int print)
-{
-  tree_constant retval;
-  return retval;
-}
-
 void
-tree_plot_range::print (ostrstream& plot_buf)
+plot_range::print (ostrstream& plot_buf)
 {
   plot_buf << " [";
 
@@ -508,7 +401,7 @@
   plot_buf << "]";
 }
 
-tree_subplot_using::tree_subplot_using (void)
+subplot_using::subplot_using (void)
 {
   qualifier_count = 0;
   x[0] = 0;
@@ -518,7 +411,7 @@
   scanf_fmt = 0;
 }
 
-tree_subplot_using::tree_subplot_using (tree_expression *fmt)
+subplot_using::subplot_using (tree_expression *fmt)
 {
   qualifier_count = 0;
   x[0] = 0;
@@ -528,20 +421,20 @@
   scanf_fmt = fmt;
 }
 
-tree_subplot_using::~tree_subplot_using (void)
+subplot_using::~subplot_using (void)
 {
   delete scanf_fmt;
 }
 
-tree_subplot_using *
-tree_subplot_using::set_format (tree_expression *fmt)
+subplot_using *
+subplot_using::set_format (tree_expression *fmt)
 {
   scanf_fmt = fmt;
   return this;
 }
 
-tree_subplot_using *
-tree_subplot_using::add_qualifier (tree_expression *t)
+subplot_using *
+subplot_using::add_qualifier (tree_expression *t)
 {
   if (qualifier_count < 4)
     x[qualifier_count] = t;
@@ -551,15 +444,8 @@
   return this;
 }
 
-tree_constant
-tree_subplot_using::eval (int print)
-{
-  tree_constant retval;
-  return retval;
-}
-
 int
-tree_subplot_using::print (int ndim, int n_max, ostrstream& plot_buf)
+subplot_using::print (int ndim, int n_max, ostrstream& plot_buf)
 {
   if ((ndim == 2 && qualifier_count > 4)
       || (ndim == 3 && qualifier_count > 3))
@@ -608,28 +494,28 @@
   return 0;
 }
 
-tree_subplot_style::tree_subplot_style (void)
+subplot_style::subplot_style (void)
 {
   style = 0;
   linetype = 0;
   pointtype = 0;
 }
 
-tree_subplot_style::tree_subplot_style (char *s)
+subplot_style::subplot_style (char *s)
 {
   style = strsave (s);
   linetype = 0;
   pointtype = 0;
 }
 
-tree_subplot_style::tree_subplot_style (char *s, tree_expression *lt)
+subplot_style::subplot_style (char *s, tree_expression *lt)
 {
   style = strsave (s);
   linetype = lt;
   pointtype = 0;
 }
 
-tree_subplot_style::tree_subplot_style (char *s, tree_expression *lt,
+subplot_style::subplot_style (char *s, tree_expression *lt,
 					tree_expression *pt)
 {
   style = strsave (s);
@@ -637,22 +523,15 @@
   pointtype = pt;
 }
 
-tree_subplot_style::~tree_subplot_style (void)
+subplot_style::~subplot_style (void)
 { 
   delete [] style;
   delete linetype;
   delete pointtype;
 }
 
-tree_constant
-tree_subplot_style::eval (int print)
-{
-  tree_constant retval;
-  return retval;
-}
-
 int
-tree_subplot_style::print (ostrstream& plot_buf)
+subplot_style::print (ostrstream& plot_buf)
 {
   if (style)
     {
--- a/src/pt-plot.h	Wed Aug 03 20:06:54 1994 +0000
+++ b/src/pt-plot.h	Wed Aug 03 20:07:26 1994 +0000
@@ -29,16 +29,18 @@
 #endif
 
 class tree_command;
-class tree_plot_limits;
-class tree_plot_range;
-class tree_subplot;
-class tree_subplot_using;
-class tree_subplot_style;
-class tree_subplot_list;
 class tree_plot_command;
+class plot_limits;
+class plot_range;
+class subplot_using;
+class subplot_style;
+class subplot;
+class subplot_list;
 
 class ostream;
 
+#include <SLList.h>
+
 #include "tree.h"
 
 class
@@ -46,83 +48,47 @@
 {
  public:
   tree_plot_command (void);
-  tree_plot_command (tree_subplot_list *plt, int nd);
-  tree_plot_command (tree_subplot_list *plt, tree_plot_limits *rng, int nd);
+  tree_plot_command (subplot_list *plt, int nd);
+  tree_plot_command (subplot_list *plt, plot_limits *rng, int nd);
 
   ~tree_plot_command (void);
 
-  tree_constant eval (int print);
+  void eval (void);
 
  private:
   int ndim;
-  tree_plot_limits *range;
-  tree_subplot_list *plot_list;
+  plot_limits *range;
+  subplot_list *plot_list;
 };
 
 class
-tree_subplot_list : public tree
+plot_limits
 {
  public:
-  tree_subplot_list (void);
-  tree_subplot_list (tree_expression *data);
-  tree_subplot_list (tree_subplot_list *t);
-  tree_subplot_list (tree_subplot_using *u, tree_expression *t,
-		     tree_subplot_style *s);
-
-  ~tree_subplot_list (void);
-
-  tree_subplot_list *set_data (tree_expression *data);
-
-  tree_subplot_list *chain (tree_subplot_list *t);
-
-  tree_subplot_list *reverse (void);
-
-  tree_subplot_list *next_elem (void);
-
-  tree_constant eval (int print);
-
-  int print (int ndim, ostrstream& plot_buf);
+  plot_limits (void);
+  plot_limits (plot_range *xlim);
+  plot_limits (plot_range *xlim, plot_range *ylim);
+  plot_limits (plot_range *xlim, plot_range *ylim,
+		    plot_range *zlim);
 
- private:
-  tree_expression *plot_data;
-  tree_subplot_using *using;
-  tree_expression *title;
-  tree_subplot_style *style;
-  tree_subplot_list *next;
-};
-
-class
-tree_plot_limits : public tree
-{
- public:
-  tree_plot_limits (void);
-  tree_plot_limits (tree_plot_range *xlim);
-  tree_plot_limits (tree_plot_range *xlim, tree_plot_range *ylim);
-  tree_plot_limits (tree_plot_range *xlim, tree_plot_range *ylim,
-		    tree_plot_range *zlim);
-
-  ~tree_plot_limits (void);
-
-  tree_constant eval (int print);
+  ~plot_limits (void);
 
   void print (int print, ostrstream& plot_buf);
 
  private:
-  tree_plot_range *x_range;
-  tree_plot_range *y_range;
-  tree_plot_range *z_range;
+  plot_range *x_range;
+  plot_range *y_range;
+  plot_range *z_range;
 };
 
 class
-tree_plot_range : public tree
+plot_range
 {
  public:
-  tree_plot_range (void);
-  tree_plot_range (tree_expression *l, tree_expression *u);
+  plot_range (void);
+  plot_range (tree_expression *l, tree_expression *u);
 
-  ~tree_plot_range (void);
-
-  tree_constant eval (int print);
+  ~plot_range (void);
 
   void print (ostrstream& plot_buf);
 
@@ -132,19 +98,17 @@
 };
 
 class
-tree_subplot_using : public tree
+subplot_using
 {
  public:
-  tree_subplot_using (void);
-  tree_subplot_using (tree_expression *fmt);
-
-  ~tree_subplot_using (void);
+  subplot_using (void);
+  subplot_using (tree_expression *fmt);
 
-  tree_subplot_using *set_format (tree_expression *fmt);
+  ~subplot_using (void);
 
-  tree_subplot_using *add_qualifier (tree_expression *t);
+  subplot_using *set_format (tree_expression *fmt);
 
-  tree_constant eval (int print);
+  subplot_using *add_qualifier (tree_expression *t);
 
   int print (int ndim, int n_max, ostrstream& plot_buf);
 
@@ -155,17 +119,15 @@
 };
 
 class
-tree_subplot_style : public tree
+subplot_style
 {
  public:
-  tree_subplot_style (void);
-  tree_subplot_style (char *s);
-  tree_subplot_style (char *s, tree_expression *lt);
-  tree_subplot_style (char *s, tree_expression *lt, tree_expression *pt);
+  subplot_style (void);
+  subplot_style (char *s);
+  subplot_style (char *s, tree_expression *lt);
+  subplot_style (char *s, tree_expression *lt, tree_expression *pt);
 
-  ~tree_subplot_style (void);
-
-  tree_constant eval (int print);
+  ~subplot_style (void);
 
   int print (ostrstream& plot_buf);
 
@@ -175,6 +137,73 @@
   tree_expression *pointtype;
 };
 
+class
+subplot
+{
+public:
+  subplot (void)
+    {
+      plot_data = 0;
+      using = 0;
+      title = 0;
+      style = 0;
+    }
+
+  subplot (tree_expression *data)
+    {
+      plot_data = data;
+      using = 0;
+      title = 0;
+      style = 0;
+    }
+
+  subplot (subplot_using *u, tree_expression *t,
+		subplot_style *s)
+    {
+      plot_data = 0;
+      using = u;
+      title = t;
+      style = s;
+    }
+
+  ~subplot (void)
+    {
+      delete plot_data;
+      delete using;
+      delete title;
+      delete style;
+    }
+
+  void set_data (tree_expression *data)
+    { plot_data = data; }
+
+  int print (int ndim, ostrstream& plot_buf);
+
+private:
+  tree_expression *plot_data;
+  subplot_using *using;
+  tree_expression *title;
+  subplot_style *style;
+};
+
+class
+subplot_list : public SLList<subplot *>
+{
+ public:
+  subplot_list (void) : SLList<subplot *> () { }
+  subplot_list (subplot *t) : SLList<subplot *> ()
+    { append (t); }
+
+  ~subplot_list (void)
+    {
+      while (! empty ())
+	{
+	  subplot *t = remove_front ();
+	  delete t;
+	}
+    }
+};
+
 extern char *save_in_tmp_file (tree_constant& t, int ndim = 2,
 			       int parametric = 0);
 
--- a/src/tc-rep.cc	Wed Aug 03 20:06:54 1994 +0000
+++ b/src/tc-rep.cc	Wed Aug 03 20:07:26 1994 +0000
@@ -921,7 +921,7 @@
 }
 
 tree_constant
-do_binary_op (tree_constant& a, tree_constant& b, tree::expression_type t)
+do_binary_op (tree_constant& a, tree_constant& b, tree_expression::type t)
 {
   tree_constant ans;
 
@@ -1066,7 +1066,7 @@
 }
 
 tree_constant
-do_unary_op (tree_constant& a, tree::expression_type t)
+do_unary_op (tree_constant& a, tree_expression::type t)
 {
   tree_constant ans;
 
@@ -1113,11 +1113,11 @@
 }
 
 void
-tree_constant_rep::bump_value (tree::expression_type etype)
+tree_constant_rep::bump_value (tree_expression::type etype)
 {
   switch (etype)
     {
-    case tree::increment:
+    case tree_expression::increment:
       switch (type_tag)
 	{
 	case scalar_constant:
@@ -1145,7 +1145,7 @@
 	  break;
 	}
       break;
-    case tree::decrement:
+    case tree_expression::decrement:
       switch (type_tag)
 	{
 	case scalar_constant:
--- a/src/tc-rep.h	Wed Aug 03 20:06:54 1994 +0000
+++ b/src/tc-rep.h	Wed Aug 03 20:07:26 1994 +0000
@@ -240,7 +240,7 @@
   void delete_columns (idx_vector& j);
   void delete_columns (Range& j);
 
-  void bump_value (tree::expression_type);
+  void bump_value (tree_expression::type);
 
   void maybe_mutate (void);
   void print (void);
@@ -345,10 +345,10 @@
 };
 
 extern tree_constant do_binary_op (tree_constant& a, tree_constant& b,
-				   tree::expression_type t);
+				   tree_expression::type t);
 
 extern tree_constant do_unary_op (tree_constant& a,
-				  tree::expression_type t);
+				  tree_expression::type t);
 
 #endif
 
--- a/src/toplev.h	Wed Aug 03 20:06:54 1994 +0000
+++ b/src/toplev.h	Wed Aug 03 20:07:26 1994 +0000
@@ -26,7 +26,7 @@
 
 #include <stdio.h>
 
-class tree;
+class tree_statement_list;
 class tree_function;
 
 // Tell g++ that clean_up_and_exit doesn't return;
@@ -78,7 +78,7 @@
 extern int quitting_gracefully;
 
 // Current command to execute.
-extern tree *global_command;
+extern tree_statement_list *global_command;
 
 // Pointer to function that is currently being evaluated.
 extern tree_function *curr_function;
--- a/src/utils.cc	Wed Aug 03 20:06:54 1994 +0000
+++ b/src/utils.cc	Wed Aug 03 20:07:26 1994 +0000
@@ -456,19 +456,19 @@
 }
 
 char **
-make_argv (const Octave_object& args, const char *warnfor)
+make_argv (const Octave_object& args, const char *fcn_name)
 {
   char **argv = 0;
   if (all_strings (args))
     {
       int n = args.length ();
       argv = new char * [n + 1];
-      argv[0] = 0;
+      argv[0] = strsave (fcn_name);
       for (int i = 1; i < n; i++)
 	argv[i] = strsave (args(i).string_value ());
     }
   else
-    error ("%s: expecting all arguments to be strings", warnfor);
+    error ("%s: expecting all arguments to be strings", fcn_name);
 
   return argv;
 }
--- a/src/utils.h	Wed Aug 03 20:06:54 1994 +0000
+++ b/src/utils.h	Wed Aug 03 20:07:26 1994 +0000
@@ -55,7 +55,7 @@
 extern int NINT (double x);
 extern double D_NINT (double x);
 
-extern char **make_argv (const Octave_object& args, const char *warnfor);
+extern char **make_argv (const Octave_object& args, const char *fcn_name);
 
 extern ostrstream& list_in_columns (ostrstream& os, char **list);