Mercurial > hg > octave-lyh
changeset 5861:2a6cb4ed8f1e
[project @ 2006-06-16 05:09:41 by jwe]
line wrap: on
line diff
--- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,110 @@ +2006-06-16 John W. Eaton <jwe@octave.org> + + * parse.y (%union): New type, anon_fcn_handle_type. + (anon_fcn_handle): Now anon_fcn_handle_type, not tree_constant_type. + (make_anon_fcn_handle): Return tree_anon_fcn_handle, not tree_constant. + + * comment-list.cc (octave_comment_list::dup): New function. + * comment-list.h: Provide decl. + + * pt-cmd.cc (tree_no_op_command::dup): New function. + * pt-cmd.h: Provide decl. + (tree_command::dup): New pure virtual function. + + * pt-loop.cc (tree_while_command::dup, tree_do_until_command::dup, + tree_simple_for_command::dup, tree_complex_for_command::dup): + New functions. + * pt-loop.h: Provide decls. + + * pt-jump.cc (tree_break_command::dup, tree_continue_command::dup, + tree_return_command::dup): New functions. + * pt-jump.h: Provide decls. + + * pt-except.cc (tree_try_catch_command::dup, + tree_unwind_protect_command::dup): New functions. + * pt-except.h: Provide decls. + + * pt-select.cc (tree_if_clause::dup, tree_if_command_list::dup, + tree_if_command::dup, tree_switch_case::dup, + tree_switch_case_list::dup, tree_switch_command::dup): + New functions. + * pt-select.h: Provide decls. + + * pt-decl.cc (tree_decl_elt::dup, tree_decl_init_list::dup, + tree_global_command::dup, tree_static_command::dup): New functions. + * pt-decl.h: Provide decls. + + * pt-exp.h (tree_expression::copy_base): New function. + (tree_expression::dup): New pure virtual function. + + * pt-fcn-handle.cc, pt-fcn-handle.h (tree_anon_fcn_handle): New class. + + * pt-fcn-handle.cc (tree_function_handle::dup): New function. + * pt-fcn-handle.h: Provide decl. + + * pt-colon.cc (tree_colon_expression::dup): New function. + * pt-colon.h: Provide decl. + (tree_colon_expression::tree_colon_expression (tree_expression *, + tree_expression *, tree_expression *, int, int)): New constructor. + + * pt-const.cc (tree_constant::dup): New function. + (tree_constant::tree_constant (const octave_value&, const + std::string&, int, int)): New constructor. + * pt-const.h: Provide decls. + + * pt-idx.cc (tree_index_expression::dup): New functoin. + (tree_index_expression::tree_index_expression (int, int)): + New constructor. + * pt-idx.h: Provide decls. + + * pt-arg-list.cc (tree_argument_list::dup): New function. + * pt-arg-list.h: Provide decl. + + * pt-id.cc (tree_identifier::dup): New function. + * pt-id.h: Provide decl. + + * pt-cell.cc (tree_cell::dup): New function. + * pt-cell.h: Provide decl. + + * pt-mat.cc (tree_matrix::dup): New function. + * pt-mat.h: Provide decl. + + * pt-assign.cc (tree_simple_assignment::dup, + tree_multi_assignment::dup): New functions. + * pt-assign.h: Provide decls. + + * pt-binop.cc (tree_binary_expression::dup, + tree_boolean_expression::dup): New functions. + * pt-binop.h: Provide decls. + + * pt-unop.cc (tree_prefix_expression::dup, + tree_postfix_expression::dup): New functions. + * pt-unop.h: Provide decls. + + * pt-stmt.cc (tree_statement::dup, tree_statement_list::dup): + New functions. + * pt-stmt.h: Provide decls. + + * pt-misc.cc (tree_parameter_list::dup, + tree_return_list::dup): New functions. + * pt-misc.h: Provide decls. + + * symtab.cc (symbol_table::dup, symbol_table::inherit, + symbol_record:is_automatic_variable): New functions. + * symtab.h: Provide decls. + (symbol_record::automatic_variable): New data member. + (symbol_record::symbol_record): Initialize it. + (symbol_record::mark_as_automatic_variable): New function. + + * pt-walk.h (tree_walker::visit_anon_fcn_handle): + New pure virtual function. + * pt-pr-code.cc (tree_print_code::visit_anon_fcn_handle): New function. + * pt-pr-code.h: Provide decl. + * pt-bp.cc (tree_breakpoint::visit_anon_fcn_handle): New function. + * pt-bp.h: Provide decl. + * pt-check.cc (tree_checker::visit_anon_fcn_handle): New function. + * pt-check.h: Provide decl. + 2006-06-13 John W. Eaton <jwe@octave.org> * pt-stmt.cc (tree_statement_list::eval): Revise previous change
--- a/src/comment-list.cc +++ b/src/comment-list.cc @@ -32,6 +32,21 @@ octave_comment_buffer *octave_comment_buffer::instance = 0; +octave_comment_list * +octave_comment_list::dup (void) +{ + octave_comment_list *new_cl = new octave_comment_list (); + + for (iterator p = begin (); p != end (); p++) + { + octave_comment_elt elt = *p; + + new_cl->append (elt); + } + + return new_cl; +} + bool octave_comment_buffer::instance_ok (void) {
--- a/src/comment-list.h +++ b/src/comment-list.h @@ -86,12 +86,16 @@ { public: + octave_comment_list (void) { } + void append (const octave_comment_elt& elt) { octave_base_list<octave_comment_elt>::append (elt); } void append (const std::string& s, octave_comment_elt::comment_type t = octave_comment_elt::unknown) { append (octave_comment_elt (s, t)); } + + octave_comment_list *dup (void); }; class @@ -100,7 +104,7 @@ public: octave_comment_buffer (void) - : comment_list (new octave_comment_list) { } + : comment_list (new octave_comment_list ()) { } static bool instance_ok (void);
--- a/src/parse.y +++ b/src/parse.y @@ -158,7 +158,7 @@ make_fcn_handle (token *tok_val); // Build an anonymous function handle. -static tree_constant * +static tree_anon_fcn_handle * make_anon_fcn_handle (tree_parameter_list *param_list, tree_statement *stmt); // Build a binary expression. @@ -347,6 +347,7 @@ tree_expression *tree_expression_type; tree_constant *tree_constant_type; tree_fcn_handle *tree_fcn_handle_type; + tree_anon_fcn_handle *tree_anon_fcn_handle_type; tree_identifier *tree_identifier_type; tree_index_expression *tree_index_expression_type; tree_colon_expression *tree_colon_expression_type; @@ -401,7 +402,8 @@ %type <comment_type> stash_comment function_beg %type <sep_type> sep_no_nl opt_sep_no_nl sep opt_sep %type <tree_type> input -%type <tree_constant_type> string constant magic_colon anon_fcn_handle +%type <tree_constant_type> string constant magic_colon +%type <tree_anon_fcn_handle_type> anon_fcn_handle %type <tree_fcn_handle_type> fcn_handle %type <tree_matrix_type> matrix_rows matrix_rows1 %type <tree_cell_type> cell_rows cell_rows1 @@ -1756,7 +1758,7 @@ // Make an anonymous function handle. -static tree_constant * +static tree_anon_fcn_handle * make_anon_fcn_handle (tree_parameter_list *param_list, tree_statement *stmt) { // FIXME -- need to get these from the location of the @ symbol. @@ -1766,9 +1768,18 @@ tree_parameter_list *ret_list = 0; + symbol_table *fcn_sym_tab = curr_sym_tab; + + if (symtab_context.empty ()) + panic_impossible (); + + curr_sym_tab = symtab_context.top (); + + symtab_context.pop (); + if (stmt && stmt->is_expression ()) { - symbol_record *sr = curr_sym_tab->lookup ("__retval__", true); + symbol_record *sr = fcn_sym_tab->lookup ("__retval__", true); tree_expression *e = stmt->expression (); @@ -1793,18 +1804,8 @@ body->mark_as_function_body (); - octave_value fcn (new octave_user_function (param_list, ret_list, - body, curr_sym_tab)); - - if (symtab_context.empty ()) - panic_impossible (); - - curr_sym_tab = symtab_context.top (); - symtab_context.pop (); - - octave_value fh (new octave_fcn_handle (fcn, "@<anonymous>")); - - tree_constant *retval = new tree_constant (fh, l, c); + tree_anon_fcn_handle *retval + = new tree_anon_fcn_handle (param_list, ret_list, body, fcn_sym_tab, l, c); return retval; }
--- a/src/pt-arg-list.cc +++ b/src/pt-arg-list.cc @@ -253,6 +253,24 @@ return retval; } +tree_argument_list * +tree_argument_list::dup (symbol_table *sym_tab) +{ + tree_argument_list *new_list = new tree_argument_list (); + + new_list->list_includes_magic_end = list_includes_magic_end; + new_list->simple_assign_lhs = simple_assign_lhs; + + for (iterator p = begin (); p != end (); p++) + { + tree_expression *elt = *p; + + new_list->append (elt ? elt->dup (sym_tab) : 0); + } + + return new_list; +} + void tree_argument_list::accept (tree_walker& tw) {
--- a/src/pt-arg-list.h +++ b/src/pt-arg-list.h @@ -78,6 +78,8 @@ string_vector get_arg_names (void) const; + tree_argument_list *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private:
--- a/src/pt-assign.cc +++ b/src/pt-assign.cc @@ -158,6 +158,19 @@ return octave_value::assign_op_as_string (etype); } +tree_expression * +tree_simple_assignment::dup (symbol_table *sym_tab) +{ + tree_simple_assignment *new_sa + = new tree_simple_assignment (lhs ? lhs->dup (sym_tab) : 0, + rhs ? rhs->dup (sym_tab) : 0, + preserve, etype); + + new_sa->copy_base (*this); + + return new_sa; +} + void tree_simple_assignment::accept (tree_walker& tw) { @@ -359,6 +372,19 @@ return octave_value::assign_op_as_string (etype); } +tree_expression * +tree_multi_assignment::dup (symbol_table *sym_tab) +{ + tree_multi_assignment *new_ma + = new tree_multi_assignment (lhs ? lhs->dup (sym_tab) : 0, + rhs ? rhs->dup (sym_tab) : 0, + preserve, etype); + + new_ma->copy_base (*this); + + return new_ma; +} + void tree_multi_assignment::accept (tree_walker& tw) {
--- a/src/pt-assign.h +++ b/src/pt-assign.h @@ -74,6 +74,8 @@ tree_expression *right_hand_side (void) { return rhs; } + tree_expression *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private: @@ -142,6 +144,8 @@ tree_expression *right_hand_side (void) { return rhs; } + tree_expression *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private:
--- a/src/pt-binop.cc +++ b/src/pt-binop.cc @@ -105,6 +105,19 @@ return octave_value::binary_op_as_string (etype); } +tree_expression * +tree_binary_expression::dup (symbol_table *sym_tab) +{ + tree_binary_expression *new_be + = new tree_binary_expression (op_lhs ? op_lhs->dup (sym_tab) : 0, + op_rhs ? op_rhs->dup (sym_tab) : 0, + line (), column (), etype); + + new_be->copy_base (*this); + + return new_be; +} + void tree_binary_expression::accept (tree_walker& tw) { @@ -219,6 +232,19 @@ return retval; } +tree_expression * +tree_boolean_expression::dup (symbol_table *sym_tab) +{ + tree_boolean_expression *new_be + = new tree_boolean_expression (op_lhs ? op_lhs->dup (sym_tab) : 0, + op_rhs ? op_rhs->dup (sym_tab) : 0, + line (), column (), etype); + + new_be->copy_base (*this); + + return new_be; +} + /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/src/pt-binop.h +++ b/src/pt-binop.h @@ -82,6 +82,8 @@ tree_expression *lhs (void) { return op_lhs; } tree_expression *rhs (void) { return op_rhs; } + tree_expression *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); protected: @@ -137,6 +139,8 @@ type op_type (void) const { return etype; } + tree_expression *dup (symbol_table *sym_tab); + private: // The type of the expression.
--- a/src/pt-bp.cc +++ b/src/pt-bp.cc @@ -430,6 +430,16 @@ take_action (cmd); } +void +tree_breakpoint::visit_anon_fcn_handle (tree_anon_fcn_handle& afh) +{ + if (found) + return; + + if (afh.line () >= line) + take_action (afh); +} + void tree_breakpoint::visit_constant (tree_constant& cmd) {
--- a/src/pt-bp.h +++ b/src/pt-bp.h @@ -94,6 +94,8 @@ void visit_no_op_command (tree_no_op_command&); + void visit_anon_fcn_handle (tree_anon_fcn_handle&); + void visit_constant (tree_constant&); void visit_fcn_handle (tree_fcn_handle&);
--- a/src/pt-cell.cc +++ b/src/pt-cell.cc @@ -101,6 +101,23 @@ return retval; } +tree_expression * +tree_cell::dup (symbol_table *sym_tab) +{ + tree_cell *new_cell = new tree_cell (0, line (), column ()); + + for (iterator p = begin (); p != end (); p++) + { + tree_argument_list *elt = *p; + + append (elt ? elt->dup (sym_tab) : 0); + } + + new_cell->copy_base (*this); + + return new_cell; +} + void tree_cell::accept (tree_walker& tw) {
--- a/src/pt-cell.h +++ b/src/pt-cell.h @@ -52,6 +52,8 @@ octave_value_list rvalue (int); + tree_expression *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private:
--- a/src/pt-check.cc +++ b/src/pt-check.cc @@ -306,6 +306,11 @@ } void +tree_checker::visit_anon_fcn_handle (tree_anon_fcn_handle& /* afh */) +{ +} + +void tree_checker::visit_constant (tree_constant& /* val */) { }
--- a/src/pt-check.h +++ b/src/pt-check.h @@ -78,6 +78,8 @@ void visit_no_op_command (tree_no_op_command&); + void visit_anon_fcn_handle (tree_anon_fcn_handle&); + void visit_constant (tree_constant&); void visit_fcn_handle (tree_fcn_handle&);
--- a/src/pt-cmd.cc +++ b/src/pt-cmd.cc @@ -30,6 +30,12 @@ // No-op. +tree_command * +tree_no_op_command::dup (symbol_table *sym_tab) +{ + return new tree_no_op_command (orig_cmd, line (), column ()); +} + void tree_no_op_command::accept (tree_walker& tw) {
--- a/src/pt-cmd.h +++ b/src/pt-cmd.h @@ -27,6 +27,7 @@ #include <string> class tree_walker; +class symbol_table; #include "pt.h" #include "pt-bp.h" @@ -45,6 +46,8 @@ virtual void eval (void) = 0; + virtual tree_command *dup (symbol_table *) = 0; + private: // No copying! @@ -68,6 +71,8 @@ void eval (void) { MAYBE_DO_BREAKPOINT; } + tree_command *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); std::string original_command (void) { return orig_cmd; }
--- a/src/pt-colon.cc +++ b/src/pt-colon.cc @@ -209,6 +209,20 @@ : -1))); } +tree_expression * +tree_colon_expression::dup (symbol_table *sym_tab) +{ + tree_colon_expression *new_ce + = new tree_colon_expression (op_base ? op_base->dup (sym_tab) : 0, + op_limit ? op_limit->dup (sym_tab) : 0, + op_increment ? op_increment->dup (sym_tab) : 0, + line (), column ()); + + new_ce->copy_base (*new_ce); + + return new_ce; +} + void tree_colon_expression::accept (tree_walker& tw) {
--- a/src/pt-colon.h +++ b/src/pt-colon.h @@ -49,6 +49,11 @@ : tree_expression (l, c), op_base (e), op_limit (0), op_increment (0), save_base (false) { } + tree_colon_expression (tree_expression *bas, tree_expression *lim, + tree_expression *inc, int l = -1, int c = -1) + : tree_expression (l, c), op_base (bas), op_limit (lim), + op_increment (inc), save_base (false) { } + ~tree_colon_expression (void) { if (! save_base) @@ -86,6 +91,8 @@ int line (void) const; int column (void) const; + tree_expression *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private:
--- a/src/pt-const.cc +++ b/src/pt-const.cc @@ -70,6 +70,17 @@ return retval; } +tree_expression * +tree_constant::dup (symbol_table *sym_tab) +{ + tree_constant *new_tc + = new tree_constant (val, orig_text, line (), column ()); + + new_tc->copy_base (*this); + + return new_tc; +} + void tree_constant::accept (tree_walker& tw) {
--- a/src/pt-const.h +++ b/src/pt-const.h @@ -49,6 +49,10 @@ tree_constant (const octave_value& v, int l = -1, int c = -1) : tree_expression (l, c), val (v), orig_text () { } + tree_constant (const octave_value& v, const std::string& ot, + int l = -1, int c = -1) + : tree_expression (l, c), val (v), orig_text (ot) { } + ~tree_constant (void) { } bool has_magic_end (void) const { return false; } @@ -79,6 +83,8 @@ octave_value_list rvalue (int nargout); + tree_expression *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); // Store the original text corresponding to this constant for later
--- a/src/pt-decl.cc +++ b/src/pt-decl.cc @@ -45,6 +45,13 @@ delete expr; } +tree_decl_elt * +tree_decl_elt::dup (symbol_table *sym_tab) +{ + return new tree_decl_elt (id ? id->dup (sym_tab) : 0, + expr ? expr->dup (sym_tab) : 0); +} + void tree_decl_elt::accept (tree_walker& tw) { @@ -67,6 +74,21 @@ } } +tree_decl_init_list * +tree_decl_init_list::dup (symbol_table *sym_tab) +{ + tree_decl_init_list *new_dil = new tree_decl_init_list (); + + for (iterator p = begin (); p != end (); p++) + { + tree_decl_elt *elt = *p; + + new_dil->append (elt ? elt->dup (sym_tab) : 0); + } + + return new_dil; +} + void tree_decl_init_list::accept (tree_walker& tw) { @@ -133,6 +155,13 @@ line (), column ()); } +tree_command * +tree_global_command::dup (symbol_table *sym_tab) +{ + return new tree_global_command (init_list ? init_list->dup (sym_tab) : 0, + line (), column ()); +} + // Static. void @@ -179,6 +208,13 @@ } } +tree_command * +tree_static_command::dup (symbol_table *sym_tab) +{ + return new tree_static_command (init_list ? init_list->dup (sym_tab) : 0, + line (), column ()); +} + /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/src/pt-decl.h +++ b/src/pt-decl.h @@ -54,6 +54,8 @@ tree_expression *expression (void) { return expr; } + tree_decl_elt *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private: @@ -92,6 +94,8 @@ void eval (tree_decl_elt::eval_fcn); + tree_decl_init_list *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private: @@ -162,6 +166,8 @@ void eval (void); + tree_command *dup (symbol_table *sym_tab); + private: static void do_init (tree_decl_elt& elt); @@ -190,6 +196,8 @@ void eval (void); + tree_command *dup (symbol_table *sym_tab); + private: static void do_init (tree_decl_elt& elt);
--- a/src/pt-except.cc +++ b/src/pt-except.cc @@ -126,6 +126,17 @@ } } +tree_command * +tree_try_catch_command::dup (symbol_table *sym_tab) +{ + return new tree_try_catch_command (try_code ? try_code->dup (sym_tab) : 0, + catch_code ? catch_code->dup (sym_tab) : 0, + lead_comm ? lead_comm->dup () : 0, + mid_comm ? mid_comm->dup () : 0, + trail_comm ? trail_comm->dup () : 0, + line (), column ()); +} + void tree_try_catch_command::accept (tree_walker& tw) { @@ -231,6 +242,18 @@ unwind_protect::run (); } +tree_command * +tree_unwind_protect_command::dup (symbol_table *sym_tab) +{ + return new tree_unwind_protect_command + (unwind_protect_code ? unwind_protect_code->dup (sym_tab) : 0, + cleanup_code ? cleanup_code->dup (sym_tab) : 0, + lead_comm ? lead_comm->dup () : 0, + mid_comm ? mid_comm->dup () : 0, + trail_comm ? trail_comm->dup () : 0, + line (), column ()); +} + void tree_unwind_protect_command::accept (tree_walker& tw) {
--- a/src/pt-except.h +++ b/src/pt-except.h @@ -64,6 +64,8 @@ octave_comment_list *trailing_comment (void) { return trail_comm; } + tree_command *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private: @@ -124,6 +126,8 @@ octave_comment_list *trailing_comment (void) { return trail_comm; } + tree_command *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private:
--- a/src/pt-exp.h +++ b/src/pt-exp.h @@ -28,6 +28,7 @@ class octave_value; class octave_lvalue; +class symbol_table; #include "pt.h" @@ -46,6 +47,8 @@ virtual bool has_magic_end (void) const = 0; + virtual tree_expression *dup (symbol_table *) = 0; + virtual bool is_constant (void) const { return false; } virtual bool is_matrix_constant (void) const { return false; } @@ -104,6 +107,13 @@ return this; } + virtual void copy_base (tree_expression& e) + { + num_parens = e.num_parens; + postfix_indexed = e.postfix_indexed; + print_flag = e.print_flag; + } + protected: // A count of the number of times this expression appears directly
--- a/src/pt-fcn-handle.cc +++ b/src/pt-fcn-handle.cc @@ -33,6 +33,7 @@ #include "pt-fcn-handle.h" #include "pager.h" #include "pt-walk.h" +#include "variables.h" void tree_fcn_handle::print (std::ostream& os, bool pr_as_read_syntax, @@ -70,12 +71,96 @@ return retval; } +tree_expression * +tree_fcn_handle::dup (symbol_table *sym_tab) +{ + tree_fcn_handle *new_fh = new tree_fcn_handle (nm, line (), column ()); + + new_fh->copy_base (*this); + + return new_fh; +} + void tree_fcn_handle::accept (tree_walker& tw) { tw.visit_fcn_handle (*this); } +tree_anon_fcn_handle::~tree_anon_fcn_handle (void) +{ + delete param_list; + delete cmd_list; + delete ret_list; + delete sym_tab; +} + +octave_value +tree_anon_fcn_handle::rvalue (void) +{ + MAYBE_DO_BREAKPOINT; + + symbol_table *new_sym_tab = sym_tab ? sym_tab->dup () : 0; + + if (new_sym_tab) + new_sym_tab->inherit (curr_sym_tab); + + tree_parameter_list *new_param_list + = param_list ? param_list->dup (new_sym_tab) : 0; + + tree_statement_list *new_cmd_list + = cmd_list ? cmd_list->dup (new_sym_tab) : 0; + + tree_parameter_list *new_ret_list + = ret_list ? ret_list->dup (new_sym_tab) : 0; + + octave_user_function *uf + = new octave_user_function (new_param_list, new_ret_list, + new_cmd_list, new_sym_tab); + + octave_value fcn (uf); + + octave_value fh (new octave_fcn_handle (fcn, "@<anonymous>")); + + return fh; +} + +octave_value_list +tree_anon_fcn_handle::rvalue (int nargout) +{ + octave_value_list retval; + + if (nargout > 1) + error ("invalid number of output arguments for anonymous function handle expression"); + else + retval = rvalue (); + + return retval; +} + +tree_expression * +tree_anon_fcn_handle::dup (symbol_table *st) +{ + tree_anon_fcn_handle *new_afh + = new tree_anon_fcn_handle (param_list ? param_list->dup (st) : 0, + ret_list ? ret_list->dup (st) : 0, + cmd_list ? cmd_list->dup (st) : 0, + sym_tab ? sym_tab->dup () : 0, + line (), column ()); + + new_afh->copy_base (*this); + + return new_afh; +} + +void +tree_anon_fcn_handle::accept (tree_walker& tw) +{ + tw.visit_anon_fcn_handle (*this); +} + + + /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/src/pt-fcn-handle.h +++ b/src/pt-fcn-handle.h @@ -29,6 +29,8 @@ #include "pt-bp.h" #include "pt-exp.h" +#include "pt-misc.h" +#include "pt-stmt.h" class octave_value_list; @@ -65,6 +67,8 @@ octave_value_list rvalue (int nargout); + tree_expression *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private: @@ -79,6 +83,60 @@ tree_fcn_handle& operator = (const tree_fcn_handle&); }; +class +tree_anon_fcn_handle : public tree_expression +{ +public: + + tree_anon_fcn_handle (int l = -1, int c = -1) + : tree_expression (l, c), param_list (0), cmd_list (0), + ret_list (0), sym_tab (0) { } + + tree_anon_fcn_handle (tree_parameter_list *p, tree_parameter_list *r, + tree_statement_list *cl, symbol_table *st, + int l = -1, int c = -1) + : tree_expression (l, c), param_list (p), cmd_list (cl), + ret_list (r), sym_tab (st) { } + + ~tree_anon_fcn_handle (void); + + bool has_magic_end (void) const { return false; } + + bool rvalue_ok (void) const { return true; } + + octave_value rvalue (void); + + octave_value_list rvalue (int nargout); + + tree_parameter_list *parameter_list (void) { return param_list; } + + tree_statement_list *body (void) { return cmd_list; } + + tree_expression *dup (symbol_table *sym_tab); + + void accept (tree_walker& tw); + +private: + + // The parameter list. + tree_parameter_list *param_list; + + // The statement that makes up the body of the function. + tree_statement_list *cmd_list; + + // The list of return values. + tree_parameter_list *ret_list; + + // The symbol table. + symbol_table *sym_tab; + + // No copying! + + tree_anon_fcn_handle (const tree_anon_fcn_handle&); + + tree_anon_fcn_handle& operator = (const tree_anon_fcn_handle&); +}; + #endif /*
--- a/src/pt-id.cc +++ b/src/pt-id.cc @@ -212,6 +212,18 @@ return sym->variable_reference (); } +tree_identifier * +tree_identifier::dup (symbol_table *sym_tab) +{ + symbol_record *sr = (sym_tab && sym) ? sym_tab->lookup (sym->name ()) : 0; + + tree_identifier *new_id = new tree_identifier (sr, line (), column ()); + + new_id->copy_base (*this); + + return new_id; +} + void tree_identifier::accept (tree_walker& tw) {
--- a/src/pt-id.h +++ b/src/pt-id.h @@ -89,6 +89,8 @@ void eval_undefined_error (void); + tree_identifier *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private:
--- a/src/pt-idx.cc +++ b/src/pt-idx.cc @@ -41,6 +41,10 @@ // Index expressions. +tree_index_expression::tree_index_expression (int l, int c) + : tree_expression (l, c), expr (), args (), type (), + arg_nm (), dyn_field () { } + tree_index_expression::tree_index_expression (tree_expression *e, tree_argument_list *lst, int l, int c, char t) @@ -519,6 +523,49 @@ ::error ("evaluating %s", type_str); } +tree_index_expression * +tree_index_expression::dup (symbol_table *sym_tab) +{ + tree_index_expression *new_idx_expr + = new tree_index_expression (line (), column ()); + + new_idx_expr->expr = expr ? expr->dup (sym_tab) : 0; + + std::list<tree_argument_list *> new_args; + + for (std::list<tree_argument_list *>::iterator p = args.begin (); + p != args.end (); + p++) + { + tree_argument_list *elt = *p; + + new_args.push_back (elt ? elt->dup (sym_tab) : 0); + } + + new_idx_expr->args = new_args; + + new_idx_expr->type = type; + + new_idx_expr->arg_nm = arg_nm; + + std::list<tree_expression *> new_dyn_field; + + for (std::list<tree_expression *>::iterator p = dyn_field.begin (); + p != dyn_field.end (); + p++) + { + tree_expression *elt = *p; + + new_dyn_field.push_back (elt ? elt->dup (sym_tab) : 0); + } + + new_idx_expr->dyn_field = new_dyn_field; + + new_idx_expr->copy_base (*this); + + return new_idx_expr; +} + void tree_index_expression::accept (tree_walker& tw) {
--- a/src/pt-idx.h +++ b/src/pt-idx.h @@ -89,6 +89,8 @@ void eval_error (void) const; + tree_index_expression *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private: @@ -109,6 +111,8 @@ // The list of dynamic field names, if any. std::list<tree_expression *> dyn_field; + tree_index_expression (int l = -1, int c = -1); + Octave_map make_arg_struct (void) const; std::string
--- a/src/pt-jump.cc +++ b/src/pt-jump.cc @@ -48,6 +48,12 @@ breaking = 1; } +tree_command * +tree_break_command::dup (symbol_table *) +{ + return new tree_break_command (line (), column ()); +} + void tree_break_command::accept (tree_walker& tw) { @@ -68,6 +74,12 @@ continuing = 1; } +tree_command * +tree_continue_command::dup (symbol_table *) +{ + return new tree_continue_command (line (), column ()); +} + void tree_continue_command::accept (tree_walker& tw) { @@ -88,6 +100,12 @@ returning = 1; } +tree_command * +tree_return_command::dup (symbol_table *) +{ + return new tree_return_command (line (), column ()); +} + void tree_return_command::accept (tree_walker& tw) {
--- a/src/pt-jump.h +++ b/src/pt-jump.h @@ -42,6 +42,8 @@ void eval (void); + tree_command *dup (symbol_table *); + void accept (tree_walker& tw); static int breaking; @@ -69,6 +71,8 @@ void eval (void); + tree_command *dup (symbol_table *); + void accept (tree_walker& tw); static int continuing; @@ -96,6 +100,8 @@ void eval (void); + tree_command *dup (symbol_table *); + void accept (tree_walker& tw); static int returning;
--- a/src/pt-loop.cc +++ b/src/pt-loop.cc @@ -125,6 +125,16 @@ line (), column ()); } +tree_command * +tree_while_command::dup (symbol_table *sym_tab) +{ + return new tree_while_command (expr ? expr->dup (sym_tab) : 0, + list ? list->dup (sym_tab) : 0, + lead_comm ? lead_comm->dup () : 0, + trail_comm ? trail_comm->dup (): 0, + line (), column ()); +} + void tree_while_command::accept (tree_walker& tw) { @@ -178,6 +188,16 @@ line (), column ()); } +tree_command * +tree_do_until_command::dup (symbol_table *sym_tab) +{ + return new tree_do_until_command (expr ? expr->dup (sym_tab) : 0, + list ? list->dup (sym_tab) : 0, + lead_comm ? lead_comm->dup () : 0, + trail_comm ? trail_comm->dup (): 0, + line (), column ()); +} + void tree_do_until_command::accept (tree_walker& tw) { @@ -462,6 +482,17 @@ line (), column ()); } +tree_command * +tree_simple_for_command::dup (symbol_table *sym_tab) +{ + return new tree_simple_for_command (lhs ? lhs->dup (sym_tab) : 0, + expr ? expr->dup (sym_tab) : 0, + list ? list->dup (sym_tab) : 0, + lead_comm ? lead_comm->dup () : 0, + trail_comm ? trail_comm->dup () : 0, + line (), column ()); +} + void tree_simple_for_command::accept (tree_walker& tw) { @@ -572,6 +603,17 @@ line (), column ()); } +tree_command * +tree_complex_for_command::dup (symbol_table *sym_tab) +{ + return new tree_complex_for_command (lhs ? lhs->dup (sym_tab) : 0, + expr ? expr->dup (sym_tab) : 0, + list ? list->dup (sym_tab) : 0, + lead_comm ? lead_comm->dup () : 0, + trail_comm ? trail_comm->dup () : 0, + line (), column ()); +} + void tree_complex_for_command::accept (tree_walker& tw) {
--- a/src/pt-loop.h +++ b/src/pt-loop.h @@ -78,6 +78,8 @@ octave_comment_list *trailing_comment (void) { return trail_comm; } + tree_command *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); protected: @@ -131,6 +133,8 @@ void eval_error (void); + tree_command *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private: @@ -177,6 +181,8 @@ octave_comment_list *trailing_comment (void) { return trail_comm; } + tree_command *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private: @@ -239,6 +245,8 @@ octave_comment_list *trailing_comment (void) { return trail_comm; } + tree_command *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private:
--- a/src/pt-mat.cc +++ b/src/pt-mat.cc @@ -933,6 +933,23 @@ return retval; } +tree_expression * +tree_matrix::dup (symbol_table *sym_tab) +{ + tree_matrix *new_matrix = new tree_matrix (0, line (), column ()); + + for (iterator p = begin (); p != end (); p++) + { + tree_argument_list *elt = *p; + + append (elt ? elt->dup (sym_tab) : 0); + } + + new_matrix->copy_base (*this); + + return new_matrix; +} + void tree_matrix::accept (tree_walker& tw) {
--- a/src/pt-mat.h +++ b/src/pt-mat.h @@ -63,6 +63,8 @@ octave_value_list rvalue (int nargout); + tree_expression *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private:
--- a/src/pt-misc.cc +++ b/src/pt-misc.cc @@ -187,6 +187,24 @@ return status; } +tree_parameter_list * +tree_parameter_list::dup (symbol_table *sym_tab) +{ + tree_parameter_list *new_list = new tree_parameter_list (); + + if (takes_varargs ()) + new_list->mark_varargs (); + + for (iterator p = begin (); p != end (); p++) + { + tree_identifier *elt = *p; + + new_list->append (elt->dup (sym_tab)); + } + + return new_list; +} + void tree_parameter_list::accept (tree_walker& tw) { @@ -205,6 +223,21 @@ } } +tree_return_list * +tree_return_list::dup (symbol_table *sym_tab) +{ + tree_return_list *new_list = new tree_return_list (); + + for (iterator p = begin (); p != end (); p++) + { + tree_index_expression *elt = *p; + + new_list->append (elt->dup (sym_tab)); + } + + return new_list; +} + void tree_return_list::accept (tree_walker& tw) {
--- a/src/pt-misc.h +++ b/src/pt-misc.h @@ -75,6 +75,8 @@ octave_value_list convert_to_const_vector (const Cell& varargout); + tree_parameter_list *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private: @@ -102,6 +104,8 @@ ~tree_return_list (void); + tree_return_list *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private:
--- a/src/pt-pr-code.cc +++ b/src/pt-pr-code.cc @@ -36,6 +36,30 @@ #include "pt-all.h" void +tree_print_code::visit_anon_fcn_handle (tree_anon_fcn_handle& afh) +{ + indent (); + + print_parens (afh, "("); + + os << "@("; + + tree_parameter_list *param_list = afh.parameter_list (); + + if (param_list) + param_list->accept (*this); + + os << ") "; + + tree_statement_list *body = afh.body (); + + if (body) + body->accept (*this); + + print_parens (afh, ")"); +} + +void tree_print_code::visit_argument_list (tree_argument_list& lst) { tree_argument_list::iterator p = lst.begin ();
--- a/src/pt-pr-code.h +++ b/src/pt-pr-code.h @@ -53,6 +53,8 @@ ~tree_print_code (void) { } + void visit_anon_fcn_handle (tree_anon_fcn_handle&); + void visit_argument_list (tree_argument_list&); void visit_binary_expression (tree_binary_expression&);
--- a/src/pt-select.cc +++ b/src/pt-select.cc @@ -59,6 +59,14 @@ return 0; } +tree_if_clause * +tree_if_clause::dup (symbol_table *sym_tab) +{ + return new tree_if_clause (expr ? expr->dup (sym_tab) : 0, + list ? list->dup (sym_tab) : 0, + lead_comm ? lead_comm->dup () : 0); +} + void tree_if_clause::accept (tree_walker& tw) { @@ -79,6 +87,21 @@ } } +tree_if_command_list * +tree_if_command_list::dup (symbol_table *sym_tab) +{ + tree_if_command_list *new_icl = new tree_if_command_list (); + + for (iterator p = begin (); p != end (); p++) + { + tree_if_clause *elt = *p; + + new_icl->append (elt ? elt->dup (sym_tab) : 0); + } + + return new_icl; +} + void tree_if_command_list::accept (tree_walker& tw) { @@ -105,6 +128,15 @@ line (), column ()); } +tree_command * +tree_if_command::dup (symbol_table *sym_tab) +{ + return new tree_if_command (list ? list->dup (sym_tab) : 0, + lead_comm ? lead_comm->dup () : 0, + trail_comm ? trail_comm->dup () : 0, + line (), column ()); +} + void tree_if_command::accept (tree_walker& tw) { @@ -210,6 +242,14 @@ ::error ("evaluating switch case label"); } +tree_switch_case * +tree_switch_case::dup (symbol_table *sym_tab) +{ + return new tree_switch_case (label ? label->dup (sym_tab) : 0, + list ? list->dup (sym_tab) : 0, + lead_comm ? lead_comm->dup () : 0); +} + void tree_switch_case::accept (tree_walker& tw) { @@ -230,6 +270,21 @@ } } +tree_switch_case_list * +tree_switch_case_list::dup (symbol_table *sym_tab) +{ + tree_switch_case_list *new_scl = new tree_switch_case_list (); + + for (iterator p = begin (); p != end (); p++) + { + tree_switch_case *elt = *p; + + new_scl->append (elt ? elt->dup (sym_tab) : 0); + } + + return new_scl; +} + void tree_switch_case_list::accept (tree_walker& tw) { @@ -276,6 +331,16 @@ line (), column ()); } +tree_command * +tree_switch_command::dup (symbol_table *sym_tab) +{ + return new tree_switch_command (expr ? expr->dup (sym_tab) : 0, + list ? list->dup (sym_tab) : 0, + lead_comm ? lead_comm->dup () : 0, + trail_comm ? trail_comm->dup () : 0, + line (), column ()); +} + void tree_switch_command::accept (tree_walker& tw) {
--- a/src/pt-select.h +++ b/src/pt-select.h @@ -63,6 +63,8 @@ octave_comment_list *leading_comment (void) { return lead_comm; } + tree_if_clause *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private: @@ -104,6 +106,8 @@ void eval (void); + tree_if_command_list *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private: @@ -137,6 +141,8 @@ octave_comment_list *trailing_comment (void) { return trail_comm; } + tree_command *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private: @@ -190,6 +196,8 @@ octave_comment_list *leading_comment (void) { return lead_comm; } + tree_switch_case *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private: @@ -231,6 +239,8 @@ void eval (const octave_value& val); + tree_switch_case_list *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private: @@ -271,6 +281,8 @@ octave_comment_list *trailing_comment (void) { return trail_comm; } + tree_command *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private:
--- a/src/pt-stmt.cc +++ b/src/pt-stmt.cc @@ -143,6 +143,22 @@ return retval; } +tree_statement * +tree_statement::dup (symbol_table *sym_tab) +{ + tree_statement *new_stmt = new tree_statement (); + + new_stmt->cmd = cmd ? cmd->dup (sym_tab) : 0; + + new_stmt->expr = expr ? expr->dup (sym_tab) : 0; + + new_stmt->comm = comm ? comm->dup () : 0; + + new_stmt->print_flag = print_flag; + + return new_stmt; +} + void tree_statement::accept (tree_walker& tw) { @@ -251,6 +267,23 @@ return tbp.get_list (); } +tree_statement_list * +tree_statement_list::dup (symbol_table *sym_tab) +{ + tree_statement_list *new_list = new tree_statement_list (); + + new_list->function_body = function_body; + + for (iterator p = begin (); p != end (); p++) + { + tree_statement *elt = *p; + + new_list->append (elt ? elt->dup (sym_tab) : 0); + } + + return new_list; +} + void tree_statement_list::accept (tree_walker& tw) {
--- a/src/pt-stmt.h +++ b/src/pt-stmt.h @@ -82,6 +82,8 @@ void set_expression (tree_expression *e) { expr = e; } + tree_statement *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private: @@ -139,6 +141,8 @@ octave_value_list list_breakpoints (void); + tree_statement_list *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private:
--- a/src/pt-unop.cc +++ b/src/pt-unop.cc @@ -120,6 +120,18 @@ oper () . c_str (), line (), column ()); } +tree_expression * +tree_prefix_expression::dup (symbol_table *sym_tab) +{ + tree_prefix_expression *new_pe + = new tree_prefix_expression (op ? op->dup (sym_tab) : 0, + line (), column (), etype); + + new_pe->copy_base (*this); + + return new_pe; +} + void tree_prefix_expression::accept (tree_walker& tw) { @@ -205,6 +217,18 @@ oper () . c_str (), line (), column ()); } +tree_expression * +tree_postfix_expression::dup (symbol_table *sym_tab) +{ + tree_postfix_expression *new_pe + = new tree_postfix_expression (op ? op->dup (sym_tab) : 0, + line (), column (), etype); + + new_pe->copy_base (*this); + + return new_pe; +} + void tree_postfix_expression::accept (tree_walker& tw) {
--- a/src/pt-unop.h +++ b/src/pt-unop.h @@ -101,6 +101,8 @@ void eval_error (void); + tree_expression *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private: @@ -137,6 +139,8 @@ void eval_error (void); + tree_expression *dup (symbol_table *sym_tab); + void accept (tree_walker& tw); private:
--- a/src/pt-walk.h +++ b/src/pt-walk.h @@ -24,6 +24,7 @@ #if !defined (octave_tree_walker_h) #define octave_tree_walker_h 1 +class tree_anon_fcn_handle; class tree_argument_list; class tree_binary_expression; class tree_break_command; @@ -68,6 +69,9 @@ public: virtual void + visit_anon_fcn_handle (tree_anon_fcn_handle&) = 0; + + virtual void visit_argument_list (tree_argument_list&) = 0; virtual void
--- a/src/symtab.cc +++ b/src/symtab.cc @@ -295,6 +295,19 @@ } void +symbol_record::mark_as_automatic_variable (void) +{ + if (is_linked_to_global ()) + error ("can't mark global variable `%s' as automatic variable", + nm.c_str ()); + else if (is_static ()) + error ("can't mark static variable `%s' as automatic variable", + nm.c_str ()); + else + automatic_variable = 1; +} + +void symbol_record::mark_as_linked_to_global (void) { if (is_formal_parameter ()) @@ -1651,6 +1664,73 @@ } } +// Create a new symbol table with the same entries. Only the symbol +// names and some attributes are copied, not values. + +symbol_table * +symbol_table::dup (void) +{ + symbol_table *new_sym_tab = new symbol_table (table_size); + + for (unsigned int i = 0; i < table_size; i++) + { + symbol_record *ptr = table[i].next (); + + while (ptr) + { + std::string nm = ptr->name (); + + symbol_record *sr = new_sym_tab->lookup (nm, true); + + if (sr) + { + if (ptr->is_formal_parameter ()) + sr->mark_as_formal_parameter (); + + if (ptr->is_automatic_variable ()) + sr->mark_as_automatic_variable (); + + if (ptr->is_static ()) + sr->mark_as_static (); + } + + ptr = ptr->next (); + } + } + + return new_sym_tab; +} + +void +symbol_table::inherit (symbol_table *parent_sym_tab) +{ + for (unsigned int i = 0; i < table_size; i++) + { + symbol_record *ptr = table[i].next (); + + while (ptr) + { + std::string nm = ptr->name (); + + if (! (nm == "__retval__" + || ptr->is_automatic_variable () + || ptr->is_formal_parameter ())) + { + symbol_record *sr = parent_sym_tab->lookup (nm); + + if (sr) + { + ptr->define (sr->variable_value ()); + + ptr->mark_as_static (); + } + } + + ptr = ptr->next (); + } + } +} + void symbol_table::print_info (std::ostream& os) const {
--- a/src/symtab.h +++ b/src/symtab.h @@ -256,19 +256,19 @@ typedef int (*change_function) (void); symbol_record (void) - : formal_param (false), linked_to_global (false), - tagged_static (false), can_hide_function (true), - visible (true), nm (), chg_fcn (0), + : formal_param (false), automatic_variable (false), + linked_to_global (false), tagged_static (false), + can_hide_function (true), visible (true), nm (), chg_fcn (0), definition (new symbol_def ()), next_elem (0) { } // FIXME -- kluge alert! We obviously need a better way of // handling allow_shadow! symbol_record (const std::string& n, symbol_record *nxt) - : formal_param (false), linked_to_global (false), - tagged_static (false), can_hide_function (n != "__end__"), - visible (true), nm (n), chg_fcn (0), - definition (new symbol_def ()), next_elem (nxt) { } + : formal_param (false), automatic_variable (false), + linked_to_global (false), tagged_static (false), + can_hide_function (n != "__end__"), visible (true), nm (n), + chg_fcn (0), definition (new symbol_def ()), next_elem (nxt) { } ~symbol_record (void) { @@ -359,6 +359,9 @@ void mark_as_formal_parameter (void); bool is_formal_parameter (void) const { return formal_param; } + void mark_as_automatic_variable (void); + bool is_automatic_variable (void) const { return automatic_variable; } + void mark_as_linked_to_global (void); bool is_linked_to_global (void) const { return linked_to_global; } @@ -433,6 +436,7 @@ private: unsigned int formal_param : 1; + unsigned int automatic_variable : 1; unsigned int linked_to_global : 1; unsigned int tagged_static : 1; unsigned int can_hide_function : 1; @@ -581,6 +585,13 @@ void pop_context (void); + // Create a new symbol table with the same entries. Only the symbol + // names and some attributes are copied, not values. + symbol_table *dup (void); + + // Inherit some values from the parent_sym_tab. + void inherit (symbol_table *parent_sym_tab); + void print_info (std::ostream& os) const; private: