# HG changeset patch # User jwe # Date 784851253 0 # Node ID 708827b941b4daa0c4bbcae116401c9aa8355123 # Parent 58f0c171bbbd738baa5bc3bb88f3db669a1d4031 [project @ 1994-11-14 22:14:13 by jwe] diff --git a/src/lex.l b/src/lex.l --- a/src/lex.l +++ b/src/lex.l @@ -968,6 +968,9 @@ int l = input_line_number; int c = current_input_column; +// XXX FIXME XXX -- this has really become too large a list to search +// like this... + int end_found = 0; if (strcmp ("break", s) == 0) { @@ -1126,6 +1129,12 @@ yylval.tok_val = new token (token::unwind_protect_end, l, c); token_stack.push (yylval.tok_val); } + else if (strcmp ("all_va_args", s) == 0) + { + yylval.tok_val = new token (l, c); + token_stack.push (yylval.tok_val); + return ALL_VA_ARGS; + } if (end_found) { diff --git a/src/parse.y b/src/parse.y --- a/src/parse.y +++ b/src/parse.y @@ -231,6 +231,7 @@ %token LEXICAL_ERROR %token FCN SCREW_TWO %token ELLIPSIS +%token ALL_VA_ARGS %token END_OF_INPUT %token USING TITLE WITH COLON OPEN_BRACE CLOSE_BRACE CLEAR @@ -1116,6 +1117,15 @@ colon = new tree_constant (t); $$ = new tree_argument_list (colon); } + | expression + { $$ = new tree_argument_list ($1); } + | ALL_VA_ARGS + { + tree_constant *all_va_args; + tree_constant::all_va_args t; + all_va_args = new tree_constant (t); + $$ = new tree_argument_list (all_va_args); + } | arg_list ',' ':' { tree_constant *colon; @@ -1123,10 +1133,15 @@ colon = new tree_constant (t); $1->append (colon); } - | expression - { $$ = new tree_argument_list ($1); } | arg_list ',' expression { $1->append ($3); } + | arg_list ',' ALL_VA_ARGS + { + tree_constant *all_va_args; + tree_constant::all_va_args t; + all_va_args = new tree_constant (t); + $1->append (all_va_args); + } ; matrix : '[' screwed_again rows ']' diff --git a/src/pt-const.h b/src/pt-const.h --- a/src/pt-const.h +++ b/src/pt-const.h @@ -56,6 +56,7 @@ public: enum magic_colon { magic_colon_t }; + enum all_va_args { all_va_args_t }; // Constructors. It is possible to create the following types of // constants: @@ -77,6 +78,7 @@ // range double, double, dobule // Range // magic colon tree_constant::magic_colon +// all_va_args tree_constant::all_va_args tree_constant (void) : tree_fvc () { rep = new tree_constant_rep (); rep->count = 1; } @@ -131,6 +133,14 @@ rep->count = 1; } + tree_constant (tree_constant::all_va_args t) : tree_fvc () + { + tree_constant_rep::constant_type tmp; + tmp = tree_constant_rep::all_va_args; + rep = new tree_constant_rep (tmp); + rep->count = 1; + } + // Copy constructor. tree_constant (const tree_constant& a) : tree_fvc () @@ -202,6 +212,7 @@ int is_range (void) const { return rep->is_range (); } int is_map (void) const { return rep->is_map (); } int is_magic_colon (void) const { return rep->is_magic_colon (); } + int is_all_va_args (void) const { return rep->is_all_va_args (); } // Are any or all of the elements in this constant nonzero? @@ -236,7 +247,7 @@ int is_empty (void) const { - return ((! (is_magic_colon () || is_unknown ())) + return ((! (is_magic_colon () || is_all_va_args () || is_unknown ())) && (rows () == 0 || columns () == 0)); } @@ -244,7 +255,7 @@ int is_zero_by_zero (void) const { - return ((! (is_magic_colon () || is_unknown ())) + return ((! (is_magic_colon () || is_all_va_args () || is_unknown ())) && rows () == 0 && columns () == 0); } @@ -389,7 +400,7 @@ tree_constant make_numeric_or_magic (void) const { - if (is_numeric_type () || is_magic_colon ()) + if (is_numeric_type () || is_all_va_args () || is_magic_colon ()) return *this; else return rep->make_numeric (); @@ -397,7 +408,8 @@ tree_constant make_numeric_or_range_or_magic (void) const { - if (is_numeric_type () || is_range () || is_magic_colon ()) + if (is_numeric_type () || is_range () || is_all_va_args () + || is_magic_colon ()) return *this; else return rep->make_numeric (); diff --git a/src/pt-exp-base.cc b/src/pt-exp-base.cc --- a/src/pt-exp-base.cc +++ b/src/pt-exp-base.cc @@ -857,9 +857,16 @@ { if (sym) { - tree_fvc *tmp = sym->def (); - if (tmp) - tmp->bump_value (etype); + if (sym->is_read_only ()) + { + ::error ("can't redefined read-only variable `%s'", name ()); + } + else + { + tree_fvc *tmp = sym->def (); + if (tmp) + tmp->bump_value (etype); + } } } @@ -1238,19 +1245,23 @@ Octave_object args = list->convert_to_const_vector (); - int nargin = args.length (); - if (error_state) eval_error (); - else if (nargin > 0 && all_args_defined (args)) + else { - Octave_object tmp = id->eval (print, 1, args); + int nargin = args.length (); if (error_state) eval_error (); - - if (tmp.length () > 0) - retval = tmp(0); + else if (nargin > 0 && all_args_defined (args)) + { + Octave_object tmp = id->eval (print, 1, args); + + if (error_state) + eval_error (); + else if (tmp.length () > 0) + retval = tmp(0); + } } } else @@ -1278,16 +1289,21 @@ Octave_object args = list->convert_to_const_vector (); - int nargin = args.length (); - if (error_state) eval_error (); - else if (nargin > 0 && all_args_defined (args)) + else { - retval = id->eval (print, nargout, args); + int nargin = args.length (); if (error_state) eval_error (); + else if (nargin > 0 && all_args_defined (args)) + { + retval = id->eval (print, nargout, args); + + if (error_state) + eval_error (); + } } } else @@ -1365,12 +1381,17 @@ if (id) { id->bump_value (etype); - retval = id->eval (print); if (error_state) + eval_error (); + else { - retval = tree_constant (); + retval = id->eval (print); if (error_state) - eval_error (); + { + retval = tree_constant (); + if (error_state) + eval_error (); + } } } return retval; @@ -1906,15 +1927,20 @@ Octave_object args = index->convert_to_const_vector (); - int nargin = args.length (); - if (error_state) eval_error (); - else if (nargin > 0) + else { - retval = lhs->assign (rhs_val, args); + int nargin = args.length (); + if (error_state) eval_error (); + else if (nargin > 0) + { + retval = lhs->assign (rhs_val, args); + if (error_state) + eval_error (); + } } } } @@ -2581,6 +2607,20 @@ return retval; } +Octave_object +tree_function::octave_all_va_args (void) +{ + Octave_object retval; + + retval.resize (num_args_passed - num_named_args); + + int k = 0; + for (int i = num_named_args; i < num_args_passed; i++) + retval(k++) = args_passed(i); + + return retval; +} + int tree_function::takes_var_return (void) const { diff --git a/src/pt-exp-base.h b/src/pt-exp-base.h --- a/src/pt-exp-base.h +++ b/src/pt-exp-base.h @@ -862,6 +862,8 @@ tree_constant octave_va_arg (void); + Octave_object octave_all_va_args (void); + int takes_var_return (void) const; void octave_vr_val (const tree_constant& val); diff --git a/src/pt-misc.cc b/src/pt-misc.cc --- a/src/pt-misc.cc +++ b/src/pt-misc.cc @@ -36,6 +36,7 @@ #include "tree-base.h" #include "tree-expr.h" #include "tree-cmd.h" +#include "octave.h" #include "tree-misc.h" #include "tree-const.h" #include "user-prefs.h" @@ -203,26 +204,54 @@ { int len = length (); +// XXX FIXME XXX -- would be nice to know in advance how largs args +// needs to be even when we have a list containing an all_va_args +// token. + Octave_object args; args.resize (len); Pix p = first (); + int j = 0; for (int k = 0; k < len; k++) { tree_expression *elt = this->operator () (p); if (elt) { - args(k) = elt->eval (0); + tree_constant tmp = elt->eval (0); if (error_state) { ::error ("evaluating argument list element number %d", k); + args = Octave_object (); break; } + else + { + if (tmp.is_all_va_args ()) + { + if (curr_function) + { + Octave_object tva; + tva = curr_function->octave_all_va_args (); + int n = tva.length (); + for (int i = 0; i < n; i++) + args(j++) = tva(i); + } + else + { + ::error ("all_va_args is only valid inside functions"); + args = Octave_object (); + break; + } + } + else + args(j++) = tmp; + } next (p); } else { - args(k) = tree_constant (); + args(j) = tree_constant (); break; } } diff --git a/src/tc-rep.cc b/src/tc-rep.cc --- a/src/tc-rep.cc +++ b/src/tc-rep.cc @@ -358,8 +358,8 @@ TC_REP::tree_constant_rep (TC_REP::constant_type t) { - assert (t == magic_colon); - type_tag = magic_colon; + assert (t == magic_colon || t == all_va_args); + type_tag = t; orig_text = 0; } @@ -401,6 +401,7 @@ break; case magic_colon: + case all_va_args: break; } @@ -438,6 +439,7 @@ case unknown_constant: case scalar_constant: case magic_colon: + case all_va_args: break; } @@ -1714,6 +1716,7 @@ case unknown_constant: case magic_colon: + case all_va_args: panic_impossible (); break; } @@ -1777,6 +1780,10 @@ os << ":"; break; + case all_va_args: + os << "all_va_args"; + break; + case map_constant: case unknown_constant: panic_impossible (); diff --git a/src/tc-rep.h b/src/tc-rep.h --- a/src/tc-rep.h +++ b/src/tc-rep.h @@ -44,6 +44,7 @@ range_constant, map_constant, magic_colon, + all_va_args, }; enum force_orient @@ -121,6 +122,9 @@ int is_magic_colon (void) const { return type_tag == tree_constant_rep::magic_colon; } + int is_all_va_args (void) const + { return type_tag == tree_constant_rep::all_va_args; } + tree_constant all (void) const; tree_constant any (void) const;