# HG changeset patch # User Jaroslav Hajek # Date 1264592509 -3600 # Node ID 37a08e0ce2dcecc92932e76f1f5153eb5aacaaa0 # Parent eea99d24adae1c0c315f5631280820feb5e6cb19 support Matlab-style empty output/input arguments diff -r eea99d24adae -r 37a08e0ce2dc src/ChangeLog --- a/src/ChangeLog Wed Jan 27 02:24:17 2010 -0500 +++ b/src/ChangeLog Wed Jan 27 12:41:49 2010 +0100 @@ -1,3 +1,29 @@ +2010-01-27 Jaroslav Hajek + + * oct-lvalue.h (octave_lvalue::is_black_hole): New method. + (octave_lvalue::black_hole): New field. + (octave_lvalue::is_defined, octave_lvalue::is_undefined, + octave_lvalue::is_map): Make const. + (octave_lvalue::index_set): Remove field. + (octave_lvalue::octave_lvalue, octave_lvalue::operator =): Correctly + handle black holes. Update. + (dummy_value): Remove. + * pt-id.h (tree_identifier::is_black_hole): New method. + (tree_identifier::is_variable): Make virtual. + (tree_black_hole): New class. + * oct-parse.yy (magic_tilde): New terminal. + (param_list): Allow magic_tilde. + (arg_list): Allow magic_tilde. + * pt-misc.cc (tree_parameter_list::validate): Handle black holes. + * pt-idx.cc (tree_index_expression::append): Gripe if arguments + contain magic tilde. + * pt-arg-list.h (tree_argument_list::has_magic_tilde): New method + decl. + (tree_argument_list::list_includes_magic_tilde): New field. + (tree_argument_list::tree_argument_list): Initialize it in ctors. + * pt-arg-list.cc (tree_argument_list::has_magic_tilde): New method. + (tree_argument_list::append): Update list_includes_magic_tilde. + 2010-01-27 Judd Storrs * ov-class.cc (octave_class::print_with_name) Add default case for diff -r eea99d24adae -r 37a08e0ce2dc src/oct-lvalue.cc --- a/src/oct-lvalue.cc Wed Jan 27 02:24:17 2010 -0500 +++ b/src/oct-lvalue.cc Wed Jan 27 12:41:49 2010 +0100 @@ -45,11 +45,10 @@ octave_lvalue::set_index (const std::string& t, const std::list& i) { - if (! index_set) + if (idx.empty ()) { type = t; idx = i; - index_set = true; } else error ("invalid index expression in assignment"); diff -r eea99d24adae -r 37a08e0ce2dc src/oct-lvalue.h --- a/src/oct-lvalue.h Wed Jan 27 02:24:17 2010 -0500 +++ b/src/oct-lvalue.h Wed Jan 27 12:41:49 2010 +0100 @@ -32,32 +32,35 @@ #include "oct-obj.h" #include "pt-idx.h" -// FIXME -- eliminate the following kluge? - -// This variable is used when creating dummy octave_lvalue objects. -static octave_value dummy_val; - class octave_lvalue { public: - octave_lvalue (octave_value *v = &dummy_val) - : val (v), type (), idx (), nel (1), index_set (false) { } + octave_lvalue (octave_value *v = 0) + : val (v), type (), idx (), nel (1) + { + if (! v) + val = &black_hole; + } octave_lvalue (const octave_lvalue& vr) - : val (vr.val), type (vr.type), idx (vr.idx), nel (vr.nel), - index_set (vr.index_set) { } + : val (vr.val), type (vr.type), idx (vr.idx), nel (vr.nel) + { + if (vr.is_black_hole ()) + val = &black_hole; + } octave_lvalue& operator = (const octave_lvalue& vr) { if (this != &vr) { val = vr.val; + if (vr.is_black_hole ()) + val = &black_hole; type = vr.type; idx = vr.idx; nel = vr.nel; - index_set = vr.index_set; } return *this; @@ -65,11 +68,13 @@ ~octave_lvalue (void) { } - bool is_defined (void) { return val->is_defined (); } + bool is_black_hole (void) const { return val == &black_hole; } + + bool is_defined (void) const { return val->is_defined (); } - bool is_undefined (void) { return val->is_undefined (); } + bool is_undefined (void) const { return val->is_undefined (); } - bool is_map (void) { return val->is_map (); } + bool is_map (void) const { return val->is_map (); } void define (const octave_value& v) { *val = v; } @@ -99,7 +104,7 @@ octave_idx_type nel; - bool index_set; + octave_value black_hole; }; #endif diff -r eea99d24adae -r 37a08e0ce2dc src/oct-parse.yy --- a/src/oct-parse.yy Wed Jan 27 02:24:17 2010 -0500 +++ b/src/oct-parse.yy Wed Jan 27 12:41:49 2010 +0100 @@ -463,7 +463,7 @@ %type matrix cell %type primary_expr postfix_expr prefix_expr binary_expr %type simple_expr colon_expr assign_expr expression -%type identifier fcn_name +%type identifier fcn_name magic_tilde %type superclass_identifier meta_identifier %type function1 function2 classdef1 %type word_list_cmd @@ -755,15 +755,28 @@ } ; +magic_tilde : EXPR_NOT + { + $$ = new tree_black_hole (); + } + ; + arg_list : expression { $$ = new tree_argument_list ($1); } | magic_colon { $$ = new tree_argument_list ($1); } + | magic_tilde + { $$ = new tree_argument_list ($1); } | arg_list ',' magic_colon { $1->append ($3); $$ = $1; } + | arg_list ',' magic_tilde + { + $1->append ($3); + $$ = $1; + } | arg_list ',' expression { $1->append ($3); @@ -1005,6 +1018,10 @@ lexer_flags.looking_at_initializer_expression = false; $$ = new tree_decl_elt ($1, $4); } + | magic_tilde + { + $$ = new tree_decl_elt ($1); + } ; // ==================== @@ -2972,6 +2989,12 @@ char type) { tree_index_expression *retval = 0; + + if (args && args->has_magic_tilde ()) + { + yyerror ("invalid use of empty argument (~) in index expression"); + return retval; + } int l = expr->line (); int c = expr->column (); diff -r eea99d24adae -r 37a08e0ce2dc src/pt-arg-list.cc --- a/src/pt-arg-list.cc Wed Jan 27 02:24:17 2010 -0500 +++ b/src/pt-arg-list.cc Wed Jan 27 12:41:49 2010 +0100 @@ -39,6 +39,7 @@ #include "parse.h" #include "pt-arg-list.h" #include "pt-exp.h" +#include "pt-id.h" #include "pt-pr-code.h" #include "pt-walk.h" #include "toplev.h" @@ -77,6 +78,12 @@ if (! list_includes_magic_end && s && s->has_magic_end ()) list_includes_magic_end = true; + + if (! list_includes_magic_tilde && s && s->is_identifier ()) + { + tree_identifier *id = dynamic_cast (s); + list_includes_magic_tilde = id && id->is_black_hole (); + } } bool diff -r eea99d24adae -r 37a08e0ce2dc src/pt-arg-list.h --- a/src/pt-arg-list.h Wed Jan 27 02:24:17 2010 -0500 +++ b/src/pt-arg-list.h Wed Jan 27 12:41:49 2010 +0100 @@ -46,16 +46,21 @@ typedef tree_expression* element_type; tree_argument_list (void) - : list_includes_magic_end (false), simple_assign_lhs (false) { } + : list_includes_magic_end (false), list_includes_magic_tilde (false), + simple_assign_lhs (false) { } tree_argument_list (tree_expression *t) - : list_includes_magic_end (false), simple_assign_lhs (false) + : list_includes_magic_end (false), list_includes_magic_tilde (false), + simple_assign_lhs (false) { append (t); } ~tree_argument_list (void); bool has_magic_end (void) const; + bool has_magic_tilde (void) const + { return list_includes_magic_tilde; } + tree_expression *remove_front (void) { iterator p = begin (); @@ -87,6 +92,8 @@ bool list_includes_magic_end; + bool list_includes_magic_tilde; + bool simple_assign_lhs; // No copying! diff -r eea99d24adae -r 37a08e0ce2dc src/pt-id.h --- a/src/pt-id.h Wed Jan 27 02:24:17 2010 -0500 +++ b/src/pt-id.h Wed Jan 27 12:41:49 2010 +0100 @@ -66,7 +66,9 @@ bool is_defined (void) { return xsym().is_defined (); } - bool is_variable (void) { return xsym().is_variable (); } + virtual bool is_variable (void) { return xsym().is_variable (); } + + virtual bool is_black_hole (void) { return false; } // Try to find a definition for an identifier. Here's how: // @@ -143,4 +145,26 @@ tree_identifier& operator = (const tree_identifier&); }; +class tree_black_hole : public tree_identifier +{ +public: + + tree_black_hole (int l = -1, int c = -1) + : tree_identifier (l, c) { } + + std::string name (void) const { return "~"; } + + bool is_variable (void) { return false; } + + bool is_black_hole (void) { return true; } + + tree_black_hole *dup (void) const + { return new tree_black_hole; } + + octave_lvalue lvalue (void) + { + return octave_lvalue (0); // black hole lvalue + } +}; + #endif diff -r eea99d24adae -r 37a08e0ce2dc src/pt-idx.cc --- a/src/pt-idx.cc Wed Jan 27 02:24:17 2010 -0500 +++ b/src/pt-idx.cc Wed Jan 27 12:41:49 2010 +0100 @@ -81,6 +81,9 @@ type.append (1, t); arg_nm.push_back (lst ? lst->get_arg_names () : string_vector ()); dyn_field.push_back (static_cast (0)); + + if (lst && lst->has_magic_tilde ()) + error ("invalid use of empty argument (~) in index expression"); } void diff -r eea99d24adae -r 37a08e0ce2dc src/pt-misc.cc --- a/src/pt-misc.cc Wed Jan 27 02:24:17 2010 -0500 +++ b/src/pt-misc.cc Wed Jan 27 12:41:49 2010 +0100 @@ -76,7 +76,12 @@ { std::string name = id->name (); - if (dict.find (name) != dict.end ()) + if (id->is_black_hole ()) + { + if (type != in) + error ("invalid use of ~ in output list"); + } + else if (dict.find (name) != dict.end ()) { retval = false; error ("`%s' appears more than once in parameter list",