Mercurial > hg > octave-terminal
changeset 2124:97a566037a75
[project @ 1996-05-12 07:16:36 by jwe]
author | jwe |
---|---|
date | Sun, 12 May 1996 07:16:36 +0000 |
parents | ee55d81f585a |
children | 5049a300eee0 |
files | src/help.cc src/parse.y src/pt-base.cc src/pt-base.h src/pt-cmd.cc src/pt-cmd.h src/pt-const.cc src/pt-const.h src/pt-exp-base.h src/pt-exp.cc src/pt-exp.h src/pt-fcn.cc src/pt-fcn.h src/pt-fvc.cc src/pt-fvc.h src/pt-mat.cc src/pt-mat.h src/pt-misc.cc src/pt-misc.h src/pt-mvr-base.h src/pt-mvr.cc src/pt-mvr.h src/pt-plot.cc src/pt-plot.h |
diffstat | 24 files changed, 739 insertions(+), 1154 deletions(-) [+] |
line wrap: on
line diff
--- a/src/help.cc +++ b/src/help.cc @@ -49,6 +49,7 @@ #include "pathsearch.h" #include "pt-const.h" #include "pt-exp.h" +#include "pt-pr-code.h" #include "sighandlers.h" #include "symtab.h" #include "toplev.h" @@ -754,7 +755,9 @@ if (nargout == 0 && ! quiet) output_buf << argv[i] << " is a user-defined function\n"; - defn->print_code (output_buf); + tree_print_code tpc (output_buf); + + defn->accept (tpc); } // XXX FIXME XXX -- this code should be shared with @@ -808,7 +811,9 @@ } if (! tmp->is_map ()) { - tmp->print_code (output_buf); + tree_print_code tpc (output_buf); + + tmp->accept (tpc); if (nargout == 0) output_buf << "\n";
--- a/src/parse.y +++ b/src/parse.y @@ -763,7 +763,7 @@ { $$ = make_constant (TEXT, $1); } | '(' simple_expr ')' { - $2->in_parens++; + $2->mark_in_parens (); $$ = $2; } | word_list_cmd @@ -1327,7 +1327,7 @@ { if (user_pref.warn_assign_as_truth_value && expr->is_assignment_expression () - && expr->in_parens < 2) + && expr->is_in_parens () < 2) { warning ("suggest parenthesis around assignment used as truth value"); }
--- a/src/pt-base.cc +++ b/src/pt-base.cc @@ -35,48 +35,6 @@ #include "pt-base.h" #include "user-prefs.h" -// Current indentation. -int tree_print_code::curr_print_indent_level = 0; - -// Nonzero means we are at the beginning of a line. -bool tree_print_code::beginning_of_line = true; - -// All print_code() functions should use this to print new lines. - -void -tree_print_code::print_code_new_line (ostream& os) -{ - os << "\n"; - - beginning_of_line = true; -} - -// Each print_code() function should call this before printing -// anything. -// -// This doesn't need to be fast, but isn't there a better way? - -void -tree_print_code::print_code_indent (ostream& os) -{ - assert (curr_print_indent_level >= 0); - - if (beginning_of_line) - { - os.form ("%s%*s", user_pref.ps4.c_str (), curr_print_indent_level, ""); - beginning_of_line = false; - } -} - -// For ressetting print_code state. - -void -tree_print_code::print_code_reset (void) -{ - beginning_of_line = true; - curr_print_indent_level = 0; -} - /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/src/pt-base.h +++ b/src/pt-base.h @@ -27,44 +27,15 @@ #pragma interface #endif -class ostream; - -// How to print the code that the trees represent. - -class -tree_print_code -{ -public: - virtual ~tree_print_code (void) { } - - virtual void print_code (ostream& os) = 0; - - void reset_indent_level (void) - { curr_print_indent_level = 0; } - - void increment_indent_level (void) - { curr_print_indent_level += 2; } - - void decrement_indent_level (void) - { curr_print_indent_level -= 2; } - - void print_code_new_line (ostream& os); - - void print_code_indent (ostream& os); - - void print_code_reset (void); - -private: - static int curr_print_indent_level; - static bool beginning_of_line; -}; +class tree_walker; // Base class for the parse tree. class -tree : public tree_print_code +tree { public: + tree (int l = -1, int c = -1) { line_num = l; @@ -77,7 +48,12 @@ virtual int column (void) const { return column_num; } + virtual void accept (tree_walker& tw) = 0; + private: + + // The input line and column where we found the text that was + // eventually converted to this tree node. int line_num; int column_num; };
--- a/src/pt-cmd.cc +++ b/src/pt-cmd.cc @@ -50,6 +50,7 @@ #include "pt-fvc.h" #include "pt-misc.h" #include "pt-mvr.h" +#include "pt-walk.h" #include "unwind-prot.h" #include "user-prefs.h" #include "variables.h" @@ -118,14 +119,9 @@ } void -tree_global_command::print_code (ostream& os) +tree_global_command::accept (tree_walker& tw) { - print_code_indent (os); - - os << "global "; - - if (init_list) - init_list->print_code (os); + tw.visit_global_command (*this); } // While. @@ -176,27 +172,9 @@ } void -tree_while_command::print_code (ostream& os) +tree_while_command::accept (tree_walker& tw) { - print_code_indent (os); - - os << "while "; - - if (expr) - expr->print_code (os); - - print_code_new_line (os); - - if (list) - { - increment_indent_level (); - list->print_code (os); - decrement_indent_level (); - } - - print_code_indent (os); - - os << "endwhile"; + tw.visit_while_command (*this); } // For. @@ -537,32 +515,9 @@ } void -tree_for_command::print_code (ostream& os) +tree_for_command::accept (tree_walker& tw) { - print_code_indent (os); - - os << "for "; - - if (id) - id->print_code (os); - - os << " = "; - - if (expr) - expr->print_code (os); - - print_code_new_line (os); - - if (list) - { - increment_indent_level (); - list->print_code (os); - decrement_indent_level (); - } - - print_code_indent (os); - - os << "endfor"; + tw.visit_for_command (*this); } // If. @@ -584,18 +539,9 @@ } void -tree_if_command::print_code (ostream& os) +tree_if_command::accept (tree_walker& tw) { - print_code_indent (os); - - os << "if "; - - if (list) - list->print_code (os); - - print_code_indent (os); - - os << "endif"; + tw.visit_if_command (*this); } // Simple exception handling. @@ -682,37 +628,9 @@ } void -tree_try_catch_command::print_code (ostream& os) +tree_try_catch_command::accept (tree_walker& tw) { - print_code_indent (os); - - os << "try_catch"; - - print_code_new_line (os); - - if (try_code) - { - increment_indent_level (); - try_code->print_code (os); - decrement_indent_level (); - } - - print_code_indent (os); - - os << "catch_code"; - - print_code_new_line (os); - - if (catch_code) - { - increment_indent_level (); - catch_code->print_code (os); - decrement_indent_level (); - } - - print_code_indent (os); - - os << "end_try_catch"; + tw.visit_try_catch_command (*this); } // Simple exception handling. @@ -790,37 +708,9 @@ } void -tree_unwind_protect_command::print_code (ostream& os) +tree_unwind_protect_command::accept (tree_walker& tw) { - print_code_indent (os); - - os << "unwind_protect"; - - print_code_new_line (os); - - if (unwind_protect_code) - { - increment_indent_level (); - unwind_protect_code->print_code (os); - decrement_indent_level (); - } - - print_code_indent (os); - - os << "cleanup_code"; - - print_code_new_line (os); - - if (cleanup_code) - { - increment_indent_level (); - cleanup_code->print_code (os); - decrement_indent_level (); - } - - print_code_indent (os); - - os << "end_unwind_protect"; + tw.visit_unwind_protect_command (*this); } // Break. @@ -833,11 +723,9 @@ } void -tree_break_command::print_code (ostream& os) +tree_break_command::accept (tree_walker& tw) { - print_code_indent (os); - - os << "break"; + tw.visit_break_command (*this); } // Continue. @@ -850,11 +738,9 @@ } void -tree_continue_command::print_code (ostream& os) +tree_continue_command::accept (tree_walker& tw) { - print_code_indent (os); - - os << "continue"; + tw.visit_continue_command (*this); } // Return. @@ -867,11 +753,9 @@ } void -tree_return_command::print_code (ostream& os) +tree_return_command::accept (tree_walker& tw) { - print_code_indent (os); - - os << "return"; + tw.visit_return_command (*this); } /*
--- a/src/pt-cmd.h +++ b/src/pt-cmd.h @@ -52,6 +52,8 @@ class tree_continue_command; class tree_return_command; +class tree_walker; + #include "pt-base.h" // A base class for commands. @@ -60,6 +62,7 @@ tree_command : public tree { public: + tree_command (int l = -1, int c = -1) : tree (l, c) { } virtual ~tree_command (void) { } @@ -71,6 +74,7 @@ tree_global_command : public tree_command { public: + tree_global_command (int l = -1, int c = -1) : tree_command (l, c), init_list (0) { } @@ -81,9 +85,14 @@ void eval (void); - void print_code (ostream& os); + tree_global_init_list *initializer_list (void) { return init_list; } + + void accept (tree_walker& tw); private: + + // The list of global variables or initializers in this global + // command. tree_global_init_list *init_list; }; @@ -93,6 +102,7 @@ tree_while_command : public tree_command { public: + tree_while_command (int l = -1, int c = -1) : tree_command (l, c), expr (0), list (0) { } @@ -109,11 +119,19 @@ void eval_error (void); - void print_code (ostream& os); + tree_expression *condition (void) { return expr; } + + tree_statement_list *body (void) { return list; } + + void accept (tree_walker& tw); private: - tree_expression *expr; // Expression to test. - tree_statement_list *list; // List of commands to execute. + + // Expression to test. + tree_expression *expr; + + // List of commands to execute. + tree_statement_list *list; }; // For. @@ -122,6 +140,7 @@ tree_for_command : public tree_command { public: + tree_for_command (int l = -1, int c = -1) : tree_command (l, c), id (0), id_list (0), expr (0), list (0) { } @@ -141,9 +160,28 @@ void eval_error (void); - void print_code (ostream& os); + tree_index_expression *ident (void) { return id; } + + tree_expression *control_expr (void) { return expr; } + + tree_statement_list *body (void) { return list; } + + void accept (tree_walker& tw); private: + + // Identifier to modify. + tree_index_expression *id; + + // List of identifiers to modify. + tree_return_list *id_list; + + // Expression to evaluate. + tree_expression *expr; + + // List of commands to execute. + tree_statement_list *list; + void do_for_loop_once (tree_return_list *lst, const octave_value_list& rhs, bool& quit); @@ -152,11 +190,6 @@ void do_for_loop_once (tree_identifier *ident, octave_value& rhs, bool& quit); - - tree_index_expression *id; // Identifier to modify. - tree_return_list *id_list; // List of identifiers to modify. - tree_expression *expr; // Expression to evaluate. - tree_statement_list *list; // List of commands to execute. }; // If. @@ -165,6 +198,7 @@ tree_if_command : public tree_command { public: + tree_if_command (int l = -1, int c = -1) : tree_command (l, c), list (0) { } @@ -177,9 +211,13 @@ void eval_error (void); - void print_code (ostream& os); + 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; }; @@ -189,6 +227,7 @@ 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) { } @@ -201,10 +240,19 @@ void eval (void); - void print_code (ostream& os); + 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; }; @@ -214,6 +262,7 @@ 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) { } @@ -226,10 +275,18 @@ void eval (void); - void print_code (ostream& os); + 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; }; @@ -239,13 +296,14 @@ 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 print_code (ostream& os); + void accept (tree_walker& tw); }; // Continue. @@ -254,13 +312,14 @@ 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 print_code (ostream& os); + void accept (tree_walker& tw); }; // Return. @@ -269,13 +328,14 @@ 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 print_code (ostream& os); + void accept (tree_walker& tw); }; #endif
--- a/src/pt-const.cc +++ b/src/pt-const.cc @@ -53,6 +53,7 @@ #include "pr-output.h" #include "sysdep.h" #include "pt-const.h" +#include "pt-walk.h" #include "unwind-prot.h" #include "user-prefs.h" #include "utils.h" @@ -407,18 +408,9 @@ } void -octave_value::print_code (ostream& os) +octave_value::accept (tree_walker& tw) { - print_code_indent (os); - - if (in_parens) - os << "("; - - if (rep) - rep->print_code (os); - - if (in_parens) - os << ")"; + tw.visit_octave_value (*this); } // The real representation of constants. @@ -2320,69 +2312,6 @@ } void -OCT_VAL_REP::print_code (ostream& os) -{ - switch (type_tag) - { - case scalar_constant: - if (orig_text.empty ()) - octave_print_internal (os, scalar, 1); - else - os << orig_text; - break; - - case matrix_constant: - octave_print_internal (os, *matrix, 1); - break; - - case complex_scalar_constant: - { - double re = complex_scalar->real (); - double im = complex_scalar->imag (); - - // If we have the original text and a pure imaginary, just - // print the original text, because this must be a constant - // that was parsed as part of a function. - - if (! orig_text.empty () && re == 0.0 && im > 0.0) - os << orig_text; - else - octave_print_internal (os, *complex_scalar, 1); - } - break; - - case complex_matrix_constant: - octave_print_internal (os, *complex_matrix, 1); - break; - - case char_matrix_constant: - octave_print_internal (os, *char_matrix, 1); - break; - - case char_matrix_constant_str: - octave_print_internal (os, *char_matrix, 1, 1); - break; - - case range_constant: - octave_print_internal (os, *range, 1); - break; - - case magic_colon: - os << ":"; - break; - - case all_va_args: - os << "all_va_args"; - break; - - case map_constant: - case unknown_constant: - panic_impossible (); - break; - } -} - -void OCT_VAL_REP::gripe_wrong_type_arg (const char *name, const octave_value_rep& tcr) const {
--- a/src/pt-const.h +++ b/src/pt-const.h @@ -42,6 +42,8 @@ class Octave_map; class octave_value_list; +class tree_walker; + // Constants. class @@ -239,13 +241,13 @@ void stash_original_text (const string& s); + string original_text (void) { return orig_text; } + void maybe_mutate (void); void print (void); void print (ostream& os); - void print_code (ostream& os); - void gripe_wrong_type_arg (const char *name, const octave_value_rep& tcr) const; @@ -493,6 +495,7 @@ bool is_real_matrix (void) const { return rep->is_real_matrix (); } bool is_complex_scalar (void) const { return rep->is_complex_scalar (); } bool is_complex_matrix (void) const { return rep->is_complex_matrix (); } + bool is_char_matrix (void) const { return rep->is_char_matrix (); } bool is_string (void) const { return rep->is_string (); } bool is_range (void) const { return rep->is_range (); } bool is_map (void) const { return rep->is_map (); } @@ -645,9 +648,9 @@ void stash_original_text (const string& s) { rep->stash_original_text (s); } - // Pretty print this constant. - - void print_code (ostream& os); + string original_text (void) { return rep->original_text (); } + + void accept (tree_walker& tw); char *type_as_string (void) const { return rep->type_as_string (); }
--- a/src/pt-exp-base.h +++ b/src/pt-exp-base.h @@ -37,7 +37,6 @@ tree_expression : public tree { public: - int in_parens; enum type { @@ -110,11 +109,22 @@ virtual bool is_logically_true (const char *); + virtual void mark_in_parens (void) { in_parens++; } + + virtual bool is_in_parens (void) { return in_parens; } + + virtual type expression_type (void) { return etype; } + virtual void mark_for_possible_ans_assign (void); virtual octave_value eval (bool print) = 0; protected: + + // Nonzero if this expression appears inside parentheses. + int in_parens; + + // The type of this expression. type etype; };
--- a/src/pt-exp.cc +++ b/src/pt-exp.cc @@ -43,6 +43,7 @@ #include "pt-fvc.h" #include "pt-misc.h" #include "pt-mvr.h" +#include "pt-walk.h" #include "user-prefs.h" #include "utils.h" @@ -120,20 +121,9 @@ } void -tree_prefix_expression::print_code (ostream& os) +tree_prefix_expression::accept (tree_walker& tw) { - print_code_indent (os); - - if (in_parens) - os << "("; - - os << oper (); - - if (id) - id->print_code (os); - - if (in_parens) - os << ")"; + tw.visit_prefix_expression (*this); } // Postfix expressions. @@ -199,20 +189,9 @@ } void -tree_postfix_expression::print_code (ostream& os) +tree_postfix_expression::accept (tree_walker& tw) { - print_code_indent (os); - - if (in_parens) - os << "("; - - if (id) - id->print_code (os); - - os << oper (); - - if (in_parens) - os << ")"; + tw.visit_postfix_expression (*this); } // Unary expressions. @@ -299,38 +278,9 @@ } void -tree_unary_expression::print_code (ostream& os) +tree_unary_expression::accept (tree_walker& tw) { - print_code_indent (os); - - if (in_parens) - os << "("; - - switch (etype) - { - case tree_expression::not: - case tree_expression::uminus: - os << oper (); - if (op) - op->print_code (os); - break; - - case tree_expression::hermitian: - case tree_expression::transpose: - if (op) - op->print_code (os); - os << oper (); - break; - - default: - os << oper (); - if (op) - op->print_code (os); - break; - } - - if (in_parens) - os << ")"; + tw.visit_unary_expression (*this); } // Binary expressions. @@ -363,14 +313,14 @@ case tree_expression::cmp_ne: case tree_expression::and: case tree_expression::or: - if (op1) + if (op_lhs) { - octave_value a = op1->eval (false); + octave_value a = op_lhs->eval (false); if (error_state) eval_error (); - else if (a.is_defined () && op2) + else if (a.is_defined () && op_rhs) { - octave_value b = op2->eval (false); + octave_value b = op_rhs->eval (false); if (error_state) eval_error (); else if (b.is_defined ()) @@ -391,9 +341,9 @@ case tree_expression::or_or: { bool result = false; - if (op1) + if (op_lhs) { - octave_value a = op1->eval (false); + octave_value a = op_lhs->eval (false); if (error_state) { eval_error (); @@ -424,9 +374,9 @@ } } - if (op2) + if (op_rhs) { - octave_value b = op2->eval (false); + octave_value b = op_rhs->eval (false); if (error_state) { eval_error (); @@ -560,23 +510,9 @@ } void -tree_binary_expression::print_code (ostream& os) +tree_binary_expression::accept (tree_walker& tw) { - print_code_indent (os); - - if (in_parens) - os << "("; - - if (op1) - op1->print_code (os); - - os << " " << oper () << " "; - - if (op2) - op2->print_code (os); - - if (in_parens) - os << ")"; + tw.visit_binary_expression (*this); } // Simple assignment expressions. @@ -701,33 +637,9 @@ } void -tree_simple_assignment_expression::print_code (ostream& os) +tree_simple_assignment_expression::accept (tree_walker& tw) { - print_code_indent (os); - - if (in_parens) - os << "("; - - if (! is_ans_assign ()) - { - if (lhs) - lhs->print_code (os); - - if (index) - { - os << " ("; - index->print_code (os); - os << ")"; - } - - os << " = "; - } - - if (rhs) - rhs->print_code (os); - - if (in_parens) - os << ")"; + tw.visit_simple_assignment_expression (*this); } // Colon expressions. @@ -735,22 +647,27 @@ bool tree_colon_expression::is_range_constant (void) const { - bool tmp = (op1 && op1->is_constant () - && op2 && op2->is_constant ()); + bool tmp = (op_base && op_base->is_constant () + && op_limit && op_limit->is_constant ()); - return op3 ? (tmp && op3->is_constant ()) : tmp; + return op_increment ? (tmp && op_increment->is_constant ()) : tmp; } tree_colon_expression * tree_colon_expression::chain (tree_expression *t) { tree_colon_expression *retval = 0; - if (! op1 || op3) + if (! op_base || op_increment) ::error ("invalid colon expression"); else { - op3 = op2; // Stupid syntax. - op2 = t; + // Stupid syntax: + // + // base : limit + // base : increment : limit + + op_increment = op_limit; + op_limit = t; retval = this; } @@ -762,10 +679,10 @@ { octave_value retval; - if (error_state || ! op1 || ! op2) + if (error_state || ! op_base || ! op_limit) return retval; - octave_value tmp = op1->eval (false); + octave_value tmp = op_base->eval (false); if (tmp.is_undefined ()) { @@ -782,7 +699,7 @@ return retval; } - tmp = op2->eval (false); + tmp = op_limit->eval (false); if (tmp.is_undefined ()) { @@ -800,9 +717,10 @@ } double inc = 1.0; - if (op3) + + if (op_increment) { - tmp = op3->eval (false); + tmp = op_increment->eval (false); if (tmp.is_undefined ()) { @@ -840,35 +758,11 @@ } void -tree_colon_expression::print_code (ostream& os) +tree_colon_expression::accept (tree_walker& tw) { - print_code_indent (os); - - if (in_parens) - os << "("; - - if (op1) - op1->print_code (os); - - // Stupid syntax. - - if (op3) - { - os << ":"; - op3->print_code (os); - } - - if (op2) - { - os << ":"; - op2->print_code (os); - } - - if (in_parens) - os << ")"; + tw.visit_colon_expression (*this); } - /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/src/pt-exp.h +++ b/src/pt-exp.h @@ -34,6 +34,8 @@ class tree_indirect_ref; class tree_argument_list; +class tree_walker; + #include "pt-exp-base.h" // Prefix expressions. @@ -41,7 +43,8 @@ class tree_prefix_expression : public tree_expression { - public: +public: + tree_prefix_expression (int l = -1, int c = -1) : tree_expression (l, c), id (0) { } @@ -60,9 +63,13 @@ char *oper (void) const; - void print_code (ostream& os); + tree_identifier *ident (void) { return id; } + + void accept (tree_walker& tw); - private: +private: + + // Currently, a prefix expression can only apply to an identifier. tree_identifier *id; }; @@ -71,7 +78,8 @@ class tree_postfix_expression : public tree_expression { - public: +public: + tree_postfix_expression (int l = -1, int c = -1) : tree_expression (l, c), id (0) { } @@ -87,9 +95,13 @@ char *oper (void) const; - void print_code (ostream& os); + tree_identifier *ident (void) { return id; } + + void accept (tree_walker& tw); - private: +private: + + // Currently, a prefix expression can only apply to an identifier. tree_identifier *id; }; @@ -98,7 +110,8 @@ class tree_unary_expression : public tree_expression { - public: +public: + tree_unary_expression (int l = -1, int c = -1) : tree_expression (l, c), op (0) { } @@ -115,9 +128,13 @@ char *oper (void) const; - void print_code (ostream& os); + tree_expression *operand (void) { return op; } + + void accept (tree_walker& tw); - private: +private: + + // The operand for the expression. tree_expression *op; }; @@ -126,18 +143,19 @@ class tree_binary_expression : public tree_expression { - public: +public: + tree_binary_expression (int l = -1, int c = -1) - : tree_expression (l, c), op1 (0), op2 (0) { } + : tree_expression (l, c), op_lhs (0), op_rhs (0) { } tree_binary_expression (tree_expression *a, tree_expression *b, tree_expression::type t, int l = -1, int c = -1) - : tree_expression (l, c, t), op1 (a), op2 (b) { } + : tree_expression (l, c, t), op_lhs (a), op_rhs (b) { } ~tree_binary_expression (void) { - delete op1; - delete op2; + delete op_lhs; + delete op_rhs; } octave_value eval (bool print); @@ -146,11 +164,16 @@ char *oper (void) const; - void print_code (ostream& os); + tree_expression *lhs (void) { return op_lhs; } + tree_expression *rhs (void) { return op_rhs; } + + void accept (tree_walker& tw); - private: - tree_expression *op1; - tree_expression *op2; +private: + + // The operands for the expression. + tree_expression *op_lhs; + tree_expression *op_rhs; }; // Simple assignment expressions. @@ -158,19 +181,8 @@ class tree_simple_assignment_expression : public tree_expression { -private: - void init (bool plhs, bool ans_assign) - { - etype = tree_expression::assignment; - lhs_idx_expr = 0; - lhs = 0; - index = 0; - rhs = 0; - preserve = plhs; - ans_ass = ans_assign; - } +public: - public: tree_simple_assignment_expression (bool plhs = false, bool ans_assign = false, int l = -1, int c = -1) @@ -217,15 +229,48 @@ void eval_error (void); - void print_code (ostream& os); + tree_indirect_ref *left_hand_side (void) { return lhs; } + + tree_argument_list *lhs_index (void) { return index; } + + tree_expression *right_hand_side (void) { return rhs; } + + void accept (tree_walker& tw); - private: +private: + + // The left hand side of the assignment, as an index expression. If + // the assignment is constructed from an index expression, the index + // expression is split into the its components in the constructor. tree_index_expression *lhs_idx_expr; + + // The indirect reference (id or structure reference) on the left + // hand side of the assignemnt. tree_indirect_ref *lhs; + + // The index of the left hand side of the assignment, if any. tree_argument_list *index; + + // The right hand side of the assignment. tree_expression *rhs; + + // True if we should not delete the lhs. bool preserve; + + // True if this is an assignment to the built-in variable ans. bool ans_ass; + + void init (bool plhs, bool ans_assign) + { + etype = tree_expression::assignment; + lhs_idx_expr = 0; + lhs = 0; + index = 0; + rhs = 0; + preserve = plhs; + ans_ass = ans_assign; + } + }; // Colon expressions. @@ -233,21 +278,22 @@ class tree_colon_expression : public tree_expression { - public: +public: + tree_colon_expression (int l = -1, int c = -1) : tree_expression (l, c, tree_expression::colon), - op1(0), op2 (0), op3 (0) { } + op_base (0), op_limit (0), op_increment (0) { } tree_colon_expression (tree_expression *a, tree_expression *b, int l = -1, int c = -1) : tree_expression (l, c, tree_expression::colon), - op1 (a), op2 (b), op3 (0) { } + op_base (a), op_limit (b), op_increment (0) { } ~tree_colon_expression (void) { - delete op1; - delete op2; - delete op3; + delete op_base; + delete op_limit; + delete op_increment; } bool is_range_constant (void) const; @@ -258,12 +304,18 @@ void eval_error (const char *s); - void print_code (ostream& os); + tree_expression *base (void) { return op_base; } + tree_expression *limit (void) { return op_limit; } + tree_expression *increment (void) { return op_increment; } + + void accept (tree_walker& tw); - private: - tree_expression *op1; - tree_expression *op2; - tree_expression *op3; +private: + + // The components of the expression. + tree_expression *op_base; + tree_expression *op_limit; + tree_expression *op_increment; }; #endif
--- a/src/pt-fcn.cc +++ b/src/pt-fcn.cc @@ -41,6 +41,8 @@ #include "pt-exp.h" #include "pt-fcn.h" #include "pt-misc.h" +#include "pt-pr-code.h" +#include "pt-walk.h" #include "unwind-prot.h" #include "user-prefs.h" #include "utils.h" @@ -396,87 +398,25 @@ } void -tree_function::print_code (ostream& os) -{ - print_code_reset (); - - print_code_function_header (os); - - if (cmd_list) - { - increment_indent_level (); - cmd_list->print_code (os); - decrement_indent_level (); - } - - print_code_function_trailer (os); -} - -void tree_function::print_code_function_header (void) { - print_code_function_header (octave_stdout); -} - -void -tree_function::print_code_function_header (ostream& os) -{ - print_code_indent (os); - - os << "function "; - - if (ret_list) - { - int len = ret_list->length (); - - if (len > 1) - os << "["; - - ret_list->print_code (os); - - if (len > 1) - os << "]"; + tree_print_code tpc (octave_stdout); - os << " = "; - } - - os << (fcn_name.empty () ? string ("(empty)") : fcn_name) << " "; - - if (param_list) - { - int len = param_list->length (); - if (len > 0) - os << "("; - - param_list->print_code (os); - - if (len > 0) - { - os << ")"; - print_code_new_line (os); - } - } - else - { - os << "()"; - print_code_new_line (os); - } + tpc.visit_function_header (*this); } void tree_function::print_code_function_trailer (void) { - print_code_function_trailer (octave_stdout); + tree_print_code tpc (octave_stdout); + + tpc.visit_function_trailer (*this); } void -tree_function::print_code_function_trailer (ostream& os) +tree_function::accept (tree_walker& tw) { - print_code_indent (os); - - os << "endfunction"; - - print_code_new_line (os); + tw.visit_function (*this); } DEFUN (va_arg, args, ,
--- a/src/pt-fcn.h +++ b/src/pt-fcn.h @@ -37,6 +37,8 @@ class tree_statement_list; class tree_va_return_list; +class tree_walker; + #include "oct-obj.h" #include "symtab.h" #include "pt-fvc.h" @@ -46,27 +48,8 @@ class tree_function : public tree_fvc { -private: - void install_nargin_and_nargout (void); - - void bind_nargin_and_nargout (int nargin, int nargout); +public: - void init (void) - { - call_depth = 0; - param_list = 0; - ret_list = 0; - sym_tab = 0; - cmd_list = 0; - t_parsed = 0; - system_fcn_file = 0; - num_named_args = 0; - num_args_passed = 0; - curr_va_arg_number = 0; - vr_list = 0; - } - -public: tree_function (int l = -1, int c = -1) : tree_fvc (l, c) { init (); } @@ -126,31 +109,89 @@ void traceback_error (void); - void print_code (ostream& os); + tree_parameter_list *parameter_list (void) { return param_list; } + + tree_parameter_list *return_list (void) { return ret_list; } + + tree_statement_list *body (void) { return cmd_list; } + + void accept (tree_walker& tw); private: - int call_depth; + + // List of arguments for this function. These are local variables. tree_parameter_list *param_list; + + // List of parameters we return. These are also local variables in + // this function. tree_parameter_list *ret_list; + + // The list of commands that make up the body of this function. + tree_statement_list *cmd_list; + + // The local symbol table for this function. symbol_table *sym_tab; - tree_statement_list *cmd_list; + + // Used to keep track of recursion depth. + int call_depth; + + // The name of the file we parsed string file_name; + + // The name of the function. string fcn_name; + + // The time the file was parsed. time_t t_parsed; + + // True if this function came from a file that is considered to be a + // system function. This affects whether we check the time stamp + // on the file to see if it has changed. bool system_fcn_file; + + // The number of arguments that have names. int num_named_args; + + // The values that were passed as arguments. octave_value_list args_passed; + + // The number of arguments passed in. int num_args_passed; + + // Used to keep track of the current offset into the list of va_args. int curr_va_arg_number; + + // The list of return values when an unspecified number can be + // returned. tree_va_return_list *vr_list; + + // The symbol record for nargin in the local symbol table. symbol_record *nargin_sr; + + // The symbol record for nargout in the local symbol table. symbol_record *nargout_sr; void print_code_function_header (void); - void print_code_function_header (ostream& os); + void print_code_function_trailer (void); + + void install_nargin_and_nargout (void); + + void bind_nargin_and_nargout (int nargin, int nargout); - void print_code_function_trailer (void); - void print_code_function_trailer (ostream& os); + void init (void) + { + call_depth = 0; + param_list = 0; + ret_list = 0; + sym_tab = 0; + cmd_list = 0; + t_parsed = 0; + system_fcn_file = 0; + num_named_args = 0; + num_args_passed = 0; + curr_va_arg_number = 0; + vr_list = 0; + } }; #endif
--- a/src/pt-fvc.cc +++ b/src/pt-fvc.cc @@ -41,6 +41,7 @@ #include "symtab.h" #include "pt-const.h" #include "pt-fvc.h" +#include "pt-walk.h" #include "user-prefs.h" #include "utils.h" @@ -443,18 +444,9 @@ } void -tree_identifier::print_code (ostream& os) +tree_identifier::accept (tree_walker& tw) { - print_code_indent (os); - - if (in_parens) - os << "("; - - string nm = name (); - os << (nm.empty () ? string ("(empty)") : nm); - - if (in_parens) - os << ")"; + tw.visit_identifier (*this); } // Indirect references to values (structure elements). @@ -591,21 +583,9 @@ } void -tree_indirect_ref::print_code (ostream& os) +tree_indirect_ref::accept (tree_walker& tw) { - print_code_indent (os); - - if (in_parens) - os << "("; - - string nm = id ? id->name () : string ("(null)"); - os << (nm.empty () ? string ("(empty)") : nm); - - for (Pix p = refs.first (); p != 0; refs.next (p)) - os << "." << refs (p); - - if (in_parens) - os << ")"; + tw.visit_indirect_ref (*this); } // Builtin functions. @@ -818,9 +798,9 @@ } void -tree_builtin::print_code (ostream& os) +tree_builtin::accept (tree_walker& tw) { - os << my_name << " can't be printed because it is a builtin function\n"; + tw.visit_builtin (*this); } /*
--- a/src/pt-fvc.h +++ b/src/pt-fvc.h @@ -34,6 +34,8 @@ class symbol_record; class tree_function; +class tree_walker; + #include "mappers.h" #include "pt-fvc-base.h" #include "variables.h" @@ -46,6 +48,7 @@ friend class tree_index_expression; public: + tree_identifier (int l = -1, int c = -1) : tree_fvc (l, c), sym (0), maybe_do_ans_assign (false) { } @@ -90,10 +93,15 @@ void eval_undefined_error (void); - void print_code (ostream& os); + void accept (tree_walker& tw); private: + + // The symbol record that this identifier references. symbol_record *sym; + + // True if we should consider assigning the result of evaluating + // this identifier to the built-in variable ans. bool maybe_do_ans_assign; }; @@ -103,6 +111,7 @@ tree_indirect_ref : public tree_fvc { public: + tree_indirect_ref (int l = -1, int c = -1) : tree_fvc (l, c), id (0), preserve_ident (false) { } @@ -135,13 +144,24 @@ octave_value eval (bool print); - octave_value_list eval (bool print, int nargout, const octave_value_list& args); + octave_value_list eval (bool print, int nargout, + const octave_value_list& args); - void print_code (ostream& os); + SLList<string> references (void) { return refs; } + + void accept (tree_walker& tw); private: + + // The identifier for this structure reference. For example, in + // a.b, a is the id. tree_identifier *id; + + // The list of sub-element names. For example, in a.b.c, refs + // contains the strings b and c. SLList<string> refs; + + // True if we should not delete the identifier. bool preserve_ident; }; @@ -151,6 +171,7 @@ tree_builtin : public tree_fvc { public: + tree_builtin (const string& nm = string ()); tree_builtin (const builtin_mapper_function& m_fcn, @@ -172,12 +193,20 @@ string name (void) const { return my_name; } - void print_code (ostream& os); + void accept (tree_walker& tw); private: + + // True if this is a mapper function. bool is_mapper; + + // A structure describing the mapper function. builtin_mapper_function mapper_fcn; + + // The actual function, if it is not a mapper. Octave_builtin_fcn fcn; + + // The name of this function. string my_name; };
--- a/src/pt-mat.cc +++ b/src/pt-mat.cc @@ -39,6 +39,7 @@ #include "pt-mat.h" #include "pt-misc.h" #include "pt-mvr.h" +#include "pt-walk.h" #include "user-prefs.h" // General matrices. This list type is much more work to handle than @@ -393,24 +394,9 @@ } void -tree_matrix_row::print_code (ostream& os) +tree_matrix_row::accept (tree_walker& tw) { - Pix p = first (); - - while (p) - { - tree_expression *elt = this->operator () (p); - - next (p); - - if (elt) - { - elt->print_code (os); - - if (p) - os << ", "; - } - } + tw.visit_matrix_row (*this); } bool @@ -534,36 +520,9 @@ } void -tree_matrix::print_code (ostream& os) +tree_matrix::accept (tree_walker& tw) { - print_code_indent (os); - - if (in_parens) - os << "("; - - os << "["; - - Pix p = first (); - - while (p) - { - tree_matrix_row *elt = this->operator () (p); - - next (p); - - if (elt) - { - elt->print_code (os); - - if (p) - os << "; "; - } - } - - os << "]"; - - if (in_parens) - os << ")"; + tw.visit_matrix (*this); } /*
--- a/src/pt-mat.h +++ b/src/pt-mat.h @@ -32,6 +32,8 @@ class octave_value; class tree_return_list; +class tree_walker; + #include <SLList.h> #include "pt-exp.h" @@ -56,7 +58,7 @@ tree_return_list *to_return_list (void); - void print_code (ostream& os); + void accept (tree_walker& tw); }; class @@ -77,7 +79,7 @@ octave_value eval (bool print); - void print_code (ostream& os); + void accept (tree_walker& tw); }; #endif
--- a/src/pt-misc.cc +++ b/src/pt-misc.cc @@ -46,6 +46,8 @@ #include "pt-fvc.h" #include "pt-misc.h" #include "pt-mvr.h" +#include "pt-walk.h" +#include "pt-pr-code.h" #include "user-prefs.h" // Nonzero means we're breaking out of a loop or function body. @@ -61,22 +63,20 @@ tree_statement::~tree_statement (void) { - delete command; - delete expression; + delete cmd; + delete expr; } int tree_statement::line (void) { - return command - ? command->line () : (expression ? expression->line () : -1); + return cmd ? cmd->line () : (expr ? expr->line () : -1); } int tree_statement::column (void) { - return command - ? command->column () : (expression ? expression->column () : -1); + return cmd ? cmd->column () : (expr ? expr->column () : -1); } void @@ -84,30 +84,17 @@ { if (in_function_body && (user_pref.echo_executing_commands & ECHO_FUNCTIONS)) - print_code (octave_stdout); + { + tree_print_code tpc (octave_stdout); + + accept (tpc); + } } void -tree_statement::print_code (ostream& os) +tree_statement::accept (tree_walker& tw) { - if (command) - { - command->print_code (os); - - if (! print_flag) - os << ";"; - - command->print_code_new_line (os); - } - else if (expression) - { - expression->print_code (os); - - if (! print_flag) - os << ";"; - - expression->print_code_new_line (os); - } + tw.visit_statement (*this); } octave_value @@ -128,8 +115,8 @@ else pf = elt->print_flag; - tree_command *cmd = elt->command; - tree_expression *expr = elt->expression; + tree_command *cmd = elt->command (); + tree_expression *expr = elt->expression (); if (cmd || expr) { @@ -176,8 +163,8 @@ else pf = elt->print_flag; - tree_command *cmd = elt->command; - tree_expression *expr = elt->expression; + tree_command *cmd = elt->command (); + tree_expression *expr = elt->expression (); if (cmd || expr) { @@ -218,15 +205,9 @@ } void -tree_statement_list::print_code (ostream& os) +tree_statement_list::accept (tree_walker& tw) { - for (Pix p = first (); p != 0; next (p)) - { - tree_statement *elt = this->operator () (p); - - if (elt) - elt->print_code (os); - } + tw.visit_statement_list (*this); } octave_value_list @@ -292,24 +273,9 @@ } void -tree_argument_list::print_code (ostream& os) +tree_argument_list::accept (tree_walker& tw) { - Pix p = first (); - - while (p) - { - tree_expression *elt = this->operator () (p); - - next (p); - - if (elt) - { - elt->print_code (os); - - if (p) - os << ", "; - } - } + tw.visit_argument_list (*this); } // Parameter lists. @@ -433,24 +399,9 @@ } void -tree_parameter_list::print_code (ostream& os) +tree_parameter_list::accept (tree_walker& tw) { - Pix p = first (); - - while (p) - { - tree_identifier *elt = this->operator () (p); - - next (p); - - if (elt) - { - elt->print_code (os); - - if (p) - os << ", "; - } - } + tw.visit_parameter_list (*this); } // Return lists. @@ -465,49 +416,35 @@ } void -tree_return_list::print_code (ostream& os) +tree_return_list::accept (tree_walker& tw) { - Pix p = first (); - - while (p) - { - tree_index_expression *elt = this->operator () (p); - - next (p); - - if (elt) - { - elt->print_code (os); - - if (p) - os << ", "; - } - } + tw.visit_return_list (*this); } // Global. tree_global::~tree_global (void) { - delete ident; - delete assign_expr; + delete id; + delete ass_expr; } void tree_global::eval (void) { - if (ident) + if (id) { - ident->link_to_global (); + id->link_to_global (); } - else if (assign_expr) + else if (ass_expr) { - tree_identifier *id = 0; - if (assign_expr->left_hand_side_is_identifier_only () - && (id = assign_expr->left_hand_side_id ())) + tree_identifier *idnt = 0; + + if (ass_expr->left_hand_side_is_identifier_only () + && (idnt = ass_expr->left_hand_side_id ())) { - id->link_to_global (); - assign_expr->eval (false); + idnt->link_to_global (); + ass_expr->eval (false); } else error ("global: unable to make individual structure elements global"); @@ -515,13 +452,9 @@ } void -tree_global::print_code (ostream& os) +tree_global::accept (tree_walker& tw) { - if (ident) - ident->print_code (os); - - if (assign_expr) - assign_expr->print_code (os); + tw.visit_global (*this); } // Global initializer lists. @@ -537,24 +470,9 @@ } void -tree_global_init_list::print_code (ostream& os) +tree_global_init_list::accept (tree_walker& tw) { - Pix p = first (); - - while (p) - { - tree_global *elt = this->operator () (p); - - next (p); - - if (elt) - { - elt->print_code (os); - - if (p) - os << ", "; - } - } + tw.visit_global_init_list (*this); } // If. @@ -580,21 +498,9 @@ } void -tree_if_clause::print_code (ostream& os) +tree_if_clause::accept (tree_walker& tw) { - if (expr) - expr->print_code (os); - - print_code_new_line (os); - - increment_indent_level (); - - if (list) - { - list->print_code (os); - - decrement_indent_level (); - } + tw.visit_if_clause (*this); } // List of if commands. @@ -612,34 +518,9 @@ } void -tree_if_command_list::print_code (ostream& os) +tree_if_command_list::accept (tree_walker& tw) { - Pix p = first (); - - bool first_elt = true; - - while (p) - { - tree_if_clause *elt = this->operator () (p); - - if (elt) - { - if (! first_elt) - { - print_code_indent (os); - - if (elt->is_else_clause ()) - os << "else"; - else - os << "elseif "; - } - - elt->print_code (os); - } - - first_elt = false; - next (p); - } + tw.visit_if_command_list (*this); } /*
--- a/src/pt-misc.h +++ b/src/pt-misc.h @@ -48,26 +48,30 @@ class tree_global; class tree_global_init_list; +class tree_walker; + #include <SLList.h> #include "pt-base.h" -// A list of expressions and commands to be executed. +// A statement is either a command to execute or an expression to +// evaluate. class -tree_statement : public tree_print_code +tree_statement { friend class tree_statement_list; public: + tree_statement (void) - : tree_print_code (), command (0), expression (0), print_flag (true) { } + : cmd (0), expr (0), print_flag (true) { } tree_statement (tree_command *c) - : tree_print_code (), command (c), expression (0), print_flag (true) { } + : cmd (c), expr (0), print_flag (true) { } tree_statement (tree_expression *e) - : tree_print_code (), command (0), expression (e), print_flag (true) { } + : cmd (0), expr (e), print_flag (true) { } ~tree_statement (void); @@ -75,35 +79,50 @@ { print_flag = print; } bool is_command (void) - { return command != 0; } + { return cmd != 0; } bool is_expression (void) - { return expression != 0; } + { return expr != 0; } int line (void); int column (void); void maybe_echo_code (bool); - void print_code (ostream& os); + bool print_result (void) { return print_flag; } + + tree_command *command (void) { return cmd; } + + tree_expression *expression (void) { return expr; } + + void accept (tree_walker& tw); private: - tree_command *command; // Command to execute. - tree_expression *expression; // Command to execute. - bool print_flag; // Print result of eval for this command? + + // 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_print_code +tree_statement_list : public SLList<tree_statement *> { public: + tree_statement_list (void) - : SLList<tree_statement *> (), tree_print_code (), function_body (false) - { } + : SLList<tree_statement *> (), function_body (false) { } tree_statement_list (tree_statement *s) - : SLList<tree_statement *> (), tree_print_code (), function_body (false) - { append (s); } + : SLList<tree_statement *> (), function_body (false) { append (s); } ~tree_statement_list (void) { @@ -120,9 +139,11 @@ octave_value_list eval (bool print, int nargout); - void print_code (ostream& os); + void accept (tree_walker& tw); private: + + // Does this list of statements make up the body of a function? bool function_body; }; @@ -130,15 +151,15 @@ // arguments in a function call or index expression. class -tree_argument_list : public SLList<tree_expression *>, public tree_print_code +tree_argument_list : public SLList<tree_expression *> { public: + tree_argument_list (void) - : SLList<tree_expression *> (), tree_print_code () { } + : SLList<tree_expression *> () { } tree_argument_list (tree_expression *t) - : SLList<tree_expression *> (), tree_print_code () - { append (t); } + : SLList<tree_expression *> () { append (t); } ~tree_argument_list (void) { @@ -151,7 +172,7 @@ octave_value_list convert_to_const_vector (void); - void print_code (ostream& os); + void accept (tree_walker& tw); }; // Parameter lists. Used to hold the list of input and output @@ -159,22 +180,18 @@ // only. class -tree_parameter_list : public SLList<tree_identifier *>, public tree_print_code +tree_parameter_list : public SLList<tree_identifier *> { public: + tree_parameter_list (void) - : SLList<tree_identifier *> (), tree_print_code (), - marked_for_varargs (0) { } + : SLList<tree_identifier *> (), marked_for_varargs (0) { } tree_parameter_list (tree_identifier *t) - : SLList<tree_identifier *> (), tree_print_code (), - marked_for_varargs (0) - { append (t); } + : SLList<tree_identifier *> (), marked_for_varargs (0) { append (t); } ~tree_parameter_list (void); -// char *name (void) const; - void mark_as_formal_parameters (void); void mark_varargs (void) @@ -197,9 +214,10 @@ octave_value_list convert_to_const_vector (tree_va_return_list *vr_list); - void print_code (ostream& os); + void accept (tree_walker& tw); private: + int marked_for_varargs; }; @@ -207,26 +225,26 @@ // assignment expressions. class -tree_return_list : public SLList<tree_index_expression *>, - public tree_print_code +tree_return_list : public SLList<tree_index_expression *> { public: + tree_return_list (void) - : SLList<tree_index_expression *> (), tree_print_code () { } + : SLList<tree_index_expression *> () { } tree_return_list (tree_index_expression *t) - : SLList<tree_index_expression *> (), tree_print_code () - { append (t); } + : SLList<tree_index_expression *> () { append (t); } ~tree_return_list (void); - void print_code (ostream& os); + void accept (tree_walker& tw); }; class tree_va_return_list : public SLList<octave_value> { public: + tree_va_return_list (void) : SLList<octave_value> () { } ~tree_va_return_list (void) { } @@ -235,38 +253,51 @@ // List of expressions that make up a global statement. class -tree_global : public tree_print_code +tree_global { public: - tree_global (void) : tree_print_code (), ident (0), assign_expr (0) { } - tree_global (tree_identifier *id) - : tree_print_code (), ident (id), assign_expr (0) { } + tree_global (void) + : id (0), ass_expr (0) { } + + tree_global (tree_identifier *i) + : id (i), ass_expr (0) { } tree_global (tree_simple_assignment_expression *ass) - : tree_print_code (), ident (0), assign_expr (ass) { } + : id (0), ass_expr (ass) { } ~tree_global (void); void eval (void); - void print_code (ostream& os); + tree_identifier *ident (void) { return id; } + + tree_simple_assignment_expression *assign_expr (void) { return ass_expr; } + + void accept (tree_walker& tw); private: - tree_identifier *ident; - tree_simple_assignment_expression *assign_expr; + + // Only one of id or ass_expr can be valid at once. + + // An identifier to make global. + tree_identifier *id; + + // An assignemnt expression. Valid only if the left hand side of + // the assignment is a simple identifier. + tree_simple_assignment_expression *ass_expr; }; class -tree_global_init_list : public SLList<tree_global *>, public tree_print_code +tree_global_init_list : public SLList<tree_global *> { public: + tree_global_init_list (void) - : SLList<tree_global *> (), tree_print_code () { } + : SLList<tree_global *> () { } tree_global_init_list (tree_global *t) - : SLList<tree_global *> (), tree_print_code () - { append (t); } + : SLList<tree_global *> () { append (t); } ~tree_global_init_list (void) { @@ -279,20 +310,21 @@ void eval (void); - void print_code (ostream& os); + void accept (tree_walker& tw); }; class -tree_if_clause : public tree_print_code +tree_if_clause { public: - tree_if_clause (void) : tree_print_code (), expr (0), list (0) { } + + tree_if_clause (void) : expr (0), list (0) { } tree_if_clause (tree_statement_list *l) - : tree_print_code (), expr (0), list (l) { } + : expr (0), list (l) { } tree_if_clause (tree_expression *e, tree_statement_list *l) - : tree_print_code (), expr (e), list (l) { } + : expr (e), list (l) { } ~tree_if_clause (void); @@ -301,23 +333,31 @@ int eval (void); - void print_code (ostream& os); + 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_print_code +tree_if_command_list : public SLList<tree_if_clause *> { public: + tree_if_command_list (void) - : SLList<tree_if_clause *> (), tree_print_code () { } + : SLList<tree_if_clause *> () { } tree_if_command_list (tree_if_clause *t) - : SLList<tree_if_clause *> (), tree_print_code () - { append (t); } + : SLList<tree_if_clause *> () { append (t); } ~tree_if_command_list (void) { @@ -330,7 +370,7 @@ void eval (void); - void print_code (ostream& os); + void accept (tree_walker& tw); }; #endif
--- a/src/pt-mvr-base.h +++ b/src/pt-mvr-base.h @@ -38,6 +38,7 @@ tree_multi_val_ret : public tree_expression { public: + tree_multi_val_ret (int l = -1, int c = -1) : tree_expression (l, c) { } tree_multi_val_ret (int l = -1, int c = -1, tree_expression::type et)
--- a/src/pt-mvr.cc +++ b/src/pt-mvr.cc @@ -38,6 +38,7 @@ #include "pt-fvc.h" #include "pt-misc.h" #include "pt-mvr.h" +#include "pt-walk.h" #include "user-prefs.h" // But first, some extra functions used by the tree classes. @@ -71,6 +72,12 @@ return values; } +void +tree_oct_obj::accept (tree_walker& tw) +{ + tw.visit_oct_obj (*this); +} + // Index expressions. tree_index_expression::tree_index_expression @@ -239,25 +246,9 @@ } void -tree_index_expression::print_code (ostream& os) +tree_index_expression::accept (tree_walker& tw) { - print_code_indent (os); - - if (in_parens) - os << "("; - - if (id) - id->print_code (os); - - if (list) - { - os << " ("; - list->print_code (os); - os << ")"; - } - - if (in_parens) - os << ")"; + tw.visit_index_expression (*this); } // Multi-valued assignmnt expressions. @@ -375,33 +366,9 @@ } void -tree_multi_assignment_expression::print_code (ostream& os) +tree_multi_assignment_expression::accept (tree_walker& tw) { - print_code_indent (os); - - if (in_parens) - os << "("; - - if (lhs) - { - int len = lhs->length (); - - if (len > 1) - os << "["; - - lhs->print_code (os); - - if (len > 1) - os << "]"; - } - - os << " = "; - - if (rhs) - rhs->print_code (os); - - if (in_parens) - os << ")"; + tw.visit_multi_assignment_expression (*this); } /*
--- a/src/pt-mvr.h +++ b/src/pt-mvr.h @@ -37,6 +37,8 @@ class tree_indirect_ref; class tree_return_list; +class tree_walker; + #include <string> #include "pt-const.h" @@ -49,6 +51,7 @@ tree_oct_obj : public tree_multi_val_ret { public: + tree_oct_obj (int l = -1, int c = -1) : tree_multi_val_ret (l, c) { } tree_oct_obj (const octave_value_list& v, int l = -1, int c = -1) @@ -58,11 +61,13 @@ octave_value eval (bool print); - octave_value_list eval (bool print, int nargout, const octave_value_list& args); + octave_value_list eval (bool print, int nargout, + const octave_value_list& args); - void print_code (ostream&) { } + void accept (tree_walker& tw); private: + const octave_value_list values; }; @@ -72,6 +77,7 @@ tree_index_expression : public tree_multi_val_ret { public: + tree_index_expression (int l = -1, int c = -1) : tree_multi_val_ret (l, c), id (0), list (0) { } @@ -108,10 +114,12 @@ void eval_error (void); - void print_code (ostream& os); + void accept (tree_walker& tw); - private: +private: + tree_indirect_ref *id; + tree_argument_list *list; }; @@ -120,7 +128,8 @@ class tree_multi_assignment_expression : public tree_multi_val_ret { - public: +public: + tree_multi_assignment_expression (bool plhs = false, int l = -1, int c = -1) : tree_multi_val_ret (l, c, tree_expression::multi_assignment), preserve (plhs), lhs (0), rhs (0) { } @@ -143,9 +152,14 @@ void eval_error (void); - void print_code (ostream& os); + tree_return_list *left_hand_side (void) { return lhs; } + + tree_multi_val_ret *right_hand_side (void) { return rhs; } - private: + void accept (tree_walker& tw); + +private: + bool preserve; tree_return_list *lhs; tree_multi_val_ret *rhs;
--- a/src/pt-plot.cc +++ b/src/pt-plot.cc @@ -57,6 +57,7 @@ #include "pt-cmd.h" #include "pt-exp.h" #include "pt-plot.h" +#include "pt-walk.h" #include "sysdep.h" #include "user-prefs.h" #include "utils.h" @@ -321,34 +322,9 @@ } void -tree_plot_command::print_code (ostream& os) +tree_plot_command::accept (tree_walker& tw) { - print_code_indent (os); - - switch (ndim) - { - case 1: - os << "replot"; - break; - - case 2: - os << "gplot"; - break; - - case 3: - os << "gsplot"; - break; - - default: - os << "<unkown plot command>"; - break; - } - - if (range) - range->print_code (os); - - if (plot_list) - plot_list->print_code (os); + tw.visit_plot_command (*this); } plot_limits::~plot_limits (void) @@ -379,16 +355,9 @@ } void -plot_limits::print_code (ostream& os) +plot_limits::accept (tree_walker& tw) { - if (x_range) - x_range->print_code (os); - - if (y_range) - y_range->print_code (os); - - if (z_range) - z_range->print_code (os); + tw.visit_plot_limits (*this); } plot_range::~plot_range (void) @@ -438,19 +407,9 @@ } void -plot_range::print_code (ostream& os) +plot_range::accept (tree_walker& tw) { - os << " ["; - - if (lower) - lower->print_code (os); - - os << ":"; - - if (upper) - upper->print_code (os); - - os << "]"; + tw.visit_plot_range (*this); } subplot_using::~subplot_using (void) @@ -461,14 +420,14 @@ int subplot_using::eval (int ndim, int n_max) { - if ((ndim == 2 && qualifier_count > 4) - || (ndim == 3 && qualifier_count > 3)) + if ((ndim == 2 && qual_count > 4) + || (ndim == 3 && qual_count > 3)) return -1; - if (qualifier_count > 0) - val.resize (qualifier_count); + if (qual_count > 0) + val.resize (qual_count); - for (int i = 0; i < qualifier_count; i++) + for (int i = 0; i < qual_count; i++) { if (x[i]) { @@ -535,7 +494,7 @@ if (status < 0) return -1; - for (int i = 0; i < qualifier_count; i++) + for (int i = 0; i < qual_count; i++) { if (i == 0) plot_buf << " " << GNUPLOT_COMMAND_USING << " "; @@ -549,57 +508,27 @@ } void -subplot_using::print_code (ostream& os) -{ - os << " using "; - for (int i = 0; i < qualifier_count; i++) - { - if (i > 0) - os << ":"; - - if (x[i]) - x[i]->print_code (os); - } -} - -subplot_style::subplot_style (const string& s) +subplot_using::accept (tree_walker& tw) { - style = s; - linetype = 0; - pointtype = 0; -} - -subplot_style::subplot_style (const string& s, tree_expression *lt) -{ - style = s; - linetype = lt; - pointtype = 0; -} - -subplot_style::subplot_style (const string& s, tree_expression *lt, - tree_expression *pt) -{ - style = s; - linetype = lt; - pointtype = pt; + tw.visit_subplot_using (*this); } subplot_style::~subplot_style (void) { - delete linetype; - delete pointtype; + delete sp_linetype; + delete sp_pointtype; } int subplot_style::print (ostrstream& plot_buf) { - if (! style.empty ()) + if (! sp_style.empty ()) { - plot_buf << " " << GNUPLOT_COMMAND_WITH << " " << style; + plot_buf << " " << GNUPLOT_COMMAND_WITH << " " << sp_style; - if (linetype) + if (sp_linetype) { - octave_value tmp = linetype->eval (false); + octave_value tmp = sp_linetype->eval (false); if (! error_state && tmp.is_defined ()) { double val = tmp.double_value (); @@ -618,9 +547,9 @@ } } - if (pointtype) + if (sp_pointtype) { - octave_value tmp = pointtype->eval (false); + octave_value tmp = sp_pointtype->eval (false); if (! error_state && tmp.is_defined ()) { double val = tmp.double_value (); @@ -648,34 +577,22 @@ int subplot_style::errorbars (void) { - return (almost_match ("errorbars", style, 1, 0) - || almost_match ("boxerrorbars", style, 5, 0)); + return (almost_match ("errorbars", sp_style, 1, 0) + || almost_match ("boxerrorbars", sp_style, 5, 0)); } void -subplot_style::print_code (ostream& os) +subplot_style::accept (tree_walker& tw) { - os << " with " << style; - - if (linetype) - { - os << " "; - linetype->print_code (os); - } - - if (pointtype) - { - os << " "; - pointtype->print_code (os); - } + tw.visit_subplot_style (*this); } subplot::~subplot (void) { - delete plot_data; - delete using_clause; - delete title_clause; - delete style_clause; + delete sp_plot_data; + delete sp_using_clause; + delete sp_title_clause; + delete sp_style_clause; } octave_value @@ -683,9 +600,9 @@ { octave_value retval; - if (using_clause) + if (sp_using_clause) { - ColumnVector val = using_clause->values (ndim); + ColumnVector val = sp_using_clause->values (ndim); octave_value_list args; args(1) = val; @@ -702,7 +619,7 @@ retval = data; } - if (ndim == 2 && style_clause && style_clause->errorbars ()) + if (ndim == 2 && sp_style_clause && sp_style_clause->errorbars ()) { int nc = retval.columns (); @@ -720,9 +637,9 @@ int subplot::handle_plot_data (int ndim, ostrstream& plot_buf) { - if (plot_data) + if (sp_plot_data) { - octave_value data = plot_data->eval (false); + octave_value data = sp_plot_data->eval (false); if (! error_state && data.is_defined ()) { @@ -754,9 +671,9 @@ plot_buf << " " << data.string_value (); } - if (using_clause) + if (sp_using_clause) { - int status = using_clause->print (ndim, n_max, plot_buf); + int status = sp_using_clause->print (ndim, n_max, plot_buf); if (status < 0) return -1; @@ -812,9 +729,9 @@ if (status < 0) return -1; - if (title_clause) + if (sp_title_clause) { - octave_value tmp = title_clause->eval (false); + octave_value tmp = sp_title_clause->eval (false); if (! error_state && tmp.is_string ()) plot_buf << " " << GNUPLOT_COMMAND_TITLE << " " << '"' << tmp.string_value () << '"'; @@ -829,9 +746,9 @@ plot_buf << " " << GNUPLOT_COMMAND_TITLE << " " << '"' << "line " << plot_line_count << '"'; - if (style_clause) + if (sp_style_clause) { - int status = style_clause->print (plot_buf); + int status = sp_style_clause->print (plot_buf); if (status < 0) return -1; } @@ -840,22 +757,9 @@ } void -subplot::print_code (ostream& os) +subplot::accept (tree_walker& tw) { - if (plot_data) - { - os << " "; - plot_data->print_code (os); - } - - if (using_clause) - using_clause->print_code (os); - - if (title_clause) - title_clause->print_code (os); - - if (style_clause) - style_clause->print_code (os); + tw.visit_subplot (*this); } subplot_list::~subplot_list (void) @@ -891,24 +795,9 @@ } void -subplot_list::print_code (ostream& os) +subplot_list::accept (tree_walker& tw) { - Pix p = first (); - - while (p) - { - subplot *elt = this->operator () (p); - - next (p); - - if (elt) - { - elt->print_code (os); - - if (p) - os << ","; - } - } + tw.visit_subplot_list (*this); } string
--- a/src/pt-plot.h +++ b/src/pt-plot.h @@ -39,6 +39,8 @@ class subplot; class subplot_list; +class tree_walker; + #include <string> #include <SLList.h> @@ -53,6 +55,7 @@ tree_plot_command : public tree_command { public: + tree_plot_command (subplot_list *plt = 0, plot_limits *rng = 0, int nd = 0) : tree_command (), ndim (nd), range (rng), plot_list (plt) { } @@ -60,69 +63,91 @@ void eval (void); - void print_code (ostream& os); + int num_dimensions (void) { return ndim; } + + plot_limits *limits (void) { return range; } + + subplot_list *subplots (void) { return plot_list; } + + void accept (tree_walker& tw); private: + + // The number of dimensions. 1 indicates a replot command. int ndim; + + // The data ranges for the plot. plot_limits *range; + + // The list of plots for this plot command. For example, the + // command "plot sin(x), cos(x)" has two subplot commands. subplot_list *plot_list; }; class -plot_limits : public tree_print_code +plot_limits { public: + plot_limits (plot_range *xlim = 0, plot_range *ylim = 0, plot_range *zlim = 0) - : tree_print_code (), x_range (xlim), y_range (ylim), z_range (zlim) { } + : x_range (xlim), y_range (ylim), z_range (zlim) { } ~plot_limits (void); void print (int ndim, ostrstream& plot_buf); - void print_code (ostream& os); + plot_range *x_limits (void) { return x_range; } + plot_range *y_limits (void) { return y_range; } + plot_range *z_limits (void) { return z_range; } + + void accept (tree_walker& tw); private: + + // Specified limits of the x, y, and z axes we should display for + // this plot. plot_range *x_range; plot_range *y_range; plot_range *z_range; }; class -plot_range : public tree_print_code +plot_range { public: + plot_range (tree_expression *l = 0, tree_expression *u = 0) - : tree_print_code (), lower (l), upper (u) { } + : lower (l), upper (u) { } ~plot_range (void); void print (ostrstream& plot_buf); - void print_code (ostream& os); + tree_expression *lower_bound (void) { return lower; } + + tree_expression *upper_bound (void) { return upper; } + + void accept (tree_walker& tw); private: + + // A range can specify a lower or upper bound or both. If neither + // is specified, the range to display is determined from the data. tree_expression *lower; tree_expression *upper; }; class -subplot_using : public tree_print_code +subplot_using { public: - subplot_using (void) - { - qualifier_count = 0; - x[0] = x[1] = x[2] = x[3] = 0; - scanf_fmt = 0; - } - subplot_using (tree_expression *fmt) : val (4, -1) - { - qualifier_count = 0; - x[0] = x[1] = x[2] = x[3] = 0; - scanf_fmt = fmt; - } + subplot_using (tree_expression *fmt = 0) + : qual_count (0), scanf_fmt (fmt), val (4, -1) + { + x[0] = x[1] = x[2] = x[3] = 0; + } ~subplot_using (void); @@ -134,10 +159,10 @@ subplot_using *add_qualifier (tree_expression *t) { - if (qualifier_count < 4) - x[qualifier_count] = t; + if (qual_count < 4) + x[qual_count] = t; - qualifier_count++; + qual_count++; return this; } @@ -148,25 +173,40 @@ int print (int ndim, int n_max, ostrstream& plot_buf); - void print_code (ostream& os); + int qualifier_count (void) { return qual_count; } + + tree_expression **qualifiers (void) { return x; } + + tree_expression *scanf_format (void) { return scanf_fmt; } + + void accept (tree_walker& tw); private: - int qualifier_count; + + // The number of using qualifiers (in "using 1:2", 1 and 2 are the + // qualifiers). + int qual_count; + + // An optional scanf-style format. This is parsed and stored but + // not currently used. + tree_expression *scanf_fmt; + + // This is a cache for evaluated versions of the qualifiers stored + // in x. + ColumnVector val; + + // A vector to hold using qualifiers. tree_expression *x[4]; - tree_expression *scanf_fmt; - ColumnVector val; }; class -subplot_style : public tree_print_code +subplot_style { public: - subplot_style (void) - : tree_print_code (), style (0), linetype (0), pointtype (0) { } - subplot_style (const string& s); - subplot_style (const string& s, tree_expression *lt); - subplot_style (const string& s, tree_expression *lt, tree_expression *pt); + subplot_style (const string& s = string (), + tree_expression *lt = 0, tree_expression *pt = 0) + : sp_style (s), sp_linetype (lt), sp_pointtype (pt) { } ~subplot_style (void); @@ -174,31 +214,44 @@ int errorbars (void); - void print_code (ostream& os); + string style (void) { return sp_style; } + + tree_expression *linetype (void) { return sp_linetype; } + + tree_expression *pointtype (void) { return sp_pointtype; } + + void accept (tree_walker& tw); private: - string style; - tree_expression *linetype; - tree_expression *pointtype; + + // The style we are using: `lines', `points', etc. + string sp_style; + + // The number of the line type to use. + tree_expression *sp_linetype; + + // The number of the point type to use. + tree_expression *sp_pointtype; }; class -subplot : public tree_print_code +subplot { public: + subplot (tree_expression *data = 0) - : tree_print_code (), plot_data (data), using_clause (0), - title_clause (0), style_clause (0) { } + : sp_plot_data (data), sp_using_clause (0), sp_title_clause (0), + sp_style_clause (0) { } subplot (subplot_using *u, tree_expression *t, subplot_style *s) - : tree_print_code (), plot_data (0), using_clause (u), - title_clause (t), style_clause (s) { } + : sp_plot_data (0), sp_using_clause (u), sp_title_clause (t), + sp_style_clause (s) { } ~subplot (void); subplot *set_data (tree_expression *data) { - plot_data = data; + sp_plot_data = data; return this; } @@ -208,29 +261,47 @@ int print (int ndim, ostrstream& plot_buf); - void print_code (ostream& os); + tree_expression *plot_data (void) { return sp_plot_data; } + + subplot_using *using_clause (void) { return sp_using_clause; } + + tree_expression *title_clause (void) { return sp_title_clause; } + + subplot_style *style_clause (void) { return sp_style_clause; } + + void accept (tree_walker& tw); private: - tree_expression *plot_data; - subplot_using *using_clause; - tree_expression *title_clause; - subplot_style *style_clause; + + // The data to plot. + tree_expression *sp_plot_data; + + // The `using' option + subplot_using *sp_using_clause; + + // The `title' option + tree_expression *sp_title_clause; + + // The `style' option + subplot_style *sp_style_clause; }; class -subplot_list : public SLList<subplot *>, public tree_print_code +subplot_list : public SLList<subplot *> { public: - subplot_list (void) : SLList<subplot *> (), tree_print_code () { } - subplot_list (subplot *t) : SLList<subplot *> (), tree_print_code () - { append (t); } + subplot_list (void) + : SLList<subplot *> () { } + + subplot_list (subplot *t) + : SLList<subplot *> () { append (t); } ~subplot_list (void); int print (int ndim, ostrstream& plot_buf); - void print_code (ostream& os); + void accept (tree_walker& tw); }; extern string save_in_tmp_file (octave_value& t, int ndim = 2,