# HG changeset patch # User John W. Eaton # Date 1205427943 14400 # Node ID 1f662945c2be859b6051bacb77aa1b2a05e141f7 # Parent 84122fb29c754281b397edf119de16fd79848943 handle varargin and varargout without keywords diff --git a/src/ChangeLog b/src/ChangeLog --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,16 @@ +2008-03-13 John W. Eaton + + * octave.gperf: Eliminate varargin and varargout keywords. + * lex.l (is_keyword_token): Eliminate varargin_kw and varargout_kw + from switch statement. + * parse.y (return_list): Eliminate special cases for VARARGOUT. + Call validate on tree_parameter_list object. + (param_list1): Likewise, for VARARGIN. + * pt-misc.cc (tree_parameter_list::validate): New function. + (tree_parameter_list::mark_varargs_only): Now private. + (tree_parameter_list::mark_varargs): Now private. + * pt-misc.h (tree_parameter_list::validate): Provide decl. + 2008-03-12 John W. Eaton * variables.cc (Vwhos_line_format): Omit print_dims parameter. diff --git a/src/lex.l b/src/lex.l --- a/src/lex.l +++ b/src/lex.l @@ -1144,18 +1144,6 @@ yylval.tok_val = new token (static_cast (l), "", l, c); break; - case varargin_kw: - if (! lexer_flags.looking_at_parameter_list) - return 0; - break; - - case varargout_kw: - if (! (lexer_flags.looking_at_return_list - || (lexer_flags.defining_func - && ! lexer_flags.parsed_function_name))) - return 0; - break; - default: panic_impossible (); } diff --git a/src/octave.gperf b/src/octave.gperf --- a/src/octave.gperf +++ b/src/octave.gperf @@ -54,8 +54,6 @@ until_kw, unwind_protect_kw, unwind_protect_cleanup_kw, - varargin_kw, - varargout_kw, while_kw }; @@ -91,8 +89,6 @@ until, UNTIL, until_kw unwind_protect, UNWIND, unwind_protect_kw unwind_protect_cleanup, CLEANUP, unwind_protect_cleanup_kw -varargin, VARARGIN, varargin_kw -varargout, VARARGOUT, varargout_kw while, WHILE, while_kw __FILE__, DQ_STRING, magic_file_kw __LINE__, NUM, magic_line_kw diff --git a/src/parse.y b/src/parse.y --- a/src/parse.y +++ b/src/parse.y @@ -399,7 +399,8 @@ // Other tokens. %token END_OF_INPUT LEXICAL_ERROR -%token FCN VARARGIN VARARGOUT +%token FCN +// %token VARARGIN VARARGOUT %token CLOSE_BRACE // Nonterminals we construct. @@ -1147,19 +1148,10 @@ | param_list2 { $1->mark_as_formal_parameters (); - $$ = $1; - } - | VARARGIN - { - tree_parameter_list *tmp = new tree_parameter_list (); - tmp->mark_varargs_only (); - $$ = tmp; - } - | param_list2 ',' VARARGIN - { - $1->mark_as_formal_parameters (); - $1->mark_varargs (); - $$ = $1; + if ($1->validate (tree_parameter_list::in)) + $$ = $1; + else + ABORT_PARSE; } ; @@ -1181,35 +1173,21 @@ lexer_flags.looking_at_return_list = false; $$ = new tree_parameter_list (); } - | '[' VARARGOUT ']' - { - lexer_flags.looking_at_return_list = false; - tree_parameter_list *tmp = new tree_parameter_list (); - tmp->mark_varargs_only (); - $$ = tmp; - } - | VARARGOUT - { - lexer_flags.looking_at_return_list = false; - tree_parameter_list *tmp = new tree_parameter_list (); - tmp->mark_varargs_only (); - $$ = tmp; - } | return_list1 { lexer_flags.looking_at_return_list = false; - $$ = $1; + if ($1->validate (tree_parameter_list::out)) + $$ = $1; + else + ABORT_PARSE; } | '[' return_list1 ']' { lexer_flags.looking_at_return_list = false; - $$ = $2; - } - | '[' return_list1 ',' VARARGOUT ']' - { - lexer_flags.looking_at_return_list = false; - $2->mark_varargs (); - $$ = $2; + if ($2->validate (tree_parameter_list::out)) + $$ = $2; + else + ABORT_PARSE; } ; diff --git a/src/pt-misc.cc b/src/pt-misc.cc --- a/src/pt-misc.cc +++ b/src/pt-misc.cc @@ -59,6 +59,65 @@ } } +bool +tree_parameter_list::validate (in_or_out type) +{ + bool retval = true; + + std::set dict; + + for (iterator p = begin (); p != end (); p++) + { + tree_decl_elt *elt = *p; + + tree_identifier *id = elt->ident (); + + if (id) + { + std::string name = id->name (); + + if (dict.find (name) != dict.end ()) + { + retval = false; + error ("`%s' appears more than once in parameter list", + name.c_str ()); + break; + } + else + dict.insert (name); + } + } + + if (! error_state) + { + std::string va_type = (type == in ? "varargin" : "varargout"); + + size_t len = length (); + + if (len > 0) + { + tree_decl_elt *elt = back (); + + tree_identifier *id = elt->ident (); + + if (id && id->name () == va_type) + { + if (len == 1) + mark_varargs_only (); + else + mark_varargs (); + + iterator p = end (); + --p; + delete *p; + erase (p); + } + } + } + + return retval; +} + void tree_parameter_list::initialize_undefined_elements (const std::string& warnfor, int nargout, diff --git a/src/pt-misc.h b/src/pt-misc.h --- a/src/pt-misc.h +++ b/src/pt-misc.h @@ -48,6 +48,12 @@ { public: + enum in_or_out + { + in = 1, + out = 2 + }; + tree_parameter_list (void) : marked_for_varargs (0) { } @@ -58,12 +64,10 @@ void mark_as_formal_parameters (void); - void mark_varargs (void) { marked_for_varargs = 1; } + bool validate (in_or_out type); bool takes_varargs (void) const { return marked_for_varargs != 0; } - void mark_varargs_only (void) { marked_for_varargs = -1; } - bool varargs_only (void) { return (marked_for_varargs < 0); } void initialize_undefined_elements (const std::string& warnfor, @@ -85,6 +89,10 @@ int marked_for_varargs; + void mark_varargs (void) { marked_for_varargs = 1; } + + void mark_varargs_only (void) { marked_for_varargs = -1; } + // No copying! tree_parameter_list (const tree_parameter_list&);