changeset 2982:20f5cec4f11c

[project @ 1997-05-16 03:29:26 by jwe]
author jwe
date Fri, 16 May 1997 03:30:14 +0000
parents 38365813950d
children 145d5acfc68b
files src/Makefile.in src/TEMPLATE-INST/SLList-misc.cc src/lex.l src/octave.cc src/ov-usr-fcn.cc src/parse.y src/pt-arg-list.cc src/pt-arg-list.h src/pt-assign.cc src/pt-binop.cc src/pt-cmd.cc src/pt-cmd.h src/pt-colon.cc src/pt-decl.cc src/pt-decl.h src/pt-except.cc src/pt-except.h src/pt-exp.cc src/pt-idx.cc src/pt-indir.cc src/pt-jump.cc src/pt-jump.h src/pt-loop.cc src/pt-loop.h src/pt-mat.cc src/pt-mat.h src/pt-misc.cc src/pt-misc.h src/pt-plot.cc src/pt-pr-code.cc src/pt-select.cc src/pt-select.h src/pt-stmt.cc src/pt-stmt.h src/pt-unop.cc src/toplev.cc
diffstat 36 files changed, 2610 insertions(+), 1976 deletions(-) [+]
line wrap: on
line diff
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -70,10 +70,11 @@
 	ov-str-mat.h ov-bool-mat.h ov-bool.h ov-file.h ov.h \
 	ov-fcn.h ov-builtin.h ov-mapper.h ov-usr-fcn.h ov-typeinfo.h
 
-PT_INCLUDES := pt-base.h pt-cmd.h pt-const.h pt-exp.h pt-id.h \
-	pt-indir.h pt-mat.h pt-misc.h pt-plot.h pt-pr-code.h \
-	pt-walk.h pt-unop.h pt-binop.h pt-colon.h pt-idx.h \
-	pt-assign.h
+PT_INCLUDES := pt-arg-list.h pt-assign.h pt-base.h pt-binop.h \
+	pt-cmd.h pt-colon.h pt-const.h pt-decl.h pt-except.h \
+	pt-exp.h pt-id.h pt-idx.h pt-indir.h pt-jump.h pt-loop.h \
+	pt-mat.h pt-misc.h pt-plot.h pt-pr-code.h pt-select.h \
+	pt-stmt.h pt-unop.h pt-walk.h
 
 INCLUDES := BaseSLList.h Map.h SLList.h SLStack.h Stack.h defun-dld.h \
 	defun-int.h defun.h dirfns.h dynamic-ld.h error.h file-io.h \
@@ -110,9 +111,11 @@
 	ov-bool-mat.cc ov-bool.cc ov-file.cc ov.cc ov-fcn.cc \
 	ov-builtin.cc ov-mapper.cc ov-usr-fcn.cc ov-typeinfo.cc
 
-PT_SRC := pt-base.cc pt-cmd.cc pt-const.cc pt-exp.cc pt-id.cc \
-	pt-indir.cc pt-mat.cc pt-misc.cc pt-plot.cc pt-pr-code.cc \
-	pt-unop.cc pt-binop.cc pt-colon.cc pt-idx.cc pt-assign.cc
+PT_SRC := pt-arg-list.cc pt-assign.cc pt-base.cc pt-binop.cc \
+	pt-cmd.cc pt-colon.cc pt-const.cc pt-decl.cc pt-except.cc \
+	pt-exp.cc pt-id.cc pt-idx.cc pt-indir.cc pt-jump.cc \
+	pt-loop.cc pt-mat.cc pt-misc.cc pt-plot.cc pt-pr-code.cc \
+	pt-select.cc pt-stmt.cc pt-unop.cc
 
 SOURCES := BaseSLList.cc Map.cc SLList.cc SLStack.cc Stack.cc \
 	data.cc defaults.cc defun.cc dirfns.cc dynamic-ld.cc \
--- a/src/TEMPLATE-INST/SLList-misc.cc
+++ b/src/TEMPLATE-INST/SLList-misc.cc
@@ -30,7 +30,10 @@
 #include "SLList.cc"
 
 #include "ov.h"
-#include "pt-misc.h"
+#include "pt-arg-list.h"
+#include "pt-decl.h"
+#include "pt-select.h"
+#include "pt-stmt.h"
 
 template class SLNode<tree_argument_list *>;
 template class SLList<tree_argument_list *>;
--- a/src/lex.l
+++ b/src/lex.l
@@ -51,13 +51,30 @@
 #include "lex.h"
 #include "ov.h"
 #include "parse.h"
+#include "pt-arg-list.h"
+#include "pt-assign.h"
 #include "pt-base.h"
+#include "pt-binop.h"
 #include "pt-cmd.h"
+#include "pt-colon.h"
 #include "pt-const.h"
+#include "pt-decl.h"
+#include "pt-except.h"
 #include "pt-exp.h"
+#include "pt-id.h"
+#include "pt-idx.h"
+#include "pt-indir.h"
+#include "pt-jump.h"
+#include "pt-loop.h"
 #include "pt-mat.h"
 #include "pt-misc.h"
 #include "pt-plot.h"
+#include "pt-pr-code.h"
+#include "pt-select.h"
+#include "pt-stmt.h"
+#include "pt-unop.h"
+#include "pt-pr-code.h"
+#include "pt-walk.h"
 #include "symtab.h"
 #include "token.h"
 #include "toplev.h"
--- a/src/octave.cc
+++ b/src/octave.cc
@@ -62,13 +62,12 @@
 #include "toplev.h"
 #include "parse.h"
 #include "pathsearch.h"
+#include "pt-plot.h"
 #include "procstream.h"
 #include "prog-args.h"
 #include "sighandlers.h"
 #include "sysdep.h"
 #include "ov.h"
-#include "pt-misc.h"
-#include "pt-plot.h"
 #include "unwind-prot.h"
 #include "utils.h"
 #include "variables.h"
--- a/src/ov-usr-fcn.cc
+++ b/src/ov-usr-fcn.cc
@@ -41,6 +41,7 @@
 #include "pager.h"
 #include "pt-misc.h"
 #include "pt-pr-code.h"
+#include "pt-stmt.h"
 #include "pt-walk.h"
 #include "symtab.h"
 #include "toplev.h"
--- a/src/parse.y
+++ b/src/parse.y
@@ -48,15 +48,30 @@
 #include "toplev.h"
 #include "pager.h"
 #include "parse.h"
+#include "pt-arg-list.h"
+#include "pt-assign.h"
+#include "pt-base.h"
+#include "pt-binop.h"
 #include "pt-cmd.h"
+#include "pt-colon.h"
 #include "pt-const.h"
+#include "pt-decl.h"
+#include "pt-except.h"
 #include "pt-exp.h"
 #include "pt-id.h"
+#include "pt-idx.h"
 #include "pt-indir.h"
+#include "pt-jump.h"
+#include "pt-loop.h"
 #include "pt-mat.h"
 #include "pt-misc.h"
 #include "pt-plot.h"
 #include "pt-pr-code.h"
+#include "pt-select.h"
+#include "pt-stmt.h"
+#include "pt-unop.h"
+#include "pt-pr-code.h"
+#include "pt-walk.h"
 #include "symtab.h"
 #include "token.h"
 #include "utils.h"
