changeset 4234:90e44267e8cf

[project @ 2002-12-21 17:15:25 by jwe]
author jwe
date Sat, 21 Dec 2002 17:15:25 +0000
parents ccfdb55c8156
children 23bb43fc1184
files src/ChangeLog src/Makefile.in src/defun-int.h src/defun.cc src/defun.h src/lex.h src/lex.l src/mkbuiltins src/mkgendoc src/oct-lvalue.h src/parse.y src/pt-arg-list.cc src/pt-arg-list.h src/pt-idx.cc src/symtab.cc src/symtab.h
diffstat 16 files changed, 192 insertions(+), 61 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Fri Dec 20 22:43:55 2002 +0000
+++ b/src/ChangeLog	Sat Dec 21 17:15:25 2002 +0000
@@ -1,10 +1,39 @@
+2002-12-21  John W. Eaton  <jwe@bevo.che.wisc.edu>
+
+	* pt-arg-list.cc (indexed_object, indexed_position):
+	New file-scope static variables.
+	(tree_argument_list::convert_to_const_vector): New arg, object.
+	Protect and set indexed_object and indexed_position.
+	(F__end__): New function.
+
+	* octave-lvalue.h (octave_lvalue::object): New member function.
+	* pt-idx.cc (make_value_list): New arg, object.  Change all
+	callers.  Pass object to convert_to_const_vector.
+
+	* lex.h (lexical_feedback.looking_at_object_index): New data member.
+	* lex.l (lexical_feedback::init): Initialize it.
+	(is_keyword): If looking at object index, end is not a keyword.
+	(handle_identifier): If end is not a keyword, transform it to __end__.
+	* parse.y (begin_obj_idx): New non-terminal.
+	(postfix_expr): Use it.
+
+	* defun.cc (install_builtin_function): New arg, can_hide_function.
+	* defun-int.h: Fix decl.
+	(DEFCONSTFUN_INTERNAL): New macro.
+	* defun.h (DEFCONSTFUN): New macro.
+	* mkbuiltins (XDEFCONSTFUN_INTERNAL): New macro.
+	* mkgendoc: Likewise.
+	* Makefile.in (DEFUN_PATTERN): Make it work for DEFCONSTFUN too.
+	* symtab.h (symbol_record::can_hide_function): New data member.
+	(symbol_record::symbol_record): Initialize it.
+	* symtab.cc (symbol_record::variable_reference): Also check
+	can_hide_function flag.
+
 2002-12-20  John W. Eaton  <jwe@bevo.che.wisc.edu>
 
 	* DLD-FUNCTIONS/time.cc (extract_tm): Use int_value() instead of
 	casting double_value() to int.
 
-	* DLD-FUNCITONS/time.cc ()
-
 	* ov.cc (octave_value::next_subsref): Arg "skip" is now size_t.
 
 	* oct-obj.h (octave_value_list::octave_value_list (double),
--- a/src/Makefile.in	Fri Dec 20 22:43:55 2002 +0000
+++ b/src/Makefile.in	Sat Dec 21 17:15:25 2002 +0000
@@ -163,7 +163,7 @@
 # so we have to repeat ourselves because some stupid egreps don't like
 # empty elements in alternation patterns.
 
-DEFUN_PATTERN = "^[ \t]*DEF(CMD|UN|UN_DLD|UN_TEXT|UN_MAPPER)[ \t]*\\("
+DEFUN_PATTERN = "^[ \t]*DEF(CONSTFUN|CMD|UN|UN_DLD|UN_TEXT|UN_MAPPER)[ \t]*\\("
 
 DLD_DEF_FILES := $(patsubst %.cc, %.df, $(DLD_XSRC))
 
--- a/src/defun-int.h	Fri Dec 20 22:43:55 2002 +0000
+++ b/src/defun-int.h	Sat Dec 21 17:15:25 2002 +0000
@@ -42,7 +42,8 @@
 
 extern void
 install_builtin_function (octave_builtin::fcn f, const std::string& name,
-			  const std::string& doc, bool is_text_fcn = false);
+			  const std::string& doc, bool is_text_fcn = false,
+			  bool can_hide_function = true);
 
 extern void
 install_builtin_variable (const std::string& n, const octave_value& v,
@@ -107,6 +108,11 @@
     XDEFUN_INTERNAL (name, args_name, nargout_name, is_text_fcn, doc) \
   END_INSTALL_BUILTIN
 
+#define DEFCONSTFUN_INTERNAL(name, args_name, nargout_name, is_text_fcn, doc) \
+  BEGIN_INSTALL_BUILTIN \
+    XDEFCONSTFUN_INTERNAL (name, args_name, nargout_name, is_text_fcn, doc) \
+  END_INSTALL_BUILTIN
+
 #define DEFUNX_INTERNAL(name, fname, args_name, nargout_name, \
 			is_text_fcn, doc) \
   BEGIN_INSTALL_BUILTIN \
