Mercurial > hg > octave-terminal
changeset 3203:bc61b0e8d60e
[project @ 1998-10-30 20:26:27 by jwe]
author | jwe |
---|---|
date | Fri, 30 Oct 1998 20:26:31 +0000 |
parents | 44d82b369c78 |
children | 81738e630f57 |
files | doc/interpreter/preface.texi liboctave/ChangeLog liboctave/boolMatrix.cc liboctave/boolMatrix.h src/ChangeLog src/Makefile.in src/OPERATORS/op-b-b.cc src/OPERATORS/op-bm-bm.cc src/OPERATORS/op-cm-cm.cc src/OPERATORS/op-cs-cs.cc src/OPERATORS/op-m-m.cc src/OPERATORS/op-s-s.cc src/OPERATORS/op-str-str.cc src/oct-lvalue.cc src/oct-lvalue.h src/ops.h src/ov-base.cc src/ov-base.h src/ov-bool-mat.h src/ov-bool.h src/ov-ch-mat.h src/ov-complex.h src/ov-cx-mat.h src/ov-range.cc src/ov-range.h src/ov-re-mat.h src/ov-scalar.h src/ov-str-mat.cc src/ov-str-mat.h src/ov-typeinfo.cc src/ov-typeinfo.h src/ov.cc src/ov.h src/parse.y src/pt-unop.cc src/pt-unop.h |
diffstat | 36 files changed, 937 insertions(+), 391 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/interpreter/preface.texi +++ b/doc/interpreter/preface.texi @@ -132,7 +132,7 @@ @code{ferror}. @item -Tony Richardson @email{arichard@stark.cc.oh.us} wrote Octave's +Tony Richardson @email{arichard@@stark.cc.oh.us} wrote Octave's image processing functions as well as most of the original polynomial functions.
--- a/liboctave/ChangeLog +++ b/liboctave/ChangeLog @@ -1,3 +1,7 @@ +Thu Oct 29 18:57:50 1998 John W. Eaton <jwe@bevo.che.wisc.edu> + + * boolMatrix.cc (boolMatrix::operator !): New function. + Fri Oct 23 21:46:20 1998 John W. Eaton <jwe@bevo.che.wisc.edu> * pathsearch.h (dir_path::default_path): New data member.
--- a/liboctave/boolMatrix.cc +++ b/liboctave/boolMatrix.cc @@ -75,6 +75,25 @@ return result; } +// unary operations + +boolMatrix +boolMatrix::operator ! (void) const +{ + int nr = rows (); + int nc = cols (); + + boolMatrix b (nr, nc); + + for (int j = 0; j < nc; j++) + for (int i = 0; i < nr; i++) + b.elem (i, j) = ! elem (i, j); + + return b; +} + +// other operations + boolMatrix boolMatrix::all (void) const {
--- a/liboctave/boolMatrix.h +++ b/liboctave/boolMatrix.h @@ -57,6 +57,12 @@ boolMatrix transpose (void) const; + // unary operations + + boolMatrix operator ! (void) const; + + // other operations + boolMatrix all (void) const; boolMatrix any (void) const;
--- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,144 @@ +Fri Oct 30 08:39:30 1998 John W. Eaton <jwe@bevo.che.wisc.edu> + + * parse.y (matrix): Dont' forget to reset + lexer_flags.looking_at_matrix_or_assign_lhs. + + * oct-lvalue.cc (octave_lvalue::assign): Don't call change + function if error occurs. + (octave_lvalue::do_unary_op): If we have an index, fail with message. + Thu Oct 29 09:27:04 1998 John W. Eaton <jwe@bevo.che.wisc.edu> + * ov.cc (do_binary_op): Protect against invalid type conversions. + (try_assignment_with_conversion): Likewise. + (do_unary_op): Likewise. + + * ov.h (OV_UNOP_FN, OV_UNOP_OP, OV_UNOP_FN_OP): New macros. + Use them to define not, uminus, transpose, hermitian functions + and operators ! and -. + (OV_BINOP_FN, OV_BINOP_OP, OV_BINOP_FN_OP): New macros. + Use them to define add, sub, mul, div, pow, ldiv, lshift, rshift, + lt, le, eq, ge, gt, ne, el_mul, el_div, el_pow, el_ldiv, el_and, + el_or, struct_ref, functions and operators <, <=, ==, >=, >, !=, + +, -, *, and /. + + * ops.h (CONVDECLX): New macro. + * ov-base.cc (matrix_conv, complex_matrix_conv, string_conv): + Use it to declare these functions. + + * ops.h (CONVDECL, INSTALL_WIDENOP): + Prefix function name with `oct_conv_'. + (INSTALL_BINOP, BINOPDECL): Prefix function name with `oct_binop_'. + (INSTALL_ASSIGNOP, INSTALL_ASSIGNANYOP, ASSIGNOPDECL): + Prefix function name with `oct_assignop_'. + (UNOPDECL, DEFNCUNOP_METHOD, INSTALL_UNOP, INSTALL_NCUNOP): + Prefix function name with `oct_unop_'. + + * ov-str-mat.cc (default_numeric_conversion_function): + Return 0 if conversion fails. + + * parse.y (make_prefix_op, make_postfix_op): Use + octave_value::unary_op enum. + + * pt-unop.cc (tree_prefix_expression::rvalue): Use new unary_op + functions from octave_value and octave_lvalue classes. + (tree_prefix_expression::rvalue): Likewise. + + * pt-unop.cc (tree_unary_expression::oper): Move here. + (tree_prefix_expression::oper, tree_postfix_expression): From here. + + * pt-unop.h (tree_prefix_expression, tree_postfix_expression): + Delete enums. + (tree_unary_expression): Use octave_value::unary_op enum. + * parse.y (make_prefix_op, make_postfix_op): Likewise. + + * oct-lvalue.h (octave_lvalue::do_unary_op): New function. + (octave_lvalue::increment, octave_lvalue::decrement): Delete. + + * ov-typeinfo.h (octave_value_typeinfo::non_const_unary_ops): + New data member. + * ov-typeinfo.h (octave_value_typeinfo::lookup_non_const_unary_op): + New function. + * ov-typeinfo.cc (octave_value_typeinfo::register_non_const_unary_op): + New function. + (octave_value_typeinfo::do_register_non_const_unary_op): Ditto. + (octave_value_typeinfo::do_lookup_non_const_unary_op): Ditto. + + * ov.cc (octave_value::do_non_const_unary_op): New function. + + * Makefile.in (OP_XSRC): Add op-chm.cc and op-range.cc to the list. + + * OPERATORS/op-str-str.cc: Define string matrix unary operators here. + (install_str_str_ops): Install them here. + * ov-bool-mat.h (octave_bool_matrix::transpose, + octave_bool_matrix_value::hermitian): Delete. + + * OPERATORS/op-chm.cc: New file. Define char matrix unary operators. + (install_chm_ops): Install them here. + * ov-ch-mat.h (octave_char_matrix::transpose, + octave_char_matrix_value::hermitian): Delete. + * ops.cc (install_ops): Call install_chm_ops. + + * OPERATORS/op-bm-bm.cc: Define bool matrix unary operators here. + (install_bm_bm_ops): Install them here. + * ov-bool-mat.h (octave_bool_matrix::transpose, + octave_bool_matrix_value::hermitian): Delete. + + * ov-bool.h (octave_bool::not, octave_bool::uminus, + octave_bool::transpose, octave_bool::hermitian): Delete. + + * OPERATORS/op-cs-cs.cc: Define complex scalar unary operators here. + (install_cs_cs_ops): Install them here. + * ov-complex.h (octave_complex::not, octave_complex::uminus, + octave_complex::transpose, octave_complex::hermitian): Delete. + + * OPERATORS/op-cm-cm.cc: Define complex matrix unary operators here. + (install_cm_cm_ops): Install them here. + * ov-cx-mat.h (octave_complex_matrix::not, + octave_complex_matrix::uminus, octave_complex_matrix::transpose, + octave_complex_matrix::hermitian): Delete. + + * OPERATORS/op-m-m.cc: Define matrix unary operators here. + (install_m_m_ops): Install them here. + * ov-re-mat.h (octave_matrix::not, octave_matrix::uminus, + octave_matrix::transpose, octave_matrix::hermitian): Delete. + + * OPERATORS/op-range.cc: New file. Define range unary operators. + (install_range_ops): Install them here. + * ov-range.h (octave_range::not, octave_range::uminus, + octave_range::transpose, octave_range::hermitian): Delete. + * ops.cc (install_ops): Call install_range_ops. + + * OPERATORS/op-s-s.cc: Define scalar unary operators here. + (install_s_s_ops): Install them here. + * ov-scalar.h (octave_scalar::not, octave_scalar::uminus, + octave_scalar::transpose, octave_scalar::hermitian): Delete. + + * ops.h (INSTALL_UNOP, CAST_UNOP_ARG, UNOPDECL, DEFUNOPX, DEFUNOP, + DEFUNOP_OP, DEFUNOP_FN): New macros. + + * ov.h (unary_op_fcn): New typedef. + (octave_value::unary_op): New enum. + * ov.cc (octave_value::octave_value): New function. + + * ov.h (octave_value::not, octave_value::uminus, + octave_value::transpose, octave_value::hermitian, + octave_value::increment, octave_value::decrement): Delete. + + * ov-base.cc (octave_base_value::not, octave_base_value::uminus, + octave_base_value::transpose, octave_base_value::hermitian, + octave_base_value::increment, octave_base_value::decrement): Delete. + + * ov.cc (gripe_unary_op): New function. + (do_unary_op): New function. + * ov-typeinfo.h (octave_value_typeinfo::unary_ops): + New data member. + * ov-typeinfo.cc (octave_value_info::register_unary_op, + octave_value_info::do_register_unary_op, + octave_value_info::lookup_unary_op, + octave_value_info::do_lookup_unary_op): + New functions. + * ov-list.cc (Fsplice): Use new octave_value::int_value function here. (octave_list::do_index_op): Likewise. (octave_list::assign): Likewise.
--- a/src/Makefile.in +++ b/src/Makefile.in @@ -94,13 +94,13 @@ TI_SRC := $(addprefix TEMPLATE-INST/, $(TI_XSRC)) -OP_XSRC := op-b-b.cc op-bm-bm.cc op-cm-cm.cc op-cm-cs.cc \ +OP_XSRC := op-b-b.cc op-bm-bm.cc op-chm.cc op-cm-cm.cc op-cm-cs.cc \ op-cm-m.cc op-cm-s.cc op-cs-cm.cc op-cs-cs.cc op-cs-m.cc \ - op-cs-s.cc op-list.cc op-m-cm.cc op-m-cs.cc op-m-m.cc op-m-s.cc \ - op-s-cm.cc op-s-cs.cc op-s-m.cc op-s-s.cc op-str-str.cc \ - op-fil-b.cc op-fil-bm.cc op-fil-cm.cc op-fil-cs.cc \ + op-cs-s.cc op-fil-b.cc op-fil-bm.cc op-fil-cm.cc op-fil-cs.cc \ op-fil-m.cc op-fil-s.cc op-fil-lis.cc op-fil-rec.cc \ - op-fil-str.cc + op-fil-str.cc op-list.cc op-m-cm.cc op-m-cs.cc op-m-m.cc \ + op-m-s.cc op-range.cc op-s-cm.cc op-s-cs.cc op-s-m.cc \ + op-s-s.cc op-str-str.cc OP_SRC := $(addprefix OPERATORS/, $(OP_XSRC))
--- a/src/OPERATORS/op-b-b.cc +++ b/src/OPERATORS/op-b-b.cc @@ -36,6 +36,14 @@ #include "xdiv.h" #include "xpow.h" +// bool unary ops. + +// scalar unary ops. + +DEFUNOP_OP (not, bool, !) +DEFUNOP_OP (transpose, bool, /* no-op */) +DEFUNOP_OP (hermitian, bool, /* no-op */) + // bool by bool ops. DEFBINOP_OP (eq, bool, bool, ==) @@ -44,6 +52,10 @@ void install_b_b_ops (void) { + INSTALL_UNOP (not, octave_bool, not); + INSTALL_UNOP (transpose, octave_bool, transpose); + INSTALL_UNOP (hermitian, octave_bool, hermitian); + INSTALL_BINOP (eq, octave_bool, octave_bool, eq); INSTALL_BINOP (ne, octave_bool, octave_bool, ne); }
--- a/src/OPERATORS/op-bm-bm.cc +++ b/src/OPERATORS/op-bm-bm.cc @@ -36,6 +36,17 @@ #include "xdiv.h" #include "xpow.h" +// unary bool matrix ops. + +DEFUNOP_OP (not, bool_matrix, !) + +DEFUNOP (transpose, bool_matrix) +{ + CAST_UNOP_ARG (const octave_bool_matrix&); + + return octave_value (v.bool_matrix_value().transpose ()); +} + // bool matrix by bool matrix ops. DEFBINOP_OP (eq, bool_matrix, bool_matrix, ==) @@ -44,6 +55,10 @@ void install_bm_bm_ops (void) { + INSTALL_UNOP (not, octave_bool_matrix, not); + INSTALL_UNOP (transpose, octave_bool_matrix, transpose); + INSTALL_UNOP (hermitian, octave_bool_matrix, transpose); + INSTALL_BINOP (eq, octave_bool_matrix, octave_bool_matrix, eq); INSTALL_BINOP (ne, octave_bool_matrix, octave_bool_matrix, ne); }
--- a/src/OPERATORS/op-cm-cm.cc +++ b/src/OPERATORS/op-cm-cm.cc @@ -36,6 +36,28 @@ #include "xdiv.h" #include "xpow.h" +// unary complex matrix ops. + +DEFUNOP_OP (not, complex_matrix, !) +DEFUNOP_OP (uminus, complex_matrix, -) + +DEFUNOP (transpose, complex_matrix) +{ + CAST_UNOP_ARG (const octave_complex_matrix&); + + return octave_value (v.complex_matrix_value().transpose ()); +} + +DEFUNOP (hermitian, complex_matrix) +{ + CAST_UNOP_ARG (const octave_complex_matrix&); + + return octave_value (v.complex_matrix_value().hermitian ()); +} + +DEFNCUNOP_METHOD (incr, complex_matrix, increment) +DEFNCUNOP_METHOD (decr, complex_matrix, decrement) + // complex matrix by complex matrix ops. DEFBINOP_OP (add, complex_matrix, complex_matrix, +) @@ -78,6 +100,14 @@ void install_cm_cm_ops (void) { + INSTALL_UNOP (not, octave_complex_matrix, not); + INSTALL_UNOP (uminus, octave_complex_matrix, uminus); + INSTALL_UNOP (transpose, octave_complex_matrix, transpose); + INSTALL_UNOP (hermitian, octave_complex_matrix, hermitian); + + INSTALL_NCUNOP (incr, octave_complex_matrix, incr); + INSTALL_NCUNOP (decr, octave_complex_matrix, decr); + INSTALL_BINOP (add, octave_complex_matrix, octave_complex_matrix, add); INSTALL_BINOP (sub, octave_complex_matrix, octave_complex_matrix, sub); INSTALL_BINOP (mul, octave_complex_matrix, octave_complex_matrix, mul);
--- a/src/OPERATORS/op-cs-cs.cc +++ b/src/OPERATORS/op-cs-cs.cc @@ -37,6 +37,28 @@ #include "xdiv.h" #include "xpow.h" +// unary complex scalar ops. + +DEFUNOP (not, complex) +{ + CAST_UNOP_ARG (const octave_complex&); + + return octave_value (v.complex_value () == 0.0); +} + +DEFUNOP_OP (uminus, complex, -) +DEFUNOP_OP (transpose, complex, /* no-op */) + +DEFUNOP (hermitian, complex) +{ + CAST_UNOP_ARG (const octave_complex&); + + return octave_value (conj (v.complex_value ())); +} + +DEFNCUNOP_METHOD (incr, complex, increment) +DEFNCUNOP_METHOD (decr, complex, decrement) + // complex scalar by complex scalar ops. DEFBINOP_OP (add, complex, complex, +) @@ -163,6 +185,14 @@ void install_cs_cs_ops (void) { + INSTALL_UNOP (not, octave_complex, not); + INSTALL_UNOP (uminus, octave_complex, uminus); + INSTALL_UNOP (transpose, octave_complex, transpose); + INSTALL_UNOP (hermitian, octave_complex, hermitian); + + INSTALL_NCUNOP (incr, octave_complex, incr); + INSTALL_NCUNOP (decr, octave_complex, decr); + INSTALL_BINOP (add, octave_complex, octave_complex, add); INSTALL_BINOP (sub, octave_complex, octave_complex, sub); INSTALL_BINOP (mul, octave_complex, octave_complex, mul);
--- a/src/OPERATORS/op-m-m.cc +++ b/src/OPERATORS/op-m-m.cc @@ -36,6 +36,21 @@ #include "xdiv.h" #include "xpow.h" +// matrix unary ops. + +DEFUNOP_OP (not, matrix, !) +DEFUNOP_OP (uminus, matrix, -) + +DEFUNOP (transpose, matrix) +{ + CAST_UNOP_ARG (const octave_matrix&); + + return octave_value (v.matrix_value().transpose ()); +} + +DEFNCUNOP_METHOD (incr, matrix, increment) +DEFNCUNOP_METHOD (decr, matrix, decrement) + // matrix by matrix ops. DEFBINOP_OP (add, matrix, matrix, +) @@ -83,6 +98,14 @@ void install_m_m_ops (void) { + INSTALL_UNOP (not, octave_matrix, not); + INSTALL_UNOP (uminus, octave_matrix, uminus); + INSTALL_UNOP (transpose, octave_matrix, transpose); + INSTALL_UNOP (hermitian, octave_matrix, transpose); + + INSTALL_NCUNOP (incr, octave_matrix, incr); + INSTALL_NCUNOP (decr, octave_matrix, decr); + INSTALL_BINOP (add, octave_matrix, octave_matrix, add); INSTALL_BINOP (sub, octave_matrix, octave_matrix, sub); INSTALL_BINOP (mul, octave_matrix, octave_matrix, mul);
--- a/src/OPERATORS/op-s-s.cc +++ b/src/OPERATORS/op-s-s.cc @@ -37,6 +37,16 @@ #include "xdiv.h" #include "xpow.h" +// scalar unary ops. + +DEFUNOP_OP (not, scalar, !) +DEFUNOP_OP (uminus, scalar, -) +DEFUNOP_OP (transpose, scalar, /* no-op */) +DEFUNOP_OP (hermitian, scalar, /* no-op */) + +DEFNCUNOP_METHOD (incr, scalar, increment) +DEFNCUNOP_METHOD (decr, scalar, decrement) + // scalar by scalar ops. DEFBINOP_OP (add, scalar, scalar, +) @@ -132,6 +142,14 @@ void install_s_s_ops (void) { + INSTALL_UNOP (not, octave_scalar, not); + INSTALL_UNOP (uminus, octave_scalar, uminus); + INSTALL_UNOP (transpose, octave_scalar, transpose); + INSTALL_UNOP (hermitian, octave_scalar, hermitian); + + INSTALL_NCUNOP (incr, octave_scalar, incr); + INSTALL_NCUNOP (decr, octave_scalar, decr); + INSTALL_BINOP (add, octave_scalar, octave_scalar, add); INSTALL_BINOP (sub, octave_scalar, octave_scalar, sub); INSTALL_BINOP (mul, octave_scalar, octave_scalar, mul);
--- a/src/OPERATORS/op-str-str.cc +++ b/src/OPERATORS/op-str-str.cc @@ -34,6 +34,15 @@ #include "ov-typeinfo.h" #include "ops.h" +// string unary ops. + +DEFUNOP (transpose, matrix) +{ + CAST_UNOP_ARG (const octave_char_matrix_str&); + + return octave_value (v.char_matrix_value().transpose (), true); +} + // string by string ops. DEFBINOP (eq, char_matrix_str, char_matrix_str) @@ -104,6 +113,9 @@ void install_str_str_ops (void) { + INSTALL_UNOP (transpose, octave_char_matrix_str, transpose); + INSTALL_UNOP (hermitian, octave_char_matrix_str, transpose); + INSTALL_BINOP (eq, octave_char_matrix_str, octave_char_matrix_str, eq); INSTALL_BINOP (ne, octave_char_matrix_str, octave_char_matrix_str, ne);
--- a/src/oct-lvalue.cc +++ b/src/oct-lvalue.cc @@ -24,6 +24,7 @@ #include <config.h> #endif +#include "error.h" #include "oct-obj.h" #include "oct-lvalue.h" #include "ov.h" @@ -34,7 +35,7 @@ octave_value saved_val; if (chg_fcn) - octave_value saved_val = *val; + saved_val = *val; if (idx.empty ()) { @@ -51,7 +52,28 @@ val->assign_struct_elt (op, struct_elt_name, idx, rhs); } - if (chg_fcn && chg_fcn () < 0) + if (chg_fcn && ! error_state && chg_fcn () < 0) + *val = saved_val; +} + +void +octave_lvalue::do_unary_op (octave_value::unary_op op) +{ + octave_value saved_val; + + if (chg_fcn) + saved_val = *val; + + if (idx.empty ()) + val->do_non_const_unary_op (op); + else + { + string on = octave_value::unary_op_as_string (op); + error ("indexed operations not implemented yet for operator `%s'", + on.c_str ()); + } + + if (chg_fcn && ! error_state && chg_fcn () < 0) *val = saved_val; }
--- a/src/oct-lvalue.h +++ b/src/oct-lvalue.h @@ -82,11 +82,7 @@ void clear_index (void) { idx = octave_value_list (); } - // XXX FIXME XXX -- need to handle index increment and decrement too. - - void increment (void) { val->increment (); } - - void decrement (void) { val->decrement (); } + void do_unary_op (octave_value::unary_op op); octave_value value (void) {
--- a/src/ops.h +++ b/src/ops.h @@ -25,17 +25,27 @@ extern void install_ops (void); +#define INSTALL_UNOP(op, t, f) \ + octave_value_typeinfo::register_unary_op \ + (octave_value::op, t::static_type_id (), oct_unop_ ## f); + +#define INSTALL_NCUNOP(op, t, f) \ + octave_value_typeinfo::register_non_const_unary_op \ + (octave_value::op, t::static_type_id (), oct_unop_ ## f); + #define INSTALL_BINOP(op, t1, t2, f) \ octave_value_typeinfo::register_binary_op \ - (octave_value::op, t1::static_type_id (), t2::static_type_id (), f); + (octave_value::op, t1::static_type_id (), t2::static_type_id (), \ + oct_binop_ ## f); #define INSTALL_ASSIGNOP(op, t1, t2, f) \ octave_value_typeinfo::register_assign_op \ - (octave_value::op, t1::static_type_id (), t2::static_type_id (), f); + (octave_value::op, t1::static_type_id (), t2::static_type_id (), \ + oct_assignop_ ## f); #define INSTALL_ASSIGNANYOP(op, t1, f) \ octave_value_typeinfo::register_assignany_op \ - (octave_value::op, t1::static_type_id (), f); + (octave_value::op, t1::static_type_id (), oct_assignop_ ## f); #define INSTALL_ASSIGNCONV(t1, t2, tr) \ octave_value_typeinfo::register_pref_assign_conv \ @@ -43,7 +53,7 @@ #define INSTALL_WIDENOP(t1, t2, f) \ octave_value_typeinfo::register_widening_op \ - (t1::static_type_id (), t2::static_type_id (), f); + (t1::static_type_id (), t2::static_type_id (), oct_conv_ ## f); #define BOOL_OP1(xt, xn, get_x, yt, yn, get_y) \ xt xn = get_x; \ @@ -115,6 +125,9 @@ } \ while (0) +#define CAST_UNOP_ARG(t) \ + t v = DYNAMIC_CAST (t, a); + #define CAST_BINOP_ARGS(t1, t2) \ t1 v1 = DYNAMIC_CAST (t1, a1); \ t2 v2 = DYNAMIC_CAST (t2, a2); @@ -124,7 +137,9 @@ #define ASSIGNOPDECL(name) \ static octave_value \ - name (octave_value& a1, const octave_value_list& idx, const octave_value& a2) + oct_assignop_ ## name (octave_value& a1, \ + const octave_value_list& idx, \ + const octave_value& a2) #define DEFASSIGNOP(name, t1, t2) \ ASSIGNOPDECL (name) @@ -149,14 +164,52 @@ #define CONVDECL(name) \ static octave_value * \ - name (const octave_value& a) + oct_conv_ ## name (const octave_value& a) + +#define CONVDECLX(name) \ + static octave_value * \ + oct_conv_ ## name (const octave_value&) #define DEFCONV(name, from, to) \ CONVDECL (name) +#define UNOPDECL(name, a) \ + static octave_value \ + oct_unop_ ## name (const octave_value& a) + +#define DEFUNOPX(name, t) \ + UNOPDECL (name, , ) + +#define DEFUNOP(name, t) \ + UNOPDECL (name, a) + +#define DEFUNOP_OP(name, t, op) \ + UNOPDECL (name, a) \ + { \ + CAST_UNOP_ARG (const octave_ ## t&); \ + return octave_value (op v.t ## _value ()); \ + } + +// XXX FIXME XXX -- in some cases, the constructor isn't necessary. + +#define DEFUNOP_FN(name, t, f) \ + UNOPDECL (name, a) \ + { \ + CAST_UNOP_ARG (const octave_ ## t&); \ + return octave_value (f (v.t ## _value ())); \ + } + +#define DEFNCUNOP_METHOD(name, t, method) \ + static void \ + oct_unop_ ## name (octave_value& a) \ + { \ + CAST_UNOP_ARG (octave_ ## t&); \ + v.method (); \ + } + #define BINOPDECL(name, a1, a2) \ static octave_value \ - name (const octave_value& a1, const octave_value& a2) + oct_binop_ ## name (const octave_value& a1, const octave_value& a2) #define DEFBINOPX(name, t1, t2) \ BINOPDECL (name, , )
--- a/src/ov-base.cc +++ b/src/ov-base.cc @@ -339,64 +339,17 @@ return retval; } -octave_value -octave_base_value::not (void) const -{ - octave_value retval; - gripe_wrong_type_arg ("octave_base_value::not()", type_name ()); - return retval; -} - -octave_value -octave_base_value::uminus (void) const -{ - octave_value retval; - gripe_wrong_type_arg ("octave_base_value::uminus()", type_name ()); - return retval; -} - -octave_value -octave_base_value::transpose (void) const -{ - octave_value retval; - gripe_wrong_type_arg ("octave_base_value::transpose()", type_name ()); - return retval; -} - -octave_value -octave_base_value::hermitian (void) const -{ - octave_value retval; - gripe_wrong_type_arg ("octave_base_value::hermitian()", type_name ()); - return retval; -} - -void -octave_base_value::increment (void) -{ - gripe_wrong_type_arg ("octave_base_value::increment()", type_name ()); -} - -void -octave_base_value::decrement (void) -{ - gripe_wrong_type_arg ("octave_base_value::decrement()", type_name ()); -} - -static octave_value * -matrix_conv (const octave_value&) +CONVDECLX (matrix_conv) { return new octave_matrix (); } -static octave_value * -complex_matrix_conv (const octave_value&) +CONVDECLX (complex_matrix_conv) { return new octave_complex_matrix (); } -static octave_value * -string_conv (const octave_value&) +CONVDECLX (string_conv) { return new octave_char_matrix_str (); }
--- a/src/ov-base.h +++ b/src/ov-base.h @@ -184,18 +184,6 @@ boolMatrix bool_matrix_value (void) const; - octave_value not (void) const; - - octave_value uminus (void) const; - - octave_value transpose (void) const; - - octave_value hermitian (void) const; - - void increment (void); - - void decrement (void); - octave_value convert_to_str (void) const; void convert_to_row_or_column_vector (void);
--- a/src/ov-bool-mat.h +++ b/src/ov-bool-mat.h @@ -131,12 +131,6 @@ octave_value convert_to_str (void) const { return octave_value (matrix); } - octave_value transpose (void) const - { return octave_value (matrix.transpose ()); } - - octave_value hermitian (void) const - { return octave_value (matrix.transpose ()); } - void print (ostream& os, bool pr_as_read_syntax = false) const; void print_raw (ostream& os, bool pr_as_read_syntax = false) const;
--- a/src/ov-bool.h +++ b/src/ov-bool.h @@ -119,14 +119,6 @@ boolMatrix bool_matrix_value (void) const { return boolMatrix (1, 1, scalar); } - octave_value not (void) const { return octave_value (! scalar); } - - octave_value uminus (void) const { return octave_value (- (double) scalar); } - - octave_value transpose (void) const { return octave_value (scalar); } - - octave_value hermitian (void) const { return octave_value (scalar); } - octave_value convert_to_str (void) const; void print (ostream& os, bool pr_as_read_syntax = false) const;
--- a/src/ov-ch-mat.h +++ b/src/ov-ch-mat.h @@ -134,12 +134,6 @@ octave_value convert_to_str (void) const { return octave_value (matrix, true); } - octave_value transpose (void) const - { return octave_value (matrix.transpose ()); } - - octave_value hermitian (void) const - { return octave_value (matrix.transpose ()); } - void print (ostream& os, bool pr_as_read_syntax = false) const; void print_raw (ostream& os, bool pr_as_read_syntax = false) const;
--- a/src/ov-complex.h +++ b/src/ov-complex.h @@ -121,14 +121,6 @@ ComplexMatrix complex_matrix_value (bool = false) const; - octave_value not (void) const { return octave_value (scalar == 0.0); } - - octave_value uminus (void) const { return octave_value (- scalar); } - - octave_value transpose (void) const { return octave_value (scalar); } - - octave_value hermitian (void) const { return octave_value (conj (scalar)); } - void increment (void) { scalar += 1.0; } void decrement (void) { scalar -= 1.0; }
--- a/src/ov-cx-mat.h +++ b/src/ov-cx-mat.h @@ -131,16 +131,6 @@ ComplexMatrix complex_matrix_value (bool = false) const; - octave_value not (void) const { return octave_value (! matrix); } - - octave_value uminus (void) const { return octave_value (- matrix); } - - octave_value transpose (void) const - { return octave_value (matrix.transpose ()); } - - octave_value hermitian (void) const - { return octave_value (matrix.hermitian ()); } - void increment (void) { matrix += Complex (1.0); } void decrement (void) { matrix -= Complex (1.0); }
--- a/src/ov-range.cc +++ b/src/ov-range.cc @@ -176,27 +176,6 @@ } octave_value -octave_range::not (void) const -{ - Matrix tmp (range.matrix_value ()); - return (! tmp); -} - -octave_value -octave_range::transpose (void) const -{ - Matrix tmp (range.matrix_value ()); - return tmp.transpose (); -} - -octave_value -octave_range::hermitian (void) const -{ - Matrix tmp (range.matrix_value ()); - return tmp.transpose (); -} - -octave_value octave_range::convert_to_str (void) const { octave_value tmp (range.matrix_value ());
--- a/src/ov-range.h +++ b/src/ov-range.h @@ -144,14 +144,6 @@ Range range_value (void) const { return range; } - octave_value not (void) const; - - octave_value uminus (void) const { return octave_value (- range); } - - octave_value transpose (void) const; - - octave_value hermitian (void) const; - octave_value convert_to_str (void) const; void print (ostream& os, bool pr_as_read_syntax = false) const;
--- a/src/ov-re-mat.h +++ b/src/ov-re-mat.h @@ -146,16 +146,6 @@ ComplexMatrix complex_matrix_value (bool = false) const { return matrix; } - octave_value not (void) const { return octave_value (! matrix); } - - octave_value uminus (void) const { return octave_value (- matrix); } - - octave_value transpose (void) const - { return octave_value (matrix.transpose ()); } - - octave_value hermitian (void) const - { return octave_value (matrix.transpose ()); } - void increment (void) { matrix += 1.0; } void decrement (void) { matrix -= 1.0; }
--- a/src/ov-scalar.h +++ b/src/ov-scalar.h @@ -115,14 +115,6 @@ ComplexMatrix complex_matrix_value (bool = false) const { return ComplexMatrix (1, 1, Complex (scalar)); } - octave_value not (void) const { return octave_value (! scalar); } - - octave_value uminus (void) const { return octave_value (- scalar); } - - octave_value transpose (void) const { return octave_value (scalar); } - - octave_value hermitian (void) const { return octave_value (scalar); } - void increment (void) { ++scalar; } void decrement (void) { --scalar; }
--- a/src/ov-str-mat.cc +++ b/src/ov-str-mat.cc @@ -51,7 +51,9 @@ { CAST_CONV_ARG (const octave_char_matrix_str&); - return new octave_matrix (v.matrix_value ()); + Matrix m = v.matrix_value (); + + return error_state ? 0 : new octave_matrix (m); } type_conv_fcn
--- a/src/ov-str-mat.h +++ b/src/ov-str-mat.h @@ -103,12 +103,6 @@ string string_value (void) const; - octave_value transpose (void) const - { return octave_value (matrix.transpose (), true); } - - octave_value hermitian (void) const - { return octave_value (matrix.transpose (), true); } - void print (ostream& os, bool pr_as_read_syntax = false) const; void print_raw (ostream& os, bool pr_as_read_syntax = false) const;
--- a/src/ov-typeinfo.cc +++ b/src/ov-typeinfo.cc @@ -44,6 +44,12 @@ #include <Array2.cc> #include <Array3.cc> +template class Array<unary_op_fcn>; +template class Array2<unary_op_fcn>; + +template class Array<non_const_unary_op_fcn>; +template class Array2<non_const_unary_op_fcn>; + template class Array<binary_op_fcn>; template class Array2<binary_op_fcn>; template class Array3<binary_op_fcn>; @@ -80,6 +86,23 @@ } bool +octave_value_typeinfo::register_unary_op (octave_value::unary_op op, + int t, unary_op_fcn f) +{ + return (instance_ok ()) + ? instance->do_register_unary_op (op, t, f) : false; +} + +bool +octave_value_typeinfo::register_non_const_unary_op (octave_value::unary_op op, + int t, + non_const_unary_op_fcn f) +{ + return (instance_ok ()) + ? instance->do_register_non_const_unary_op (op, t, f) : false; +} + +bool octave_value_typeinfo::register_binary_op (octave_value::binary_op op, int t1, int t2, binary_op_fcn f) @@ -138,6 +161,13 @@ types.resize (len, string ()); + unary_ops.resize (static_cast<int> (octave_value::num_unary_ops), + len, static_cast<unary_op_fcn> (0)); + + non_const_unary_ops.resize + (static_cast<int> (octave_value::num_unary_ops), + len, static_cast<non_const_unary_op_fcn> (0)); + binary_ops.resize (static_cast<int> (octave_value::num_binary_ops), len, len, static_cast<binary_op_fcn> (0)); @@ -160,6 +190,24 @@ } bool +octave_value_typeinfo::do_register_unary_op (octave_value::unary_op op, + int t, unary_op_fcn f) +{ + unary_ops.checkelem (static_cast<int> (op), t) = f; + + return false; +} + +bool +octave_value_typeinfo::do_register_non_const_unary_op + (octave_value::unary_op op, int t, non_const_unary_op_fcn f) +{ + non_const_unary_ops.checkelem (static_cast<int> (op), t) = f; + + return false; +} + +bool octave_value_typeinfo::do_register_binary_op (octave_value::binary_op op, int t1, int t2, binary_op_fcn f) @@ -208,6 +256,19 @@ #include <iostream.h> +unary_op_fcn +octave_value_typeinfo::do_lookup_unary_op (octave_value::unary_op op, int t) +{ + return unary_ops.checkelem (static_cast<int> (op), t); +} + +non_const_unary_op_fcn +octave_value_typeinfo::do_lookup_non_const_unary_op + (octave_value::unary_op op, int t) +{ + return non_const_unary_ops.checkelem (static_cast<int> (op), t); +} + binary_op_fcn octave_value_typeinfo::do_lookup_binary_op (octave_value::binary_op op, int t1, int t2)
--- a/src/ov-typeinfo.h +++ b/src/ov-typeinfo.h @@ -46,6 +46,11 @@ static int register_type (const string&); + static bool register_unary_op (octave_value::unary_op, int, unary_op_fcn); + + static bool register_non_const_unary_op (octave_value::unary_op, int, + non_const_unary_op_fcn); + static bool register_binary_op (octave_value::binary_op, int, int, binary_op_fcn); @@ -59,6 +64,18 @@ static bool register_widening_op (int, int, type_conv_fcn); + static unary_op_fcn + lookup_unary_op (octave_value::unary_op op, int t) + { + return instance->do_lookup_unary_op (op, t); + } + + static non_const_unary_op_fcn + lookup_non_const_unary_op (octave_value::unary_op op, int t) + { + return instance->do_lookup_non_const_unary_op (op, t); + } + static binary_op_fcn lookup_binary_op (octave_value::binary_op op, int t1, int t2) { @@ -98,6 +115,10 @@ octave_value_typeinfo (void) : num_types (0), types (init_tab_sz, string ()), + unary_ops (octave_value::num_unary_ops, init_tab_sz, + (unary_op_fcn) 0), + non_const_unary_ops (octave_value::num_unary_ops, init_tab_sz, + (non_const_unary_op_fcn) 0), binary_ops (octave_value::num_binary_ops, init_tab_sz, init_tab_sz, (binary_op_fcn) 0), assign_ops (octave_value::num_assign_ops, init_tab_sz, @@ -117,6 +138,10 @@ Array<string> types; + Array2<unary_op_fcn> unary_ops; + + Array2<non_const_unary_op_fcn> non_const_unary_ops; + Array3<binary_op_fcn> binary_ops; Array3<assign_op_fcn> assign_ops; @@ -129,6 +154,11 @@ int do_register_type (const string&); + bool do_register_unary_op (octave_value::unary_op, int, unary_op_fcn); + + bool do_register_non_const_unary_op (octave_value::unary_op, int, + non_const_unary_op_fcn); + bool do_register_binary_op (octave_value::binary_op, int, int, binary_op_fcn); @@ -142,14 +172,16 @@ bool do_register_widening_op (int, int, type_conv_fcn); - binary_op_fcn - do_lookup_binary_op (octave_value::binary_op, int, int); + unary_op_fcn do_lookup_unary_op (octave_value::unary_op, int); + + non_const_unary_op_fcn do_lookup_non_const_unary_op + (octave_value::unary_op, int); - assign_op_fcn - do_lookup_assign_op (octave_value::assign_op, int, int); + binary_op_fcn do_lookup_binary_op (octave_value::binary_op, int, int); - assign_op_fcn - do_lookup_assignany_op (octave_value::assign_op, int); + assign_op_fcn do_lookup_assign_op (octave_value::assign_op, int, int); + + assign_op_fcn do_lookup_assignany_op (octave_value::assign_op, int); int do_lookup_pref_assign_conv (int, int);
--- a/src/ov.cc +++ b/src/ov.cc @@ -122,6 +122,44 @@ // Octave's value type. string +octave_value::unary_op_as_string (unary_op op) +{ + string retval; + + switch (op) + { + case not: + retval = "!"; + break; + + case uminus: + retval = "-"; + break; + + case transpose: + retval = ".'"; + break; + + case hermitian: + retval = "'"; + break; + + case incr: + retval = "++"; + break; + + case decr: + retval = "--"; + break; + + default: + retval = "<unknown>"; + } + + return retval; +} + +string octave_value::binary_op_as_string (binary_op op) { string retval; @@ -503,18 +541,24 @@ } static void -gripe_no_conversion (const string& tn1, const string& tn2) +gripe_no_conversion (const string& on, const string& tn1, const string& tn2) { - error ("no suitable conversion found for assignment of `%s' to indexed `%s'", - tn2.c_str (), tn1.c_str ()); + error ("operator %s: no conversion for assignment of `%s' to indexed `%s'", + on.c_str (), tn2.c_str (), tn1.c_str ()); } void -octave_value::assign (assign_op, const octave_value& rhs) +octave_value::assign (assign_op op, const octave_value& rhs) { // XXX FIXME XXX -- make this work for ops other than `='. - operator = (rhs); + if (op == asn_eq) + operator = (rhs); + else + { + string on = assign_op_as_string (op); + error ("operator `%s' not supported yet", on.c_str ()); + } } void @@ -530,10 +574,11 @@ if (! (error_state || assignment_ok)) { - assignment_ok = try_assignment_with_conversion (op,idx, rhs); + assignment_ok = try_assignment_with_conversion (op, idx, rhs); if (! (error_state || assignment_ok)) - gripe_no_conversion (type_name (), rhs.type_name ()); + gripe_no_conversion (assign_op_as_string (op), + type_name (), rhs.type_name ()); } if (! error_state) @@ -718,7 +763,7 @@ } static void -gripe_conversion_failed (const string& tn1, const string& tn2) +gripe_assign_conversion_failed (const string& tn1, const string& tn2) { error ("type conversion for assignment of `%s' to indexed `%s' failed", tn2.c_str (), tn1.c_str ()); @@ -767,7 +812,7 @@ delete old_rep; } else - gripe_conversion_failed (type_name (), rhs.type_name ()); + gripe_assign_conversion_failed (type_name (), rhs.type_name ()); } else gripe_indexed_assignment (type_name (), rhs.type_name ()); @@ -789,7 +834,17 @@ type_conv_fcn cf_rhs = rhs.numeric_conversion_function (); if (cf_rhs) - tmp_rhs = octave_value (cf_rhs (*rhs.rep)); + { + octave_value *tmp = cf_rhs (*rhs.rep); + + if (tmp) + tmp_rhs = octave_value (tmp); + else + { + gripe_assign_conversion_failed (type_name (), rhs.type_name ()); + return false; + } + } else tmp_rhs = rhs; @@ -799,8 +854,19 @@ if (cf_this) { old_rep = rep; - rep = cf_this (*rep); - rep->count = 1; + + octave_value *tmp = cf_this (*rep); + + if (tmp) + { + rep = tmp; + rep->count = 1; + } + else + { + gripe_assign_conversion_failed (type_name (), rhs.type_name ()); + return false; + } } if (cf_this || cf_rhs) @@ -868,6 +934,12 @@ on.c_str (), tn1.c_str (), tn2.c_str ()); } +static void +gripe_binary_op_conv (const string& on) +{ + error ("type conversion failed for binary operator `%s'", on.c_str ()); +} + octave_value do_binary_op (octave_value::binary_op op, const octave_value& v1, const octave_value& v2) @@ -888,8 +960,18 @@ if (cf1) { - tv1 = octave_value (cf1 (*v1.rep)); - t1 = tv1.type_id (); + octave_value *tmp = cf1 (*v1.rep); + + if (tmp) + { + tv1 = octave_value (tmp); + t1 = tv1.type_id (); + } + else + { + gripe_binary_op_conv (octave_value::binary_op_as_string (op)); + return retval; + } } else tv1 = v1; @@ -899,8 +981,18 @@ if (cf2) { - tv2 = octave_value (cf2 (*v2.rep)); - t2 = tv2.type_id (); + octave_value *tmp = cf2 (*v2.rep); + + if (tmp) + { + tv2 = octave_value (tmp); + t2 = tv2.type_id (); + } + else + { + gripe_binary_op_conv (octave_value::binary_op_as_string (op)); + return retval; + } } else tv2 = v2; @@ -924,6 +1016,134 @@ return retval; } +static void +gripe_unary_op (const string& on, const string& tn) +{ + error ("unary operator `%s' not implemented for `%s' operands", + on.c_str (), tn.c_str ()); +} + +static void +gripe_unary_op_conv (const string& on) +{ + error ("type conversion failed for unary operator `%s'", on.c_str ()); +} + +octave_value +do_unary_op (octave_value::unary_op op, const octave_value& v) +{ + octave_value retval; + + int t = v.type_id (); + + unary_op_fcn f = octave_value_typeinfo::lookup_unary_op (op, t); + + if (f) + retval = f (*v.rep); + else + { + octave_value tv; + type_conv_fcn cf = v.numeric_conversion_function (); + + if (cf) + { + octave_value *tmp = cf (*v.rep); + + if (tmp) + { + tv = octave_value (tmp); + t = tv.type_id (); + + unary_op_fcn f = octave_value_typeinfo::lookup_unary_op (op, t); + + if (f) + retval = f (*tv.rep); + else + gripe_unary_op (octave_value::unary_op_as_string (op), + v.type_name ()); + } + else + gripe_unary_op_conv (octave_value::unary_op_as_string (op)); + } + else + gripe_unary_op (octave_value::unary_op_as_string (op), + v.type_name ()); + } + + return retval; +} + +static void +gripe_unary_op_conversion_failed (const string& op, const string& tn) +{ + error ("operator %s: type conversion for `%s' failed", + op.c_str (), tn.c_str ()); +} + +void +octave_value::do_non_const_unary_op (octave_value::unary_op op) +{ + octave_value retval; + + int t = type_id (); + + non_const_unary_op_fcn f + = octave_value_typeinfo::lookup_non_const_unary_op (op, t); + + if (f) + { + make_unique (); + + f (*rep); + } + else + { + type_conv_fcn cf = numeric_conversion_function (); + + if (cf) + { + octave_value *tmp = cf (*rep); + + if (tmp) + { + octave_value *old_rep = rep; + rep = tmp; + rep->count = 1; + + t = type_id (); + + f = octave_value_typeinfo::lookup_non_const_unary_op (op, t); + + if (f) + { + f (*rep); + + if (old_rep && --old_rep->count == 0) + delete old_rep; + } + else + { + if (old_rep) + { + if (--rep->count == 0) + delete rep; + + rep = old_rep; + } + + gripe_unary_op (octave_value::unary_op_as_string (op), + type_name ()); + } + } + else + gripe_unary_op_conversion_failed + (octave_value::unary_op_as_string (op), type_name ()); + } + else + gripe_unary_op (octave_value::unary_op_as_string (op), type_name ()); + } +} + // Current indentation. int octave_value::curr_print_indent_level = 0;
--- a/src/ov.h +++ b/src/ov.h @@ -62,7 +62,13 @@ // XXX FIXME XXX -- these should probably really be inside the scope // of the octave_value class, but the cygwin32 beta16 version of g++ -// can't handlt that. +// can't handle that. + +typedef octave_value (*unary_op_fcn) + (const octave_value&); + +typedef void (*non_const_unary_op_fcn) + (octave_value&); typedef octave_value (*binary_op_fcn) (const octave_value&, const octave_value&); @@ -77,6 +83,18 @@ { public: + enum unary_op + { + not, + uminus, + transpose, + hermitian, + incr, + decr, + num_unary_ops, + unknown_unary_op + }; + enum binary_op { add, @@ -121,6 +139,8 @@ unknown_assign_op }; + static string unary_op_as_string (unary_op); + static string binary_op_as_string (binary_op); static string assign_op_as_string (assign_op); @@ -409,28 +429,6 @@ virtual boolMatrix bool_matrix_value (void) const { return rep->bool_matrix_value (); } - // Unary ops. - - virtual octave_value not (void) const { return rep->not (); } - - virtual octave_value uminus (void) const { return rep->uminus (); } - - virtual octave_value transpose (void) const { return rep->transpose (); } - - virtual octave_value hermitian (void) const { return rep->hermitian (); } - - virtual void increment (void) - { - make_unique (); - rep->increment (); - } - - virtual void decrement (void) - { - make_unique (); - rep->decrement (); - } - ColumnVector vector_value (bool frc_str_conv = false, bool frc_vec_conv = false) const; @@ -464,7 +462,12 @@ virtual string type_name (void) const { return rep->type_name (); } - // Binary and unary operations. + // Unary and binary operations. + + friend octave_value do_unary_op (octave_value::unary_op, + const octave_value&); + + void do_non_const_unary_op (octave_value::unary_op); friend octave_value do_binary_op (octave_value::binary_op, const octave_value&, @@ -516,6 +519,79 @@ static bool beginning_of_line; }; +#define OV_UNOP_FN(name) \ + inline octave_value \ + name (const octave_value& a) \ + { \ + return do_unary_op (octave_value::name, a); \ + } + +#define OV_UNOP_OP(name, op) \ + inline octave_value \ + operator op (const octave_value& a) \ + { \ + return name (a); \ + } + +#define OV_UNOP_FN_OP(name, op) \ + OV_UNOP_FN (name) \ + OV_UNOP_OP (name, op) + +OV_UNOP_FN_OP (not, !) +OV_UNOP_FN_OP (uminus, -) + +OV_UNOP_FN (transpose) +OV_UNOP_FN (hermitian) + +// No simple way to define these for prefix and suffix ops? +// +// incr +// decr + +#define OV_BINOP_FN(name) \ + inline octave_value \ + name (const octave_value& a1, const octave_value& a2) \ + { \ + return do_binary_op (octave_value::name, a1, a2); \ + } + +#define OV_BINOP_OP(name, op) \ + inline octave_value \ + operator op (const octave_value& a1, const octave_value& a2) \ + { \ + return name (a1, a2); \ + } + +#define OV_BINOP_FN_OP(name, op) \ + OV_BINOP_FN (name) \ + OV_BINOP_OP (name, op) + +OV_BINOP_FN_OP (add, +) +OV_BINOP_FN_OP (sub, -) +OV_BINOP_FN_OP (mul, *) +OV_BINOP_FN_OP (div, /) + +OV_BINOP_FN (pow) +OV_BINOP_FN (ldiv) +OV_BINOP_FN (lshift) +OV_BINOP_FN (rshift) + +OV_BINOP_FN_OP (lt, <) +OV_BINOP_FN_OP (le, <=) +OV_BINOP_FN_OP (eq, ==) +OV_BINOP_FN_OP (ge, >=) +OV_BINOP_FN_OP (gt, >) +OV_BINOP_FN_OP (ne, !=) + +OV_BINOP_FN (el_mul) +OV_BINOP_FN (el_div) +OV_BINOP_FN (el_pow) +OV_BINOP_FN (el_ldiv) +OV_BINOP_FN (el_and) +OV_BINOP_FN (el_or) + +OV_BINOP_FN (struct_ref) + // If TRUE, allow assignments like // // octave> A(1) = 3; A(2) = 5
--- a/src/parse.y +++ b/src/parse.y @@ -532,7 +532,10 @@ | '[' ';' ']' { $$ = new tree_constant (octave_value (Matrix ())); } | '[' in_matrix_or_assign_lhs rows ']' - { $$ = finish_matrix ($3); } + { + $$ = finish_matrix ($3); + lexer_flags.looking_at_matrix_or_assign_lhs = false; + } ; rows : rows1 @@ -1842,24 +1845,24 @@ static tree_expression * make_prefix_op (int op, tree_expression *op1, token *tok_val) { - tree_prefix_expression::type t; + octave_value::unary_op t = octave_value::unknown_unary_op; switch (op) { case EXPR_NOT: - t = tree_prefix_expression::unot; + t = octave_value::not; break; case '-': - t = tree_prefix_expression::uminus; + t = octave_value::uminus; break; case PLUS_PLUS: - t = tree_prefix_expression::increment; + t = octave_value::incr; break; case MINUS_MINUS: - t = tree_prefix_expression::decrement; + t = octave_value::decr; break; default: @@ -1880,24 +1883,24 @@ static tree_expression * make_postfix_op (int op, tree_expression *op1, token *tok_val) { - tree_postfix_expression::type t; + octave_value::unary_op t = octave_value::unknown_unary_op; switch (op) { case QUOTE: - t = tree_postfix_expression::hermitian; + t = octave_value::hermitian; break; case TRANSPOSE: - t = tree_postfix_expression::transpose; + t = octave_value::transpose; break; case PLUS_PLUS: - t = tree_postfix_expression::increment; + t = octave_value::incr; break; case MINUS_MINUS: - t = tree_postfix_expression::decrement; + t = octave_value::decr; break; default:
--- a/src/pt-unop.cc +++ b/src/pt-unop.cc @@ -35,6 +35,14 @@ #include "pt-unop.h" #include "pt-walk.h" +// Unary expressions. + +string +tree_unary_expression::oper (void) const +{ + return octave_value::unary_op_as_string (etype); +} + // Prefix expressions. octave_value_list @@ -61,46 +69,40 @@ if (op) { - if (etype == unot || etype == uminus) + if (etype == octave_value::incr || etype == octave_value::decr) + { + octave_lvalue ref = op->lvalue (); + + if (error_state) + eval_error (); + else if (ref.is_defined ()) + { + ref.do_unary_op (etype); + + retval = ref.value (); + } + else + eval_error (); + } + else { octave_value val = op->rvalue (); - if (! error_state) + if (error_state) + eval_error (); + else if (val.is_defined ()) { - if (val.is_defined ()) - { - if (etype == unot) - retval = val.not (); - else - retval = val.uminus (); - } - else - error ("argument to prefix operator `%s' undefined", - oper () . c_str ()); - } - } - else if (etype == increment || etype == decrement) - { - octave_lvalue ref = op->lvalue (); + retval = ::do_unary_op (etype, val); - if (! error_state) - { - if (ref.is_defined ()) + if (error_state) { - if (etype == increment) - ref.increment (); - else - ref.decrement (); - - retval = ref.value (); + retval = octave_value (); + eval_error (); } - else - error ("argument to prefix operator `%s' undefined", - oper () . c_str ()); } + else + eval_error (); } - else - error ("prefix operator %d not implemented", etype); } return retval; @@ -114,36 +116,6 @@ oper () . c_str (), line (), column ()); } -string -tree_prefix_expression::oper (void) const -{ - string retval = "<unknown>"; - - switch (etype) - { - case unot: - retval = "!"; - break; - - case uminus: - retval = "-"; - break; - - case increment: - retval = "++"; - break; - - case decrement: - retval = "--"; - break; - - default: - break; - } - - return retval; -} - void tree_prefix_expression::accept (tree_walker& tw) { @@ -176,47 +148,43 @@ if (op) { - if (etype == transpose || etype == hermitian) + if (etype == octave_value::incr || etype == octave_value::decr) + { + octave_lvalue ref = op->lvalue (); + + if (error_state) + eval_error (); + else if (ref.is_defined ()) + { + retval = ref.value (); + + ref.do_unary_op (etype); + } + else + eval_error (); + } + else { octave_value val = op->rvalue (); - if (! error_state) + if (error_state) + eval_error (); + else if (val.is_defined ()) { - if (val.is_defined ()) - { - if (etype == transpose) - retval = val.transpose (); - else - retval = val.hermitian (); - } - else - error ("argument to postfix operator `%s' undefined", - oper () . c_str ()); - } - } - else if (etype == increment || etype == decrement) - { - octave_lvalue ref = op->lvalue (); + retval = ::do_unary_op (etype, val); - if (! error_state) - { - if (ref.is_defined ()) + if (error_state) { - retval = ref.value (); - - if (etype == increment) - ref.increment (); - else - ref.decrement (); + retval = octave_value (); + eval_error (); } - else - error ("argument to postfix operator `%s' undefined", - oper () . c_str ()); } + else + eval_error (); } - else - error ("postfix operator %d not implemented", etype); } + else + eval_error (); return retval; } @@ -229,36 +197,6 @@ oper () . c_str (), line (), column ()); } -string -tree_postfix_expression::oper (void) const -{ - string retval = "<unknown>"; - - switch (etype) - { - case transpose: - retval = ".'"; - break; - - case hermitian: - retval = "'"; - break; - - case increment: - retval = "++"; - break; - - case decrement: - retval = "--"; - break; - - default: - break; - } - - return retval; -} - void tree_postfix_expression::accept (tree_walker& tw) {
--- a/src/pt-unop.h +++ b/src/pt-unop.h @@ -44,21 +44,32 @@ { public: - tree_unary_expression (int l = -1, int c = -1) - : tree_expression (l, c), op (0) { } + tree_unary_expression (int l = -1, int c = -1, + octave_value::unary_op t + = octave_value::unknown_unary_op) + : tree_expression (l, c), op (0), etype (t) { } - tree_unary_expression (tree_expression *e, int l = -1, int c = -1) - : tree_expression (l, c), op (e) { } + tree_unary_expression (tree_expression *e, int l = -1, int c = -1, + octave_value::unary_op t + = octave_value::unknown_unary_op) + : tree_expression (l, c), op (e), etype (t) { } ~tree_unary_expression (void) { delete op; } tree_expression *operand (void) { return op; } + string oper (void) const; + protected: // The operand for the expression. tree_expression *op; + // The type of the expression. + octave_value::unary_op etype; + +private: + // No copying! tree_unary_expression (const tree_unary_expression&); @@ -73,21 +84,13 @@ { public: - enum type - { - unknown, - unot, - uminus, - increment, - decrement - }; - tree_prefix_expression (int l = -1, int c = -1) - : tree_unary_expression (l, c), etype (unknown) { } + : tree_unary_expression (l, c, octave_value::unknown_unary_op) { } tree_prefix_expression (tree_expression *e, int l = -1, int c = -1, - type t = unknown) - : tree_unary_expression (e, l, c), etype (t) { } + octave_value::unary_op t + = octave_value::unknown_unary_op) + : tree_unary_expression (e, l, c, t) { } ~tree_prefix_expression (void) { } @@ -100,15 +103,10 @@ void eval_error (void); - string oper (void) const; - void accept (tree_walker& tw); private: - // The type of the expression. - type etype; - // No copying! tree_prefix_expression (const tree_prefix_expression&); @@ -123,21 +121,13 @@ { public: - enum type - { - unknown, - hermitian, - transpose, - increment, - decrement - }; - tree_postfix_expression (int l = -1, int c = -1) - : tree_unary_expression (l, c), etype (unknown) { } + : tree_unary_expression (l, c, octave_value::unknown_unary_op) { } tree_postfix_expression (tree_expression *e, int l = -1, int c = -1, - type t = unknown) - : tree_unary_expression (e, l, c), etype (t) { } + octave_value::unary_op t + = octave_value::unknown_unary_op) + : tree_unary_expression (e, l, c, t) { } ~tree_postfix_expression (void) { } @@ -150,15 +140,10 @@ void eval_error (void); - string oper (void) const; - void accept (tree_walker& tw); private: - // The type of the expression. - type etype; - // No copying! tree_postfix_expression (const tree_postfix_expression&);