new file mode 100644
--- /dev/null
+++ b/src/pt-arg-list.cc
@@ -0,0 +1,178 @@
+/*
+
+Copyright (C) 1996, 1997 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#if defined (__GNUG__)
+#pragma implementation
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+
+#include <iostream.h>
+#include <strstream.h>
+
+#include "str-vec.h"
+
+#include "error.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-usr-fcn.h"
+#include "pt-arg-list.h"
+#include "pt-exp.h"
+#include "pt-pr-code.h"
+#include "pt-walk.h"
+#include "toplev.h"
+
+// Argument lists.
+
+tree_argument_list::~tree_argument_list (void)
+{
+  while (! empty ())
+    {
+      tree_expression *t = remove_front ();
+      delete t;
+    }
+}
+
+bool
+tree_argument_list::all_elements_are_constant (void) const
+{
+  for (Pix p = first (); p != 0; next (p))
+    {
+      tree_expression *elt = this->operator () (p);
+
+      if (! elt->is_constant ())
+	return false;
+    }
+
+  return true;
+}
+
+octave_value_list
+tree_argument_list::convert_to_const_vector (void)
+{
+  int len = length ();
+
+  // XXX FIXME XXX -- would be nice to know in advance how largs args
+  // needs to be even when we have a list containing an all_va_args
+  // token.
+
+  octave_value_list args;
+  args.resize (len);
+
+  Pix p = first ();
+  int j = 0;
+  for (int k = 0; k < len; k++)
+    {
+      tree_expression *elt = this->operator () (p);
+
+      if (elt)
+	{
+	  octave_value tmp = elt->rvalue ();
+
+	  if (error_state)
+	    {
+	      ::error ("evaluating argument list element number %d", k);
+	      args = octave_value_list ();
+	      break;
+	    }
+	  else
+	    {
+	      if (tmp.is_all_va_args ())
+		{
+		  if (curr_function)
+		    {
+		      octave_value_list tva;
+		      tva = curr_function->octave_all_va_args ();
+		      int n = tva.length ();
+		      for (int i = 0; i < n; i++)
+			args(j++) = tva(i);
+		    }
+		  else
+		    {
+		      ::error ("all_va_args is only valid inside functions");
+		      args = octave_value_list ();
+		      break;
+		    }
+		}
+	      else
+		args(j++) = tmp;
+	    }
+	  next (p);
+	}
+      else
+	{
+	  args(j++) = octave_value ();
+	  break;
+	}
+    }
+
+  args.resize (j);
+
+  return args;
+}
+
+string_vector
+tree_argument_list::get_arg_names (void) const
+{
+  int len = length ();
+
+  string_vector retval (len);
+
+  int k = 0;
+
+  for (Pix p = first (); p; next (p))
+    {
+      tree_expression *elt = this->operator () (p);
+
+      strstream str_buf;
+
+      tree_print_code pc_buf (str_buf);
+
+      elt->accept (pc_buf);
+
+      str_buf << ends;
+
+      const char *s = str_buf.str ();
+
+      retval(k++) = s;
+
+      delete [] s;
+    }
+
+  return retval;
+}
+
+void
+tree_argument_list::accept (tree_walker& tw)
+{
+  tw.visit_argument_list (*this);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
new file mode 100644
--- /dev/null
+++ b/src/pt-arg-list.h
@@ -0,0 +1,71 @@
+/*
+
+Copyright (C) 1996, 1997 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#if !defined (octave_tree_arg_list_h)
+#define octave_tree_arg_list_h 1
+
+#if defined (__GNUG__)
+#pragma interface
+#endif
+
+#include <SLList.h>
+
+class octave_value_list;
+
+class tree_expression;
+
+class tree_walker;
+
+#include "str-vec.h"
+
+// Argument lists.  Used to hold the list of expressions that are the
+// arguments in a function call or index expression.
+
+class
+tree_argument_list : public SLList<tree_expression *>
+{
+public:
+
+  tree_argument_list (void)
+    : SLList<tree_expression *> () { }
+
+  tree_argument_list (tree_expression *t)
+    : SLList<tree_expression *> () { append (t); }
+
+  ~tree_argument_list (void);
+
+  bool all_elements_are_constant (void) const;
+
+  octave_value_list convert_to_const_vector (void);
+
+  string_vector get_arg_names (void) const;
+
+  void accept (tree_walker& tw);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
--- a/src/pt-assign.cc
+++ b/src/pt-assign.cc
@@ -38,8 +38,8 @@
 #include "oct-lvalue.h"
 #include "pager.h"
 #include "ov.h"
+#include "pt-arg-list.h"
 #include "pt-assign.h"
-#include "pt-misc.h"
 #include "pt-pr-code.h"
 #include "pt-walk.h"
 #include "utils.h"
--- a/src/pt-binop.cc
+++ b/src/pt-binop.cc
@@ -32,7 +32,6 @@
 #include "oct-obj.h"
 #include "ov.h"
 #include "pt-binop.h"
-#include "pt-pr-code.h"
 #include "pt-walk.h"
 
 // Binary expressions.
--- a/src/pt-cmd.cc
+++ b/src/pt-cmd.cc
@@ -28,705 +28,8 @@
 #include <config.h>
 #endif
 
-#include <iostream.h>
-
-// Nonzero means we're breaking out of a loop or function body.
-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 "error.h"
-#include "gripes.h"
-#include "oct-map.h"
-#include "oct-lvalue.h"
 #include "pt-cmd.h"
-#include "symtab.h"
-#include "ov.h"
-#include "pt-exp.h"
-#include "pt-id.h"
-#include "pt-indir.h"
-#include "pt-misc.h"
 #include "pt-walk.h"
-#include "unwind-prot.h"
-#include "variables.h"
-
-// Decide if it's time to quit a for or while loop.
-static inline bool
-quit_loop_now (void)
-{
-  // Maybe handle `continue N' someday...
-
-  if (continuing)
-    continuing--;
-
-  bool quit = (error_state || returning || breaking || continuing);
-
-  if (breaking)
-    breaking--;
-
-  return quit;
-}
-
-// Base class for declaration commands (global, static).
-
-tree_decl_command::~tree_decl_command (void)
-{
-  delete init_list;
-}
-
-void
-tree_decl_command::accept (tree_walker& tw)
-{
-  tw.visit_decl_command (*this);
-}
-
-// Global.
-
-static void
-do_global_init (tree_decl_elt& elt, bool skip_initializer)
-{
-  tree_identifier *id = elt.ident ();
-
-  if (id)
-    {
-      id->link_to_global ();
-
-      tree_expression *expr = elt.expression ();
-
-      if (expr)
-	{
-	  octave_value init_val = expr->rvalue ();
-
-	  octave_lvalue ult = id->lvalue ();
-
-	  ult.assign (octave_value::asn_eq, init_val);
-	}
-    }
-}
-
-void
-tree_global_command::eval (void)
-{
-  if (init_list)
-    {
-      init_list->eval (do_global_init, initialized);
-
-      initialized = true;
-    }
-
-  if (error_state > 0)
-    ::error ("evaluating global command near line %d, column %d",
-	     line (), column ());
-}
-
-// Static.
-
-static void
-do_static_init (tree_decl_elt& elt, bool)
-{
-  tree_identifier *id = elt.ident ();
-
-  if (id)
-    {
-      id->mark_as_static ();
-
-      tree_expression *expr = elt.expression ();
-
-      if (expr)
-	{
-	  octave_value init_val = expr->rvalue ();
-
-	  octave_lvalue ult = id->lvalue ();
-
-	  ult.assign (octave_value::asn_eq, init_val);
-	}
-    }
-}
-
-void
-tree_static_command::eval (void)
-{
-  // Static variables only need to be marked and initialized once.
-
-  if (init_list && ! initialized)
-    {
-      init_list->eval (do_static_init, initialized);
-
-      initialized = true;
-
-      if (error_state > 0)
-	::error ("evaluating static command near line %d, column %d",
-		 line (), column ());
-    }
-}
-
-// While.
-
-tree_while_command::~tree_while_command (void)
-{
-  delete expr;
-  delete list;
-}
-
-void
-tree_while_command::eval (void)
-{
-  if (error_state)
-    return;
-
-  if (! expr)
-    panic_impossible ();
-
-  for (;;)
-    {
-      if (expr->is_logically_true ("while"))
-	{
-	  if (list)
-	    {
-	      list->eval ();
-
-	      if (error_state)
-		{
-		  eval_error ();
-		  return;
-		}
-	    }
-
-	  if (quit_loop_now ())
-	    break;
-	}
-      else
-	break;
-    }
-}
-
-void
-tree_while_command::eval_error (void)
-{
-  if (error_state > 0)
-    ::error ("evaluating while command near line %d, column %d",
-	     line (), column ());
-}
-
-void
-tree_while_command::accept (tree_walker& tw)
-{
-  tw.visit_while_command (*this);
-}
-
-// For.
-
-tree_simple_for_command::~tree_simple_for_command (void)
-{
-  delete expr;
-  delete list;
-}
-
-inline void
-tree_simple_for_command::do_for_loop_once (octave_lvalue& ult,
-					   const octave_value& rhs,
-					   bool& quit)
-{
-  quit = false;
-
-  ult.assign (octave_value::asn_eq, rhs);
-
-  if (! error_state)
-    {
-      if (list)
-	{
-	  list->eval ();
-
-	  if (error_state)
-	    eval_error ();
-	}
-    }
-  else
-    eval_error ();
-
-  quit = quit_loop_now ();
-}
-
-#define DO_LOOP(arg) \
-  do \
-    { \
-      for (int i = 0; i < steps; i++) \
-	{ \
-	  octave_value val (arg); \
- \
-	  bool quit = false; \
- \
-	  do_for_loop_once (ult, val, quit); \
- \
-	  if (quit) \
-	    break; \
-	} \
-    } \
-  while (0)
-
-void
-tree_simple_for_command::eval (void)
-{
-  if (error_state)
-    return;
-
-  octave_value rhs = expr->rvalue ();
-
-  if (error_state || rhs.is_undefined ())
-    {
-      eval_error ();
-      return;
-    }
-
-  octave_lvalue ult = lhs->lvalue ();
-
-  if (error_state)
-    {
-      eval_error ();
-      return;
-    }
-
-  if (rhs.is_scalar_type ())
-    {
-      bool quit = false;
-
-      do_for_loop_once (ult, rhs, quit);
-    }
-  else if (rhs.is_matrix_type ())
-    {
-      Matrix m_tmp;
-      ComplexMatrix cm_tmp;
-
-      int nr;
-      int steps;
-
-      if (rhs.is_real_matrix ())
-	{
-	  m_tmp = rhs.matrix_value ();
-	  nr = m_tmp.rows ();
-	  steps = m_tmp.columns ();
-	}
-      else
-	{
-	  cm_tmp = rhs.complex_matrix_value ();
-	  nr = cm_tmp.rows ();
-	  steps = cm_tmp.columns ();
-	}
-
-      if (rhs.is_real_matrix ())
-	{
-	  if (nr == 1)
-	    DO_LOOP (m_tmp (0, i));
-	  else
-	    DO_LOOP (m_tmp.extract (0, i, nr-1, i));
-	}
-      else
-	{
-	  if (nr == 1)
-	    DO_LOOP (cm_tmp (0, i));
-	  else
-	    DO_LOOP (cm_tmp.extract (0, i, nr-1, i));
-	}
-    }
-  else if (rhs.is_string ())
-    {
-      gripe_string_invalid ();
-    }
-  else if (rhs.is_range ())
-    {
-      Range rng = rhs.range_value ();
-
-      int steps = rng.nelem ();
-      double b = rng.base ();
-      double increment = rng.inc ();
-
-      for (int i = 0; i < steps; i++)
-	{
-	  double tmp_val = b + i * increment;
-
-	  octave_value val (tmp_val);
-
-	  bool quit = false;
-
-	  do_for_loop_once (ult, val, quit);
-
-	  if (quit)
-	    break;
-	}
-    }
-  else if (rhs.is_map ())
-    {
-      Octave_map tmp_val (rhs.map_value ());
-
-      for (Pix p = tmp_val.first (); p != 0; tmp_val.next (p))
-	{
-	  octave_value val = tmp_val.contents (p);
-
-	  bool quit = false;
-
-	  do_for_loop_once (ult, val, quit);
-
-	  if (quit)
-	    break;
-	}
-    }
-  else
-    {
-      ::error ("invalid type in for loop expression near line %d, column %d",
-	       line (), column ());
-    }
-}
-
-void
-tree_simple_for_command::eval_error (void)
-{
-  if (error_state > 0)
-    ::error ("evaluating for command near line %d, column %d",
-	     line (), column ());
-}
-
-void
-tree_simple_for_command::accept (tree_walker& tw)
-{
-  tw.visit_simple_for_command (*this);
-}
-
-tree_complex_for_command::~tree_complex_for_command (void)
-{
-  delete expr;
-  delete list;
-}
-
-void
-tree_complex_for_command::do_for_loop_once (octave_lvalue &val_ref,
-					    octave_lvalue &key_ref,
-					    const octave_value& val,
-					    const octave_value& key,
-					    bool& quit)
-{
-  quit = false;
-
-  val_ref.assign (octave_value::asn_eq, val);
-  key_ref.assign (octave_value::asn_eq, key);
-
-  if (! error_state)
-    {
-      if (list)
-	{
-	  list->eval ();
-
-	  if (error_state)
-	    eval_error ();
-	}
-    }
-  else
-    eval_error ();
-
-  quit = quit_loop_now ();
-}
-
-void
-tree_complex_for_command::eval (void)
-{
-  if (error_state)
-    return;
-
-  octave_value rhs = expr->rvalue ();
-
-  if (error_state || rhs.is_undefined ())
-    {
-      eval_error ();
-      return;
-    }
-
-  if (rhs.is_map ())
-    {
-      // Cycle through structure elements.  First element of id_list
-      // is set to value and the second is set to the name of the
-      // structure element.
-
-      Pix p = lhs->first ();
-      tree_expression *elt = lhs->operator () (p);
-      octave_lvalue val_ref = elt->lvalue ();
-
-      lhs->next (p);
-      elt = lhs->operator () (p);
-      octave_lvalue key_ref = elt->lvalue ();
-
-      Octave_map tmp_val (rhs.map_value ());
-
-      for (p = tmp_val.first (); p != 0; tmp_val.next (p))
-	{
-	  octave_value key = tmp_val.key (p);
-	  octave_value val = tmp_val.contents (p);
-
-	  bool quit = false;
-
-	  do_for_loop_once (key_ref, val_ref, key, val, quit);
-
-	  if (quit)
-	    break;
-	}
-    }
-  else
-    error ("in statement `for [X, Y] = VAL', VAL must be a structure");
-}
-
-void
-tree_complex_for_command::eval_error (void)
-{
-  if (error_state > 0)
-    ::error ("evaluating for command near line %d, column %d",
-	     line (), column ());
-}
-
-void
-tree_complex_for_command::accept (tree_walker& tw)
-{
-  tw.visit_complex_for_command (*this);
-}
-
-// If.
-
-tree_if_command::~tree_if_command (void)
-{
-  delete list;
-}
-
-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 ());
-}
-
-void
-tree_if_command::accept (tree_walker& tw)
-{
-  tw.visit_if_command (*this);
-}
-
-// Switch.
-
-tree_switch_command::~tree_switch_command (void)
-{
-  delete expr;
-  delete list;
-}
-
-void
-tree_switch_command::eval (void)
-{
-  if (expr)
-    {
-      octave_value val = expr->rvalue ();
-
-      if (! error_state)
-	{
-	  if (list)
-	    list->eval (val);
-
-	  if (error_state)
-	    eval_error ();
-	}
-      else
-	eval_error ();
-    }
-  else
-    ::error ("missing value in switch command near line %d, column %d",
-	     line (), column ());
-}
-
-void
-tree_switch_command::eval_error (void)
-{
-  ::error ("evaluating switch command near line %d, column %d",
-	   line (), column ());
-}
-
-void
-tree_switch_command::accept (tree_walker& tw)
-{
-  tw.visit_switch_command (*this);
-}
-
-// Simple exception handling.
-
-tree_try_catch_command::~tree_try_catch_command (void)
-{
-  delete try_code;
-  delete catch_code;
-}
-
-static void
-do_catch_code (void *ptr)
-{
-  tree_statement_list *list = static_cast<tree_statement_list *> (ptr);
-
-  // Set up for letting the user print any messages from errors that
-  // occurred in the body of the try_catch statement.
-
-  buffer_error_messages = 0;
-  bind_global_error_variable ();
-  add_unwind_protect (clear_global_error_variable, 0);
-
-  // Similarly, if we have seen a return or break statement, allow all
-  // the catch code to run before returning or handling the break.
-  // We don't have to worry about continue statements because they can
-  // only occur in loops.
-
-  unwind_protect_int (returning);
-  returning = 0;
-
-  unwind_protect_int (breaking);
-  breaking = 0;
-
-  if (list)
-    list->eval ();
-
-  // This is the one for breaking.  (The unwind_protects are popped
-  // off the stack in the reverse of the order they are pushed on).
-
-  // XXX FIXME XXX -- inside a try-catch, should break work like
-  // a return, or just jump to the end of the try_catch block?
-  // The following code makes it just jump to the end of the block.
-
-  run_unwind_protect ();
-  if (breaking)
-    breaking--;
-
-  // This is the one for returning.
-
-  if (returning)
-    discard_unwind_protect ();
-  else
-    run_unwind_protect ();
-
-  run_unwind_protect ();
-}
-
-void
-tree_try_catch_command::eval (void)
-{
-  begin_unwind_frame ("tree_try_catch::eval");
-
-  add_unwind_protect (do_catch_code, catch_code);
-
-  if (catch_code)
-    {
-      unwind_protect_int (buffer_error_messages);
-      buffer_error_messages = 1;
-    }
-
-  if (try_code)
-    try_code->eval ();
-
-  if (catch_code && error_state)
-    {
-      error_state = 0;
-      run_unwind_frame ("tree_try_catch::eval");
-    }
-  else
-    {
-      error_state = 0;
-      discard_unwind_frame ("tree_try_catch::eval");
-    }
-}
-
-void
-tree_try_catch_command::accept (tree_walker& tw)
-{
-  tw.visit_try_catch_command (*this);
-}
-
-// Simple exception handling.
-
-tree_unwind_protect_command::~tree_unwind_protect_command (void)
-{
-  delete unwind_protect_code;
-  delete cleanup_code;
-}
-
-static void
-do_unwind_protect_cleanup_code (void *ptr)
-{
-  tree_statement_list *list = static_cast<tree_statement_list *> (ptr);
-
-  // We want to run the cleanup code without error_state being set,
-  // but we need to restore its value, so that any errors encountered
-  // in the first part of the unwind_protect are not completely
-  // ignored.
-
-  unwind_protect_int (error_state);
-  error_state = 0;
-
-  // Similarly, if we have seen a return or break statement, allow all
-  // the cleanup code to run before returning or handling the break.
-  // We don't have to worry about continue statements because they can
-  // only occur in loops.
-
-  unwind_protect_int (returning);
-  returning = 0;
-
-  unwind_protect_int (breaking);
-  breaking = 0;
-
-  if (list)
-    list->eval ();
-
-  // This is the one for breaking.  (The unwind_protects are popped
-  // off the stack in the reverse of the order they are pushed on).
-
-  // XXX FIXME XXX -- inside an unwind_protect, should break work like
-  // a return, or just jump to the end of the unwind_protect block?
-  // The following code makes it just jump to the end of the block.
-
-  run_unwind_protect ();
-  if (breaking)
-    breaking--;
-
-  // This is the one for returning.
-
-  if (returning)
-    discard_unwind_protect ();
-  else
-    run_unwind_protect ();
-
-  // We don't want to ignore errors that occur in the cleanup code, so
-  // if an error is encountered there, leave error_state alone.
-  // Otherwise, set it back to what it was before.
-
-  if (error_state)
-    discard_unwind_protect ();
-  else
-    run_unwind_protect ();
-}
-
-void
-tree_unwind_protect_command::eval (void)
-{
-  add_unwind_protect (do_unwind_protect_cleanup_code, cleanup_code);
-
-  if (unwind_protect_code)
-    unwind_protect_code->eval ();
-
-  run_unwind_protect ();
-}
-
-void
-tree_unwind_protect_command::accept (tree_walker& tw)
-{
-  tw.visit_unwind_protect_command (*this);
-}
 
 // No-op.
 
@@ -736,51 +39,6 @@
   tw.visit_no_op_command (*this);
 }
 
-// Break.
-
-void
-tree_break_command::eval (void)
-{
-  if (! error_state)
-    breaking = 1;
-}
-
-void
-tree_break_command::accept (tree_walker& tw)
-{
-  tw.visit_break_command (*this);
-}
-
-// Continue.
-
-void
-tree_continue_command::eval (void)
-{
-  if (! error_state)
-    continuing = 1;
-}
-
-void
-tree_continue_command::accept (tree_walker& tw)
-{
-  tw.visit_continue_command (*this);
-}
-
-// Return.
-
-void
-tree_return_command::eval (void)
-{
-  if (! error_state)
-    returning = 1;
-}
-
-void
-tree_return_command::accept (tree_walker& tw)
-{
-  tw.visit_return_command (*this);
-}
-
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/src/pt-cmd.h
+++ b/src/pt-cmd.h
@@ -27,41 +27,10 @@
 #pragma interface
 #endif
 
-class ostream;
-
-class octave_value_list;
-
-class tree_argument_list;
-class tree_statement_list;
-class tree_decl_init_list;
-class tree_if_command_list;
-class tree_switch_case_list;
-class tree_expression;
-class tree_index_expression;
-class tree_identifier;
-class tree_return_list;
-class octave_value;
-
-class tree_command;
-class tree_decl_command;
-class tree_global_command;
-class tree_static_command;
-class tree_while_command;
-class tree_simple_for_command;
-class tree_complex_for_command;
-class tree_if_command;
-class tree_switch_command;
-class tree_try_catch_command;
-class tree_unwind_protect_command;
-class tree_no_op_command;
-class tree_break_command;
-class tree_continue_command;
-class tree_return_command;
+#include <string>
 
 class tree_walker;
 
-#include <string>
-
 #include "pt-base.h"
 
 // A base class for commands.
@@ -71,337 +40,14 @@
 {
 public:
 
-  tree_command (int l = -1, int c = -1) : tree (l, c) { }
+  tree_command (int l = -1, int c = -1)
+    : tree (l, c) { }
 
   virtual ~tree_command (void) { }
 
   virtual void eval (void) = 0;
 };
 
-// Base class for declaration commands -- global, static, etc.
-
-class
-tree_decl_command : public tree_command
-{
-public:
-
-  tree_decl_command (const string& n, int l = -1, int c = -1)
-    : tree_command (l, c), cmd_name (n), initialized (false), init_list (0) { }
-
-  tree_decl_command (const string& n, tree_decl_init_list *t,
-		     int l = -1, int c = -1)
-    : tree_command (l, c), cmd_name (n), initialized (false), init_list (t) { }
-
-  ~tree_decl_command (void);
-
-  tree_decl_init_list *initializer_list (void) { return init_list; }
-
-  void accept (tree_walker& tw);
-
-  string name (void) { return cmd_name; }
-
-protected:
-
-  // The name of this command -- global, static, etc.
-  string cmd_name;
-
-  // TRUE if this command has been evaluated.
-  bool initialized;
-
-  // The list of variables or initializers in this declaration command.
-  tree_decl_init_list *init_list;
-};
-
-// Global.
-
-class
-tree_global_command : public tree_decl_command
-{
-public:
-
-  tree_global_command (int l = -1, int c = -1)
-    : tree_decl_command ("global", l, c) { }
-
-  tree_global_command (tree_decl_init_list *t, int l = -1, int c = -1)
-    : tree_decl_command ("global", t, l, c) { }
-
-  ~tree_global_command (void) { }
-
-  void eval (void);
-};
-
-// Static.
-
-class
-tree_static_command : public tree_decl_command
-{
-public:
-
-  tree_static_command (int l = -1, int c = -1)
-    : tree_decl_command ("static", l, c) { }
-
-  tree_static_command (tree_decl_init_list *t, int l = -1, int c = -1)
-    : tree_decl_command ("static", t, l, c) { }
-
-  ~tree_static_command (void) { }
-
-  void eval (void);
-};
-
-// While.
-
-class
-tree_while_command : public tree_command
-{
-public:
-
-  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);
-
-  void eval (void);
-
-  void eval_error (void);
-
-  tree_expression *condition (void) { return expr; }
-
-  tree_statement_list *body (void) { return list; }
-
-  void accept (tree_walker& tw);
-
-private:
-
-  // Expression to test.
-  tree_expression *expr;
-
-  // List of commands to execute.
-  tree_statement_list *list;
-};
-
-// For.
-
-class
-tree_simple_for_command : public tree_command
-{
-public:
-
-  tree_simple_for_command (int l = -1, int c = -1)
-    : tree_command (l, c), lhs (0), expr (0), list (0) { }
-
-  tree_simple_for_command (tree_expression *le, tree_expression *re,
-			   tree_statement_list *lst, int l = -1, int c = -1)
-    : tree_command (l, c), lhs (le), expr (re), list (lst) { }
-
-  ~tree_simple_for_command (void);
-
-  void eval (void);
-
-  void eval_error (void);
-
-  tree_expression *left_hand_side (void) { return lhs; }
-
-  tree_expression *control_expr (void) { return expr; }
-
-  tree_statement_list *body (void) { return list; }
-
-  void accept (tree_walker& tw);
-
-private:
-
-  // Expression to modify.
-  tree_expression *lhs;
-
-  // Expression to evaluate.
-  tree_expression *expr;
-
-  // List of commands to execute.
-  tree_statement_list *list;
-
-  void do_for_loop_once (octave_lvalue &ult, const octave_value& rhs,
-			 bool& quit);
-};
-
-class
-tree_complex_for_command : public tree_command
-{
-public:
-
-  tree_complex_for_command (int l = -1, int c = -1)
-    : tree_command (l, c), lhs (0), expr (0), list (0) { }
-
-  tree_complex_for_command (tree_argument_list *le, tree_expression *re,
-			    tree_statement_list *lst, int l = -1, int c = -1)
-    : tree_command (l, c), lhs (le), expr (re), list (lst) { }
-
-  ~tree_complex_for_command (void);
-
-  void eval (void);
-
-  void eval_error (void);
-
-  tree_argument_list *left_hand_side (void) { return lhs; }
-
-  tree_expression *control_expr (void) { return expr; }
-
-  tree_statement_list *body (void) { return list; }
-
-  void accept (tree_walker& tw);
-
-private:
-
-  // Expression to modify.
-  tree_argument_list *lhs;
-
-  // Expression to evaluate.
-  tree_expression *expr;
-
-  // List of commands to execute.
-  tree_statement_list *list;
-
-  void do_for_loop_once (octave_lvalue &val_ref, octave_lvalue &key_ref,
-			 const octave_value& val, const octave_value& key,
-			 bool& quit);
-};
-
-// If.
-
-class
-tree_if_command : public tree_command
-{
-public:
-
-  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);
-
-  void eval (void);
-
-  tree_if_command_list *cmd_list (void) { return list; }
-
-  void accept (tree_walker& tw);
-
-private:
-
-  // List of if commands (if, elseif, elseif, ... else, endif)
-  tree_if_command_list *list;
-};
-
-// Switch.
-
-class
-tree_switch_command : public tree_command
-{
-public:
-
-  tree_switch_command (int l = -1, int c = -1)
-    : tree_command (l, c), expr (0), list (0) { }
-
-  tree_switch_command (tree_expression *e, tree_switch_case_list *lst,
-		       int l = -1, int c = -1)
-    : tree_command (l, c), expr (e), list (lst) { }
-
-  ~tree_switch_command (void);
-
-  void eval (void);
-
-  void eval_error (void);
-
-  tree_expression *switch_value (void) { return expr; }
-
-  tree_switch_case_list *case_list (void) { return list; }
-
-  void accept (tree_walker& tw);
-
-private:
-
-  // Value on which to switch.
-  tree_expression *expr;
-
-  // List of cases (case 1, case 2, ..., default)
-  tree_switch_case_list *list;
-};
-
-// Simple exception handling.
-
-class
-tree_unwind_protect_command : public tree_command
-{
-public:
-
-  tree_unwind_protect_command (int l = -1, int c = -1)
-    : tree_command (l, c), unwind_protect_code (0), cleanup_code (0) { }
-
-  tree_unwind_protect_command (tree_statement_list *tc,
-			       tree_statement_list *cc,
-			       int l = -1, int c = -1)
-    : tree_command (l, c), unwind_protect_code (tc), cleanup_code (cc) { }
-
-  ~tree_unwind_protect_command (void);
-
-  void eval (void);
-
-  tree_statement_list *body (void) { return unwind_protect_code; }
-
-  tree_statement_list *cleanup (void) { return cleanup_code; }
-
-  void accept (tree_walker& tw);
-
-private:
-
-  // The first body of code to attempt to execute.
-  tree_statement_list *unwind_protect_code;
-
-  // The body of code to execute no matter what happens in the first
-  // body of code.
-  tree_statement_list *cleanup_code;
-};
-
-// Simple exception handling.
-
-class
-tree_try_catch_command : public tree_command
-{
-public:
-
-  tree_try_catch_command (int l = -1, int c = -1)
-    : tree_command (l, c), try_code (0), catch_code (0) { }
-
-  tree_try_catch_command (tree_statement_list *tc,
-			       tree_statement_list *cc,
-			       int l = -1, int c = -1)
-    : tree_command (l, c), try_code (tc), catch_code (cc) { }
-
-  ~tree_try_catch_command (void);
-
-  void eval (void);
-
-  tree_statement_list *body (void) { return try_code; }
-
-  tree_statement_list *cleanup (void) { return catch_code; }
-
-  void accept (tree_walker& tw);
-
-private:
-
-  // The first block of code to attempt to execute.
-  tree_statement_list *try_code;
-
-  // The code to execute if an error occurs in the first block.
-  tree_statement_list *catch_code;
-};
-
 // No-op.
 
 class
@@ -425,54 +71,6 @@
   string orig_cmd;
 };
 
-// Break.
-
-class
-tree_break_command : public tree_command
-{
-public:
-
-  tree_break_command (int l = -1, int c = -1) : tree_command (l, c) { }
-
-  ~tree_break_command (void) { }
-
-  void eval (void);
-
-  void accept (tree_walker& tw);
-};
-
-// Continue.
-
-class
-tree_continue_command : public tree_command
-{
-public:
-
-  tree_continue_command (int l = -1, int c = -1) : tree_command (l, c) { }
-
-  ~tree_continue_command (void) { }
-
-  void eval (void);
-
-  void accept (tree_walker& tw);
-};
-
-// Return.
-
-class
-tree_return_command : public tree_command
-{
-public:
-
-  tree_return_command (int l = -1, int c = -1) : tree_command (l, c) { }
-
-  ~tree_return_command (void) { }
-
-  void eval (void);
-
-  void accept (tree_walker& tw);
-};
-
 #endif
 
 /*
--- a/src/pt-colon.cc
+++ b/src/pt-colon.cc
@@ -33,7 +33,6 @@
 #include "pager.h"
 #include "ov.h"
 #include "pt-colon.h"
-#include "pt-pr-code.h"
 #include "pt-walk.h"
 
 // Colon expressions.
new file mode 100644
--- /dev/null
+++ b/src/pt-decl.cc
@@ -0,0 +1,171 @@
+/*
+
+Copyright (C) 1996, 1997 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#if defined (__GNUG__)
+#pragma implementation
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "error.h"
+#include "pt-cmd.h"
+#include "ov.h"
+#include "oct-lvalue.h"
+#include "pt-decl.h"
+#include "pt-exp.h"
+#include "pt-id.h"
+#include "pt-walk.h"
+
+// Declarations (global, static, etc.).
+
+tree_decl_elt::~tree_decl_elt (void)
+{
+  delete id;
+  delete expr;
+}
+
+void
+tree_decl_elt::accept (tree_walker& tw)
+{
+  tw.visit_decl_elt (*this);
+}
+
+// Initializer lists for declaration statements.
+
+void
+tree_decl_init_list::eval (tree_decl_elt::eval_fcn f, bool skip_init)
+{
+  for (Pix p = first (); p != 0; next (p))
+    {
+      f (*(this->operator () (p)), skip_init);
+
+      if (error_state)
+	break;
+    }
+}
+
+void
+tree_decl_init_list::accept (tree_walker& tw)
+{
+  tw.visit_decl_init_list (*this);
+}
+
+// Base class for declaration commands (global, static).
+
+tree_decl_command::~tree_decl_command (void)
+{
+  delete init_list;
+}
+
+void
+tree_decl_command::accept (tree_walker& tw)
+{
+  tw.visit_decl_command (*this);
+}
+
+// Global.
+
+static void
+do_global_init (tree_decl_elt& elt, bool skip_initializer)
+{
+  tree_identifier *id = elt.ident ();
+
+  if (id)
+    {
+      id->link_to_global ();
+
+      tree_expression *expr = elt.expression ();
+
+      if (expr)
+	{
+	  octave_value init_val = expr->rvalue ();
+
+	  octave_lvalue ult = id->lvalue ();
+
+	  ult.assign (octave_value::asn_eq, init_val);
+	}
+    }
+}
+
+void
+tree_global_command::eval (void)
+{
+  if (init_list)
+    {
+      init_list->eval (do_global_init, initialized);
+
+      initialized = true;
+    }
+
+  if (error_state > 0)
+    ::error ("evaluating global command near line %d, column %d",
+	     line (), column ());
+}
+
+// Static.
+
+static void
+do_static_init (tree_decl_elt& elt, bool)
+{
+  tree_identifier *id = elt.ident ();
+
+  if (id)
+    {
+      id->mark_as_static ();
+
+      tree_expression *expr = elt.expression ();
+
+      if (expr)
+	{
+	  octave_value init_val = expr->rvalue ();
+
+	  octave_lvalue ult = id->lvalue ();
+
+	  ult.assign (octave_value::asn_eq, init_val);
+	}
+    }
+}
+
+void
+tree_static_command::eval (void)
+{
+  // Static variables only need to be marked and initialized once.
+
+  if (init_list && ! initialized)
+    {
+      init_list->eval (do_static_init, initialized);
+
+      initialized = true;
+
+      if (error_state > 0)
+	::error ("evaluating static command near line %d, column %d",
+		 line (), column ());
+    }
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
new file mode 100644
--- /dev/null
+++ b/src/pt-decl.h
@@ -0,0 +1,173 @@
+/*
+
+Copyright (C) 1996, 1997 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#if !defined (octave_tree_decl_h)
+#define octave_tree_decl_h 1
+
+#if defined (__GNUG__)
+#pragma interface
+#endif
+
+#include <SLList.h>
+
+class tree_expression;
+class tree_identifier;
+
+class tree_walker;
+
+#include <string>
+
+#include "pt-cmd.h"
+
+// List of expressions that make up a declaration statement.
+
+class
+tree_decl_elt
+{
+public:
+
+  typedef void (*eval_fcn) (tree_decl_elt &, bool);
+
+  tree_decl_elt (tree_identifier *i = 0, tree_expression *e = 0)
+    : id (i), expr (e) { }
+
+  ~tree_decl_elt (void);
+
+  void eval (void);
+
+  tree_identifier *ident (void) { return id; }
+
+  tree_expression *expression (void) { return expr; }
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // An identifier to tag with the declared property.
+  tree_identifier *id;
+
+  // An initializer expression (may be zero);
+  tree_expression *expr;
+};
+
+class
+tree_decl_init_list : public SLList<tree_decl_elt *>
+{
+public:
+
+  tree_decl_init_list (void)
+    : SLList<tree_decl_elt *> () { }
+
+  tree_decl_init_list (tree_decl_elt *t)
+    : SLList<tree_decl_elt *> () { append (t); }
+
+  ~tree_decl_init_list (void)
+    {
+      while (! empty ())
+	{
+	  tree_decl_elt *t = remove_front ();
+	  delete t;
+	}
+    }
+
+  void eval (tree_decl_elt::eval_fcn, bool);
+
+  void accept (tree_walker& tw);
+};
+
+// Base class for declaration commands -- global, static, etc.
+
+class
+tree_decl_command : public tree_command
+{
+public:
+
+  tree_decl_command (const string& n, int l = -1, int c = -1)
+    : tree_command (l, c), cmd_name (n), initialized (false), init_list (0) { }
+
+  tree_decl_command (const string& n, tree_decl_init_list *t,
+		     int l = -1, int c = -1)
+    : tree_command (l, c), cmd_name (n), initialized (false), init_list (t) { }
+
+  ~tree_decl_command (void);
+
+  tree_decl_init_list *initializer_list (void) { return init_list; }
+
+  void accept (tree_walker& tw);
+
+  string name (void) { return cmd_name; }
+
+protected:
+
+  // The name of this command -- global, static, etc.
+  string cmd_name;
+
+  // TRUE if this command has been evaluated.
+  bool initialized;
+
+  // The list of variables or initializers in this declaration command.
+  tree_decl_init_list *init_list;
+};
+
+// Global.
+
+class
+tree_global_command : public tree_decl_command
+{
+public:
+
+  tree_global_command (int l = -1, int c = -1)
+    : tree_decl_command ("global", l, c) { }
+
+  tree_global_command (tree_decl_init_list *t, int l = -1, int c = -1)
+    : tree_decl_command ("global", t, l, c) { }
+
+  ~tree_global_command (void) { }
+
+  void eval (void);
+};
+
+// Static.
+
+class
+tree_static_command : public tree_decl_command
+{
+public:
+
+  tree_static_command (int l = -1, int c = -1)
+    : tree_decl_command ("static", l, c) { }
+
+  tree_static_command (tree_decl_init_list *t, int l = -1, int c = -1)
+    : tree_decl_command ("static", t, l, c) { }
+
+  ~tree_static_command (void) { }
+
+  void eval (void);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
new file mode 100644
--- /dev/null
+++ b/src/pt-except.cc
@@ -0,0 +1,225 @@
+/*
+
+Copyright (C) 1996, 1997 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#if defined (__GNUG__)
+#pragma implementation
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Nonzero means we're breaking out of a loop or function body.
+extern int breaking;
+
+// Nonzero means we're jumping to the end of a loop.
+extern int continuing;
+
+// Nonzero means we're returning from a function.  Global because it
+// is also needed in tree-expr.cc.
+extern int returning;
+
+#include "error.h"
+#include "oct-lvalue.h"
+#include "ov.h"
+#include "pt-cmd.h"
+#include "pt-except.h"
+#include "pt-exp.h"
+#include "pt-stmt.h"
+#include "pt-walk.h"
+#include "unwind-prot.h"
+#include "variables.h"
+
+// Simple exception handling.
+
+tree_try_catch_command::~tree_try_catch_command (void)
+{
+  delete try_code;
+  delete catch_code;
+}
+
+static void
+do_catch_code (void *ptr)
+{
+  tree_statement_list *list = static_cast<tree_statement_list *> (ptr);
+
+  // Set up for letting the user print any messages from errors that
+  // occurred in the body of the try_catch statement.
+
+  buffer_error_messages = 0;
+  bind_global_error_variable ();
+  add_unwind_protect (clear_global_error_variable, 0);
+
+  // Similarly, if we have seen a return or break statement, allow all
+  // the catch code to run before returning or handling the break.
+  // We don't have to worry about continue statements because they can
+  // only occur in loops.
+
+  unwind_protect_int (returning);
+  returning = 0;
+
+  unwind_protect_int (breaking);
+  breaking = 0;
+
+  if (list)
+    list->eval ();
+
+  // This is the one for breaking.  (The unwind_protects are popped
+  // off the stack in the reverse of the order they are pushed on).
+
+  // XXX FIXME XXX -- inside a try-catch, should break work like
+  // a return, or just jump to the end of the try_catch block?
+  // The following code makes it just jump to the end of the block.
+
+  run_unwind_protect ();
+  if (breaking)
+    breaking--;
+
+  // This is the one for returning.
+
+  if (returning)
+    discard_unwind_protect ();
+  else
+    run_unwind_protect ();
+
+  run_unwind_protect ();
+}
+
+void
+tree_try_catch_command::eval (void)
+{
+  begin_unwind_frame ("tree_try_catch::eval");
+
+  add_unwind_protect (do_catch_code, catch_code);
+
+  if (catch_code)
+    {
+      unwind_protect_int (buffer_error_messages);
+      buffer_error_messages = 1;
+    }
+
+  if (try_code)
+    try_code->eval ();
+
+  if (catch_code && error_state)
+    {
+      error_state = 0;
+      run_unwind_frame ("tree_try_catch::eval");
+    }
+  else
+    {
+      error_state = 0;
+      discard_unwind_frame ("tree_try_catch::eval");
+    }
+}
+
+void
+tree_try_catch_command::accept (tree_walker& tw)
+{
+  tw.visit_try_catch_command (*this);
+}
+
+// Simple exception handling.
+
+tree_unwind_protect_command::~tree_unwind_protect_command (void)
+{
+  delete unwind_protect_code;
+  delete cleanup_code;
+}
+
+static void
+do_unwind_protect_cleanup_code (void *ptr)
+{
+  tree_statement_list *list = static_cast<tree_statement_list *> (ptr);
+
+  // We want to run the cleanup code without error_state being set,
+  // but we need to restore its value, so that any errors encountered
+  // in the first part of the unwind_protect are not completely
+  // ignored.
+
+  unwind_protect_int (error_state);
+  error_state = 0;
+
+  // Similarly, if we have seen a return or break statement, allow all
+  // the cleanup code to run before returning or handling the break.
+  // We don't have to worry about continue statements because they can
+  // only occur in loops.
+
+  unwind_protect_int (returning);
+  returning = 0;
+
+  unwind_protect_int (breaking);
+  breaking = 0;
+
+  if (list)
+    list->eval ();
+
+  // This is the one for breaking.  (The unwind_protects are popped
+  // off the stack in the reverse of the order they are pushed on).
+
+  // XXX FIXME XXX -- inside an unwind_protect, should break work like
+  // a return, or just jump to the end of the unwind_protect block?
+  // The following code makes it just jump to the end of the block.
+
+  run_unwind_protect ();
+  if (breaking)
+    breaking--;
+
+  // This is the one for returning.
+
+  if (returning)
+    discard_unwind_protect ();
+  else
+    run_unwind_protect ();
+
+  // We don't want to ignore errors that occur in the cleanup code, so
+  // if an error is encountered there, leave error_state alone.
+  // Otherwise, set it back to what it was before.
+
+  if (error_state)
+    discard_unwind_protect ();
+  else
+    run_unwind_protect ();
+}
+
+void
+tree_unwind_protect_command::eval (void)
+{
+  add_unwind_protect (do_unwind_protect_cleanup_code, cleanup_code);
+
+  if (unwind_protect_code)
+    unwind_protect_code->eval ();
+
+  run_unwind_protect ();
+}
+
+void
+tree_unwind_protect_command::accept (tree_walker& tw)
+{
+  tw.visit_unwind_protect_command (*this);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
new file mode 100644
--- /dev/null
+++ b/src/pt-except.h
@@ -0,0 +1,110 @@
+/*
+
+Copyright (C) 1996, 1997 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#if !defined (octave_tree_except_h)
+#define octave_tree_except_h 1
+
+#if defined (__GNUG__)
+#pragma interface
+#endif
+
+class tree_statement_list;
+
+class tree_walker;
+
+#include "pt-cmd.h"
+
+// Simple exception handling.
+
+class
+tree_try_catch_command : public tree_command
+{
+public:
+
+  tree_try_catch_command (int l = -1, int c = -1)
+    : tree_command (l, c), try_code (0), catch_code (0) { }
+
+  tree_try_catch_command (tree_statement_list *tc, tree_statement_list *cc,
+			  int l = -1, int c = -1)
+    : tree_command (l, c), try_code (tc), catch_code (cc) { }
+
+  ~tree_try_catch_command (void);
+
+  void eval (void);
+
+  tree_statement_list *body (void) { return try_code; }
+
+  tree_statement_list *cleanup (void) { return catch_code; }
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // The first block of code to attempt to execute.
+  tree_statement_list *try_code;
+
+  // The code to execute if an error occurs in the first block.
+  tree_statement_list *catch_code;
+};
+
+// Simple exception handling.
+
+class
+tree_unwind_protect_command : public tree_command
+{
+public:
+
+  tree_unwind_protect_command (int l = -1, int c = -1)
+    : tree_command (l, c), unwind_protect_code (0), cleanup_code (0) { }
+
+  tree_unwind_protect_command (tree_statement_list *tc,
+			       tree_statement_list *cc,
+			       int l = -1, int c = -1)
+    : tree_command (l, c), unwind_protect_code (tc), cleanup_code (cc) { }
+
+  ~tree_unwind_protect_command (void);
+
+  void eval (void);
+
+  tree_statement_list *body (void) { return unwind_protect_code; }
+
+  tree_statement_list *cleanup (void) { return cleanup_code; }
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // The first body of code to attempt to execute.
+  tree_statement_list *unwind_protect_code;
+
+  // The body of code to execute no matter what happens in the first
+  // body of code.
+  tree_statement_list *cleanup_code;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
--- a/src/pt-exp.cc
+++ b/src/pt-exp.cc
@@ -70,7 +70,7 @@
 }
 
 octave_value_list
-tree_expression::rvalue (int nargout)
+tree_expression::rvalue (int)
 {
   ::error ("invalid rvalue function called in expression");
   return octave_value_list ();
--- a/src/pt-idx.cc
+++ b/src/pt-idx.cc
@@ -32,9 +32,8 @@
 #include "oct-obj.h"
 #include "oct-lvalue.h"
 #include "ov.h"
+#include "pt-arg-list.h"
 #include "pt-idx.h"
-#include "pt-misc.h"
-#include "pt-pr-code.h"
 #include "pt-walk.h"
 
 // Index expressions.
--- a/src/pt-indir.cc
+++ b/src/pt-indir.cc
@@ -29,16 +29,13 @@
 #endif
 
 #include "error.h"
-#include "gripes.h"
 #include "oct-map.h"
 #include "oct-obj.h"
 #include "oct-lvalue.h"
+#include "ov.h"
 #include "pager.h"
-#include "pt-const.h"
-#include "pt-id.h"
 #include "pt-indir.h"
 #include "pt-walk.h"
-#include "symtab.h"
 #include "utils.h"
 #include "variables.h"
 
@@ -52,7 +49,10 @@
 string
 tree_indirect_ref::name (void) const
 {
-  return expr->name () + "." + nm;
+  // ??? FIXME ???
+  string xname = expr->name ();
+
+  return (xname == "<unknown>") ? xname : xname + "." + nm;
 }
 
 octave_value_list
@@ -73,7 +73,16 @@
 	  octave_value val = tmp(0).do_struct_elt_index_op (nm);
 
 	  if (print_result () && nargout == 0 && val.is_defined ())
-	    val.print_with_name (octave_stdout, name ());
+	    {
+	      // ??? FIXME ???
+
+	      string xname = name ();
+
+	      if (xname == "<unknown>")
+		bind_ans (val, true);
+	      else
+		val.print_with_name (octave_stdout, xname);
+	    }
 
 	  retval = val;
 	}
new file mode 100644
--- /dev/null
+++ b/src/pt-jump.cc
@@ -0,0 +1,94 @@
+/*
+
+Copyright (C) 1996, 1997 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#if defined (__GNUG__)
+#pragma implementation
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Nonzero means we're breaking out of a loop or function body.
+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 "error.h"
+#include "pt-jump.h"
+#include "pt-walk.h"
+
+// Break.
+
+void
+tree_break_command::eval (void)
+{
+  if (! error_state)
+    breaking = 1;
+}
+
+void
+tree_break_command::accept (tree_walker& tw)
+{
+  tw.visit_break_command (*this);
+}
+
+// Continue.
+
+void
+tree_continue_command::eval (void)
+{
+  if (! error_state)
+    continuing = 1;
+}
+
+void
+tree_continue_command::accept (tree_walker& tw)
+{
+  tw.visit_continue_command (*this);
+}
+
+// Return.
+
+void
+tree_return_command::eval (void)
+{
+  if (! error_state)
+    returning = 1;
+}
+
+void
+tree_return_command::accept (tree_walker& tw)
+{
+  tw.visit_return_command (*this);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
new file mode 100644
--- /dev/null
+++ b/src/pt-jump.h
@@ -0,0 +1,91 @@
+/*
+
+Copyright (C) 1996, 1997 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#if !defined (octave_tree_jump_h)
+#define octave_tree_jump_h 1
+
+#if defined (__GNUG__)
+#pragma interface
+#endif
+
+class tree_walker;
+
+#include "pt-cmd.h"
+
+// Break.
+
+class
+tree_break_command : public tree_command
+{
+public:
+
+  tree_break_command (int l = -1, int c = -1)
+    : tree_command (l, c) { }
+
+  ~tree_break_command (void) { }
+
+  void eval (void);
+
+  void accept (tree_walker& tw);
+};
+
+// Continue.
+
+class
+tree_continue_command : public tree_command
+{
+public:
+
+  tree_continue_command (int l = -1, int c = -1)
+    : tree_command (l, c) { }
+
+  ~tree_continue_command (void) { }
+
+  void eval (void);
+
+  void accept (tree_walker& tw);
+};
+
+// Return.
+
+class
+tree_return_command : public tree_command
+{
+public:
+
+  tree_return_command (int l = -1, int c = -1)
+    : tree_command (l, c) { }
+
+  ~tree_return_command (void) { }
+
+  void eval (void);
+
+  void accept (tree_walker& tw);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
new file mode 100644
--- /dev/null
+++ b/src/pt-loop.cc
@@ -0,0 +1,400 @@
+/*
+
+Copyright (C) 1996, 1997 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#if defined (__GNUG__)
+#pragma implementation
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+// Nonzero means we're breaking out of a loop or function body.
+extern int breaking;
+
+// Nonzero means we're jumping to the end of a loop.
+extern int continuing;
+
+// Nonzero means we're returning from a function.  Global because it
+// is also needed in tree-expr.cc.
+extern int returning;
+
+#include "error.h"
+#include "gripes.h"
+#include "oct-map.h"
+#include "oct-lvalue.h"
+#include "ov.h"
+#include "pt-arg-list.h"
+#include "pt-cmd.h"
+#include "pt-exp.h"
+#include "pt-loop.h"
+#include "pt-stmt.h"
+#include "pt-walk.h"
+
+// Decide if it's time to quit a for or while loop.
+static inline bool
+quit_loop_now (void)
+{
+  // Maybe handle `continue N' someday...
+
+  if (continuing)
+    continuing--;
+
+  bool quit = (error_state || returning || breaking || continuing);
+
+  if (breaking)
+    breaking--;
+
+  return quit;
+}
+
+// While.
+
+tree_while_command::~tree_while_command (void)
+{
+  delete expr;
+  delete list;
+}
+
+void
+tree_while_command::eval (void)
+{
+  if (error_state)
+    return;
+
+  if (! expr)
+    panic_impossible ();
+
+  for (;;)
+    {
+      if (expr->is_logically_true ("while"))
+	{
+	  if (list)
+	    {
+	      list->eval ();
+
+	      if (error_state)
+		{
+		  eval_error ();
+		  return;
+		}
+	    }
+
+	  if (quit_loop_now ())
+	    break;
+	}
+      else
+	break;
+    }
+}
+
+void
+tree_while_command::eval_error (void)
+{
+  if (error_state > 0)
+    ::error ("evaluating while command near line %d, column %d",
+	     line (), column ());
+}
+
+void
+tree_while_command::accept (tree_walker& tw)
+{
+  tw.visit_while_command (*this);
+}
+
+// For.
+
+tree_simple_for_command::~tree_simple_for_command (void)
+{
+  delete expr;
+  delete list;
+}
+
+inline void
+tree_simple_for_command::do_for_loop_once (octave_lvalue& ult,
+					   const octave_value& rhs,
+					   bool& quit)
+{
+  quit = false;
+
+  ult.assign (octave_value::asn_eq, rhs);
+
+  if (! error_state)
+    {
+      if (list)
+	{
+	  list->eval ();
+
+	  if (error_state)
+	    eval_error ();
+	}
+    }
+  else
+    eval_error ();
+
+  quit = quit_loop_now ();
+}
+
+#define DO_LOOP(arg) \
+  do \
+    { \
+      for (int i = 0; i < steps; i++) \
+	{ \
+	  octave_value val (arg); \
+ \
+	  bool quit = false; \
+ \
+	  do_for_loop_once (ult, val, quit); \
+ \
+	  if (quit) \
+	    break; \
+	} \
+    } \
+  while (0)
+
+void
+tree_simple_for_command::eval (void)
+{
+  if (error_state)
+    return;
+
+  octave_value rhs = expr->rvalue ();
+
+  if (error_state || rhs.is_undefined ())
+    {
+      eval_error ();
+      return;
+    }
+
+  octave_lvalue ult = lhs->lvalue ();
+
+  if (error_state)
+    {
+      eval_error ();
+      return;
+    }
+
+  if (rhs.is_scalar_type ())
+    {
+      bool quit = false;
+
+      do_for_loop_once (ult, rhs, quit);
+    }
+  else if (rhs.is_matrix_type ())
+    {
+      Matrix m_tmp;
+      ComplexMatrix cm_tmp;
+
+      int nr;
+      int steps;
+
+      if (rhs.is_real_matrix ())
+	{
+	  m_tmp = rhs.matrix_value ();
+	  nr = m_tmp.rows ();
+	  steps = m_tmp.columns ();
+	}
+      else
+	{
+	  cm_tmp = rhs.complex_matrix_value ();
+	  nr = cm_tmp.rows ();
+	  steps = cm_tmp.columns ();
+	}
+
+      if (rhs.is_real_matrix ())
+	{
+	  if (nr == 1)
+	    DO_LOOP (m_tmp (0, i));
+	  else
+	    DO_LOOP (m_tmp.extract (0, i, nr-1, i));
+	}
+      else
+	{
+	  if (nr == 1)
+	    DO_LOOP (cm_tmp (0, i));
+	  else
+	    DO_LOOP (cm_tmp.extract (0, i, nr-1, i));
+	}
+    }
+  else if (rhs.is_string ())
+    {
+      gripe_string_invalid ();
+    }
+  else if (rhs.is_range ())
+    {
+      Range rng = rhs.range_value ();
+
+      int steps = rng.nelem ();
+      double b = rng.base ();
+      double increment = rng.inc ();
+
+      for (int i = 0; i < steps; i++)
+	{
+	  double tmp_val = b + i * increment;
+
+	  octave_value val (tmp_val);
+
+	  bool quit = false;
+
+	  do_for_loop_once (ult, val, quit);
+
+	  if (quit)
+	    break;
+	}
+    }
+  else if (rhs.is_map ())
+    {
+      Octave_map tmp_val (rhs.map_value ());
+
+      for (Pix p = tmp_val.first (); p != 0; tmp_val.next (p))
+	{
+	  octave_value val = tmp_val.contents (p);
+
+	  bool quit = false;
+
+	  do_for_loop_once (ult, val, quit);
+
+	  if (quit)
+	    break;
+	}
+    }
+  else
+    {
+      ::error ("invalid type in for loop expression near line %d, column %d",
+	       line (), column ());
+    }
+}
+
+void
+tree_simple_for_command::eval_error (void)
+{
+  if (error_state > 0)
+    ::error ("evaluating for command near line %d, column %d",
+	     line (), column ());
+}
+
+void
+tree_simple_for_command::accept (tree_walker& tw)
+{
+  tw.visit_simple_for_command (*this);
+}
+
+tree_complex_for_command::~tree_complex_for_command (void)
+{
+  delete expr;
+  delete list;
+}
+
+void
+tree_complex_for_command::do_for_loop_once (octave_lvalue &val_ref,
+					    octave_lvalue &key_ref,
+					    const octave_value& val,
+					    const octave_value& key,
+					    bool& quit)
+{
+  quit = false;
+
+  val_ref.assign (octave_value::asn_eq, val);
+  key_ref.assign (octave_value::asn_eq, key);
+
+  if (! error_state)
+    {
+      if (list)
+	{
+	  list->eval ();
+
+	  if (error_state)
+	    eval_error ();
+	}
+    }
+  else
+    eval_error ();
+
+  quit = quit_loop_now ();
+}
+
+void
+tree_complex_for_command::eval (void)
+{
+  if (error_state)
+    return;
+
+  octave_value rhs = expr->rvalue ();
+
+  if (error_state || rhs.is_undefined ())
+    {
+      eval_error ();
+      return;
+    }
+
+  if (rhs.is_map ())
+    {
+      // Cycle through structure elements.  First element of id_list
+      // is set to value and the second is set to the name of the
+      // structure element.
+
+      Pix p = lhs->first ();
+      tree_expression *elt = lhs->operator () (p);
+      octave_lvalue val_ref = elt->lvalue ();
+
+      lhs->next (p);
+      elt = lhs->operator () (p);
+      octave_lvalue key_ref = elt->lvalue ();
+
+      Octave_map tmp_val (rhs.map_value ());
+
+      for (p = tmp_val.first (); p != 0; tmp_val.next (p))
+	{
+	  octave_value key = tmp_val.key (p);
+	  octave_value val = tmp_val.contents (p);
+
+	  bool quit = false;
+
+	  do_for_loop_once (key_ref, val_ref, key, val, quit);
+
+	  if (quit)
+	    break;
+	}
+    }
+  else
+    error ("in statement `for [X, Y] = VAL', VAL must be a structure");
+}
+
+void
+tree_complex_for_command::eval_error (void)
+{
+  if (error_state > 0)
+    ::error ("evaluating for command near line %d, column %d",
+	     line (), column ());
+}
+
+void
+tree_complex_for_command::accept (tree_walker& tw)
+{
+  tw.visit_complex_for_command (*this);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
new file mode 100644
--- /dev/null
+++ b/src/pt-loop.h
@@ -0,0 +1,170 @@
+/*
+
+Copyright (C) 1996, 1997 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#if !defined (octave_tree_loop_h)
+#define octave_tree_loop_h 1
+
+#if defined (__GNUG__)
+#pragma interface
+#endif
+
+class octave_value;
+class octave_lvalue;
+
+class tree_argument_list;
+class tree_expression;
+class tree_statement_list;
+
+class tree_walker;
+
+#include "pt-cmd.h"
+
+// While.
+
+class
+tree_while_command : public tree_command
+{
+public:
+
+  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);
+
+  void eval (void);
+
+  void eval_error (void);
+
+  tree_expression *condition (void) { return expr; }
+
+  tree_statement_list *body (void) { return list; }
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // Expression to test.
+  tree_expression *expr;
+
+  // List of commands to execute.
+  tree_statement_list *list;
+};
+
+// For.
+
+class
+tree_simple_for_command : public tree_command
+{
+public:
+
+  tree_simple_for_command (int l = -1, int c = -1)
+    : tree_command (l, c), lhs (0), expr (0), list (0) { }
+
+  tree_simple_for_command (tree_expression *le, tree_expression *re,
+			   tree_statement_list *lst, int l = -1, int c = -1)
+    : tree_command (l, c), lhs (le), expr (re), list (lst) { }
+
+  ~tree_simple_for_command (void);
+
+  void eval (void);
+
+  void eval_error (void);
+
+  tree_expression *left_hand_side (void) { return lhs; }
+
+  tree_expression *control_expr (void) { return expr; }
+
+  tree_statement_list *body (void) { return list; }
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // Expression to modify.
+  tree_expression *lhs;
+
+  // Expression to evaluate.
+  tree_expression *expr;
+
+  // List of commands to execute.
+  tree_statement_list *list;
+
+  void do_for_loop_once (octave_lvalue &ult, const octave_value& rhs,
+			 bool& quit);
+};
+
+class
+tree_complex_for_command : public tree_command
+{
+public:
+
+  tree_complex_for_command (int l = -1, int c = -1)
+    : tree_command (l, c), lhs (0), expr (0), list (0) { }
+
+  tree_complex_for_command (tree_argument_list *le, tree_expression *re,
+			    tree_statement_list *lst, int l = -1, int c = -1)
+    : tree_command (l, c), lhs (le), expr (re), list (lst) { }
+
+  ~tree_complex_for_command (void);
+
+  void eval (void);
+
+  void eval_error (void);
+
+  tree_argument_list *left_hand_side (void) { return lhs; }
+
+  tree_expression *control_expr (void) { return expr; }
+
+  tree_statement_list *body (void) { return list; }
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // Expression to modify.
+  tree_argument_list *lhs;
+
+  // Expression to evaluate.
+  tree_expression *expr;
+
+  // List of commands to execute.
+  tree_statement_list *list;
+
+  void do_for_loop_once (octave_lvalue &val_ref, octave_lvalue &key_ref,
+			 const octave_value& val, const octave_value& key,
+			 bool& quit);
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
--- a/src/pt-mat.cc
+++ b/src/pt-mat.cc
@@ -34,9 +34,9 @@
 #include "defun.h"
 #include "error.h"
 #include "oct-obj.h"
+#include "pt-arg-list.h"
 #include "pt-exp.h"
 #include "pt-mat.h"
-#include "pt-misc.h"
 #include "pt-walk.h"
 #include "utils.h"
 #include "ov.h"
--- a/src/pt-mat.h
+++ b/src/pt-mat.h
@@ -30,7 +30,8 @@
 class ostream;
 
 class octave_value;
-class tree_return_list;
+class octave_value_list;
+class tree_argument_list;
 
 class tree_walker;
 
--- a/src/pt-misc.cc
+++ b/src/pt-misc.cc
@@ -28,301 +28,15 @@
 #include <config.h>
 #endif
 
-#include <iostream.h>
-#include <strstream.h>
-
-#ifdef HAVE_UNISTD_H
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#include <unistd.h>
-#endif
-
-#include "str-vec.h"
-
-#include "defun.h"
-#include "error.h"
-#include "input.h"
-#include "oct-obj.h"
-#include "oct-lvalue.h"
-#include "ov-usr-fcn.h"
-#include "ov.h"
-#include "pager.h"
-#include "pt-cmd.h"
-#include "pt-const.h"
-#include "pt-exp.h"
-#include "pt-id.h"
-#include "pt-indir.h"
-#include "pt-misc.h"
-#include "pt-pr-code.h"
-#include "pt-walk.h"
-#include "toplev.h"
-#include "utils.h"
-#include "variables.h"
-
-// Nonzero means we're breaking out of a loop or function body.
-extern int breaking;
-
-// Nonzero means we're jumping to the end of a loop.
-extern int continuing;
-
-// Nonzero means we're returning from a function.
-extern int returning;
-
-// If TRUE, turn off printing of results in functions (as if a
-// semicolon has been appended to each statement).
-static bool Vsilent_functions;
-
-// A list of commands to be executed.
-
-tree_statement::~tree_statement (void)
-{
-  delete cmd;
-  delete expr;
-}
-
-int
-tree_statement::line (void)
-{
-  return cmd ? cmd->line () : (expr ? expr->line () : -1);
-}
-
-int
-tree_statement::column (void)
-{
-  return cmd ? cmd->column () : (expr ? expr->column () : -1);
-}
-
-void
-tree_statement::maybe_echo_code (bool in_function_body)
-{
-  if (in_function_body
-      && (Vecho_executing_commands & ECHO_FUNCTIONS))
-    {
-      tree_print_code tpc (octave_stdout, Vps4);
-
-      accept (tpc);
-    }
-}
-
-octave_value_list
-tree_statement::eval (bool silent, int nargout, bool in_function_body)
-{
-  octave_value_list retval;
-
-  bool pf = silent ? false : print_flag;
-
-  if (cmd || expr)
-    {
-      maybe_echo_code (in_function_body);
-
-      if (cmd)
-	cmd->eval ();
-      else
-	{
-	  expr->set_print_flag (pf);
-
-	  // XXX FIXME XXX -- maybe all of this should be packaged in
-	  // one virtual function that returns a flag saying whether
-	  // or not the expression will take care of binding ans and
-	  // printing the result.
-
-	  bool do_bind_ans = false;
-
-	  if (expr->is_identifier ())
-	    {
-	      bool script_file_executed = false;
-
-	      tree_identifier *id = static_cast<tree_identifier *> (expr);
-
-	      id->do_lookup (script_file_executed, false);
-
-	      do_bind_ans = id->is_function ();
-	    }
-	  else
-	    do_bind_ans = (! (expr->is_indirect_ref ()
-			      || expr->is_assignment_expression ()));
-
-	  retval = expr->rvalue (nargout);
-
-	  if (do_bind_ans && ! (error_state || retval.empty ()))
-	    bind_ans (retval(0), pf);
-	}
-    }
-
-  return retval;
-}
-
-void
-tree_statement::accept (tree_walker& tw)
-{
-  tw.visit_statement (*this);
-}
-
-octave_value_list
-tree_statement_list::eval (bool silent, int nargout)
-{
-  octave_value_list retval;
-
-  if (error_state)
-    return retval;
-
-  for (Pix p = first (); p != 0; next (p))
-    {
-      tree_statement *elt = this->operator () (p);
-
-      if (elt)
-	{
-	  bool silent_flag =
-	    silent ? true : (function_body ? Vsilent_functions : false);
+#include <SLList.h>
 
-	  retval = elt->eval (silent_flag, nargout, function_body);
-
-	  if (error_state)
-	    break;
-
-	  if (breaking || continuing)
-	    break;
-
-	  if (returning)
-	    break;
-	}
-      else
-	error ("invalid statement found in statement list!");
-    }
-
-  return retval;
-}
-
-void
-tree_statement_list::accept (tree_walker& tw)
-{
-  tw.visit_statement_list (*this);
-}
-
-tree_argument_list::~tree_argument_list (void)
-{
-  while (! empty ())
-    {
-      tree_expression *t = remove_front ();
-      delete t;
-    }
-}
-
-bool
-tree_argument_list::all_elements_are_constant (void) const
-{
-  for (Pix p = first (); p != 0; next (p))
-    {
-      tree_expression *elt = this->operator () (p);
-
-      if (! elt->is_constant ())
-	return false;
-    }
-
-  return true;
-}
-
-octave_value_list
-tree_argument_list::convert_to_const_vector (void)
-{
-  int len = length ();
-
-  // XXX FIXME XXX -- would be nice to know in advance how largs args
-  // needs to be even when we have a list containing an all_va_args
-  // token.
-
-  octave_value_list args;
-  args.resize (len);
-
-  Pix p = first ();
-  int j = 0;
-  for (int k = 0; k < len; k++)
-    {
-      tree_expression *elt = this->operator () (p);
-
-      if (elt)
-	{
-	  octave_value tmp = elt->rvalue ();
-
-	  if (error_state)
-	    {
-	      ::error ("evaluating argument list element number %d", k);
-	      args = octave_value_list ();
-	      break;
-	    }
-	  else
-	    {
-	      if (tmp.is_all_va_args ())
-		{
-		  if (curr_function)
-		    {
-		      octave_value_list tva;
-		      tva = curr_function->octave_all_va_args ();
-		      int n = tva.length ();
-		      for (int i = 0; i < n; i++)
-			args(j++) = tva(i);
-		    }
-		  else
-		    {
-		      ::error ("all_va_args is only valid inside functions");
-		      args = octave_value_list ();
-		      break;
-		    }
-		}
-	      else
-		args(j++) = tmp;
-	    }
-	  next (p);
-	}
-      else
-	{
-	  args(j++) = octave_value ();
-	  break;
-	}
-    }
-
-  args.resize (j);
-
-  return args;
-}
-
-string_vector
-tree_argument_list::get_arg_names (void) const
-{
-  int len = length ();
-
-  string_vector retval (len);
-
-  int k = 0;
-
-  for (Pix p = first (); p; next (p))
-    {
-      tree_expression *elt = this->operator () (p);
-
-      strstream str_buf;
-
-      tree_print_code pc_buf (str_buf);
-
-      elt->accept (pc_buf);
-
-      str_buf << ends;
-
-      const char *s = str_buf.str ();
-
-      retval(k++) = s;
-
-      delete [] s;
-    }
-
-  return retval;
-}
-
-void
-tree_argument_list::accept (tree_walker& tw)
-{
-  tw.visit_argument_list (*this);
-}
+#include "error.h"
+#include "ov.h"
+#include "oct-lvalue.h"
+#include "pt-id.h"
+#include "pt-idx.h"
+#include "pt-misc.h"
+#include "pt-walk.h"
 
 // Parameter lists.
 
@@ -473,192 +187,6 @@
   tw.visit_return_list (*this);
 }
 
-// Declarations (global, static, etc.).
-
-tree_decl_elt::~tree_decl_elt (void)
-{
-  delete id;
-  delete expr;
-}
-
-void
-tree_decl_elt::accept (tree_walker& tw)
-{
-  tw.visit_decl_elt (*this);
-}
-
-// Initializer lists for declaration statements.
-
-void
-tree_decl_init_list::eval (tree_decl_elt::eval_fcn f, bool skip_init)
-{
-  for (Pix p = first (); p != 0; next (p))
-    {
-      f (*(this->operator () (p)), skip_init);
-
-      if (error_state)
-	break;
-    }
-}
-
-void
-tree_decl_init_list::accept (tree_walker& tw)
-{
-  tw.visit_decl_init_list (*this);
-}
-
-// If.
-
-tree_if_clause::~tree_if_clause (void)
-{
-  delete expr;
-  delete list;
-}
-
-int
-tree_if_clause::eval (void)
-{
-  if (is_else_clause () || expr->is_logically_true ("if"))
-    {
-      if (list)
-	list->eval ();
-
-      return 1;
-    }
-
-  return 0;
-}
-
-void
-tree_if_clause::accept (tree_walker& tw)
-{
-  tw.visit_if_clause (*this);
-}
-
-// List of if commands.
-
-void
-tree_if_command_list::eval (void)
-{
-  for (Pix p = first (); p != 0; next (p))
-    {
-      tree_if_clause *t = this->operator () (p);
-
-      if (t->eval () || error_state)
-	break;
-    }
-}
-
-void
-tree_if_command_list::accept (tree_walker& tw)
-{
-  tw.visit_if_command_list (*this);
-}
-
-// Switch.
-
-tree_switch_case::~tree_switch_case (void)
-{
-  delete label;
-  delete list;
-}
-
-bool
-tree_switch_case::label_matches (const octave_value& val)
-{
-  bool retval = false;
-
-  octave_value label_value = label->rvalue ();
-
-  if (! error_state)
-    {
-      if (label_value.is_defined ())
-	{
-	  octave_value tmp = do_binary_op (octave_value::eq,
-					   val, label_value);
-
-	  if (! error_state)
-	    {
-	      if (tmp.is_defined ())
-		retval = tmp.is_true ();
-	      else
-		eval_error ();
-	    }
-	  else
-	    eval_error ();
-	}
-      else
-	eval_error ();
-    }
-  else
-    eval_error ();
-
-  return retval;
-}
-
-int
-tree_switch_case::eval (const octave_value& val)
-{
-  int retval = 0;
-
-  if (is_default_case () || label_matches (val))
-    {
-      if (list)
-	list->eval ();
-
-      retval = 1;
-    }
-
-  return retval;
-}
-
-void
-tree_switch_case::eval_error (void)
-{
-  ::error ("evaluating switch case label");
-}
-
-void
-tree_switch_case::accept (tree_walker& tw)
-{
-  tw.visit_switch_case (*this);
-}
-
-// List of switch cases.
-
-void
-tree_switch_case_list::eval (const octave_value& val)
-{
-  for (Pix p = first (); p != 0; next (p))
-    {
-      tree_switch_case *t = this->operator () (p);
-
-      if (t->eval (val) || error_state)
-	break;
-    }
-}
-
-void
-tree_switch_case_list::accept (tree_walker& tw)
-{
-  tw.visit_switch_case_list (*this);
-}
-
-static int
-silent_functions (void)
-{
-  Vsilent_functions = check_preference ("silent_functions");
-
-  return 0;
-}
-
-void
-symbols_of_pt_misc (void)
-{
-  DEFVAR (silent_functions, 0.0, 0, silent_functions,
-    "suppress printing results in called functions");
-}
-
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***
--- a/src/pt-misc.h
+++ b/src/pt-misc.h
@@ -27,152 +27,16 @@
 #pragma interface
 #endif
 
-class ostream;
-
-class string_vector;
-
-class octave_value_list;
-class octave_value;
-class tree_command;
-class tree_expression;
-class tree_simple_assignment;
-class tree_index_expression;
-class tree_identifier;
-class symbol_record;
-class symbol_table;
-
-class tree_statement;
-class tree_statement_list;
-class tree_argument_list;
-class tree_parameter_list;
-class tree_return_list;
-class tree_va_return_list;
-class tree_decl_elt;
-class tree_decl_init_list;
-class tree_if_clause;
-class tree_if_command_list;
-class tree_switch_case;
-class tree_switch_case_list;
-
-class tree_walker;
-
 #include <SLList.h>
 
-// A statement is either a command to execute or an expression to
-// evaluate.
-
-class
-tree_statement
-{
-public:
-
-  tree_statement (void)
-    : cmd (0), expr (0), print_flag (true) { }
-
-  tree_statement (tree_command *c)
-    : cmd (c), expr (0), print_flag (true) { }
-
-  tree_statement (tree_expression *e)
-    : cmd (0), expr (e), print_flag (true) { }
-
-  ~tree_statement (void);
-
-  void set_print_flag (bool print)
-    { print_flag = print; }
-
-  bool is_command (void)
-    { return cmd != 0; }
-
-  bool is_expression (void)
-    { return expr != 0; }
-
-  int line (void);
-  int column (void);
-
-  void maybe_echo_code (bool in_function_body);
-
-  bool print_result (void) { return print_flag; }
-
-  tree_command *command (void) { return cmd; }
-
-  octave_value_list eval (bool silent, int nargout, bool in_function_body);
-
-  tree_expression *expression (void) { return expr; }
-
-  void accept (tree_walker& tw);
-
-private:
-
-  // Only one of cmd or expr can be valid at once.
-
-  // Command to execute.
-  tree_command *cmd;
-
-  // Expression to evaluate.
-  tree_expression *expr;
-
-  // Print result of eval for this command?
-  bool print_flag;
-};
+class octave_value;
+class octave_value_list;
 
-// A list of statements to evaluate.
-
-class
-tree_statement_list : public SLList<tree_statement *>
-{
-public:
-
-  tree_statement_list (void)
-    : SLList<tree_statement *> (), function_body (false) { }
-
-  tree_statement_list (tree_statement *s)
-    : SLList<tree_statement *> (), function_body (false) { append (s); }
-
-  ~tree_statement_list (void)
-    {
-      while (! empty ())
-	{
-	  tree_statement *t = remove_front ();
-	  delete t;
-	}
-    }
-
-  void mark_as_function_body (void) { function_body = true; }
-
-  octave_value_list eval (bool silent = false, int nargout = 0);
-
-  void accept (tree_walker& tw);
+class tree_identifier;
+class tree_index_expression;
+class tree_va_return_list;
 
-private:
-
-  // Does this list of statements make up the body of a function?
-  bool function_body;
-};
-
-// Argument lists.  Used to hold the list of expressions that are the
-// arguments in a function call or index expression.
-
-class
-tree_argument_list : public SLList<tree_expression *>
-{
-public:
-
-  tree_argument_list (void)
-    : SLList<tree_expression *> () { }
-
-  tree_argument_list (tree_expression *t)
-    : SLList<tree_expression *> () { append (t); }
-
-  ~tree_argument_list (void);
-
-  bool all_elements_are_constant (void) const;
-
-  octave_value_list convert_to_const_vector (void);
-
-  string_vector get_arg_names (void) const;
-
-  void accept (tree_walker& tw);
-};
+class tree_walker;
 
 // Parameter lists.  Used to hold the list of input and output
 // parameters in a function definition.  Elements are identifiers
@@ -249,186 +113,6 @@
   ~tree_va_return_list (void) { }
 };
 
-// List of expressions that make up a declaration statement.
-
-class
-tree_decl_elt
-{
-public:
-
-  typedef void (*eval_fcn) (tree_decl_elt &, bool);
-
-  tree_decl_elt (tree_identifier *i = 0, tree_expression *e = 0)
-    : id (i), expr (e) { }
-
-  ~tree_decl_elt (void);
-
-  void eval (void);
-
-  tree_identifier *ident (void) { return id; }
-
-  tree_expression *expression (void) { return expr; }
-
-  void accept (tree_walker& tw);
-
-private:
-
-  // An identifier to tag with the declared property.
-  tree_identifier *id;
-
-  // An initializer expression (may be zero);
-  tree_expression *expr;
-};
-
-class
-tree_decl_init_list : public SLList<tree_decl_elt *>
-{
-public:
-
-  tree_decl_init_list (void)
-    : SLList<tree_decl_elt *> () { }
-
-  tree_decl_init_list (tree_decl_elt *t)
-    : SLList<tree_decl_elt *> () { append (t); }
-
-  ~tree_decl_init_list (void)
-    {
-      while (! empty ())
-	{
-	  tree_decl_elt *t = remove_front ();
-	  delete t;
-	}
-    }
-
-  void eval (tree_decl_elt::eval_fcn, bool);
-
-  void accept (tree_walker& tw);
-};
-
-class
-tree_if_clause
-{
-public:
-
-  tree_if_clause (void) : expr (0), list (0) { }
-
-  tree_if_clause (tree_statement_list *l)
-    : expr (0), list (l) { }
-
-  tree_if_clause (tree_expression *e, tree_statement_list *l)
-    : expr (e), list (l) { }
-
-  ~tree_if_clause (void);
-
-  bool is_else_clause (void)
-    { return ! expr; }
-
-  int eval (void);
-
-  tree_expression *condition (void) { return expr; }
-
-  tree_statement_list *commands (void) { return list; }
-
-  void accept (tree_walker& tw);
-
-private:
-
-  // The condition to test.
-  tree_expression *expr;
-
-  // The list of statements to evaluate if expr is true.
-  tree_statement_list *list;
-};
-
-class
-tree_if_command_list : public SLList<tree_if_clause *>
-{
-public:
-
-  tree_if_command_list (void)
-    : SLList<tree_if_clause *> () { }
-
-  tree_if_command_list (tree_if_clause *t)
-    : SLList<tree_if_clause *> () { append (t); }
-
-  ~tree_if_command_list (void)
-    {
-      while (! empty ())
-	{
-	  tree_if_clause *t = remove_front ();
-	  delete t;
-	}
-    }
-
-  void eval (void);
-
-  void accept (tree_walker& tw);
-};
-
-class
-tree_switch_case
-{
-public:
-
-  tree_switch_case (void) : label (0), list (0) { }
-
-  tree_switch_case (tree_statement_list *l)
-    : label (0), list (l) { }
-
-  tree_switch_case (tree_expression *e, tree_statement_list *l)
-    : label (e), list (l) { }
-
-  ~tree_switch_case (void);
-
-  bool is_default_case (void)
-    { return ! label; }
-
-  bool label_matches (const octave_value& val);
-
-  int eval (const octave_value& val);
-
-  void eval_error (void);
-
-  tree_expression *case_label (void) { return label; }
-
-  tree_statement_list *commands (void) { return list; }
-
-  void accept (tree_walker& tw);
-
-private:
-
-  // The case label.
-  tree_expression *label;
-
-  // The list of statements to evaluate if the label matches.
-  tree_statement_list *list;
-};
-
-class
-tree_switch_case_list : public SLList<tree_switch_case *>
-{
-public:
-
-  tree_switch_case_list (void)
-    : SLList<tree_switch_case *> () { }
-
-  tree_switch_case_list (tree_switch_case *t)
-    : SLList<tree_switch_case *> () { append (t); }
-
-  ~tree_switch_case_list (void)
-    {
-      while (! empty ())
-	{
-	  tree_switch_case *t = remove_front ();
-	  delete t;
-	}
-    }
-
-  void eval (const octave_value& val);
-
-  void accept (tree_walker& tw);
-};
-
 #endif
 
 /*
--- a/src/pt-plot.cc
+++ b/src/pt-plot.cc
@@ -58,7 +58,6 @@
 #include "oct-obj.h"
 #include "pt-cmd.h"
 #include "pt-exp.h"
-#include "pt-misc.h"
 #include "pt-plot.h"
 #include "pt-walk.h"
 #include "sighandlers.h"
--- a/src/pt-pr-code.cc
+++ b/src/pt-pr-code.cc
@@ -33,15 +33,30 @@
 #include "error.h"
 #include "ov-usr-fcn.h"
 #include "pr-output.h"
+#include "pt-arg-list.h"
+#include "pt-assign.h"
+#include "pt-base.h"
+#include "pt-binop.h"
 #include "pt-cmd.h"
+#include "pt-colon.h"
 #include "pt-const.h"
+#include "pt-decl.h"
+#include "pt-except.h"
 #include "pt-exp.h"
 #include "pt-id.h"
+#include "pt-idx.h"
 #include "pt-indir.h"
+#include "pt-jump.h"
+#include "pt-loop.h"
 #include "pt-mat.h"
 #include "pt-misc.h"
 #include "pt-plot.h"
 #include "pt-pr-code.h"
+#include "pt-select.h"
+#include "pt-stmt.h"
+#include "pt-unop.h"
+#include "pt-pr-code.h"
+#include "pt-walk.h"
 
 void
 tree_print_code::visit_argument_list (tree_argument_list& lst)
new file mode 100644
--- /dev/null
+++ b/src/pt-select.cc
@@ -0,0 +1,249 @@
+/*
+
+Copyright (C) 1996, 1997 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#if defined (__GNUG__)
+#pragma implementation
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "error.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "pt-cmd.h"
+#include "pt-exp.h"
+#include "pt-select.h"
+#include "pt-stmt.h"
+#include "pt-walk.h"
+
+// If clauses.
+
+tree_if_clause::~tree_if_clause (void)
+{
+  delete expr;
+  delete list;
+}
+
+int
+tree_if_clause::eval (void)
+{
+  if (is_else_clause () || expr->is_logically_true ("if"))
+    {
+      if (list)
+	list->eval ();
+
+      return 1;
+    }
+
+  return 0;
+}
+
+void
+tree_if_clause::accept (tree_walker& tw)
+{
+  tw.visit_if_clause (*this);
+}
+
+// List of if commands.
+
+void
+tree_if_command_list::eval (void)
+{
+  for (Pix p = first (); p != 0; next (p))
+    {
+      tree_if_clause *t = this->operator () (p);
+
+      if (t->eval () || error_state)
+	break;
+    }
+}
+
+void
+tree_if_command_list::accept (tree_walker& tw)
+{
+  tw.visit_if_command_list (*this);
+}
+
+// If.
+
+tree_if_command::~tree_if_command (void)
+{
+  delete list;
+}
+
+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 ());
+}
+
+void
+tree_if_command::accept (tree_walker& tw)
+{
+  tw.visit_if_command (*this);
+}
+
+// Switch cases.
+
+tree_switch_case::~tree_switch_case (void)
+{
+  delete label;
+  delete list;
+}
+
+bool
+tree_switch_case::label_matches (const octave_value& val)
+{
+  bool retval = false;
+
+  octave_value label_value = label->rvalue ();
+
+  if (! error_state)
+    {
+      if (label_value.is_defined ())
+	{
+	  octave_value tmp = do_binary_op (octave_value::eq,
+					   val, label_value);
+
+	  if (! error_state)
+	    {
+	      if (tmp.is_defined ())
+		retval = tmp.is_true ();
+	      else
+		eval_error ();
+	    }
+	  else
+	    eval_error ();
+	}
+      else
+	eval_error ();
+    }
+  else
+    eval_error ();
+
+  return retval;
+}
+
+int
+tree_switch_case::eval (const octave_value& val)
+{
+  int retval = 0;
+
+  if (is_default_case () || label_matches (val))
+    {
+      if (list)
+	list->eval ();
+
+      retval = 1;
+    }
+
+  return retval;
+}
+
+void
+tree_switch_case::eval_error (void)
+{
+  ::error ("evaluating switch case label");
+}
+
+void
+tree_switch_case::accept (tree_walker& tw)
+{
+  tw.visit_switch_case (*this);
+}
+
+// List of switch cases.
+
+void
+tree_switch_case_list::eval (const octave_value& val)
+{
+  for (Pix p = first (); p != 0; next (p))
+    {
+      tree_switch_case *t = this->operator () (p);
+
+      if (t->eval (val) || error_state)
+	break;
+    }
+}
+
+void
+tree_switch_case_list::accept (tree_walker& tw)
+{
+  tw.visit_switch_case_list (*this);
+}
+
+// Switch.
+
+tree_switch_command::~tree_switch_command (void)
+{
+  delete expr;
+  delete list;
+}
+
+void
+tree_switch_command::eval (void)
+{
+  if (expr)
+    {
+      octave_value val = expr->rvalue ();
+
+      if (! error_state)
+	{
+	  if (list)
+	    list->eval (val);
+
+	  if (error_state)
+	    eval_error ();
+	}
+      else
+	eval_error ();
+    }
+  else
+    ::error ("missing value in switch command near line %d, column %d",
+	     line (), column ());
+}
+
+void
+tree_switch_command::eval_error (void)
+{
+  ::error ("evaluating switch command near line %d, column %d",
+	   line (), column ());
+}
+
+void
+tree_switch_command::accept (tree_walker& tw)
+{
+  tw.visit_switch_command (*this);
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
new file mode 100644
--- /dev/null
+++ b/src/pt-select.h
@@ -0,0 +1,233 @@
+/*
+
+Copyright (C) 1996, 1997 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#if !defined (octave_tree_select_h)
+#define octave_tree_select_h 1
+
+#if defined (__GNUG__)
+#pragma interface
+#endif
+
+#include <SLList.h>
+
+class expression;
+class tree_statement_list;
+
+class tree_walker;
+
+#include "pt-cmd.h"
+
+// If.
+
+class
+tree_if_clause
+{
+public:
+
+  tree_if_clause (void)
+    : expr (0), list (0) { }
+
+  tree_if_clause (tree_statement_list *l)
+    : expr (0), list (l) { }
+
+  tree_if_clause (tree_expression *e, tree_statement_list *l)
+    : expr (e), list (l) { }
+
+  ~tree_if_clause (void);
+
+  bool is_else_clause (void)
+    { return ! expr; }
+
+  int eval (void);
+
+  tree_expression *condition (void) { return expr; }
+
+  tree_statement_list *commands (void) { return list; }
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // The condition to test.
+  tree_expression *expr;
+
+  // The list of statements to evaluate if expr is true.
+  tree_statement_list *list;
+};
+
+class
+tree_if_command_list : public SLList<tree_if_clause *>
+{
+public:
+
+  tree_if_command_list (void)
+    : SLList<tree_if_clause *> () { }
+
+  tree_if_command_list (tree_if_clause *t)
+    : SLList<tree_if_clause *> () { append (t); }
+
+  ~tree_if_command_list (void)
+    {
+      while (! empty ())
+	{
+	  tree_if_clause *t = remove_front ();
+	  delete t;
+	}
+    }
+
+  void eval (void);
+
+  void accept (tree_walker& tw);
+};
+
+class
+tree_if_command : public tree_command
+{
+public:
+
+  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);
+
+  void eval (void);
+
+  tree_if_command_list *cmd_list (void) { return list; }
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // List of if commands (if, elseif, elseif, ... else, endif)
+  tree_if_command_list *list;
+};
+
+// Switch.
+
+class
+tree_switch_case
+{
+public:
+
+  tree_switch_case (void)
+    : label (0), list (0) { }
+
+  tree_switch_case (tree_statement_list *l)
+    : label (0), list (l) { }
+
+  tree_switch_case (tree_expression *e, tree_statement_list *l)
+    : label (e), list (l) { }
+
+  ~tree_switch_case (void);
+
+  bool is_default_case (void)
+    { return ! label; }
+
+  bool label_matches (const octave_value& val);
+
+  int eval (const octave_value& val);
+
+  void eval_error (void);
+
+  tree_expression *case_label (void) { return label; }
+
+  tree_statement_list *commands (void) { return list; }
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // The case label.
+  tree_expression *label;
+
+  // The list of statements to evaluate if the label matches.
+  tree_statement_list *list;
+};
+
+class
+tree_switch_case_list : public SLList<tree_switch_case *>
+{
+public:
+
+  tree_switch_case_list (void)
+    : SLList<tree_switch_case *> () { }
+
+  tree_switch_case_list (tree_switch_case *t)
+    : SLList<tree_switch_case *> () { append (t); }
+
+  ~tree_switch_case_list (void)
+    {
+      while (! empty ())
+	{
+	  tree_switch_case *t = remove_front ();
+	  delete t;
+	}
+    }
+
+  void eval (const octave_value& val);
+
+  void accept (tree_walker& tw);
+};
+
+class
+tree_switch_command : public tree_command
+{
+public:
+
+  tree_switch_command (int l = -1, int c = -1)
+    : tree_command (l, c), expr (0), list (0) { }
+
+  tree_switch_command (tree_expression *e, tree_switch_case_list *lst,
+		       int l = -1, int c = -1)
+    : tree_command (l, c), expr (e), list (lst) { }
+
+  ~tree_switch_command (void);
+
+  void eval (void);
+
+  void eval_error (void);
+
+  tree_expression *switch_value (void) { return expr; }
+
+  tree_switch_case_list *case_list (void) { return list; }
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // Value on which to switch.
+  tree_expression *expr;
+
+  // List of cases (case 1, case 2, ..., default)
+  tree_switch_case_list *list;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
new file mode 100644
--- /dev/null
+++ b/src/pt-stmt.cc
@@ -0,0 +1,207 @@
+/*
+
+Copyright (C) 1996, 1997 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#if defined (__GNUG__)
+#pragma implementation
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <SLList.h>
+
+#include "defun.h"
+#include "error.h"
+#include "ov.h"
+#include "oct-lvalue.h"
+#include "input.h"
+#include "pager.h"
+#include "pt-cmd.h"
+#include "pt-id.h"
+#include "pt-idx.h"
+#include "pt-pr-code.h"
+#include "pt-stmt.h"
+#include "pt-walk.h"
+#include "utils.h"
+#include "variables.h"
+
+// Nonzero means we're breaking out of a loop or function body.
+extern int breaking;
+
+// Nonzero means we're jumping to the end of a loop.
+extern int continuing;
+
+// Nonzero means we're returning from a function.
+extern int returning;
+
+// If TRUE, turn off printing of results in functions (as if a
+// semicolon has been appended to each statement).
+static bool Vsilent_functions;
+
+// A list of commands to be executed.
+
+tree_statement::~tree_statement (void)
+{
+  delete cmd;
+  delete expr;
+}
+
+int
+tree_statement::line (void)
+{
+  return cmd ? cmd->line () : (expr ? expr->line () : -1);
+}
+
+int
+tree_statement::column (void)
+{
+  return cmd ? cmd->column () : (expr ? expr->column () : -1);
+}
+
+void
+tree_statement::maybe_echo_code (bool in_function_body)
+{
+  if (in_function_body
+      && (Vecho_executing_commands & ECHO_FUNCTIONS))
+    {
+      tree_print_code tpc (octave_stdout, Vps4);
+
+      accept (tpc);
+    }
+}
+
+octave_value_list
+tree_statement::eval (bool silent, int nargout, bool in_function_body)
+{
+  octave_value_list retval;
+
+  bool pf = silent ? false : print_flag;
+
+  if (cmd || expr)
+    {
+      maybe_echo_code (in_function_body);
+
+      if (cmd)
+	cmd->eval ();
+      else
+	{
+	  expr->set_print_flag (pf);
+
+	  // XXX FIXME XXX -- maybe all of this should be packaged in
+	  // one virtual function that returns a flag saying whether
+	  // or not the expression will take care of binding ans and
+	  // printing the result.
+
+	  bool do_bind_ans = false;
+
+	  if (expr->is_identifier ())
+	    {
+	      bool script_file_executed = false;
+
+	      tree_identifier *id = static_cast<tree_identifier *> (expr);
+
+	      id->do_lookup (script_file_executed, false);
+
+	      do_bind_ans = id->is_function ();
+	    }
+	  else
+	    do_bind_ans = (! (expr->is_indirect_ref ()
+			      || expr->is_assignment_expression ()));
+
+	  retval = expr->rvalue (nargout);
+
+	  if (do_bind_ans && ! (error_state || retval.empty ()))
+	    bind_ans (retval(0), pf);
+	}
+    }
+
+  return retval;
+}
+
+void
+tree_statement::accept (tree_walker& tw)
+{
+  tw.visit_statement (*this);
+}
+
+octave_value_list
+tree_statement_list::eval (bool silent, int nargout)
+{
+  octave_value_list retval;
+
+  if (error_state)
+    return retval;
+
+  for (Pix p = first (); p != 0; next (p))
+    {
+      tree_statement *elt = this->operator () (p);
+
+      if (elt)
+	{
+	  bool silent_flag =
+	    silent ? true : (function_body ? Vsilent_functions : false);
+
+	  retval = elt->eval (silent_flag, nargout, function_body);
+
+	  if (error_state)
+	    break;
+
+	  if (breaking || continuing)
+	    break;
+
+	  if (returning)
+	    break;
+	}
+      else
+	error ("invalid statement found in statement list!");
+    }
+
+  return retval;
+}
+
+void
+tree_statement_list::accept (tree_walker& tw)
+{
+  tw.visit_statement_list (*this);
+}
+
+static int
+silent_functions (void)
+{
+  Vsilent_functions = check_preference ("silent_functions");
+
+  return 0;
+}
+
+void
+symbols_of_pt_stmt (void)
+{
+  DEFVAR (silent_functions, 0.0, 0, silent_functions,
+    "suppress printing results in called functions");
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
new file mode 100644
--- /dev/null
+++ b/src/pt-stmt.h
@@ -0,0 +1,136 @@
+/*
+
+Copyright (C) 1996, 1997 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#if !defined (octave_tree_stmt_h)
+#define octave_tree_stmt_h 1
+
+#if defined (__GNUG__)
+#pragma interface
+#endif
+
+#include <SLList.h>
+
+class octave_value_list;
+
+class tree_command;
+class tree_expression;
+
+class tree_walker;
+
+// A statement is either a command to execute or an expression to
+// evaluate.
+
+class
+tree_statement
+{
+public:
+
+  tree_statement (void)
+    : cmd (0), expr (0), print_flag (true) { }
+
+  tree_statement (tree_command *c)
+    : cmd (c), expr (0), print_flag (true) { }
+
+  tree_statement (tree_expression *e)
+    : cmd (0), expr (e), print_flag (true) { }
+
+  ~tree_statement (void);
+
+  void set_print_flag (bool print)
+    { print_flag = print; }
+
+  bool is_command (void)
+    { return cmd != 0; }
+
+  bool is_expression (void)
+    { return expr != 0; }
+
+  int line (void);
+  int column (void);
+
+  void maybe_echo_code (bool in_function_body);
+
+  bool print_result (void) { return print_flag; }
+
+  tree_command *command (void) { return cmd; }
+
+  octave_value_list eval (bool silent, int nargout, bool in_function_body);
+
+  tree_expression *expression (void) { return expr; }
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // Only one of cmd or expr can be valid at once.
+
+  // Command to execute.
+  tree_command *cmd;
+
+  // Expression to evaluate.
+  tree_expression *expr;
+
+  // Print result of eval for this command?
+  bool print_flag;
+};
+
+// A list of statements to evaluate.
+
+class
+tree_statement_list : public SLList<tree_statement *>
+{
+public:
+
+  tree_statement_list (void)
+    : SLList<tree_statement *> (), function_body (false) { }
+
+  tree_statement_list (tree_statement *s)
+    : SLList<tree_statement *> (), function_body (false) { append (s); }
+
+  ~tree_statement_list (void)
+    {
+      while (! empty ())
+	{
+	  tree_statement *t = remove_front ();
+	  delete t;
+	}
+    }
+
+  void mark_as_function_body (void) { function_body = true; }
+
+  octave_value_list eval (bool silent = false, int nargout = 0);
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // Does this list of statements make up the body of a function?
+  bool function_body;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
--- a/src/pt-unop.cc
+++ b/src/pt-unop.cc
@@ -33,7 +33,6 @@
 #include "oct-lvalue.h"
 #include "ov.h"
 #include "pt-unop.h"
-#include "pt-pr-code.h"
 #include "pt-walk.h"
 
 // Prefix expressions.
--- a/src/toplev.cc
+++ b/src/toplev.cc
@@ -67,8 +67,8 @@
 #include "pathsearch.h"
 #include "procstream.h"
 #include "ov.h"
-#include "pt-misc.h"
 #include "pt-plot.h"
+#include "pt-stmt.h"
 #include "sighandlers.h"
 #include "sysdep.h"
 #include "syswait.h"