@@ -161,6 +167,9 @@
 #define DEFUN_INTERNAL(name, args_name, nargout_name, is_text_fcn, doc) \
   DECLARE_FUN (name, args_name, nargout_name)
 
+#define DEFCONSTFUN_INTERNAL(name, args_name, nargout_name, is_text_fcn, doc) \
+  DECLARE_FUN (name, args_name, nargout_name)
+
 #define DEFUNX_INTERNAL(name, fname, args_name, nargout_name, \
 			is_text_fcn, doc) \
   DECLARE_FUNX (fname, args_name, nargout_name)
--- a/src/defun.cc	Fri Dec 20 22:43:55 2002 +0000
+++ b/src/defun.cc	Sat Dec 21 17:15:25 2002 +0000
@@ -97,7 +97,8 @@
 
 void
 install_builtin_function (octave_builtin::fcn f, const std::string& name,
-			  const std::string& doc, bool is_text_fcn)
+			  const std::string& doc, bool is_text_fcn,
+			  bool /* can_hide_function -- not yet implemented */)
 {
   symbol_record *sym_rec = fbi_sym_tab->lookup (name, true);
 
--- a/src/defun.h	Fri Dec 20 22:43:55 2002 +0000
+++ b/src/defun.h	Sat Dec 21 17:15:25 2002 +0000
@@ -101,6 +101,10 @@
 
 #define DEFUN_TEXT DEFCMD
 
+// This is a function with a name that can't be hidden by a variable.
+#define DEFCONSTFUN(name, args_name, nargout_name, doc) \
+  DEFCONSTFUN_INTERNAL (name, args_name, nargout_name, true, doc)
+
 // Define a mapper function.
 //
 //   name is the name of the function, unquoqted.
--- a/src/lex.h	Fri Dec 20 22:43:55 2002 +0000
+++ b/src/lex.h	Sat Dec 21 17:15:25 2002 +0000
@@ -162,6 +162,9 @@
   // multi-value assignment statement.
   bool looking_at_matrix_or_assign_lhs;
 
+  // TRUE means we're parsing an indexing operation for an object.
+  bool looking_at_object_index;
+
   // GAG.  Stupid kludge so that [[1,2][3,4]] will work.
   bool do_comma_insert;
 
--- a/src/lex.l	Fri Dec 20 22:43:55 2002 +0000
+++ b/src/lex.l	Sat Dec 21 17:15:25 2002 +0000
@@ -1108,7 +1108,10 @@
  	  break;
 
 	case end_kw:
-	  yylval.tok_val = new token (token::simple_end, l, c);
+	  if (lexer_flags.looking_at_object_index)
+	    return 0;
+	  else
+	    yylval.tok_val = new token (token::simple_end, l, c);
 	  break;
 
 	case end_try_catch_kw:
@@ -2383,7 +2386,11 @@
 	}
     }
 
