changeset 4131:597fbc55ea40

[project @ 2002-10-29 17:12:53 by jwe]
author jwe
date Tue, 29 Oct 2002 17:12:54 +0000
parents 7d9bda865012
children 87eb044020ae
files src/ChangeLog src/lex.l src/parse.y src/pt-idx.cc src/pt-idx.h
diffstat 5 files changed, 128 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Mon Oct 28 21:05:31 2002 +0000
+++ b/src/ChangeLog	Tue Oct 29 17:12:54 2002 +0000
@@ -1,3 +1,25 @@
+2002-10-29  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* pt-idx.h (tree_index_expression::dyn_field): New data member.
+	* pt-idx.cc (tree_index_expression::tree_index_expression
+	(tree_expression*, tree_expression*, int, int)): New constructor.
+	(tree_index_expression::append (tree_expression*)): New function.
+	(tree_index_expression::get_struct_index): New function.
+	(tree_index_expression::make_arg_struct): Handle dynamic fields.
+	(tree_index_expression::rvalue): Likewise.
+	(tree_index_expression::lvalue): Likewise.
+
+	* parse.y (make_indirect_ref (tree_expression*, tree_expression*)):
+	New function.
+	(indirect_ref_op): New non-terminal.
+	(postfix_expr): Use it.
+	Recognize dynamic struct field references.
+	(parsing_indir): Delete unused non-terminal.
+
+	* lex.l ("("): Set lexer_flags.looking_at_indirect_ref to false here.
+
+	* pt-idx.cc (tree_index_expression::name): Simplify.
+
 2002-10-28  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* oct-conf.h.in (OCTAVE_CONF_HAVE_DLOPEN_API,
--- a/src/lex.l	Mon Oct 28 21:05:31 2002 +0000
+++ b/src/lex.l	Tue Oct 29 17:12:54 2002 +0000
@@ -691,6 +691,7 @@
   }
 
 "(" {
+    lexer_flags.looking_at_indirect_ref = false;
     if (lexer_flags.plotting && ! lexer_flags.in_plot_range)
       lexer_flags.past_plot_range = true;
     nesting_level.paren ();
--- a/src/parse.y	Mon Oct 28 21:05:31 2002 +0000
+++ b/src/parse.y	Tue Oct 29 17:12:54 2002 +0000
@@ -291,6 +291,10 @@
 static tree_index_expression *
 make_indirect_ref (tree_expression *expr, const std::string&);
 
+// Make an indirect reference expression with dynamic field name.
+static tree_index_expression *
+make_indirect_ref (tree_expression *expr, tree_expression *field);
+
 // Make a declaration command.
 static tree_decl_command *
 make_decl_command (int tok, token *tok_val, tree_decl_init_list *lst);
@@ -696,7 +700,7 @@
 		  }
 		;
 
-parsing_indir	: // empty
+indirect_ref_op	: '.'
 		  { lexer_flags.looking_at_indirect_ref = true; }
 		;
 
@@ -718,8 +722,10 @@
 		  { $$ = make_postfix_op (QUOTE, $1, $2); }
 		| postfix_expr TRANSPOSE
 		  { $$ = make_postfix_op (TRANSPOSE, $1, $2); }
-		| postfix_expr '.' parsing_indir STRUCT_ELT
-		  { $$ = make_indirect_ref ($1, $4->text ()); }
+		| postfix_expr indirect_ref_op STRUCT_ELT
+		  { $$ = make_indirect_ref ($1, $3->text ()); }
+		| postfix_expr indirect_ref_op '(' expression ')'
+		  { $$ = make_indirect_ref ($1, $4); }
 		;
 
 prefix_expr	: postfix_expr
@@ -2656,6 +2662,32 @@
   return retval;
 }
 
+// Make an indirect reference expression with dynamic field name.
+
+static tree_index_expression *
+make_indirect_ref (tree_expression *expr, tree_expression *elt)
+{
+  tree_index_expression *retval = 0;
+
+  int l = expr->line ();
+  int c = expr->column ();
+
+  if (expr->is_index_expression ())
+    {
+      tree_index_expression *tmp = static_cast<tree_index_expression *> (expr);
+
+      tmp->append (elt);
+
+      retval = tmp;
+    }
+  else
+    retval = new tree_index_expression (expr, elt, l, c);
+
+  lexer_flags.looking_at_indirect_ref = false;
+
+  return retval;
+}
+
 // Make a declaration command.
 
 static tree_decl_command *
--- a/src/pt-idx.cc	Mon Oct 28 21:05:31 2002 +0000
+++ b/src/pt-idx.cc	Tue Oct 29 17:12:54 2002 +0000
@@ -52,7 +52,8 @@
 tree_index_expression::tree_index_expression (tree_expression *e,
 					      tree_argument_list *lst,
 					      int l, int c, char t)
-  : tree_expression (l, c), expr (e), args (), type (), arg_nm ()
+  : tree_expression (l, c), expr (e), args (), type (),
+    arg_nm (), dyn_field ()
 {
   append (lst, t);
 }
@@ -60,17 +61,28 @@
 tree_index_expression::tree_index_expression (tree_expression *e,
 					      const std::string& n,
 					      int l, int c)
-  : tree_expression (l, c), expr (e), args (), type (), arg_nm ()
+  : tree_expression (l, c), expr (e), args (), type (),
+    arg_nm (), dyn_field ()
 {
   append (n);
 }
 
