# HG changeset patch # User jwe # Date 863398444 0 # Node ID 194b50e4725bb26dcb48e275ae06112f59db8c9b # Parent 5d1b71cd39f721c2ef241a193c7e719491a8d227 [project @ 1997-05-12 00:43:54 by jwe] diff --git a/src/parse.y b/src/parse.y --- a/src/parse.y +++ b/src/parse.y @@ -141,14 +141,10 @@ // Build a prefix expression. static tree_expression *make_prefix_op - (int op, tree_identifier *op1, token *tok_val); + (int op, tree_expression *op1, token *tok_val); // Build a postfix expression. static tree_expression *make_postfix_op - (int op, tree_identifier *op1, token *tok_val); - -// Build a binary expression. -static tree_expression *make_unary_op (int op, tree_expression *op1, token *tok_val); // Build an unwind-protect command. @@ -343,7 +339,7 @@ // Nonterminals we construct. %type sep_no_nl opt_sep_no_nl sep opt_sep %type input -%type magic_colon +%type constant magic_colon %type rows rows1 %type matrix_row matrix_row1 %type expression simple_expr simple_expr1 @@ -773,17 +769,18 @@ } ; -simple_expr1 : NUM +constant : NUM { $$ = make_constant (NUM, $1); } | IMAG_NUM { $$ = make_constant (IMAG_NUM, $1); } | TEXT { $$ = make_constant (TEXT, $1); } + ; + +simple_expr1 : constant + { $$ = $1; } | '(' simple_expr ')' - { - $2->mark_in_parens (); - $$ = $2; - } + { $$ = $2->mark_in_parens (); } | word_list_cmd { $$ = $1; } | variable @@ -796,16 +793,16 @@ { $$ = new tree_constant (octave_value (Matrix ())); } | '[' ';' ']' { $$ = new tree_constant (octave_value (Matrix ())); } - | PLUS_PLUS identifier %prec UNARY + | PLUS_PLUS simple_expr %prec UNARY { $$ = make_prefix_op (PLUS_PLUS, $2, $1); } - | MINUS_MINUS identifier %prec UNARY + | MINUS_MINUS simple_expr %prec UNARY { $$ = make_prefix_op (MINUS_MINUS, $2, $1); } - | EXPR_NOT simple_expr - { $$ = make_unary_op (EXPR_NOT, $2, $1); } + | EXPR_NOT simple_expr %prec UNARY + { $$ = make_prefix_op (EXPR_NOT, $2, $1); } | '+' simple_expr %prec UNARY { $$ = $2; } | '-' simple_expr %prec UNARY - { $$ = make_unary_op ('-', $2, $1); } + { $$ = make_prefix_op ('-', $2, $1); } | variable '=' simple_expr { $$ = make_assign_op ('=', $1, $2, $3); } | variable ADD_EQ simple_expr @@ -829,18 +826,15 @@ | variable OR_EQ simple_expr { $$ = make_assign_op (OR_EQ, $1, $2, $3); } | '[' screwed_again matrix_row SCREW_TWO '=' simple_expr - { - if (! ($$ = make_multi_val_ret ($3, $6, $5))) - ABORT_PARSE; - } - | identifier PLUS_PLUS + { $$ = make_multi_val_ret ($3, $6, $5); } + | simple_expr PLUS_PLUS { $$ = make_postfix_op (PLUS_PLUS, $1, $2); } - | identifier MINUS_MINUS + | simple_expr MINUS_MINUS { $$ = make_postfix_op (MINUS_MINUS, $1, $2); } | simple_expr QUOTE - { $$ = make_unary_op (QUOTE, $1, $2); } + { $$ = make_postfix_op (QUOTE, $1, $2); } | simple_expr TRANSPOSE - { $$ = make_unary_op (TRANSPOSE, $1, $2); } + { $$ = make_postfix_op (TRANSPOSE, $1, $2); } | simple_expr POW simple_expr { $$ = make_binary_op (POW, $1, $2, $3); } | simple_expr EPOW simple_expr @@ -1521,48 +1515,6 @@ return retval; } -static tree_expression * -fold (tree_unary_expression *e) -{ - tree_expression *retval = 0; - - tree_expression *op1 = e->operand (); - - if (op1->is_constant ()) - { - octave_value tmp = e->eval (); - - if (! error_state) - { - tree_constant *tc_retval = new tree_constant (tmp); - - ostrstream buf; - - tree_print_code tpc (buf); - - e->accept (tpc); - - buf << ends; - - char *s = buf.str (); - - tc_retval->stash_original_text (s); - - delete [] s; - - delete e; - - retval = tc_retval; - } - else - delete e; - } - else - retval = e; - - return retval; -} - // Finish building a range. static tree_expression * @@ -1792,12 +1744,20 @@ // Build a prefix expression. static tree_expression * -make_prefix_op (int op, tree_identifier *op1, token *tok_val) +make_prefix_op (int op, tree_expression *op1, token *tok_val) { tree_prefix_expression::type t; switch (op) { + case EXPR_NOT: + t = tree_prefix_expression::unot; + break; + + case '-': + t = tree_prefix_expression::uminus; + break; + case PLUS_PLUS: t = tree_prefix_expression::increment; break; @@ -1814,18 +1774,26 @@ int l = tok_val->line (); int c = tok_val->column (); - return new tree_prefix_expression (op1, l, c, t); + return new tree_prefix_expression (t, op1, l, c); } // Build a postfix expression. static tree_expression * -make_postfix_op (int op, tree_identifier *op1, token *tok_val) +make_postfix_op (int op, tree_expression *op1, token *tok_val) { tree_postfix_expression::type t; switch (op) { + case QUOTE: + t = tree_postfix_expression::hermitian; + break; + + case TRANSPOSE: + t = tree_postfix_expression::transpose; + break; + case PLUS_PLUS: t = tree_postfix_expression::increment; break; @@ -1842,46 +1810,7 @@ int l = tok_val->line (); int c = tok_val->column (); - return new tree_postfix_expression (op1, l, c, t); -} - -// Build a unary expression. - -static tree_expression * -make_unary_op (int op, tree_expression *op1, token *tok_val) -{ - tree_unary_expression::type t; - - switch (op) - { - case QUOTE: - t = tree_unary_expression::hermitian; - break; - - case TRANSPOSE: - t = tree_unary_expression::transpose; - break; - - case EXPR_NOT: - t = tree_unary_expression::unot; - break; - - case '-': - t = tree_unary_expression::uminus; - break; - - default: - panic_impossible (); - break; - } - - int l = tok_val->line (); - int c = tok_val->column (); - - tree_unary_expression *e - = new tree_unary_expression (op1, l, c, t); - - return fold (e); + return new tree_postfix_expression (t, op1, l, c); } // Build an unwind-protect command. diff --git a/src/pt-const.cc b/src/pt-const.cc --- a/src/pt-const.cc +++ b/src/pt-const.cc @@ -71,7 +71,7 @@ octave_value_list tree_constant::eval (bool, int, const octave_value_list& idx) { - return (idx.length () > 0) ? index (idx) : val; + return (idx.length () > 0) ? val.do_index_op (idx) : val; } void diff --git a/src/pt-const.h b/src/pt-const.h --- a/src/pt-const.h +++ b/src/pt-const.h @@ -73,11 +73,6 @@ void operator delete (void *p, size_t size) { allocator.free (p, size); } - // Indexed assignment. - - octave_value index (const octave_value_list& idx) const - { return val.index (idx); } - // Type. It would be nice to eliminate the need for this. bool is_constant (void) const { return true; } diff --git a/src/pt-exp-base.cc b/src/pt-exp-base.cc --- a/src/pt-exp-base.cc +++ b/src/pt-exp-base.cc @@ -35,6 +35,7 @@ #include "error.h" #include "pager.h" +#include "oct-var-ref.h" #include "ov.h" #include "pt-exp-base.h" @@ -74,6 +75,13 @@ return octave_value (); } +octave_variable_reference +tree_expression::reference (void) +{ + panic ("invalid attempt to convert generic expression to lvalue"); + return octave_variable_reference (); +} + string tree_expression::original_text (void) const { diff --git a/src/pt-exp-base.h b/src/pt-exp-base.h --- a/src/pt-exp-base.h +++ b/src/pt-exp-base.h @@ -30,6 +30,7 @@ #include class octave_value; +class octave_variable_reference; #include "pt-base.h" @@ -40,18 +41,8 @@ { public: - enum type - { - unknown, - assignment, - simple_assignment, - multi_assignment, - colon, - index - }; - - tree_expression (int l = -1, int c = -1, type et = unknown) - : tree (l, c), in_parens (0), etype (et) { } + tree_expression (int l = -1, int c = -1) + : tree (l, c), in_parens (0) { } virtual ~tree_expression (void) { } @@ -81,25 +72,24 @@ 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 void mark_for_possible_ans_assign (void); virtual octave_value eval (bool print = false) = 0; + virtual octave_variable_reference reference (void); + virtual string oper (void) const { return ""; } virtual string original_text (void) const; + expression *mark_in_parens (void) { in_parens++; return this; } + protected: // Nonzero if this expression appears inside parentheses. int in_parens; - - // The type of this expression. - type etype; }; #endif diff --git a/src/pt-exp.cc b/src/pt-exp.cc --- a/src/pt-exp.cc +++ b/src/pt-exp.cc @@ -62,50 +62,46 @@ // Prefix expressions. -tree_prefix_expression::~tree_prefix_expression (void) -{ - delete id; -} - octave_value -tree_prefix_expression::eval (bool print) +tree_prefix_expression::eval (bool) { octave_value retval; if (error_state) return retval; - if (id) + if (op) { - switch (etype) + if (etype == unot || etype == uminus) { - case increment: - id->increment (); - break; - - case decrement: - id->decrement (); - break; + octave_value val = op->eval (); - default: - error ("prefix operator %d not implemented", etype); - break; - } - - - if (error_state) - eval_error (); - else - { - retval = id->eval (print); - if (error_state) + if (! error_state) { - retval = octave_value (); - if (error_state) - eval_error (); + if (etype == unot) + retval = val.not (); + else + retval = val.uminus (); } } + else if (etype == increment || etype == decrement) + { + octave_variable_reference ref = op->reference (); + + if (! error_state) + { + if (etype == increment) + ref.increment (); + else + ref.decrement (); + + retval = ref.value (); + } + } + else + error ("prefix operator %d not implemented", etype); } + return retval; } @@ -116,6 +112,14 @@ switch (etype) { + case unot: + retval = "!"; + break; + + case uminus: + retval = "-"; + break; + case increment: retval = "++"; break; @@ -147,45 +151,46 @@ // Postfix expressions. -tree_postfix_expression::~tree_postfix_expression (void) -{ - delete id; -} - octave_value -tree_postfix_expression::eval (bool print) +tree_postfix_expression::eval (bool) { octave_value retval; if (error_state) return retval; - if (id) + if (op) { - retval = id->eval (print); - - switch (etype) + if (etype == transpose || etype == hermitian) { - case increment: - id->increment (); - break; + octave_value val = op->eval (); - case decrement: - id->decrement (); - break; - - default: - error ("postfix operator %d not implemented", etype); - break; + if (! error_state) + { + if (etype == transpose) + retval = val.transpose (); + else + retval = val.hermitian (); + } } - - if (error_state) + else if (etype == increment || etype == decrement) { - retval = octave_value (); - if (error_state) - eval_error (); + octave_variable_reference ref = op->reference (); + + if (! error_state) + { + retval = ref.value (); + + if (etype == increment) + ref.increment (); + else + ref.decrement (); + } } + else + error ("postfix operator %d not implemented", etype); } + return retval; } @@ -196,6 +201,14 @@ switch (etype) { + case transpose: + retval = ".'"; + break; + + case hermitian: + retval = "'"; + break; + case increment: retval = "++"; break; @@ -225,102 +238,6 @@ tw.visit_postfix_expression (*this); } -// Unary expressions. - -octave_value -tree_unary_expression::eval (bool /* print */) -{ - octave_value retval; - - if (error_state) - return retval; - - if (op) - { - octave_value u = op->eval (); - - if (error_state) - eval_error (); - else if (u.is_defined ()) - { - switch (etype) - { - case unot: - retval = u.not (); - break; - - case uminus: - retval = u.uminus (); - break; - - case transpose: - retval = u.transpose (); - break; - - case hermitian: - retval = u.hermitian (); - break; - - default: - ::error ("unary operator %d not implemented", etype); - break; - } - - if (error_state) - { - retval = octave_value (); - eval_error (); - } - } - } - - return retval; -} - -string -tree_unary_expression::oper (void) const -{ - string retval = ""; - - switch (etype) - { - case unot: - retval = "!"; - break; - - case uminus: - retval = "-"; - break; - - case transpose: - retval = ".'"; - break; - - case hermitian: - retval = "'"; - break; - - default: - break; - } - - return retval; -} - -void -tree_unary_expression::eval_error (void) -{ - if (error_state > 0) - ::error ("evaluating unary operator `%s' near line %d, column %d", - oper () . c_str (), line (), column ()); -} - -void -tree_unary_expression::accept (tree_walker& tw) -{ - tw.visit_unary_expression (*this); -} - // Binary expressions. octave_value diff --git a/src/pt-exp.h b/src/pt-exp.h --- a/src/pt-exp.h +++ b/src/pt-exp.h @@ -42,47 +42,64 @@ #include "pt-exp-base.h" +// Unary expressions. + +class +tree_unary_expression : public tree_expression +{ +public: + + tree_unary_expression (int l = -1, int c = -1) + : tree_expression (l, c), op (0) { } + + tree_unary_expression (tree_expression *e, int l = -1, int c = -1) + : tree_expression (l, c), op (e) { } + + ~tree_unary_expression (void) { delete op; } + + tree_expression *operand (void) { return op; } + +protected: + + // The operand for the expression. + tree_expression *op; +}; + // Prefix expressions. class -tree_prefix_expression : public tree_expression +tree_prefix_expression : public tree_unary_expression { public: enum type { unknown, + unot, + uminus, increment, decrement }; - tree_prefix_expression (int l = -1, int c = -1, type t = unknown) - : tree_expression (l, c), id (0), etype (t) { } + tree_prefix_expression (int l = -1, int c = -1) + : tree_unary_expression (l, c), etype (unknown) { } - tree_prefix_expression (tree_identifier *i, int l = -1, int c = -1, - type t = unknown) - : tree_expression (l, c), id (i), etype (t) { } + tree_prefix_expression (type t = unknown, tree_expression *e, + int l = -1, int c = -1) + : tree_unary_expression (e, l, c), etype (t) { } - ~tree_prefix_expression (void); + ~tree_prefix_expression (void) { } octave_value eval (bool print = false); void eval_error (void); - bool is_prefix_expression (void) const - { return true; } - string oper (void) const; - tree_identifier *ident (void) { return id; } - void accept (tree_walker& tw); private: - // Currently, a prefix expression can only apply to an identifier. - tree_identifier *id; - // The type of the expression. type etype; }; @@ -90,25 +107,27 @@ // Postfix expressions. class -tree_postfix_expression : public tree_expression +tree_postfix_expression : public tree_unary_expression { public: enum type { unknown, + hermitian, + transpose, increment, decrement }; - tree_postfix_expression (int l = -1, int c = -1, type t = unknown) - : tree_expression (l, c), id (0), etype (t) { } + tree_postfix_expression (int l = -1, int c = -1) + : tree_unary_expression (l, c), etype (unknown) { } - tree_postfix_expression (tree_identifier *i, int l = -1, int c = -1, - type t = unknown) - : tree_expression (l, c), id (i), etype (t) { } + tree_postfix_expression (type t = unknown, tree_expression *e, + int l = -1, int c = -1) + : tree_unary_expression (e, l, c), etype (t) { } - ~tree_postfix_expression (void); + ~tree_postfix_expression (void) { } octave_value eval (bool print = false); @@ -116,62 +135,10 @@ string oper (void) const; - tree_identifier *ident (void) { return id; } - void accept (tree_walker& tw); private: - // Currently, a prefix expression can only apply to an identifier. - tree_identifier *id; - - // The type of the expression. - type etype; -}; - -// Unary expressions. - -class -tree_unary_expression : public tree_expression -{ -public: - - enum type - { - unknown, - unot, - uminus, - hermitian, - transpose - }; - - tree_unary_expression (int l = -1, int c = -1, type t = unknown) - : tree_expression (l, c), op (0), etype (t) { } - - tree_unary_expression (tree_expression *a, int l = -1, int c = -1, - type t = unknown) - : tree_expression (l, c), op (a), etype (t) { } - - ~tree_unary_expression (void) - { delete op; } - - octave_value eval (bool print = false); - - void eval_error (void); - - string oper (void) const; - - bool is_prefix_op (void) { return (etype == unot || etype == uminus); } - - tree_expression *operand (void) { return op; } - - void accept (tree_walker& tw); - -private: - - // The operand for the expression. - tree_expression *op; - // The type of the expression. type etype; }; @@ -354,13 +321,11 @@ public: tree_colon_expression (int l = -1, int c = -1) - : tree_expression (l, c, tree_expression::colon), - op_base (0), op_limit (0), op_increment (0) { } + : tree_expression (l, c), 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), - op_base (a), op_limit (b), op_increment (0) { } + : tree_expression (l, c), op_base (a), op_limit (b), op_increment (0) { } ~tree_colon_expression (void) { diff --git a/src/pt-id.cc b/src/pt-id.cc --- a/src/pt-id.cc +++ b/src/pt-id.cc @@ -73,34 +73,6 @@ } void -tree_identifier::increment (void) -{ - if (sym) - { - if (sym->is_read_only ()) - ::error ("can't redefined read-only variable `%s'", name ().c_str ()); - else if (sym->is_defined () && sym->is_variable ()) - reference () . increment (); - else - ::error ("can only increment variables"); - } -} - -void -tree_identifier::decrement (void) -{ - if (sym) - { - if (sym->is_read_only ()) - ::error ("can't redefined read-only variable `%s'", name ().c_str ()); - else if (sym->is_defined () && sym->is_variable ()) - reference () . decrement (); - else - ::error ("can only decrement variables"); - } -} - -void tree_identifier::eval_undefined_error (void) { int l = line (); diff --git a/src/pt-id.h b/src/pt-id.h --- a/src/pt-id.h +++ b/src/pt-id.h @@ -69,10 +69,6 @@ bool is_defined (void); - void increment (void); - - void decrement (void); - octave_symbol *do_lookup (bool& script_file_executed, bool exec_script = true); diff --git a/src/pt-mvr-base.h b/src/pt-mvr-base.h --- a/src/pt-mvr-base.h +++ b/src/pt-mvr-base.h @@ -39,11 +39,8 @@ { public: - tree_multi_val_ret (int l = -1, int c = -1) : tree_expression (l, c) { } - - // XXX FIXME XXX -- this can't be right! - tree_multi_val_ret (int l = -1, int c = -1, tree_expression::type et) - : tree_expression (l, c, et) { } + tree_multi_val_ret (int l = -1, int c = -1) + : tree_expression (l, c) { } ~tree_multi_val_ret (void) { } diff --git a/src/pt-mvr.cc b/src/pt-mvr.cc --- a/src/pt-mvr.cc +++ b/src/pt-mvr.cc @@ -274,8 +274,6 @@ tree_multi_assignment_expression::eval (bool print, int nargout, const octave_value_list&) { - assert (etype == tree_expression::multi_assignment); - if (error_state || ! rhs) return octave_value_list (); diff --git a/src/pt-mvr.h b/src/pt-mvr.h --- a/src/pt-mvr.h +++ b/src/pt-mvr.h @@ -133,15 +133,13 @@ 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) { } + : tree_multi_val_ret (l, c), preserve (plhs), lhs (0), rhs (0) { } tree_multi_assignment_expression (tree_return_list *lst, tree_multi_val_ret *r, bool plhs = false, int l = -1, int c = -1) - : tree_multi_val_ret (l, c, tree_expression::multi_assignment), - preserve (plhs), lhs (lst), rhs (r) { } + : tree_multi_val_ret (l, c), preserve (plhs), lhs (lst), rhs (r) { } ~tree_multi_assignment_expression (void); diff --git a/src/pt-pr-code.cc b/src/pt-pr-code.cc --- a/src/pt-pr-code.cc +++ b/src/pt-pr-code.cc @@ -692,10 +692,10 @@ if (in_parens) os << "("; - tree_identifier *id = expr.ident (); + tree_expression *e = expr.operand (); - if (id) - id->accept (*this); + if (e) + e->accept (*this); os << expr.oper (); @@ -715,10 +715,10 @@ os << expr.oper (); - tree_identifier *id = expr.ident (); + tree_expression *e = expr.operand (); - if (id) - id->accept (*this); + if (e) + e->accept (*this); if (in_parens) os << ")"; @@ -1046,37 +1046,6 @@ } void -tree_print_code::visit_unary_expression (tree_unary_expression& expr) -{ - indent (); - - bool in_parens = expr.is_in_parens (); - - if (in_parens) - os << "("; - - tree_expression *op = expr.operand (); - - if (expr.is_prefix_op ()) - { - os << expr.oper (); - - if (op) - op->accept (*this); - } - else - { - if (op) - op->accept (*this); - - os << expr.oper (); - } - - if (in_parens) - os << ")"; -} - -void tree_print_code::visit_unwind_protect_command (tree_unwind_protect_command& cmd) { diff --git a/src/pt-pr-code.h b/src/pt-pr-code.h --- a/src/pt-pr-code.h +++ b/src/pt-pr-code.h @@ -130,8 +130,6 @@ void visit_try_catch_command (tree_try_catch_command&); - void visit_unary_expression (tree_unary_expression&); - void visit_unwind_protect_command (tree_unwind_protect_command&); void visit_while_command (tree_while_command&); diff --git a/src/pt-walk.h b/src/pt-walk.h --- a/src/pt-walk.h +++ b/src/pt-walk.h @@ -64,7 +64,6 @@ class subplot_style; class subplot_using; class tree_try_catch_command; -class tree_unary_expression; class tree_unwind_protect_command; class tree_while_command; @@ -197,9 +196,6 @@ visit_try_catch_command (tree_try_catch_command&) = 0; virtual void - visit_unary_expression (tree_unary_expression&) = 0; - - virtual void visit_unwind_protect_command (tree_unwind_protect_command&) = 0; virtual void