Mercurial > hg > octave-lojdl
changeset 10206:37a08e0ce2dc
support Matlab-style empty output/input arguments
author | Jaroslav Hajek <highegg@gmail.com> |
---|---|
date | Wed, 27 Jan 2010 12:41:49 +0100 |
parents | eea99d24adae |
children | 76a880a588ce |
files | src/ChangeLog src/oct-lvalue.cc src/oct-lvalue.h src/oct-parse.yy src/pt-arg-list.cc src/pt-arg-list.h src/pt-id.h src/pt-idx.cc src/pt-misc.cc |
diffstat | 9 files changed, 120 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,29 @@ +2010-01-27 Jaroslav Hajek <highegg@gmail.com> + + * 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 <jstorrs@gmail.com> * ov-class.cc (octave_class::print_with_name) Add default case for
--- a/src/oct-lvalue.cc +++ b/src/oct-lvalue.cc @@ -45,11 +45,10 @@ octave_lvalue::set_index (const std::string& t, const std::list<octave_value_list>& i) { - if (! index_set) + if (idx.empty ()) { type = t; idx = i; - index_set = true; } else error ("invalid index expression in assignment");
--- a/src/oct-lvalue.h +++ b/src/oct-lvalue.h @@ -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
--- a/src/oct-parse.yy +++ b/src/oct-parse.yy @@ -463,7 +463,7 @@ %type <tree_expression_type> matrix cell %type <tree_expression_type> primary_expr postfix_expr prefix_expr binary_expr %type <tree_expression_type> simple_expr colon_expr assign_expr expression -%type <tree_identifier_type> identifier fcn_name +%type <tree_identifier_type> identifier fcn_name magic_tilde %type <tree_identifier_type> superclass_identifier meta_identifier %type <octave_user_function_type> function1 function2 classdef1 %type <tree_index_expression_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 ();
--- a/src/pt-arg-list.cc +++ b/src/pt-arg-list.cc @@ -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<tree_identifier *> (s); + list_includes_magic_tilde = id && id->is_black_hole (); + } } bool
--- a/src/pt-arg-list.h +++ b/src/pt-arg-list.h @@ -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!
--- a/src/pt-id.h +++ b/src/pt-id.h @@ -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
--- a/src/pt-idx.cc +++ b/src/pt-idx.cc @@ -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<tree_expression *> (0)); + + if (lst && lst->has_magic_tilde ()) + error ("invalid use of empty argument (~) in index expression"); } void
--- a/src/pt-misc.cc +++ b/src/pt-misc.cc @@ -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",