+tree_index_expression::tree_index_expression (tree_expression *e,
+					      tree_expression *df,
+					      int l, int c)
+  : tree_expression (l, c), expr (e), args (), type (),
+    arg_nm (), dyn_field ()
+{
+  append (df);
+}
+
 void
 tree_index_expression::append (tree_argument_list *lst, char t)
 {
   args.append (lst);
   type.append (1, t);
   arg_nm.append (lst ? lst->get_arg_names () : string_vector ());
+  dyn_field.append (static_cast<tree_expression *> (0));
 }
 
 void
@@ -79,6 +91,16 @@
   args.append (static_cast<tree_argument_list *> (0));
   type.append (".");
   arg_nm.append (n);
+  dyn_field.append (static_cast<tree_expression *> (0));
+}
+
+void
+tree_index_expression::append (tree_expression *df)
+{
+  args.append (static_cast<tree_argument_list *> (0));
+  type.append (".");
+  arg_nm.append ("");
+  dyn_field.append (df);
 }
 
 tree_index_expression::~tree_index_expression (void)
@@ -98,11 +120,7 @@
 std::string
 tree_index_expression::name (void) const
 {
-  // ??? FIXME ???
-  std::string xname = expr->name ();
-
-  return (type[0] != '.' || xname == "<unknown>")
-    ? xname : xname + "." + arg_nm.front ()(0);
+  return expr->name ();
 }
 
 static Cell
@@ -152,6 +170,29 @@
   return retval;
 }
 
+std::string
+tree_index_expression::get_struct_index (Pix p_arg_nm, Pix p_dyn_field) const
+{
+  std::string fn = arg_nm(p_arg_nm)(0);
+
+  if (fn.empty ())
+    {
+      tree_expression *df = dyn_field (p_dyn_field);
+
+      if (df)
+	{
+	  octave_value t = df->rvalue ();
+
+	  if (! error_state)
+	    fn = t.string_value ();
+	}
+      else
+	panic_impossible ();
+    }
+
+  return fn;
+}
+
 Octave_map
 tree_index_expression::make_arg_struct (void) const
 {
@@ -162,6 +203,7 @@
 
   Pix p_args = args.first ();
   Pix p_arg_nm = arg_nm.first ();
+  Pix p_dyn_field = dyn_field.first ();
 
   Octave_map m;
 
@@ -178,7 +220,7 @@
 	  break;
 
 	case '.':
-	  subs_list(i) = arg_nm(p_arg_nm)(0);
+	  subs_list(i) = get_struct_index (p_arg_nm, p_dyn_field);
 	  break;
 
 	default:
@@ -190,6 +232,7 @@
 
       args.next (p_args);
       arg_nm.next (p_arg_nm);
+      dyn_field.next (p_dyn_field);
     }
 
   m ["subs"] = subs_list;
@@ -216,6 +259,7 @@
 
       Pix p_args = args.first ();
       Pix p_arg_nm = arg_nm.first ();
+      Pix p_dyn_field = dyn_field.first ();
 
       for (int i = 0; i < n; i++)
 	{
@@ -230,7 +274,7 @@
 	      break;
 
 	    case '.':
-	      idx.append (arg_nm(p_arg_nm)(0));
+	      idx.append (get_struct_index (p_arg_nm, p_dyn_field));
 	      break;
 
 	    default:
@@ -242,6 +286,7 @@
 
 	  args.next (p_args);
 	  arg_nm.next (p_arg_nm);
+	  dyn_field.next (p_dyn_field);
 	}
 
       if (! error_state)
@@ -275,6 +320,7 @@
 
   Pix p_args = args.first ();
   Pix p_arg_nm = arg_nm.first ();
+  Pix p_dyn_field = dyn_field.first ();
 
   for (int i = 0; i < n; i++)
     {
@@ -289,7 +335,7 @@
 	  break;
 
 	case '.':
-	  idx.append (arg_nm(p_arg_nm)(0));
+	  idx.append (get_struct_index (p_arg_nm, p_dyn_field));
 	  break;
 
 	default:
@@ -301,6 +347,7 @@
 
       args.next (p_args);
       arg_nm.next (p_arg_nm);
+      dyn_field.next (p_dyn_field);
     }
 
   if (! error_state)
--- a/src/pt-idx.h	Mon Oct 28 21:05:31 2002 +0000
+++ b/src/pt-idx.h	Tue Oct 29 17:12:54 2002 +0000
@@ -54,12 +54,17 @@
   tree_index_expression (tree_expression *e, const std::string& n,
 			 int l = -1, int c = -1);
 
+  tree_index_expression (tree_expression *e, tree_expression* df,
+			 int l = -1, int c = -1);
+
   ~tree_index_expression (void);
 
   void append (tree_argument_list *lst = 0, char t = '(');
 
   void append (const std::string& n);
 
+  void append (tree_expression *df);
+
   bool is_index_expression (void) const { return true; }
 
   std::string name (void) const;
@@ -97,10 +102,16 @@
   // The type of this index expression.
   std::string type;
 
-  // The names of the arguments.
+  // The names of the arguments.  Used for constant struct element
+  // references.
   SLList<string_vector> arg_nm;
 
-  Octave_map tree_index_expression::make_arg_struct (void) const;
+  // The list of dynamic field names, if any.
+  SLList<tree_expression *> dyn_field;
+
+  Octave_map make_arg_struct (void) const;
+
+  std::string get_struct_index (Pix p_arg_nm, Pix p_dyn_field) const;
 
   // No copying!