Mercurial > hg > octave-nkf
changeset 2388:4be11abb8d8c
[project @ 1996-10-12 18:53:51 by jwe]
author | jwe |
---|---|
date | Sat, 12 Oct 1996 18:54:13 +0000 |
parents | be4616e36133 |
children | 3db75e5cdf7c |
files | src/pt-exp-base.cc src/pt-exp-base.h src/pt-exp.cc src/pt-exp.h |
diffstat | 4 files changed, 442 insertions(+), 264 deletions(-) [+] |
line wrap: on
line diff
--- a/src/pt-exp-base.cc +++ b/src/pt-exp-base.cc @@ -33,7 +33,7 @@ #include "error.h" #include "pager.h" -#include "pt-const.h" +#include "ov.h" #include "pt-exp-base.h" // Expressions. @@ -48,40 +48,7 @@ if (! error_state) { if (t1.is_defined ()) - { - if (t1.rows () == 0 || t1.columns () == 0) - { - t1 = 0.0; - int flag = Vpropagate_empty_matrices; - if (flag < 0) - warning ("%s: empty matrix used in conditional expression", - warn_for); - else if (flag == 0) - { - ::error ("%s: empty matrix used in conditional expression", - warn_for); - return expr_value; - } - } - else if (! t1.is_scalar_type ()) - { - octave_value t2 = t1.all (); - if (! error_state) - t1 = t2.all (); - } - - if (! error_state) - { - if (t1.is_real_scalar ()) - expr_value = t1.double_value () != 0.0; - else if (t1.is_complex_scalar ()) - expr_value = t1.complex_value () != 0.0; - else - panic_impossible (); - } - else - ::error ("%s: invalid type in conditional expression", warn_for); - } + return t1.is_true (); else ::error ("%s: undefined value used in conditional expression", warn_for);
--- a/src/pt-exp-base.h +++ b/src/pt-exp-base.h @@ -44,35 +44,8 @@ assignment, simple_assignment, multi_assignment, - add, - subtract, - multiply, - el_mul, - divide, - el_div, - leftdiv, - el_leftdiv, - power, - elem_pow, - cmp_lt, - cmp_le, - cmp_eq, - cmp_ge, - cmp_gt, - cmp_ne, - and_and, - or_or, - and, - or, - not, - unot, - uminus, - hermitian, - transpose, colon, index, - increment, - decrement, }; tree_expression (int l = -1, int c = -1, type et = unknown) @@ -113,8 +86,6 @@ 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;
--- a/src/pt-exp.cc +++ b/src/pt-exp.cc @@ -38,11 +38,12 @@ #include "input.h" #include "oct-obj.h" #include "pager.h" -#include "pt-const.h" +#include "ov.h" #include "pt-exp.h" #include "pt-fvc.h" #include "pt-misc.h" #include "pt-mvr.h" +#include "pt-pr-code.h" #include "pt-walk.h" #include "utils.h" @@ -69,7 +70,22 @@ if (id) { - id->bump_value (etype); + switch (etype) + { + case increment: + id->increment (); + break; + + case decrement: + id->decrement (); + break; + + default: + error ("prefix operator %d not implemented", etype); + break; + } + + if (error_state) eval_error (); else @@ -92,11 +108,11 @@ static char *op; switch (etype) { - case tree_expression::increment: + case increment: op = "++"; break; - case tree_expression::decrement: + case decrement: op = "--"; break; @@ -143,7 +159,22 @@ if (id) { retval = id->eval (print); - id->bump_value (etype); + + switch (etype) + { + case increment: + id->increment (); + break; + + case decrement: + id->decrement (); + break; + + default: + error ("postfix operator %d not implemented", etype); + break; + } + if (error_state) { retval = octave_value (); @@ -160,11 +191,11 @@ static char *op; switch (etype) { - case tree_expression::increment: + case increment: op = "++"; break; - case tree_expression::decrement: + case decrement: op = "--"; break; @@ -198,38 +229,48 @@ octave_value tree_unary_expression::eval (bool /* print */) { - if (error_state) - return octave_value (); - octave_value retval; - switch (etype) + if (error_state) + return retval; + + if (op) { - case tree_expression::not: - case tree_expression::uminus: - case tree_expression::hermitian: - case tree_expression::transpose: - if (op) + octave_value u = op->eval (false); + + if (error_state) + eval_error (); + else if (u.is_defined ()) { - octave_value u = op->eval (false); + switch (etype) + { + case not: + 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) - eval_error (); - else if (u.is_defined ()) { - retval = do_unary_op (u, etype); - if (error_state) - { - retval = octave_value (); - if (error_state) - eval_error (); - } + retval = octave_value (); + eval_error (); } } - break; - - default: - ::error ("unary operator %d not implemented", etype); - break; } return retval; @@ -241,20 +282,20 @@ static char *op; switch (etype) { - case tree_expression::not: + case not: op = "!"; break; - case tree_expression::uminus: + case uminus: op = "-"; break; - case tree_expression::hermitian: - op = "'"; + case transpose: + op = ".'"; break; - case tree_expression::transpose: - op = ".'"; + case hermitian: + op = "'"; break; default: @@ -287,118 +328,122 @@ octave_value tree_binary_expression::eval (bool /* print */) { - if (error_state) - return octave_value (); - octave_value retval; - switch (etype) + if (error_state) + return retval; + + if (op_lhs) { - case tree_expression::add: - case tree_expression::subtract: - case tree_expression::multiply: - case tree_expression::el_mul: - case tree_expression::divide: - case tree_expression::el_div: - case tree_expression::leftdiv: - case tree_expression::el_leftdiv: - case tree_expression::power: - case tree_expression::elem_pow: - case tree_expression::cmp_lt: - case tree_expression::cmp_le: - case tree_expression::cmp_eq: - case tree_expression::cmp_ge: - case tree_expression::cmp_gt: - case tree_expression::cmp_ne: - case tree_expression::and: - case tree_expression::or: - if (op_lhs) + octave_value a = op_lhs->eval (false); + + if (error_state) + eval_error (); + else if (a.is_defined () && op_rhs) { - octave_value a = op_lhs->eval (false); + octave_value b = op_rhs->eval (false); + if (error_state) eval_error (); - else if (a.is_defined () && op_rhs) + else if (b.is_defined ()) { - octave_value b = op_rhs->eval (false); - if (error_state) - eval_error (); - else if (b.is_defined ()) + octave_value::binary_op op = octave_value::unknown_binary_op; + + switch (etype) { - retval = do_binary_op (a, b, etype); - if (error_state) - { - retval = octave_value (); - if (error_state) - eval_error (); - } + case add: + op = octave_value::add; + break; + + case subtract: + op = octave_value::sub; + break; + + case multiply: + op = octave_value::mul; + break; + + case el_mul: + op = octave_value::el_mul; + break; + + case divide: + op = octave_value::div; + break; + + case el_div: + op = octave_value::el_div; + break; + + case leftdiv: + op = octave_value::ldiv; + break; + + case el_leftdiv: + op = octave_value::el_ldiv; + break; + + case power: + op = octave_value::pow; + break; + + case elem_pow: + op = octave_value::el_pow; + break; + + case cmp_lt: + op = octave_value::lt; + break; + + case cmp_le: + op = octave_value::le; + break; + + case cmp_eq: + op = octave_value::eq; + break; + + case cmp_ge: + op = octave_value::ge; + break; + + case cmp_gt: + op = octave_value::gt; + break; + + case cmp_ne: + op = octave_value::ne; + break; + + case and: + op = octave_value::el_and; + break; + + case or: + op = octave_value::el_or; + break; + + default: + ::error ("binary operator %d not implemented", etype); + break; + } + + if (! error_state) + retval = ::do_binary_op (op, a, b); + else + { + retval = octave_value (); + eval_error (); } } + else + eval_error (); } - break; - - case tree_expression::and_and: - case tree_expression::or_or: - { - bool result = false; - if (op_lhs) - { - octave_value a = op_lhs->eval (false); - if (error_state) - { - eval_error (); - break; - } - - bool a_true = a.is_true (); - if (error_state) - { - eval_error (); - break; - } - - if (a_true) - { - if (etype == tree_expression::or_or) - { - result = true; - goto done; - } - } - else - { - if (etype == tree_expression::and_and) - { - result = false; - goto done; - } - } - - if (op_rhs) - { - octave_value b = op_rhs->eval (false); - if (error_state) - { - eval_error (); - break; - } - - result = b.is_true (); - if (error_state) - { - eval_error (); - break; - } - } - } - done: - retval = octave_value ((double) result); - } - break; - - default: - ::error ("binary operator %d not implemented", etype); - break; + else + eval_error (); } + else + eval_error (); return retval; } @@ -409,83 +454,75 @@ static char *op; switch (etype) { - case tree_expression::add: + case add: op = "+"; break; - case tree_expression::subtract: + case subtract: op = "-"; break; - case tree_expression::multiply: + case multiply: op = "*"; break; - case tree_expression::el_mul: + case el_mul: op = ".*"; break; - case tree_expression::divide: + case divide: op = "/"; break; - case tree_expression::el_div: + case el_div: op = "./"; break; - case tree_expression::leftdiv: + case leftdiv: op = "\\"; break; - case tree_expression::el_leftdiv: + case el_leftdiv: op = ".\\"; break; - case tree_expression::power: + case power: op = "^"; break; - case tree_expression::elem_pow: + case elem_pow: op = ".^"; break; - case tree_expression::cmp_lt: + case cmp_lt: op = "<"; break; - case tree_expression::cmp_le: + case cmp_le: op = "<="; break; - case tree_expression::cmp_eq: + case cmp_eq: op = "=="; break; - case tree_expression::cmp_ge: + case cmp_ge: op = ">="; break; - case tree_expression::cmp_gt: + case cmp_gt: op = ">"; break; - case tree_expression::cmp_ne: + case cmp_ne: op = "!="; break; - case tree_expression::and_and: - op = "&&"; - break; - - case tree_expression::or_or: - op = "||"; - break; - - case tree_expression::and: + case and: op = "&"; break; - case tree_expression::or: + case or: op = "|"; break; @@ -504,7 +541,7 @@ char *op = oper (); ::error ("evaluating binary operator `%s' near line %d, column %d", - op, line (), column ()); + op, line (), column ()); } } @@ -514,6 +551,97 @@ tw.visit_binary_expression (*this); } +// Boolean expressions. + +octave_value +tree_boolean_expression::eval (bool /* print */) +{ + octave_value retval; + + if (error_state) + return retval; + + bool result = false; + + if (op_lhs) + { + octave_value a = op_lhs->eval (false); + + if (error_state) + eval_error (); + else + { + bool a_true = a.is_true (); + + if (error_state) + eval_error (); + else + { + if (a_true) + { + if (etype == or) + { + result = true; + goto done; + } + } + else + { + if (etype == and) + goto done; + } + + if (op_rhs) + { + octave_value b = op_rhs->eval (false); + + if (error_state) + eval_error (); + else + { + result = b.is_true (); + + if (error_state) + eval_error (); + } + } + else + eval_error (); + + done: + + if (! error_state) + retval = octave_value ((double) result); + } + } + } + else + eval_error (); + + return retval; +} + +char * +tree_boolean_expression::oper (void) const +{ + static char *op; + switch (etype) + { + case and: + op = "&&"; + break; + + case or: + op = "||"; + break; + + default: + op = "<unknown>"; + break; + } + return op; +} + // Simple assignment expressions. tree_simple_assignment_expression::tree_simple_assignment_expression @@ -563,6 +691,11 @@ return lhs->ident (); } +// ??? FIXME ??? -- should this return the value of the RHS instead? + +// ??? FIXME ??? -- should octave_variable_reference::assign return +// the right thing for us to return? + octave_value tree_simple_assignment_expression::eval (bool print) { @@ -585,31 +718,43 @@ error ("value on right hand side of assignment is undefined"); eval_error (); } - else if (! index) - { - retval = lhs->assign (rhs_val); - if (error_state) - eval_error (); - } else { - // Extract the arguments into a simple vector. - - octave_value_list args = index->convert_to_const_vector (); + octave_variable_reference ult (lhs); if (error_state) eval_error (); else { - int nargin = args.length (); + if (index) + { + // Extract the arguments into a simple vector. - if (error_state) - eval_error (); - else if (nargin > 0) - { - retval = lhs->assign (rhs_val, args); + octave_value_list args = index->convert_to_const_vector (); + if (error_state) eval_error (); + else + { + int nargin = args.length (); + + if (nargin > 0) + { + ult.assign (args, rhs_val); + + if (error_state) + eval_error (); + else + retval = ult.value (); + } + else + error ("??? invalid index list ???"); + } + } + else + { + ult.assign (rhs_val); + retval = ult.value (); } } }
--- a/src/pt-exp.h +++ b/src/pt-exp.h @@ -45,12 +45,19 @@ { public: - tree_prefix_expression (int l = -1, int c = -1) - : tree_expression (l, c), id (0) { } + enum type + { + unknown, + increment, + decrement + }; - tree_prefix_expression (tree_identifier *t, tree_expression::type et, - int l = -1, int c = -1) - : tree_expression (l, c, et), id (t) { } + tree_prefix_expression (int l = -1, int c = -1, type t = unknown) + : tree_expression (l, c), id (0), etype (t) { } + + 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 (void); @@ -71,6 +78,9 @@ // Currently, a prefix expression can only apply to an identifier. tree_identifier *id; + + // The type of the expression. + type etype; }; // Postfix expressions. @@ -80,12 +90,19 @@ { public: - tree_postfix_expression (int l = -1, int c = -1) - : tree_expression (l, c), id (0) { } + enum type + { + unknown, + increment, + decrement + }; - tree_postfix_expression (tree_identifier *t, tree_expression::type et, - int l = -1, int c = -1) - : tree_expression (l, c, et), id (t) { } + tree_postfix_expression (int l = -1, int c = -1, type t = unknown) + : tree_expression (l, c), id (0), etype (t) { } + + 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 (void); @@ -103,6 +120,9 @@ // Currently, a prefix expression can only apply to an identifier. tree_identifier *id; + + // The type of the expression. + type etype; }; // Unary expressions. @@ -112,12 +132,22 @@ { public: - tree_unary_expression (int l = -1, int c = -1) - : tree_expression (l, c), op (0) { } + enum type + { + unknown, + not, + unot, + uminus, + hermitian, + transpose + }; - tree_unary_expression (tree_expression *a, tree_expression::type t, - int l = -1, int c = -1) - : tree_expression (l, c, t), op (a) { } + 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; } @@ -128,6 +158,8 @@ char *oper (void) const; + bool is_prefix_op (void) { return (etype == not || etype == uminus); } + tree_expression *operand (void) { return op; } void accept (tree_walker& tw); @@ -136,6 +168,9 @@ // The operand for the expression. tree_expression *op; + + // The type of the expression. + type etype; }; // Binary expressions. @@ -145,12 +180,35 @@ { public: - tree_binary_expression (int l = -1, int c = -1) - : tree_expression (l, c), op_lhs (0), op_rhs (0) { } + enum type + { + unknown, + add, + subtract, + multiply, + el_mul, + divide, + el_div, + leftdiv, + el_leftdiv, + power, + elem_pow, + cmp_lt, + cmp_le, + cmp_eq, + cmp_ge, + cmp_gt, + cmp_ne, + and, + or + }; + + tree_binary_expression (int l = -1, int c = -1, type t = unknown) + : tree_expression (l, c), op_lhs (0), op_rhs (0), etype (t) { } tree_binary_expression (tree_expression *a, tree_expression *b, - tree_expression::type t, int l = -1, int c = -1) - : tree_expression (l, c, t), op_lhs (a), op_rhs (b) { } + int l = -1, int c = -1, type t = unknown) + : tree_expression (l, c), op_lhs (a), op_rhs (b), etype (t) { } ~tree_binary_expression (void) { @@ -169,11 +227,49 @@ void accept (tree_walker& tw); -private: +protected: // The operands for the expression. tree_expression *op_lhs; tree_expression *op_rhs; + +private: + + // The type of the expression. + type etype; +}; + +// Boolean expressions. + +class +tree_boolean_expression : public tree_binary_expression +{ +public: + + enum type + { + unknown, + and, + or + }; + + tree_boolean_expression (int l = -1, int c = -1, type t) + : tree_binary_expression (l, c), etype (t) { } + + tree_boolean_expression (tree_expression *a, tree_expression *b, + int l = -1, int c = -1, type t = unknown) + : tree_binary_expression (a, b, l, c), etype (t) { } + + ~tree_boolean_expression (void) { } + + octave_value eval (bool print); + + char *oper (void) const; + +private: + + // The type of the expression. + type etype; }; // Simple assignment expressions. @@ -270,7 +366,6 @@ preserve = plhs; ans_ass = ans_assign; } - }; // Colon expressions.