Mercurial > hg > octave-nkf
changeset 3204:81738e630f57
[project @ 1998-10-30 23:28:29 by jwe]
author | jwe |
---|---|
date | Fri, 30 Oct 1998 23:28:30 +0000 |
parents | bc61b0e8d60e |
children | 549691faa638 |
files | src/ChangeLog src/data.cc src/lex.l src/ov-list.cc src/ov.cc src/ov.h src/parse.y |
diffstat | 7 files changed, 211 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,15 @@ Fri Oct 30 08:39:30 1998 John W. Eaton <jwe@bevo.che.wisc.edu> + * parse.y (LEFTDIV_EQ, ELEFTDIV_EQ): New tokens. + (assign_expr): Add rules for them. + (make_assign_op): Handle them here too. + * lex.l: Recognize them. + * ov.h (octave_value::assign_op): Add ldiv_eq and el_ldiv_eq. + * ov.cc (octave_value::assign_op_as_string): Ditto. + (octave_value::op_eq_to_binary_op): Ditto. + (octave_value::assign): Handle OP= style operators with brute force. + (octave_value::simple_assign): New function. + * parse.y (matrix): Dont' forget to reset lexer_flags.looking_at_matrix_or_assign_lhs.
--- a/src/data.cc +++ b/src/data.cc @@ -786,6 +786,19 @@ return retval; } +DEFUN (is_list, args, , + "is_list (x): return nonzero if x is a list") +{ + octave_value retval; + + if (args.length () == 1) + retval = args(0).is_list () ? 1.0 : 0.0; + else + print_usage ("is_list"); + + return retval; +} + DEFUN (is_matrix, args, , "is_matrix (x): return nonzero if x can be considered a matrix") {
--- a/src/lex.l +++ b/src/lex.l @@ -629,10 +629,12 @@ "-=" { BIN_OP_RETURN (SUB_EQ, false); } "*=" { BIN_OP_RETURN (MUL_EQ, false); } "/=" { BIN_OP_RETURN (DIV_EQ, false); } +"\\=" { BIN_OP_RETURN (LEFTDIV_EQ, false); } ".+=" { BIN_OP_RETURN (ADD_EQ, false); } ".-=" { BIN_OP_RETURN (SUB_EQ, false); } ".*=" { BIN_OP_RETURN (EMUL_EQ, false); } "./=" { BIN_OP_RETURN (EDIV_EQ, false); } +".\\=" { BIN_OP_RETURN (ELEFTDIV_EQ, false); } "&=" { BIN_OP_RETURN (AND_EQ, false); } "|=" { BIN_OP_RETURN (OR_EQ, false); } "<<=" { BIN_OP_RETURN (LSHIFT_EQ, false); }
--- a/src/ov-list.cc +++ b/src/ov-list.cc @@ -221,8 +221,9 @@ splice (LIST_1, OFFSET, LENGTH)\n\ splice (LIST_1, OFFSET)\n\ \n\ -Replace LENGTH elements of LIST_1 beginning at OFFSET with the -contents of LIST_2 (if any). If LENGTH is omitted, ") +Replace LENGTH elements of LIST_1 beginning at OFFSET with the\n\ +contents of LIST_2 (if any). If LENGTH is omitted, all elements\n\ +from OFFSET to the end of LIST_1 are replaced.") { octave_value retval;
--- a/src/ov.cc +++ b/src/ov.cc @@ -284,6 +284,10 @@ retval = "/="; break; + case ldiv_eq: + retval = "\\="; + break; + case lshift_eq: retval = "<<="; break; @@ -300,6 +304,10 @@ retval = "./="; break; + case el_ldiv_eq: + retval = ".\\="; + break; + case el_and_eq: retval = "&="; break; @@ -547,17 +555,64 @@ on.c_str (), tn2.c_str (), tn1.c_str ()); } +static void +gripe_assign_failed (const string& on, const string& tn1, const string& tn2) +{ + error ("assignment failed for `%s %s %s'", + tn1.c_str (), on.c_str (), tn2.c_str ()); +} + +static void +gripe_assign_failed_or_no_method (const string& on, const string& tn1, + const string& tn2) +{ + error ("assignment failed, or no method for `%s %s %s'", + tn1.c_str (), on.c_str (), tn2.c_str ()); +} + void octave_value::assign (assign_op op, const octave_value& rhs) { - // XXX FIXME XXX -- make this work for ops other than `='. - if (op == asn_eq) operator = (rhs); else { - string on = assign_op_as_string (op); - error ("operator `%s' not supported yet", on.c_str ()); + // XXX FIXME XXX -- only do the following stuff if we can't find + // a specific function to call to handle the op= operation for + // the types we have. + + binary_op binop = op_eq_to_binary_op (op); + + if (! error_state) + { + octave_value t = do_binary_op (binop, *this, rhs); + + if (! error_state) + operator = (t); + } + + if (error_state) + gripe_assign_failed_or_no_method (assign_op_as_string (op), + type_name (), rhs.type_name ()); + } +} + +void +octave_value::simple_assign (octave_value::assign_op orig_op, + const octave_value_list& idx, + const octave_value& rhs) +{ + make_unique (); + + bool assignment_ok = try_assignment (asn_eq, idx, rhs); + + if (! (error_state || assignment_ok)) + { + assignment_ok = try_assignment_with_conversion (asn_eq, idx, rhs); + + if (! (error_state || assignment_ok)) + gripe_no_conversion (assign_op_as_string (orig_op), + type_name (), rhs.type_name ()); } } @@ -568,16 +623,46 @@ { if (Vresize_on_range_error || is_defined ()) { - make_unique (); + if (op == asn_eq) + simple_assign (op, idx, rhs); + else + { + // XXX FIXME XXX -- only do the following stuff if we can't + // find a specific function to call to handle the op= + // operation for the types we have. + + octave_value t1 = *this; - bool assignment_ok = try_assignment (op, idx, rhs); + t1 = t1.do_index_op (idx); + + if (! error_state) + { + binary_op binop = op_eq_to_binary_op (op); + + if (! error_state) + { + octave_value t2 = do_binary_op (binop, t1, rhs); - if (! (error_state || assignment_ok)) - { - assignment_ok = try_assignment_with_conversion (op, idx, rhs); + if (! error_state) + { + simple_assign (op, idx, t2); - if (! (error_state || assignment_ok)) - gripe_no_conversion (assign_op_as_string (op), + if (error_state) + gripe_assign_failed (assign_op_as_string (op), + type_name (), rhs.type_name ()); + } + else + gripe_assign_failed_or_no_method (assign_op_as_string (op), + type_name (), + rhs.type_name ()); + } + else + gripe_assign_failed_or_no_method (assign_op_as_string (op), + type_name (), + rhs.type_name ()); + } + else + gripe_assign_failed (assign_op_as_string (op), type_name (), rhs.type_name ()); } @@ -1190,6 +1275,71 @@ curr_print_indent_level = 0; } +octave_value::binary_op +octave_value::op_eq_to_binary_op (assign_op op) +{ + binary_op binop = unknown_binary_op; + + switch (op) + { + case add_eq: + binop = add; + break; + + case sub_eq: + binop = sub; + break; + + case mul_eq: + binop = mul; + break; + + case div_eq: + binop = div; + break; + + case ldiv_eq: + binop = ldiv; + break; + + case lshift_eq: + binop = lshift; + break; + + case rshift_eq: + binop = rshift; + break; + + case el_mul_eq: + binop = el_mul; + break; + + case el_div_eq: + binop = el_div; + break; + + case el_ldiv_eq: + binop = el_ldiv; + break; + + case el_and_eq: + binop = el_and; + break; + + case el_or_eq: + binop = el_or; + break; + + default: + { + string on = assign_op_as_string (op); + error ("operator %s: no binary operator found", on.c_str ()); + } + } + + return binop; +} + void install_types (void) {
--- a/src/ov.h +++ b/src/ov.h @@ -129,10 +129,12 @@ sub_eq, mul_eq, div_eq, + ldiv_eq, lshift_eq, rshift_eq, el_mul_eq, el_div_eq, + el_ldiv_eq, el_and_eq, el_or_eq, num_assign_ops, @@ -517,6 +519,11 @@ static int curr_print_indent_level; static bool beginning_of_line; + + binary_op op_eq_to_binary_op (assign_op op); + + void simple_assign (assign_op orig_op, const octave_value_list& idx, + const octave_value& rhs); }; #define OV_UNOP_FN(name) \
--- a/src/parse.y +++ b/src/parse.y @@ -331,7 +331,8 @@ // Tokens with line and column information. %token <tok_val> '=' ':' '-' '+' '*' '/' -%token <tok_val> ADD_EQ SUB_EQ MUL_EQ DIV_EQ EMUL_EQ EDIV_EQ AND_EQ OR_EQ +%token <tok_val> ADD_EQ SUB_EQ MUL_EQ DIV_EQ LEFTDIV_EQ +%token <tok_val> EMUL_EQ EDIV_EQ ELEFTDIV_EQ AND_EQ OR_EQ %token <tok_val> LSHIFT_EQ RSHIFT_EQ LSHIFT RSHIFT %token <tok_val> EXPR_AND_AND EXPR_OR_OR %token <tok_val> EXPR_AND EXPR_OR EXPR_NOT @@ -398,7 +399,7 @@ // Precedence and associativity. %left ';' ',' '\n' -%right '=' ADD_EQ SUB_EQ MUL_EQ DIV_EQ EMUL_EQ EDIV_EQ OR_EQ AND_EQ LSHIFT_EQ RSHIFT_EQ +%right '=' ADD_EQ SUB_EQ MUL_EQ DIV_EQ LEFTDIV_EQ EMUL_EQ EDIV_EQ ELEFTDIV_EQ OR_EQ AND_EQ LSHIFT_EQ RSHIFT_EQ %left EXPR_AND_AND EXPR_OR_OR %left EXPR_AND EXPR_OR %left EXPR_LT EXPR_LE EXPR_EQ EXPR_NE EXPR_GE EXPR_GT @@ -732,6 +733,8 @@ { $$ = make_assign_op (MUL_EQ, $1, $2, $3); } | assign_lhs DIV_EQ expression { $$ = make_assign_op (DIV_EQ, $1, $2, $3); } + | assign_lhs LEFTDIV_EQ expression + { $$ = make_assign_op (LEFTDIV_EQ, $1, $2, $3); } | assign_lhs LSHIFT_EQ expression { $$ = make_assign_op (LSHIFT_EQ, $1, $2, $3); } | assign_lhs RSHIFT_EQ expression @@ -740,6 +743,8 @@ { $$ = make_assign_op (EMUL_EQ, $1, $2, $3); } | assign_lhs EDIV_EQ expression { $$ = make_assign_op (EDIV_EQ, $1, $2, $3); } + | assign_lhs ELEFTDIV_EQ expression + { $$ = make_assign_op (ELEFTDIV_EQ, $1, $2, $3); } | assign_lhs AND_EQ expression { $$ = make_assign_op (AND_EQ, $1, $2, $3); } | assign_lhs OR_EQ expression @@ -2164,6 +2169,10 @@ t = octave_value::div_eq; break; + case LEFTDIV_EQ: + t = octave_value::ldiv_eq; + break; + case LSHIFT_EQ: t = octave_value::lshift_eq; break; @@ -2180,6 +2189,10 @@ t = octave_value::el_div_eq; break; + case ELEFTDIV_EQ: + t = octave_value::el_ldiv_eq; + break; + case AND_EQ: t = octave_value::el_and_eq; break;