diff src/ov-fcn-handle.cc @ 4933:cd58733c326b

[project @ 2004-08-05 16:08:28 by jwe]
author jwe
date Thu, 05 Aug 2004 16:08:28 +0000
parents bdb307dc8613
children 4fc993a4e072
line wrap: on
line diff
--- a/src/ov-fcn-handle.cc	Thu Aug 05 13:26:15 2004 +0000
+++ b/src/ov-fcn-handle.cc	Thu Aug 05 16:08:28 2004 +0000
@@ -38,7 +38,6 @@
 #include "ov-fcn-handle.h"
 #include "pr-output.h"
 #include "variables.h"
-#include "parse.h"
 
 DEFINE_OCTAVE_ALLOCATOR (octave_fcn_handle);
 
@@ -46,57 +45,6 @@
 				     "function handle",
 				     "function handle");
 
-octave_fcn_handle::octave_fcn_handle (const std::string& f,
-				      const string_vector& a, 
-				      const std::string& n)
-  : typ (fcn_inline), nm (n), iftext (f), ifargs (a) 
-{
-  // Find a function name that isn't already in the symbol table.
-
-  std::string fname = "__inline__";
-
-  while (symbol_exist (fname))
-    fname.append ("X");
-
-  // Form a string representing the function. 
-
-  OSSTREAM buf;
-
-  buf << "function __retval__ = " << fname << "(";
-
-  for (int i = 0; i < ifargs.length (); i++)
-    {
-      if (i > 0)
-	buf << ", ";
-
-      buf << ifargs(i);
-    }
-
-  buf << ")\n  __retval__ = " << iftext << ";\nendfunction" << OSSTREAM_ENDS;
-  
-  // Parse this function and create a user function.
-
-  octave_value eval_args (OSSTREAM_STR (buf)); 
-
-  feval ("eval", eval_args, 0);
-
-  OSSTREAM_FREEZE (buf);
-
-  octave_value tmp = lookup_function (fname);
-
-  if (tmp.is_function ())
-    {
-      fcn = tmp;
-
-      // XXX FIXME XXX -- probably shouldn't be directly altering the
-      // symbol table here.
-
-      fbi_sym_tab->clear_function (fname);
-    }
-  else
-    error ("inline: unable to define function");
-}
-
 octave_value_list
 octave_fcn_handle::subsref (const std::string& type,
 			    const std::list<octave_value_list>& idx,
@@ -146,45 +94,8 @@
 void
 octave_fcn_handle::print_raw (std::ostream& os, bool pr_as_read_syntax) const
 {
-  if (is_inline ())
-    {
-      OSSTREAM buf;
-
-      if (nm.empty ())
-	buf << "@f(";
-      else
-	buf << nm << "(";
-
-      for (int i = 0; i < ifargs.length (); i++)
-	{
-	  if (i)
-	    buf << ", ";
-
-	  buf << ifargs(i);
-	}
-
-      buf << ") = " << iftext << OSSTREAM_ENDS;
-
-      octave_print_internal (os, OSSTREAM_STR (buf), pr_as_read_syntax,
-			     current_print_indent_level ());
-      OSSTREAM_FREEZE (buf);
-    }
-  else
-    octave_print_internal (os, nm, pr_as_read_syntax,
-			   current_print_indent_level ());
-}
-
-octave_value
-octave_fcn_handle::convert_to_str_internal (bool, bool) const
-{
-  octave_value retval;
-
-  if (is_inline ())
-    retval = octave_value (inline_fcn_text ());
-  else
-    error ("convert_to_str_internal: must be an inline function");
-
-  return retval;
+  octave_print_internal (os, nm, pr_as_read_syntax,
+			 current_print_indent_level ());
 }
 
 octave_value
@@ -202,222 +113,103 @@
   return retval;
 }
 
