Mercurial > hg > octave-terminal
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: *** +*/