changeset 15954:46ca8488de92 classdef

Re-engineer tree_expression postfix handling to make it more flexible. * libinterp/octave-value/ov-fcn.h (octave_function::is_postfix_index_handled): New method. * libinterp/parse-tree/oct-parse.yy (make_index_expression, make_indirect_ref): Set expression postfix index type. * libinterp/parse-tree/pt-exp.h (tree_expression::postfix_index): Remove field. (tree_expression::postfix_index_type): New field. (tree_expression::tree_expression): Initialize it. (tree_expression::copy_base): Copy it. (tree_expression::set_postfix_index, tree_expression::postfix_index): New methods. (tree_expression::mark_postfix_indexed): Remove method. (tree_expression::is_postfix_indexed): Use postfix_index_type field. * libinterp/parse-tree/pt-id.cc (tree_identifier::rvalue): Let the function object determine whether it can handle the first postfix index and call do_multi_index_op if it can't.
author Michael Goffioul <michael.goffioul@gmail.com>
date Tue, 15 Jan 2013 17:01:10 -0500
parents 0bf55f5f5d10
children 837a4a9b5049
files libinterp/octave-value/ov-fcn.h libinterp/parse-tree/oct-parse.yy libinterp/parse-tree/pt-exp.h libinterp/parse-tree/pt-id.cc
diffstat 4 files changed, 34 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/octave-value/ov-fcn.h	Tue Jan 15 14:50:43 2013 -0500
+++ b/libinterp/octave-value/ov-fcn.h	Tue Jan 15 17:01:10 2013 -0500
@@ -152,6 +152,9 @@
 
   virtual void accept (tree_walker&) { }
 
+  virtual bool is_postfix_index_handled (char type) const
+    { return (type == '(' || type == '{'); }
+
 protected:
 
   octave_function (const std::string& nm,
--- a/libinterp/parse-tree/oct-parse.yy	Tue Jan 15 14:50:43 2013 -0500
+++ b/libinterp/parse-tree/oct-parse.yy	Tue Jan 15 17:01:10 2013 -0500
@@ -3169,7 +3169,8 @@
   int l = expr->line ();
   int c = expr->column ();
 
-  expr->mark_postfix_indexed ();
+  if (! expr->is_postfix_indexed ()) 
+    expr->set_postfix_index (type);
 
   if (expr->is_index_expression ())
     {
@@ -3195,6 +3196,9 @@
   int l = expr->line ();
   int c = expr->column ();
 
+  if (! expr->is_postfix_indexed ()) 
+    expr->set_postfix_index ('.');
+
   if (expr->is_index_expression ())
     {
       tree_index_expression *tmp = static_cast<tree_index_expression *> (expr);
@@ -3221,6 +3225,9 @@
   int l = expr->line ();
   int c = expr->column ();
 
+  if (! expr->is_postfix_indexed ()) 
+    expr->set_postfix_index ('.');
+
   if (expr->is_index_expression ())
     {
       tree_index_expression *tmp = static_cast<tree_index_expression *> (expr);
--- a/libinterp/parse-tree/pt-exp.h	Tue Jan 15 14:50:43 2013 -0500
+++ b/libinterp/parse-tree/pt-exp.h	Tue Jan 15 17:01:10 2013 -0500
@@ -40,7 +40,7 @@
 public:
 
   tree_expression (int l = -1, int c = -1)
-    : tree (l, c), num_parens (0), postfix_indexed (false),
+    : tree (l, c), num_parens (0), postfix_index_type ('\0'),
       print_flag (false) { }
 
   virtual ~tree_expression (void) { }
@@ -85,7 +85,9 @@
 
   int paren_count (void) const { return num_parens; }
 
-  bool is_postfix_indexed (void) const { return postfix_indexed; }
+  bool is_postfix_indexed (void) const { return (postfix_index_type != '\0'); }
+
+  char postfix_index (void) const { return postfix_index_type; }
 
   // Check if the result of the expression should be printed.
   // Should normally be used in conjunction with
@@ -106,9 +108,9 @@
       return this;
     }
 
-  tree_expression *mark_postfix_indexed (void)
+  tree_expression *set_postfix_index (char type)
     {
-      postfix_indexed = true;
+      postfix_index_type = type;
       return this;
     }
 
@@ -121,7 +123,7 @@
   virtual void copy_base (const tree_expression& e)
     {
       num_parens = e.num_parens;
-      postfix_indexed = e.postfix_indexed;
+      postfix_index_type = e.postfix_index_type;
       print_flag = e.print_flag;
     }
 
@@ -135,9 +137,10 @@
   //                  ==> 0 for expression e2
   int num_parens;
 
-  // A flag that says whether this expression has an index associated
-  // with it.  See the code in tree_identifier::rvalue for the rationale.
-  bool postfix_indexed;
+  // The first index type associated with this expression. This field
+  // is 0 (character '\0') if the expression has no associated index.
+  // See the code in tree_identifier::rvalue for the rationale.
+  char postfix_index_type;
 
   // Print result of rvalue for this expression?
   bool print_flag;
--- a/libinterp/parse-tree/pt-id.cc	Tue Jan 15 14:50:43 2013 -0500
+++ b/libinterp/parse-tree/pt-id.cc	Tue Jan 15 17:01:10 2013 -0500
@@ -75,13 +75,19 @@
       //
       // If this identifier refers to a function, we need to know
       // whether it is indexed so that we can do the same thing
-      // for 'f' and 'f()'.  If the index is present, return the
-      // function object and let tree_index_expression::rvalue
-      // handle indexing.  Otherwise, arrange to call the function
-      // here, so that we don't return the function definition as
-      // a value.
+      // for 'f' and 'f()'.  If the index is present and the function
+      // object declares it can handle it, return the function object
+      // and let tree_index_expression::rvalue handle indexing.
+      // Otherwise, arrange to call the function here, so that we don't
+      // return the function definition as a value.
 
-      if (val.is_function () && ! is_postfix_indexed ())
+      octave_function *fcn = 0;
+
+      if (val.is_function ())
+        fcn = val.function_value (true);
+
+      if (fcn && ! (is_postfix_indexed ()
+                    && fcn->is_postfix_index_handled (postfix_index ())))
         {
           octave_value_list tmp_args;