changeset 7587:1f662945c2be

handle varargin and varargout without keywords
author John W. Eaton <jwe@octave.org>
date Thu, 13 Mar 2008 13:05:43 -0400
parents 84122fb29c75
children cbedf652a752
files src/ChangeLog src/lex.l src/octave.gperf src/parse.y src/pt-misc.cc src/pt-misc.h
diffstat 6 files changed, 97 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Wed Mar 12 21:17:07 2008 -0400
+++ b/src/ChangeLog	Thu Mar 13 13:05:43 2008 -0400
@@ -1,3 +1,16 @@
+2008-03-13  John W. Eaton  <jwe@octave.org>
+
+	* 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  <jwe@octave.org>
 
 	* variables.cc (Vwhos_line_format): Omit print_dims parameter.
--- a/src/lex.l	Wed Mar 12 21:17:07 2008 -0400
+++ b/src/lex.l	Thu Mar 13 13:05:43 2008 -0400
@@ -1144,18 +1144,6 @@
 	  yylval.tok_val = new token (static_cast<double> (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 ();
 	}
--- a/src/octave.gperf	Wed Mar 12 21:17:07 2008 -0400
+++ b/src/octave.gperf	Thu Mar 13 13:05:43 2008 -0400
@@ -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
--- a/src/parse.y	Wed Mar 12 21:17:07 2008 -0400
+++ b/src/parse.y	Thu Mar 13 13:05:43 2008 -0400
@@ -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;
 		  }
 		;
 
--- a/src/pt-misc.cc	Wed Mar 12 21:17:07 2008 -0400
+++ b/src/pt-misc.cc	Thu Mar 13 13:05:43 2008 -0400
@@ -59,6 +59,65 @@
     }
 }
 
+bool
+tree_parameter_list::validate (in_or_out type)
+{
+  bool retval = true;
+
+  std::set<std::string> 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,
--- a/src/pt-misc.h	Wed Mar 12 21:17:07 2008 -0400
+++ b/src/pt-misc.h	Thu Mar 13 13:05:43 2008 -0400
@@ -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&);