-DEFUN (inline, args, ,
+DEFUN (functions, args, ,
   "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} inline (@var{str})\n\
-@deftypefnx {Built-in Function} {} inline (@var{str}, @var{arg1}, ...)\n\
-@deftypefnx {Built-in Function} {} inline (@var{str}, @var{n})\n\
-Define a function from a string @var{str}.\n\
-\n\
-Create an inline function.  Called with a single argument, the\n\
-function is assumed to have a single argument and will be defined\n\
-as the first isolated lower case character, except i or j.\n\
-\n\
-If the second and subsequent arguments are strings, they are the names of\n\
-the arguments of the function.\n\
-\n\
-If the second argument is an integer @var{n}, the arguments are\n\
-@code{\"x\"}, @code{\"P1\"}, @dots{}, @code{\"P@var{N}\"}.\n\
-@end deftypefn\n\
-@seealso{argnames, formula, vectorize}")
+@deftypefn {Built-in Function} {} functions (@var{fcn_handle})\n\
+Return a struct containing information about the function handle\n\
+@var{fcn_handle}.\n\
+@end deftypefn")
 {
   octave_value retval;
 
-  int nargin = args.length ();
-
-  if (nargin > 0)
+  if (args.length () == 1)
     {
-      std::string fun = args(0).string_value ();
+      octave_fcn_handle *fh = args(0).fcn_handle_value ();
 
       if (! error_state)
 	{
-	  string_vector fargs;
-
-	  if (nargin == 1)
-	    {
-	      fargs.resize (1);
-
-	      // Find the first isolated string as the argument of the
-	      // function.
+	  octave_function *fcn = fh ? fh->function_value (true) : 0;
 
-	      // XXX FIXME XXX -- use just "x" for now.
-	      fargs(0) = "x";
-	    }
-	  else if (nargin == 2 && args(1).is_numeric_type ())
+	  if (fcn)
 	    {
-	      int n = args(1).int_value ();
+	      Octave_map m;
 
-	      if (! error_state)
-		{
-		  if (n >= 0)
-		    {
-		      fargs.resize (n+1);
+	      std::string fh_nm = fh->fcn_name ();
+
+	      m.assign ("function", fh_nm.substr (1));
 
-		      fargs(0) = "x";
+	      if (fcn->is_nested_function ())
+		m.assign ("type", "subfunction");
+	      else
+		m.assign ("type", "simple");
+
+	      std::string nm = fcn->fcn_file_name ();
 
-		      for (int i = 1; i < n+1; i++)
-			{
-			  OSSTREAM buf;
-			  buf << "P" << i << OSSTREAM_ENDS;
-			  fargs(i) = OSSTREAM_STR (buf);
-			  OSSTREAM_FREEZE (buf);
-			}
-		    }
-		  else
-		    {
-		      error ("inline: numeric argument must be nonnegative");
-		      return retval;
-		    }
-		}
+	      if (nm.empty ())
+		m.assign ("file", "built-in function");
 	      else
-		{
-		  error ("inline: expecting second argument to be an integer");
-		  return retval;
-		}
+		m.assign ("file", nm);
+
+	      retval = m;
 	    }
 	  else
-	    {
-	      fargs.resize (nargin - 1);
-
-	      for (int i = 1; i < nargin; i++)
-		{
-		  std::string s = args(i).string_value ();
-
-		  if (! error_state)
-		    fargs(i-1) = s;
-		  else
-		    {
-		      error ("inline: expecting string arguments");
-		      return retval;
-		    }
-		}
-	    }
-
-	  retval = octave_value (new octave_fcn_handle (fun, fargs));
+	    error ("functions: invalid function handle object");
 	}
       else
-	error ("inline: first argument must be a string");
+	error ("functions: argument must be a function handle object");
     }
   else
-    print_usage ("inline");
+    print_usage ("functions");
 
   return retval;
 }
 
-DEFUN (formula, args, ,
+DEFUN (func2str, args, ,
   "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} formula (@var{fun})\n\
-Return a string representing the inline function @var{fun}.\n\
-@end deftypefn\n\
-@seealso{argnames, inline, vectorize}")
+@deftypefn {Built-in Function} {} func2str (@var{fcn_handle})\n\
+Return a string containing the name of the function referenced by\n\
+the function handle @var{fcn_handle}.\n\
+@end deftypefn")
 {
   octave_value retval;
 
-  int nargin = args.length ();
-
-  if (nargin == 1)
+  if (args.length () == 1)
     {
-      octave_fcn_handle* fn = args(0).fcn_handle_value (true);
+      octave_fcn_handle *fh = args(0).fcn_handle_value ();
 
-      if (fn && fn->is_inline ())
-	retval = octave_value (fn->inline_fcn_text ());
+      if (! error_state && fh)
+	{
+	  std::string fh_nm = fh->fcn_name ();
+	  retval = fh_nm.substr (1);
+	}
       else
-	error ("formula: must be an inline function");
+	error ("func2str: expecting valid function handle as first argument");
     }
   else
-    print_usage ("formula");
+    print_usage ("func2str");
 
   return retval;
 }
 
-DEFUN (argnames, args, ,
+DEFUN (str2func, args, ,
   "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} argnames (@var{fun})\n\
-Return a cell array of strings containing the names of the arguments\n\
-of the inline function @var{fun}.\n\
-@end deftypefn\n\
-@seealso{argnames, inline, formula, vectorize}")
+@deftypefn {Built-in Function} {} str2func (@var{fcn_name})\n\
+Return a function handle constructed from the string @var{fcn_name}.\n\
+@end deftypefn")
 {
   octave_value retval;
 
-  int nargin = args.length ();
-
-  if (nargin == 1)
+  if (args.length () == 1)
     {
-      octave_fcn_handle *fn = args(0).fcn_handle_value (true);
-
-      if (fn && fn->is_inline ())
-	{
-	  string_vector t1 = fn->inline_fcn_arg_names ();
+      std::string nm = args(0).string_value ();
 
-	  Cell t2 (dim_vector (t1.length (), 1));
-
-	  for (int i = 0; i < t1.length (); i++)
-	    t2(i) = t1(i);
-
-	  retval = t2;
-	}
+      if (! error_state)
+	retval = make_fcn_handle (nm);
       else
-	error ("argnames: argument must be an inline function");
+	error ("str2func: expecting string as first argument");
     }
   else
-    print_usage ("argnames");
-
-  return retval;
-}
-
-DEFUN (vectorize, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} argnames (@var{fun})\n\
-Create a vectorized version of the inline function @var{fun}\n\
-by replacing all occurrences of @code{*}, @code{/}, etc., with\n\
-@code{.*}, @code{./}, etc.\n\
-@end deftypefn\n\
-@seealso{argnames, inline, formula, vectorize}")
-{
-  octave_value retval;
-
-  int nargin = args.length ();
-
-  if (nargin == 1)
-    {
-      octave_fcn_handle* old = args(0).fcn_handle_value (true);
-
-      if (old && old->is_inline ())
-	{
-	  std::string old_func = old->inline_fcn_text ();
-	  std::string new_func;
-
-	  size_t i = 0;
-
-	  while (i < old_func.length ())
-	    {
-	      std::string t1 = old_func.substr (i, 1);
-
-	      if (t1 == "*" || t1 == "/" || t1 == "\\" || t1 == "^")
-		{
-		  if (i && old_func.substr (i-1, 1) != ".")
-		    new_func.append (".");
-
-		  // Special case for ** operator.
-		  if (t1 == "*" && i < (old_func.length () - 1) 
-		      && old_func.substr (i+1, 1) == "*")
-		    {
-		      new_func.append ("*");
-		      i++;
-		    }
-		}
-	      new_func.append (t1);
-	      i++;
-	    }
-
-	  retval = octave_value (new octave_fcn_handle (new_func, old->inline_fcn_arg_names ()));
-	}
-      else
-	error ("vectorize: must be an inline function");
-    }
-  else
-    print_usage ("vectorize");
+    print_usage ("str2func");
 
   return retval;
 }