Mercurial > hg > octave-shane
changeset 2971:f2be17e6f1ea
[project @ 1997-05-15 18:55:44 by jwe]
author | jwe |
---|---|
date | Thu, 15 May 1997 18:55:47 +0000 |
parents | b9e64477f703 |
children | ae2471c4e5c0 |
files | src/pt-const.cc src/pt-const.h src/pt-exp-base.cc src/pt-exp-base.h src/pt-exp.cc src/pt-exp.h src/pt-id.cc src/pt-id.h src/pt-indir.cc src/pt-indir.h src/pt-mat.cc src/pt-mat.h |
diffstat | 12 files changed, 861 insertions(+), 643 deletions(-) [+] |
line wrap: on
line diff
--- a/src/pt-const.cc +++ b/src/pt-const.cc @@ -30,6 +30,7 @@ #include <iostream.h> +#include "error.h" #include "oct-obj.h" #include "pager.h" #include "pt-const.h" @@ -59,19 +60,17 @@ val.print_raw (os, pr_as_read_syntax); } -octave_value -tree_constant::eval (bool print_result) +octave_value_list +tree_constant::rvalue (int nargout) { - if (print_result) - val.print (octave_stdout); + octave_value_list retval; - return val; -} + if (nargout > 1) + error ("invalid number of output arguments for constant expression"); + else + retval = rvalue (); -octave_value_list -tree_constant::eval (bool, int, const octave_value_list& idx) -{ - return (idx.length () > 0) ? val.do_index_op (idx) : val; + return retval; } void
--- a/src/pt-const.h +++ b/src/pt-const.h @@ -33,7 +33,7 @@ #include "oct-alloc.h" -#include "pt-mvr-base.h" +#include "pt-exp-base.h" class octave_value_list; @@ -42,18 +42,18 @@ #include "ov.h" class -tree_constant : public tree_multi_val_ret +tree_constant : public tree_expression { public: tree_constant (int l = -1, int c = -1) - : tree_multi_val_ret (l, c), val (), orig_text () { } + : tree_expression (l, c), val (), orig_text () { } tree_constant (const octave_value& v, int l = -1, int c = -1) - : tree_multi_val_ret (l, c), val (v), orig_text () { } + : tree_expression (l, c), val (v), orig_text () { } tree_constant (const tree_constant& a) - : tree_multi_val_ret (-1, -1), val (a.val), orig_text () { } + : tree_expression (-1, -1), val (a.val), orig_text () { } ~tree_constant (void) { } @@ -61,7 +61,7 @@ { if (this != &a) { - tree_multi_val_ret::operator = (a); + tree_expression::operator = (a); val = a.val; } return *this; @@ -75,7 +75,8 @@ // Type. It would be nice to eliminate the need for this. - bool is_constant (void) const { return true; } + bool is_constant (void) const + { return true; } void maybe_mutate (void) { val.maybe_mutate (); } @@ -86,10 +87,15 @@ void print_raw (ostream& os, bool pr_as_read_syntax = false, bool pr_orig_txt = true); - octave_value eval (bool print = false); + bool rvalue_ok (void) const + { return true; } - octave_value_list - eval (bool print, int nargout, const octave_value_list& args); + octave_value rvalue (void) + { return val; } + + octave_value_list rvalue (int nargout); + + void accept (tree_walker& tw); // Store the original text corresponding to this constant for later // pretty printing. @@ -100,8 +106,6 @@ string original_text (void) const { return orig_text; } - void accept (tree_walker& tw); - private: // For custom memory management.
--- a/src/pt-exp-base.cc +++ b/src/pt-exp-base.cc @@ -46,7 +46,7 @@ { bool expr_value = false; - octave_value t1 = eval (); + octave_value t1 = rvalue (); if (! error_state) { @@ -62,23 +62,24 @@ return expr_value; } -void -tree_expression::mark_for_possible_ans_assign (void) +octave_value +tree_expression::rvalue (void) { - panic_impossible (); -} - -octave_value -tree_expression::eval (bool /* print */) -{ - panic ("invalid evaluation of generic expression"); + ::error ("invalid rvalue function called in expression"); return octave_value (); } +octave_value_list +tree_expression::rvalue (int nargout) +{ + ::error ("invalid rvalue function called in expression"); + return octave_value_list (); +} + octave_variable_reference -tree_expression::reference (void) +tree_expression::lvalue (void) { - panic ("invalid attempt to convert generic expression to lvalue"); + ::error ("invalid lvalue function called in expression"); return octave_variable_reference (); }
--- a/src/pt-exp-base.h +++ b/src/pt-exp-base.h @@ -42,7 +42,8 @@ public: tree_expression (int l = -1, int c = -1) - : tree (l, c), num_parens (0) { } + : tree (l, c), num_parens (0), postfix_indexed (false), + print_flag (false) { } virtual ~tree_expression (void) { } @@ -52,16 +53,13 @@ virtual bool is_matrix_constant (void) const { return false; } - virtual bool is_multi_val_ret_expression (void) const - { return false; } - virtual bool is_identifier (void) const { return false; } - virtual bool is_indirect_ref (void) const + virtual bool is_index_expression (void) const { return false; } - virtual bool is_index_expression (void) const + virtual bool is_indirect_ref (void) const { return false; } virtual bool is_assignment_expression (void) const @@ -72,18 +70,33 @@ virtual bool is_logically_true (const char *); - virtual int paren_count (void) const + virtual bool lvalue_ok (void) const + { return false; } + + virtual bool rvalue_ok (void) const + { return false; } + + virtual octave_value rvalue (void); + + virtual octave_value_list rvalue (int nargout); + + virtual octave_variable_reference lvalue (void); + + int paren_count (void) const { return num_parens; } - virtual void mark_for_possible_ans_assign (void); + bool is_postfix_indexed (void) const + { return postfix_indexed; } - virtual octave_value eval (bool print = false) = 0; - - virtual octave_variable_reference reference (void); + bool print_result (void) const + { return print_flag; } virtual string oper (void) const { return "<unknown>"; } + virtual string name (void) const + { return "<unknown>"; } + virtual string original_text (void) const; tree_expression *mark_in_parens (void) @@ -92,6 +105,18 @@ return this; } + tree_expression *mark_postfix_indexed (void) + { + postfix_indexed = true; + return this; + } + + tree_expression *set_print_flag (bool print) + { + print_flag = print; + return this; + } + protected: // A count of the number of times this expression appears directly @@ -101,6 +126,13 @@ // ==> 1 for expression ((e1)) + e2 // ==> 0 for expression e2 int num_parens; + + // A flag that says whether this expression has an index associated + // with it. See the code in tree_identifier::rvalue for the rationale. + bool postfix_indexed; + + // Print result of rvalue for this expression? + bool print_flag; }; #endif
--- a/src/pt-exp.cc +++ b/src/pt-exp.cc @@ -44,7 +44,6 @@ #include "pt-id.h" #include "pt-indir.h" #include "pt-misc.h" -#include "pt-mvr.h" #include "pt-pr-code.h" #include "pt-walk.h" #include "utils.h" @@ -62,8 +61,22 @@ // Prefix expressions. +octave_value_list +tree_prefix_expression::rvalue (int nargout) +{ + octave_value_list retval; + + if (nargout > 1) + error ("prefix operator `%s': invalid number of output arguments", + oper () . c_str ()); + else + retval = rvalue (); + + return retval; +} + octave_value -tree_prefix_expression::eval (bool) +tree_prefix_expression::rvalue (void) { octave_value retval; @@ -74,28 +87,40 @@ { if (etype == unot || etype == uminus) { - octave_value val = op->eval (); + octave_value val = op->rvalue (); if (! error_state) { - if (etype == unot) - retval = val.not (); + if (val.is_defined ()) + { + if (etype == unot) + retval = val.not (); + else + retval = val.uminus (); + } else - retval = val.uminus (); + error ("argument to prefix operator `%s' undefined", + oper () . c_str ()); } } else if (etype == increment || etype == decrement) { - octave_variable_reference ref = op->reference (); + octave_variable_reference ref = op->lvalue (); if (! error_state) { - if (etype == increment) - ref.increment (); + if (ref.is_defined ()) + { + if (etype == increment) + ref.increment (); + else + ref.decrement (); + + retval = ref.value (); + } else - ref.decrement (); - - retval = ref.value (); + error ("argument to prefix operator `%s' undefined", + oper () . c_str ()); } } else @@ -105,6 +130,14 @@ return retval; } +void +tree_prefix_expression::eval_error (void) +{ + if (error_state > 0) + ::error ("evaluating prefix operator `%s' near line %d, column %d", + oper () . c_str (), line (), column ()); +} + string tree_prefix_expression::oper (void) const { @@ -136,14 +169,6 @@ } void -tree_prefix_expression::eval_error (void) -{ - if (error_state > 0) - ::error ("evaluating prefix operator `%s' near line %d, column %d", - oper () . c_str (), line (), column ()); -} - -void tree_prefix_expression::accept (tree_walker& tw) { tw.visit_prefix_expression (*this); @@ -151,8 +176,22 @@ // Postfix expressions. +octave_value_list +tree_postfix_expression::rvalue (int nargout) +{ + octave_value_list retval; + + if (nargout > 1) + error ("postfix operator `%s': invalid number of output arguments", + oper () . c_str ()); + else + retval = rvalue (); + + return retval; +} + octave_value -tree_postfix_expression::eval (bool) +tree_postfix_expression::rvalue (void) { octave_value retval; @@ -163,28 +202,40 @@ { if (etype == transpose || etype == hermitian) { - octave_value val = op->eval (); + octave_value val = op->rvalue (); if (! error_state) { - if (etype == transpose) - retval = val.transpose (); + if (val.is_defined ()) + { + if (etype == transpose) + retval = val.transpose (); + else + retval = val.hermitian (); + } else - retval = val.hermitian (); + error ("argument to postfix operator `%s' undefined", + oper () . c_str ()); } } else if (etype == increment || etype == decrement) { - octave_variable_reference ref = op->reference (); + octave_variable_reference ref = op->lvalue (); if (! error_state) { - retval = ref.value (); + if (ref.is_defined ()) + { + retval = ref.value (); - if (etype == increment) - ref.increment (); + if (etype == increment) + ref.increment (); + else + ref.decrement (); + } else - ref.decrement (); + error ("argument to postfix operator `%s' undefined", + oper () . c_str ()); } } else @@ -194,6 +245,14 @@ return retval; } +void +tree_postfix_expression::eval_error (void) +{ + if (error_state > 0) + ::error ("evaluating postfix operator `%s' near line %d, column %d", + oper () . c_str (), line (), column ()); +} + string tree_postfix_expression::oper (void) const { @@ -225,14 +284,6 @@ } void -tree_postfix_expression::eval_error (void) -{ - if (error_state > 0) - ::error ("evaluating postfix operator `%s' near line %d, column %d", - oper () . c_str (), line (), column ()); -} - -void tree_postfix_expression::accept (tree_walker& tw) { tw.visit_postfix_expression (*this); @@ -240,8 +291,22 @@ // Binary expressions. +octave_value_list +tree_binary_expression::rvalue (int nargout) +{ + octave_value_list retval; + + if (nargout > 1) + error ("binary operator `%s': invalid number of output arguments", + oper () . c_str ()); + else + retval = rvalue (); + + return retval; +} + octave_value -tree_binary_expression::eval (bool /* print */) +tree_binary_expression::rvalue (void) { octave_value retval; @@ -250,13 +315,13 @@ if (op_lhs) { - octave_value a = op_lhs->eval (); + octave_value a = op_lhs->rvalue (); if (error_state) eval_error (); else if (a.is_defined () && op_rhs) { - octave_value b = op_rhs->eval (); + octave_value b = op_rhs->rvalue (); if (error_state) eval_error (); @@ -282,12 +347,6 @@ return retval; } -string -tree_binary_expression::oper (void) const -{ - return octave_value::binary_op_as_string (etype); -} - void tree_binary_expression::eval_error (void) { @@ -296,6 +355,12 @@ oper () . c_str (), line (), column ()); } +string +tree_binary_expression::oper (void) const +{ + return octave_value::binary_op_as_string (etype); +} + void tree_binary_expression::accept (tree_walker& tw) { @@ -304,8 +369,22 @@ // Boolean expressions. +octave_value_list +tree_boolean_expression::rvalue (int nargout) +{ + octave_value_list retval; + + if (nargout > 1) + error ("binary operator `%s': invalid number of output arguments", + oper () . c_str ()); + else + retval = rvalue (); + + return retval; +} + octave_value -tree_boolean_expression::eval (bool /* print */) +tree_boolean_expression::rvalue (void) { octave_value retval; @@ -316,7 +395,7 @@ if (op_lhs) { - octave_value a = op_lhs->eval (); + octave_value a = op_lhs->rvalue (); if (error_state) eval_error (); @@ -344,7 +423,7 @@ if (op_rhs) { - octave_value b = op_rhs->eval (); + octave_value b = op_rhs->rvalue (); if (error_state) eval_error (); @@ -396,50 +475,29 @@ // Simple assignment expressions. -tree_simple_assignment_expression::tree_simple_assignment_expression - (tree_identifier *i, tree_expression *r, bool plhs, bool ans_assign, - int l, int c, octave_value::assign_op t) - : tree_expression (l, c), lhs_idx_expr (0), - lhs (new tree_indirect_ref (i)), index (0), rhs (r), - preserve (plhs), ans_ass (ans_assign), etype (t) { } - -tree_simple_assignment_expression::tree_simple_assignment_expression - (tree_index_expression *idx_expr, tree_expression *r, bool plhs, - bool ans_assign, int l, int c, octave_value::assign_op t) - : tree_expression (l, c), lhs_idx_expr (idx_expr), - lhs (idx_expr->ident ()), index (idx_expr->arg_list ()), rhs (r), - preserve (plhs), ans_ass (ans_assign), etype (t) { } - -tree_simple_assignment_expression::~tree_simple_assignment_expression (void) +tree_simple_assignment::~tree_simple_assignment (void) { if (! preserve) - { - if (lhs_idx_expr) - delete lhs_idx_expr; - else - delete lhs; - } + delete lhs; delete rhs; } -bool -tree_simple_assignment_expression::left_hand_side_is_identifier_only (void) +octave_value_list +tree_simple_assignment::rvalue (int nargout) { - return lhs->is_identifier_only (); + octave_value_list retval; + + if (nargout > 1) + error ("invalid number of output arguments for expression X = RHS"); + else + retval = rvalue (); + + return retval; } -tree_identifier * -tree_simple_assignment_expression::left_hand_side_id (void) -{ - return lhs->ident (); -} - -// ??? FIXME ??? -- should octave_value::assign return the right thing -// for us to return? - octave_value -tree_simple_assignment_expression::eval (bool print) +tree_simple_assignment::rvalue (void) { octave_value rhs_val; @@ -448,12 +506,12 @@ if (rhs) { - octave_value lhs_val; + octave_value_list tmp = rhs->rvalue (); - rhs_val = rhs->eval (); + if (! (error_state || tmp.empty ())) + { + rhs_val = tmp(0); - if (! error_state) - { if (rhs_val.is_undefined ()) { error ("value on right hand side of assignment is undefined"); @@ -461,89 +519,55 @@ } else { - octave_variable_reference ult = lhs->reference (); + octave_variable_reference ult = lhs->lvalue (); if (error_state) eval_error (); else { - if (index) - { - // Extract the arguments into a simple vector. + ult.assign (etype, rhs_val); - octave_value_list args - = index->convert_to_const_vector (); - - if (! error_state) - { - int nargin = args.length (); + if (error_state) + eval_error (); + else if (! Vprint_rhs_assign_val) + { + octave_value lhs_val = ult.value (); - if (nargin > 0) + if (! error_state && print_result ()) + { + if (Vprint_rhs_assign_val) { - ult.index (args); + ostrstream buf; + + tree_print_code tpc (buf); - ult.assign (etype, rhs_val); + lhs->accept (tpc); + + buf << ends; - if (error_state) - eval_error (); - else if (! Vprint_rhs_assign_val) - lhs_val = ult.value (); + const char *tag = buf.str (); + + rhs_val.print_with_name (octave_stdout, tag); + + delete [] tag; } else - error ("??? invalid index list ???"); + lhs_val.print_with_name (octave_stdout, + lhs->name ()); } - else - eval_error (); - } - else - { - ult.assign (etype, rhs_val); - - if (error_state) - eval_error (); - else if (! Vprint_rhs_assign_val) - lhs_val = ult.value (); } } } } else eval_error (); - - if (! error_state && print) - { - if (Vprint_rhs_assign_val) - { - ostrstream buf; - - buf << lhs->name (); - - if (index) - { - buf << " ("; - tree_print_code tpc (buf); - index->accept (tpc); - buf << ")"; - } - - buf << ends; - - const char *tag = buf.str (); - - rhs_val.print_with_name (octave_stdout, tag); - - delete [] tag; - } - else - lhs_val.print_with_name (octave_stdout, lhs->name ()); - } } return rhs_val; } void -tree_simple_assignment_expression::eval_error (void) +tree_simple_assignment::eval_error (void) { if (error_state > 0) { @@ -557,49 +581,90 @@ } string -tree_simple_assignment_expression::oper (void) const +tree_simple_assignment::oper (void) const { return octave_value::assign_op_as_string (etype); } void -tree_simple_assignment_expression::accept (tree_walker& tw) +tree_simple_assignment::accept (tree_walker& tw) { - tw.visit_simple_assignment_expression (*this); + tw.visit_simple_assignment (*this); } // Colon expressions. tree_colon_expression * -tree_colon_expression::chain (tree_expression *t) +tree_colon_expression::append (tree_expression *t) { tree_colon_expression *retval = 0; - if (! op_base || op_increment) - ::error ("invalid colon expression"); - else + + if (op_base) { - // Stupid syntax: - // - // base : limit - // base : increment : limit + if (op_limit) + { + if (op_increment) + ::error ("invalid colon expression"); + else + { + // Stupid syntax: + // + // base : limit + // base : increment : limit - op_increment = op_limit; - op_limit = t; + op_increment = op_limit; + op_limit = t; + } + } + else + op_limit = t; retval = this; } + else + ::error ("invalid colon expression"); + + return retval; +} + +octave_value_list +tree_colon_expression::rvalue (int nargout) +{ + octave_value_list retval; + + if (nargout > 1) + error ("invalid number of output arguments for colon expression"); + else + retval = rvalue (); + return retval; } octave_value -tree_colon_expression::eval (bool /* print */) +tree_colon_expression::rvalue (void) { octave_value retval; if (error_state || ! op_base || ! op_limit) return retval; - octave_value tmp = op_base->eval (); + octave_value tmp = op_base->rvalue (); + + if (tmp.is_undefined ()) + { + eval_error ("invalid null value in colon expression"); + return retval; + } + + double xbase = tmp.double_value (); + + if (error_state) + { + eval_error ("colon expression elements must be scalars"); + return retval; + } + + tmp = op_limit->rvalue (); if (tmp.is_undefined ()) { @@ -607,37 +672,19 @@ return retval; } - double base = tmp.double_value (); + double xlimit = tmp.double_value (); if (error_state) { - error ("colon expression elements must be scalars"); - eval_error ("evaluating colon expression"); + eval_error ("colon expression elements must be scalars"); return retval; } - tmp = op_limit->eval (); - - if (tmp.is_undefined ()) - { - eval_error ("invalid null value in colon expression"); - return retval; - } - - double limit = tmp.double_value (); - - if (error_state) - { - error ("colon expression elements must be scalars"); - eval_error ("evaluating colon expression"); - return retval; - } - - double inc = 1.0; + double xinc = 1.0; if (op_increment) { - tmp = op_increment->eval (); + tmp = op_increment->rvalue (); if (tmp.is_undefined ()) { @@ -645,22 +692,22 @@ return retval; } - inc = tmp.double_value (); + xinc = tmp.double_value (); if (error_state) { - error ("colon expression elements must be scalars"); - eval_error ("evaluating colon expression"); + eval_error ("colon expression elements must be scalars"); return retval; } } - retval = octave_value (base, limit, inc); + retval = octave_value (xbase, xlimit, xinc); if (error_state) { if (error_state) - eval_error ("evaluating colon expression"); + eval_error (); + return octave_value (); } @@ -668,10 +715,16 @@ } void -tree_colon_expression::eval_error (const char *s) +tree_colon_expression::eval_error (const string& s) { if (error_state > 0) - ::error ("%s near line %d column %d", s, line (), column ()); + { + if (! s.empty ()) + ::error ("%s", s.c_str ()); + + ::error ("evaluating colon expression near line %d column %d", + line (), column ()); + } } void @@ -680,6 +733,253 @@ tw.visit_colon_expression (*this); } +tree_index_expression::~tree_index_expression (void) +{ + delete expr; + delete list; +} + +octave_value_list +tree_index_expression::rvalue (int nargout) +{ + octave_value_list retval; + + if (error_state) + return retval; + + octave_value tmp = expr->rvalue (); + + if (! error_state) + { + octave_value_list args; + + if (list) + args = list->convert_to_const_vector (); + + if (! error_state) + { + if (! args.empty ()) + args.stash_name_tags (arg_nm); + + // XXX FIXME XXX -- is this the right thing to do? + if (tmp.is_constant ()) + retval = tmp.do_index_op (args); + else + retval = tmp.do_index_op (nargout, args); + } + else + eval_error (); + } + else + eval_error (); + + return retval; +} + +octave_value +tree_index_expression::rvalue (void) +{ + octave_value retval; + + octave_value_list tmp = rvalue (1); + + if (! tmp.empty ()) + retval = tmp(0); + + return retval; +} + +octave_variable_reference +tree_index_expression::lvalue (void) +{ + octave_variable_reference retval; + + if (! error_state) + { + retval = expr->lvalue (); + + if (! error_state) + { + octave_value_list args; + + if (list) + args = list->convert_to_const_vector (); + + retval.index (args); + } + } + + return retval; +} + +void +tree_index_expression::eval_error (void) +{ + if (error_state > 0) + { + int l = line (); + int c = column (); + + if (l != -1 && c != -1) + { + if (list) + ::error ("evaluating index expression near line %d, column %d", + l, c); + else + ::error ("evaluating expression near line %d, column %d", l, c); + } + else + { + if (list) + ::error ("evaluating index expression"); + else + ::error ("evaluating expression"); + } + } +} + +void +tree_index_expression::accept (tree_walker& tw) +{ + tw.visit_index_expression (*this); +} + +tree_multi_assignment::~tree_multi_assignment (void) +{ + if (! preserve) + delete lhs; + + delete rhs; +} + +octave_value +tree_multi_assignment::rvalue (void) +{ + octave_value retval; + + octave_value_list tmp = rvalue (1); + + if (! tmp.empty ()) + retval = tmp(0); + + return retval; +} + +octave_value_list +tree_multi_assignment::rvalue (int nargout) +{ + octave_value_list rhs_val; + + if (error_state) + return rhs_val; + + if (rhs) + { + int n_out = lhs->length (); + + rhs_val = rhs->rvalue (n_out); + + if (! (error_state || rhs_val.empty ())) + { + if (rhs_val.empty ()) + { + error ("value on right hand side of assignment is undefined"); + eval_error (); + } + else + { + int k = 0; + + int n = rhs_val.length (); + + for (Pix p = lhs->first (); p != 0; lhs->next (p)) + { + tree_expression *lhs_elt = lhs->operator () (p); + + if (lhs_elt) + { + octave_variable_reference ult = lhs_elt->lvalue (); + + if (error_state) + eval_error (); + else + { + octave_value tmp = k < n + ? rhs_val(k++) : octave_value (); + + if (tmp.is_defined ()) + { + // XXX FIXME XXX -- handle other assignment ops. + ult.assign (octave_value::asn_eq, tmp); + } + else + error ("element number %d undefined in return list", k+1); + + if (error_state) + eval_error (); + else if (! Vprint_rhs_assign_val) + { + octave_value lhs_val = ult.value (); + + if (! error_state && print_result ()) + { + if (Vprint_rhs_assign_val) + { + ostrstream buf; + + tree_print_code tpc (buf); + + lhs_elt->accept (tpc); + + buf << ends; + + const char *tag = buf.str (); + + tmp.print_with_name + (octave_stdout, tag); + + delete [] tag; + } + else + lhs_val.print_with_name (octave_stdout, + lhs_elt->name ()); + } + } + } + } + + if (error_state) + break; + } + } + } + else + eval_error (); + } + + return rhs_val; +} + +void +tree_multi_assignment::eval_error (void) +{ + if (error_state > 0) + { + int l = line (); + int c = column (); + + if (l != -1 && c != -1) + ::error ("evaluating assignment expression near line %d, column %d", + l, c); + } +} + +void +tree_multi_assignment::accept (tree_walker& tw) +{ + tw.visit_multi_assignment (*this); +} + static int print_rhs_assign_val (void) {
--- a/src/pt-exp.h +++ b/src/pt-exp.h @@ -33,6 +33,7 @@ class tree_index_expression; class tree_indirect_ref; class tree_argument_list; +class tree_assignment_lhs; class tree_walker; @@ -40,6 +41,7 @@ class octave_value_list; class octave_variable_reference; +#include "oct-obj.h" #include "pt-exp-base.h" // Unary expressions. @@ -90,7 +92,12 @@ ~tree_prefix_expression (void) { } - octave_value eval (bool print = false); + bool rvalue_ok (void) const + { return true; } + + octave_value rvalue (void); + + octave_value_list rvalue (int nargou); void eval_error (void); @@ -129,7 +136,12 @@ ~tree_postfix_expression (void) { } - octave_value eval (bool print = false); + bool rvalue_ok (void) const + { return true; } + + octave_value rvalue (void); + + octave_value_list rvalue (int nargout); void eval_error (void); @@ -167,7 +179,12 @@ delete op_rhs; } - octave_value eval (bool print = false); + bool rvalue_ok (void) const + { return true; } + + octave_value rvalue (void); + + octave_value_list rvalue (int nargou); void eval_error (void); @@ -213,7 +230,12 @@ ~tree_boolean_expression (void) { } - octave_value eval (bool print = false); + bool rvalue_ok (void) const + { return true; } + + octave_value rvalue (void); + + octave_value_list rvalue (int nargout); string oper (void) const; @@ -226,43 +248,28 @@ // Simple assignment expressions. class -tree_simple_assignment_expression : public tree_expression +tree_simple_assignment : public tree_expression { public: - tree_simple_assignment_expression - (bool plhs = false, bool ans_assign = false, int l = -1, int c = -1, - octave_value::assign_op t = octave_value::asn_eq) - : tree_expression (l, c), lhs_idx_expr (0), lhs (0), index (0), - rhs (0), preserve (plhs), ans_ass (ans_assign), etype (t) { } - - tree_simple_assignment_expression - (tree_identifier *i, tree_expression *r, bool plhs = false, - bool ans_assign = false, int l = -1, int c = -1, - octave_value::assign_op t = octave_value::asn_eq); + tree_simple_assignment (bool plhs = false, int l = -1, int c = -1, + octave_value::assign_op t = octave_value::asn_eq) + : tree_expression (l, c), lhs (0), rhs (0), preserve (plhs), etype (t) { } - tree_simple_assignment_expression - (tree_indirect_ref *i, tree_expression *r, bool plhs = false, - bool ans_assign = false, int l = -1, int c = -1, - octave_value::assign_op t = octave_value::asn_eq) - : tree_expression (l, c), lhs_idx_expr (0), lhs (i), index (0), - rhs (r), preserve (plhs), ans_ass (ans_assign), etype (t) { } + tree_simple_assignment (tree_expression *le, tree_expression *re, + bool plhs = false, int l = -1, int c = -1, + octave_value::assign_op t = octave_value::asn_eq) + : tree_expression (l, c), lhs (le), rhs (re), preserve (plhs), + etype (t) { } - tree_simple_assignment_expression - (tree_index_expression *idx_expr, tree_expression *r, - bool plhs = false, bool ans_assign = false, int l = -1, int c = -1, - octave_value::assign_op t = octave_value::asn_eq); - - ~tree_simple_assignment_expression (void); + ~tree_simple_assignment (void); - bool left_hand_side_is_identifier_only (void); - - tree_identifier *left_hand_side_id (void); + bool rvalue_ok (void) const + { return true; } - bool is_ans_assign (void) - { return ans_ass; } + octave_value rvalue (void); - octave_value eval (bool print = false); + octave_value_list rvalue (int nargout); bool is_assignment_expression (void) const { return true; } @@ -271,9 +278,7 @@ string oper (void) const; - tree_indirect_ref *left_hand_side (void) { return lhs; } - - tree_argument_list *lhs_index (void) { return index; } + tree_expression *left_hand_side (void) { return lhs; } tree_expression *right_hand_side (void) { return rhs; } @@ -288,17 +293,8 @@ void do_assign (octave_variable_reference& ult, const octave_value& rhs_val); - // 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 left hand side of the assignment. + tree_expression *lhs; // The right hand side of the assignment. tree_expression *rhs; @@ -323,9 +319,8 @@ tree_colon_expression (int l = -1, int c = -1) : 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), op_base (a), op_limit (b), op_increment (0) { } + tree_colon_expression (tree_expression *e, int l = -1, int c = -1) + : tree_expression (l, c), op_base (e), op_limit (0), op_increment (0) { } ~tree_colon_expression (void) { @@ -334,11 +329,16 @@ delete op_increment; } - tree_colon_expression *chain (tree_expression *t); + tree_colon_expression *append (tree_expression *t); + + bool rvalue_ok (void) const + { return true; } - octave_value eval (bool print = false); + octave_value rvalue (void); - void eval_error (const char *s); + octave_value_list rvalue (int nargout); + + void eval_error (const string& s = string ()); tree_expression *base (void) { return op_base; } tree_expression *limit (void) { return op_limit; } @@ -354,6 +354,91 @@ tree_expression *op_increment; }; +// Index expressions. + +class +tree_index_expression : public tree_expression +{ +public: + + tree_index_expression (tree_expression *e = 0, tree_argument_list *lst = 0, + int l = -1, int c = -1) + : tree_expression (l, c), expr (e), list (lst), arg_nm () { } + + ~tree_index_expression (void); + + bool is_index_expression (void) const + { return true; } + + tree_expression *expression (void) + { return expr; } + + tree_argument_list *arg_list (void) + { return list; } + + bool rvalue_ok (void) const + { return true; } + + octave_value rvalue (void); + + octave_value_list rvalue (int nargout); + + octave_variable_reference lvalue (void); + + void eval_error (void); + + void accept (tree_walker& tw); + +private: + + tree_expression *expr; + + tree_argument_list *list; + + string_vector arg_nm; +}; + +// Multi-valued assignment expressions. + +class +tree_multi_assignment : public tree_expression +{ +public: + + tree_multi_assignment (bool plhs = false, int l = -1, int c = -1) + : tree_expression (l, c), preserve (plhs), lhs (0), rhs (0) { } + + tree_multi_assignment (tree_argument_list *lst, tree_expression *r, + bool plhs = false, int l = -1, int c = -1) + : tree_expression (l, c), preserve (plhs), lhs (lst), rhs (r) { } + + ~tree_multi_assignment (void); + + bool is_assignment_expression (void) const + { return true; } + + bool rvalue_ok (void) const + { return true; } + + octave_value rvalue (void); + + octave_value_list rvalue (int nargout); + + void eval_error (void); + + tree_argument_list *left_hand_side (void) { return lhs; } + + tree_expression *right_hand_side (void) { return rhs; } + + void accept (tree_walker& tw); + +private: + + bool preserve; + tree_argument_list *lhs; + tree_expression *rhs; +}; + #endif /*
--- a/src/pt-id.cc +++ b/src/pt-id.cc @@ -30,8 +30,6 @@ #include "error.h" #include "oct-obj.h" -#include "oct-fcn.h" -#include "oct-sym.h" #include "oct-var-ref.h" #include "pager.h" #include "pt-const.h" @@ -72,6 +70,12 @@ return (sym && sym->is_defined ()); } +bool +tree_identifier::is_function (void) +{ + return (sym && sym->is_function ()); +} + void tree_identifier::eval_undefined_error (void) { @@ -100,17 +104,14 @@ // * On systems that support dynamic linking, we prefer .oct files // over .m files. -octave_symbol * +octave_value tree_identifier::do_lookup (bool& script_file_executed, bool exec_script) { + static octave_value foo; + script_file_executed = lookup (sym, exec_script); - octave_symbol *retval = 0; - - if (! script_file_executed) - retval = sym->def (); - - return retval; + return script_file_executed ? foo : sym->def (); } void @@ -134,57 +135,8 @@ sym->mark_as_formal_parameter (); } -octave_value -tree_identifier::eval (bool print) -{ - octave_value retval; - - if (error_state) - return retval; - - bool script_file_executed = false; - - octave_symbol *object_to_eval = do_lookup (script_file_executed); - - if (! script_file_executed) - { - if (object_to_eval) - { - int nargout = maybe_do_ans_assign ? 0 : 1; - - if (nargout) - { - octave_value_list tmp_args; - octave_value_list tmp = object_to_eval->eval (nargout, tmp_args); - - if (tmp.length () > 0) - retval = tmp(0); - } - else - retval = object_to_eval->eval (); - } - else - eval_undefined_error (); - } - - if (! error_state) - { - if (retval.is_defined ()) - { - if (maybe_do_ans_assign && ! object_to_eval->is_constant ()) - bind_ans (retval, print); - else if (print) - retval.print_with_name (octave_stdout, name ()); - } - else if (object_to_eval && object_to_eval->is_constant ()) - eval_undefined_error (); - } - - return retval; -} - octave_value_list -tree_identifier::eval (bool print, int nargout, const octave_value_list& args) +tree_identifier::rvalue (int nargout) { octave_value_list retval; @@ -193,26 +145,36 @@ bool script_file_executed = false; - octave_symbol *object_to_eval = do_lookup (script_file_executed); + octave_value val = do_lookup (script_file_executed); if (! script_file_executed) { - if (object_to_eval) + if (val.is_defined ()) { - if (maybe_do_ans_assign && nargout == 1) - { - // Don't count the output arguments that we create - // automatically. + // XXX GAGME XXX -- this would be cleaner if we required + // parens to indicate function calls. + // + // If this identifier refers to a function, we need to know + // whether it is indexed so that we can do the same thing + // for `f' and `f()'. If the index is present, return the + // function object and let tree_index_expression::rvalue + // handle indexing. Otherwise, arrange to call the function + // here, so that we don't return the function definition as + // a value. - nargout = 0; + if (val.is_function () && ! is_postfix_indexed ()) + { + octave_value_list tmp_args; - retval = object_to_eval->eval (nargout, args); - - if (retval.length () > 0 && retval(0).is_defined ()) - bind_ans (retval(0), print); + retval = val.do_index_op (nargout, tmp_args); } else - retval = object_to_eval->eval (nargout, args); + { + if (print_result () && nargout == 0) + val.print_with_name (octave_stdout, name ()); + + retval = val; + } } else eval_undefined_error (); @@ -221,24 +183,31 @@ return retval; } +octave_value +tree_identifier::rvalue (void) +{ + octave_value retval; + + octave_value_list tmp = rvalue (1); + + if (! tmp.empty ()) + retval = tmp(0); + + return retval; +} + +octave_variable_reference +tree_identifier::lvalue (void) +{ + return sym->variable_reference (); +} + void tree_identifier::accept (tree_walker& tw) { tw.visit_identifier (*this); } -octave_value -tree_identifier::value (void) const -{ - return sym->variable_value (); -} - -octave_variable_reference -tree_identifier::reference (void) -{ - return sym->variable_reference (); -} - /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/src/pt-id.h +++ b/src/pt-id.h @@ -33,28 +33,27 @@ class octave_value; class octave_value_list; -class octave_symbol; class octave_function; class symbol_record; class tree_walker; -#include "pt-mvr-base.h" +#include "pt-exp-base.h" // Symbols from the symbol table. class -tree_identifier : public tree_multi_val_ret +tree_identifier : public tree_expression { friend class tree_index_expression; public: tree_identifier (int l = -1, int c = -1) - : tree_multi_val_ret (l, c), sym (0), maybe_do_ans_assign (false) { } + : tree_expression (l, c), sym (0) { } tree_identifier (symbol_record *s, int l = -1, int c = -1) - : tree_multi_val_ret (l, c), sym (s), maybe_do_ans_assign (false) { } + : tree_expression (l, c), sym (s) { } ~tree_identifier (void) { } @@ -69,8 +68,10 @@ bool is_defined (void); - octave_symbol *do_lookup (bool& script_file_executed, bool - exec_script = true); + bool is_function (void); + + octave_value + do_lookup (bool& script_file_executed, bool exec_script = true); void link_to_global (void); @@ -78,30 +79,20 @@ void mark_as_formal_parameter (void); - void mark_for_possible_ans_assign (void) - { maybe_do_ans_assign = true; } + octave_value rvalue (void); - octave_value eval (bool print = false); + octave_value_list rvalue (int nargout); - octave_value_list - eval (bool print, int nargout, const octave_value_list& args); + octave_variable_reference lvalue (void); void eval_undefined_error (void); void accept (tree_walker& tw); - octave_value value (void) const; - - octave_variable_reference reference (void); - 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; }; #endif
--- a/src/pt-indir.cc +++ b/src/pt-indir.cc @@ -32,7 +32,6 @@ #include "gripes.h" #include "oct-map.h" #include "oct-obj.h" -#include "oct-sym.h" #include "oct-var-ref.h" #include "pager.h" #include "pt-const.h" @@ -47,126 +46,72 @@ tree_indirect_ref::~tree_indirect_ref (void) { - if (! preserve_ident) - delete id; - - if (! preserve_indir) - delete indir; -} - -void -tree_indirect_ref::mark_for_possible_ans_assign (void) -{ - maybe_do_ans_assign = true; - - if (is_identifier_only ()) - id->mark_for_possible_ans_assign (); + delete expr; } string tree_indirect_ref::name (void) const { - string retval; + return expr->name () + "." + nm; +} - if (is_identifier_only ()) - retval = id->name (); +octave_value_list +tree_indirect_ref::rvalue (int nargout) +{ + octave_value_list retval; + + if (nargout > 1) + error ("%s, %s", __FILE__, __LINE__); else { - if (id) - retval = id->name (); - else if (indir) - retval = indir->name (); - else - panic_impossible (); - - retval.append ("."); - retval.append (nm); - } - - return retval; -} + octave_value_list tmp = expr->rvalue (nargout); -octave_value -tree_indirect_ref::eval (bool print) -{ - octave_value retval; + if (tmp.empty ()) + error ("%s, %s", __FILE__, __LINE__); + else + { + octave_value val = tmp(0).do_struct_elt_index_op (nm); - if (is_identifier_only ()) - retval = id->eval (print); - else - { - octave_variable_reference tmp = reference (); + if (print_result () && nargout == 0 && val.is_defined ()) + val.print_with_name (octave_stdout, name ()); - if (! (error_state || tmp.is_undefined ())) - { - retval = tmp.value (); - - if (! error_state && maybe_do_ans_assign && retval.is_defined ()) - bind_ans (retval, print); + retval = val; } } return retval; } -octave_value_list -tree_indirect_ref::eval (bool print, int nargout, - const octave_value_list& args) +octave_value +tree_indirect_ref::rvalue (void) { - octave_value_list retval; - - if (is_identifier_only ()) - retval = id->eval (print, nargout, args); - else - { - octave_variable_reference tmp = reference (); + octave_value retval; - if (! (error_state || tmp.is_undefined ())) - { - tmp.index (args); - - retval = tmp.value (); + octave_value_list tmp = rvalue (1); - if (! error_state && maybe_do_ans_assign && nargout == 1 - && retval.length () > 0 && retval(0).is_defined ()) - { - bind_ans (retval(0), print); - } - } - } + if (! tmp.empty ()) + retval = tmp(0); return retval; } +octave_variable_reference +tree_indirect_ref::lvalue (void) +{ + octave_variable_reference tmp = expr->lvalue (); + + if (tmp.is_undefined () || ! tmp.is_map ()) + tmp.define (Octave_map ()); + + return tmp.struct_elt_ref (nm); +} + void tree_indirect_ref::accept (tree_walker& tw) { tw.visit_indirect_ref (*this); } -octave_variable_reference -tree_indirect_ref::reference (void) -{ - if (is_identifier_only ()) - return id->reference (); - else - { - octave_variable_reference tmp; - - if (id) - tmp = id->reference (); - else if (indir) - tmp = indir->reference (); - else - panic_impossible (); - - if (tmp.is_undefined ()) - tmp.define (Octave_map ()); - - return tmp.struct_elt_ref (nm); - } -} - /* ;;; Local Variables: *** ;;; mode: C++ ***
--- a/src/pt-indir.h +++ b/src/pt-indir.h @@ -33,64 +33,42 @@ class octave_value; class octave_value_list; -class tree_identifier; class tree_walker; -#include "pt-mvr-base.h" +#include "pt-exp-base.h" // Indirect references to values (structure references). class -tree_indirect_ref : public tree_multi_val_ret +tree_indirect_ref : public tree_expression { public: tree_indirect_ref (int l = -1, int c = -1) - : tree_multi_val_ret (l, c), id (0), indir (0), nm (), - preserve_ident (false), preserve_indir (false), - maybe_do_ans_assign (false) { } + : tree_expression (l, c), expr (0), nm () { } - tree_indirect_ref (tree_identifier *i, int l = -1, int c = -1) - : tree_multi_val_ret (l, c), id (i), indir (0), nm (), - preserve_ident (false), preserve_indir (false), - maybe_do_ans_assign (false) { } - - tree_indirect_ref (tree_indirect_ref *i, const string& n, + tree_indirect_ref (tree_expression *e, const string& n, int l = -1, int c = -1) - : tree_multi_val_ret (l, c), id (0), indir (i), nm (n), - preserve_ident (false), preserve_indir (false), - maybe_do_ans_assign (false) { } + : tree_expression (l, c), expr (e), nm (n) { } ~tree_indirect_ref (void); bool is_indirect_ref (void) const { return true; } - bool is_identifier_only (void) const - { return (id && nm.empty ()); } - - tree_identifier *ident (void) - { return id; } - - tree_indirect_ref *indirect (void) - { return indir; } - - void preserve_identifier (void) - { preserve_ident = true; } - - void preserve_indirect (void) - { preserve_indir = true; } - - void mark_for_possible_ans_assign (void); - string name (void) const; - octave_value eval (bool print = false); + bool rvalue_ok (void) const + { return true; } + + octave_value rvalue (void); - octave_value_list - eval (bool print, int nargout, const octave_value_list& args); + octave_value_list rvalue (int nargout); - octave_variable_reference reference (void); + octave_variable_reference lvalue (void); + + tree_expression *expression (void) + { return expr; } string elt_name (void) { return nm; } @@ -99,25 +77,11 @@ private: - // The identifier for this structure reference. For example, in - // a.b.c, a is the id. - tree_identifier *id; - - // This element just points to another indirect reference. - tree_indirect_ref *indir; + // The LHS of this structure reference. + tree_expression *expr; // The sub-element name. string nm; - - // True if we should not delete the identifier. - bool preserve_ident; - - // True if we should not delete the indirect reference. - bool preserve_indir; - - // True if we should consider assigning the result of evaluating - // this identifier to the built-in variable ans. - bool maybe_do_ans_assign; }; #endif
--- a/src/pt-mat.cc +++ b/src/pt-mat.cc @@ -37,7 +37,6 @@ #include "pt-exp.h" #include "pt-mat.h" #include "pt-misc.h" -#include "pt-mvr.h" #include "pt-walk.h" #include "utils.h" #include "ov.h" @@ -72,10 +71,10 @@ : SLList<octave_value> (), count (1), nr (0), nc (0), all_str (false), is_cmplx (false), all_mt (true), ok (false) { } - tm_row_const_rep (const tree_matrix_row& mr) + tm_row_const_rep (const tree_argument_list& row) : SLList<octave_value> (), count (1), nr (0), nc (0), all_str (false), is_cmplx (false), all_mt (true), ok (false) - { init (mr); } + { init (row); } ~tm_row_const_rep (void) { } @@ -90,15 +89,13 @@ bool ok; - void init (const tree_matrix_row&); + void init (const tree_argument_list&); private: tm_row_const_rep (const tm_row_const_rep&); - tm_row_const_rep& operator = - (const tm_row_const_rep&); - + tm_row_const_rep& operator = (const tm_row_const_rep&); void eval_error (const char *msg, int l, int c) const; @@ -109,8 +106,8 @@ tm_row_const (void) : rep (0) { } - tm_row_const (const tree_matrix_row& mr) - : rep (new tm_row_const_rep (mr)) { } + tm_row_const (const tree_argument_list& row) + : rep (new tm_row_const_rep (row)) { } tm_row_const (const tm_row_const& x) : rep (x.rep) { @@ -167,17 +164,17 @@ }; void -tm_row_const::tm_row_const_rep::init (const tree_matrix_row& mr) +tm_row_const::tm_row_const_rep::init (const tree_argument_list& row) { all_str = true; bool first_elem = true; - for (Pix p = mr.first (); p != 0; mr.next (p)) + for (Pix p = row.first (); p != 0; row.next (p)) { - tree_expression *elt = mr (p); + tree_expression *elt = row (p); - octave_value tmp = elt->eval (); + octave_value tmp = elt->rvalue (); if (error_state || tmp.is_undefined ()) break; @@ -313,7 +310,7 @@ for (Pix p = tm.first (); p != 0; tm.next (p)) { - tree_matrix_row *elt = tm (p); + tree_argument_list *elt = tm (p); tm_row_const tmp (*elt); @@ -383,78 +380,11 @@ } bool -tree_matrix_row::all_elements_are_constant (void) const -{ - for (Pix p = first (); p != 0; next (p)) - { - tree_expression *elt = this->operator () (p); - - if (! elt->is_constant ()) - return false; - } - - return true; -} - -tree_return_list * -tree_matrix_row::to_return_list (void) -{ - tree_return_list *retval = 0; - - bool first_elem = true; - - for (Pix p = first (); p != 0; next (p)) - { - tree_expression *elt = this->operator () (p); - - bool is_id = elt->is_identifier (); - - bool is_idx_expr = elt->is_index_expression (); - - if (is_id || is_idx_expr) - { - tree_index_expression *idx_expr; - - if (is_id) - { - tree_identifier *id = static_cast<tree_identifier *> (elt); - idx_expr = new tree_index_expression (id); - } - else - idx_expr = static_cast<tree_index_expression *> (elt); - - if (first_elem) - { - first_elem = false; - - retval = new tree_return_list (idx_expr); - } - else - retval->append (idx_expr); - } - else - { - delete retval; - retval = 0; - break; - } - } - - return retval; -} - -void -tree_matrix_row::accept (tree_walker& tw) -{ - tw.visit_matrix_row (*this); -} - -bool tree_matrix::all_elements_are_constant (void) const { for (Pix p = first (); p != 0; next (p)) { - tree_matrix_row *elt = this->operator () (p); + tree_argument_list *elt = this->operator () (p); if (! elt->all_elements_are_constant ()) return false; @@ -467,8 +397,21 @@ // Less ugly than before, anyway. // Looking better all the time. +octave_value_list +tree_matrix::rvalue (int nargout) +{ + octave_value_list retval; + + if (nargout > 1) + error ("invalid number of output arguments for matrix list"); + else + retval = rvalue (); + + return retval; +} + octave_value -tree_matrix::eval (bool /* print */) +tree_matrix::rvalue (void) { octave_value retval;
--- a/src/pt-mat.h +++ b/src/pt-mat.h @@ -42,42 +42,27 @@ // other matrices, variables, and functions. class -tree_matrix_row : public SLList<tree_expression *> +tree_matrix : public tree_expression, public SLList<tree_argument_list *> { public: - tree_matrix_row (tree_expression *e = 0) : SLList<tree_expression *> () - { - if (e) - append (e); - } - - ~tree_matrix_row (void) { } - - bool all_elements_are_constant (void) const; - - tree_return_list *to_return_list (void); - - void accept (tree_walker& tw); -}; - -class -tree_matrix : public tree_expression, public SLList<tree_matrix_row *> -{ -public: - - tree_matrix (tree_matrix_row *mr = 0) - : tree_expression (), SLList<tree_matrix_row *> () + tree_matrix (tree_argument_list *row = 0) + : tree_expression (), SLList<tree_argument_list *> () { - if (mr) - append (mr); + if (row) + append (row); } ~tree_matrix (void) { } bool all_elements_are_constant (void) const; - octave_value eval (bool print = false); + bool rvalue_ok (void) const + { return true; } + + octave_value rvalue (void); + + octave_value_list rvalue (int nargout); void accept (tree_walker& tw); };