-  // Find the token in the symbol table.
+  // Find the token in the symbol table.  Beware the magic
+  // transformation of the end keyword...
+
+  if (tok == "end")
+    tok = "__end__";    
 
   yylval.tok_val = new token (lookup_identifier (tok),
 			      input_line_number,
@@ -2538,6 +2545,9 @@
   // assignment statement.
   looking_at_matrix_or_assign_lhs = false;
 
+  // Not parsing an object index.
+  looking_at_object_index = false;
+
   // Next token can be identifier.
   cant_be_identifier = false;
 
--- a/src/mkbuiltins	Fri Dec 20 22:43:55 2002 +0000
+++ b/src/mkbuiltins	Sat Dec 21 17:15:25 2002 +0000
@@ -42,12 +42,17 @@
 
 #define XDEFUN_INTERNAL(name, args_name, nargout_name, is_text_fcn, doc) \
   extern DECLARE_FUN (name, args_name, nargout_name); \
-    install_builtin_function (F ## name, #name, doc, is_text_fcn); \
+  install_builtin_function (F ## name, #name, doc, is_text_fcn); \
+
+#define XDEFCONSTFUN_INTERNAL(name, args_name, nargout_name, \
+			      is_text_fcn, doc) \
+  extern DECLARE_FUN (name, args_name, nargout_name); \
+  install_builtin_function (F ## name, #name, doc, is_text_fcn, false); \
 
 #define XDEFUNX_INTERNAL(name, fname, args_name, nargout_name, \
 			 is_text_fcn, doc) \
   extern DECLARE_FUNX (fname, args_name, nargout_name); \
-    install_builtin_function (fname, name, doc, is_text_fcn); \
+  install_builtin_function (fname, name, doc, is_text_fcn); \
 
 #define XDEFALIAS_INTERNAL(alias, name) \
   alias_builtin (#alias, #name);
--- a/src/mkgendoc	Fri Dec 20 22:43:55 2002 +0000
+++ b/src/mkgendoc	Sat Dec 21 17:15:25 2002 +0000
@@ -24,6 +24,10 @@
 #define XDEFUN_INTERNAL(name, args_name, nargout_name, is_text_fcn, doc) \
   print_doc_string (#name, doc);
 
+#define XDEFCONSTFUN_INTERNAL(name, args_name, nargout_name, \
+			      is_text_fcn, doc) \
+  print_doc_string (#name, doc);
+
 #define XDEFUNX_INTERNAL(name, fname, args_name, nargout_name, \
 			 is_text_fcn, doc) \
   print_doc_string (name, doc);
--- a/src/oct-lvalue.h	Fri Dec 20 22:43:55 2002 +0000
+++ b/src/oct-lvalue.h	Sat Dec 21 17:15:25 2002 +0000
@@ -85,6 +85,8 @@
   octave_value value (void)
     { return idx.empty () ? *val : val->subsref (type, idx); }
 
+  const octave_value *object (void) const { return val; }
+
 private:
 
   octave_value *val;
--- a/src/parse.y	Fri Dec 20 22:43:55 2002 +0000
+++ b/src/parse.y	Sat Dec 21 17:15:25 2002 +0000
@@ -705,16 +705,26 @@
 		  { lexer_flags.looking_at_indirect_ref = true; }
 		;
 
+begin_obj_idx	: // empty
+		  { lexer_flags.looking_at_object_index = true; }
+		;
+
 postfix_expr	: primary_expr
 		  { $$ = $1; }
-		| postfix_expr '(' ')'
+		| postfix_expr '(' begin_obj_idx ')'
 		  { $$ = make_index_expression ($1, 0, '('); }
-		| postfix_expr '(' arg_list ')'
-		  { $$ = make_index_expression ($1, $3, '('); }
-		| postfix_expr '{' '}'
+		| postfix_expr '(' begin_obj_idx arg_list ')'
+		  {
+		    $$ = make_index_expression ($1, $4, '(');
+		    lexer_flags.looking_at_object_index = false;
+		  }
+		| postfix_expr '{' begin_obj_idx '}'
 		  { $$ = make_index_expression ($1, 0, '{'); }
-		| postfix_expr '{' arg_list '}'
-		  { $$ = make_index_expression ($1, $3, '{'); }
+		| postfix_expr '{' begin_obj_idx arg_list '}'
+		  {
+		    $$ = make_index_expression ($1, $4, '{');
+		    lexer_flags.looking_at_object_index = false;
+		  }
 		| postfix_expr PLUS_PLUS
 		  { $$ = make_postfix_op (PLUS_PLUS, $1, $2); }
 		| postfix_expr MINUS_MINUS
--- a/src/pt-arg-list.cc	Fri Dec 20 22:43:55 2002 +0000
+++ b/src/pt-arg-list.cc	Sat Dec 21 17:15:25 2002 +0000
@@ -33,6 +33,7 @@
 
 #include "str-vec.h"
 
+#include "defun.h"
 #include "error.h"
 #include "oct-obj.h"
 #include "ov.h"
@@ -42,6 +43,7 @@
 #include "pt-pr-code.h"
 #include "pt-walk.h"
 #include "toplev.h"
+#include "unwind-prot.h"
 
 // Argument lists.
 
@@ -88,9 +90,51 @@
   return true;
 }
 
+static const octave_value *indexed_object = 0;
+static int index_position = 0;
+
+DEFCONSTFUN (__end__, , ,
+  "internal function")
+{
+  octave_value retval;
+
+  if (indexed_object)
+    {
+      switch (index_position)
+	{
+	case -1:
+	  // XXX FIXME XXX -- we really want "numel" here.
+	  retval = indexed_object->rows () * indexed_object->columns ();
+	  break;
+
+	case 0:
+	  retval = indexed_object->rows ();
+	  break;
+
+	case 1:
+	  retval = indexed_object->columns ();
+	  break;
+
+	default:
+	  ::error ("__end__: internal error");
+	  break;
+	}
+    }
+  else
+    ::error ("__end__: internal error");
+
+  return retval;
+}
+
 octave_value_list
-tree_argument_list::convert_to_const_vector (void)
+tree_argument_list::convert_to_const_vector (const octave_value *object)
 {
+  unwind_protect::begin_frame ("convert_to_const_vector");
+
+  unwind_protect_ptr (indexed_object);
+
+  indexed_object = object;
+
   int len = length ();
 
   // XXX FIXME XXX -- would be nice to know in advance how largs args
@@ -105,6 +149,8 @@
   int j = 0;
   for (int k = 0; k < len; k++)
     {
+      index_position = (len == 1) ? -1 : k;
+
       tree_expression *elt = *p++;
 
       if (elt)
@@ -160,6 +206,8 @@
 
   args.resize (j);
 
+  unwind_protect::run_frame ("convert_to_const_vector");
+
   return args;
 }
 
--- a/src/pt-arg-list.h	Fri Dec 20 22:43:55 2002 +0000
+++ b/src/pt-arg-list.h	Sat Dec 21 17:15:25 2002 +0000
@@ -63,7 +63,7 @@
 
   bool all_elements_are_constant (void) const;
 
-  octave_value_list convert_to_const_vector (void);
+  octave_value_list convert_to_const_vector (const octave_value *object = 0);
 
   string_vector get_arg_names (void) const;
 
--- a/src/pt-idx.cc	Fri Dec 20 22:43:55 2002 +0000
+++ b/src/pt-idx.cc	Sat Dec 21 17:15:25 2002 +0000
@@ -148,12 +148,13 @@
 }
 
 static inline octave_value_list
-make_value_list (tree_argument_list *args, const string_vector& arg_nm)
+make_value_list (tree_argument_list *args, const string_vector& arg_nm,
+		 const octave_value *object)
 {
   octave_value_list retval;
 
   if (args)
-    retval = args->convert_to_const_vector ();
+    retval = args->convert_to_const_vector (object);
 
   if (! error_state)
     {
@@ -274,11 +275,11 @@
 	  switch (type[i])
 	    {
 	    case '(':
-	      idx.push_back (make_value_list (*p_args, *p_arg_nm));
+	      idx.push_back (make_value_list (*p_args, *p_arg_nm, &tmp));
 	      break;
 
 	    case '{':
-	      idx.push_back (make_value_list (*p_args, *p_arg_nm));
+	      idx.push_back (make_value_list (*p_args, *p_arg_nm, &tmp));
 	      break;
 
 	    case '.':
@@ -335,42 +336,44 @@
   std::list<string_vector>::iterator p_arg_nm = arg_nm.begin ();
   std::list<tree_expression *>::iterator p_dyn_field = dyn_field.begin ();
 
-  for (int i = 0; i < n; i++)
-    {
-      switch (type[i])
-	{
-	case '(':
-	  idx.push_back (make_value_list (*p_args, *p_arg_nm));
-	  break;
-
-	case '{':
-	  idx.push_back (make_value_list (*p_args, *p_arg_nm));
-	  break;
-
-	case '.':
-	  {
-	    idx.push_back (octave_value (get_struct_index (p_arg_nm, p_dyn_field)));
-
-	    if (error_state)
-	      eval_error ();
-	  }
-	  break;
-
-	default:
-	  panic_impossible ();
-	}
-
-      if (error_state)
-	break;
-
-      p_args++;
-      p_arg_nm++;
-      p_dyn_field++;
-    }
+  retval = expr->lvalue ();
 
   if (! error_state)
     {
-      retval = expr->lvalue ();
+      const octave_value *tmp = retval.object ();
+
+      for (int i = 0; i < n; i++)
+	{
+	  switch (type[i])
+	    {
+	    case '(':
+	      idx.push_back (make_value_list (*p_args, *p_arg_nm, tmp));
+	      break;
+
+	    case '{':
+	      idx.push_back (make_value_list (*p_args, *p_arg_nm, tmp));
+	      break;
+
+	    case '.':
+	      {
+		idx.push_back (octave_value (get_struct_index (p_arg_nm, p_dyn_field)));
+
+		if (error_state)
+		  eval_error ();
+	      }
+	      break;
+
+	    default:
+	      panic_impossible ();
+	    }
+
+	  if (error_state)
+	    break;
+
+	  p_args++;
+	  p_arg_nm++;
+	  p_dyn_field++;
+	}
 
       if (! error_state)
 	retval.set_index (type, idx);
--- a/src/symtab.cc	Fri Dec 20 22:43:55 2002 +0000
+++ b/src/symtab.cc	Sat Dec 21 17:15:25 2002 +0000
@@ -332,15 +332,14 @@
     alias (tmp_sym);
 }
 
-
 octave_lvalue
 symbol_record::variable_reference (void)
 {
-  if (Vvariables_can_hide_functions <= 0
+  if ((Vvariables_can_hide_functions <= 0 || ! can_hide_function)
       && (is_function ()
 	  || (! is_defined () && is_valid_function (nm))))
     {
-      if (Vvariables_can_hide_functions < 0)
+      if (Vvariables_can_hide_functions < 0 && can_hide_function)
 	warning ("variable `%s' hides function", nm.c_str ());
       else
 	{
--- a/src/symtab.h	Fri Dec 20 22:43:55 2002 +0000
+++ b/src/symtab.h	Sat Dec 21 17:15:25 2002 +0000
@@ -221,13 +221,16 @@
 
   symbol_record (void)
     : formal_param (0), linked_to_global (0), tagged_static (0),
-      nm (), chg_fcn (0), definition (new symbol_def ()),
-      next_elem (0) { }
+      can_hide_function (1), nm (), chg_fcn (0),
+      definition (new symbol_def ()), next_elem (0) { }
+
+  // XXX FIXME XXX -- kluge alert!  We obviously need a better way of
+  // handling allow_shadow!
 
   symbol_record (const std::string& n, symbol_record *nxt)
     : formal_param (0), linked_to_global (0), tagged_static (0),
-      nm (n), chg_fcn (0), definition (new symbol_def ()),
-      next_elem (nxt) { }
+      can_hide_function (n != "__end__"), nm (n), chg_fcn (0),
+      definition (new symbol_def ()), next_elem (nxt) { }
 
   ~symbol_record (void) { }
 
@@ -356,6 +359,7 @@
   unsigned int formal_param : 1;
   unsigned int linked_to_global : 1;
   unsigned int tagged_static : 1;
+  unsigned int can_hide_function : 1;
 
   std::string nm;
   change_function chg_fcn;