home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / octave-1.1.1p1-base.tgz / octave-1.1.1p1-base.tar / fsf / octave / src / tree-expr.cc < prev    next >
C/C++ Source or Header  |  1995-02-21  |  55KB  |  3,022 lines

  1. // tree-expr.cc                                          -*- C++ -*-
  2. /*
  3.  
  4. Copyright (C) 1992, 1993, 1994, 1995 John W. Eaton
  5.  
  6. This file is part of Octave.
  7.  
  8. Octave is free software; you can redistribute it and/or modify it
  9. under the terms of the GNU General Public License as published by the
  10. Free Software Foundation; either version 2, or (at your option) any
  11. later version.
  12.  
  13. Octave is distributed in the hope that it will be useful, but WITHOUT
  14. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16. for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with Octave; see the file COPYING.  If not, write to the Free
  20. Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22. */
  23.  
  24. #ifdef HAVE_CONFIG_H
  25. #include "config.h"
  26. #endif
  27.  
  28. #include <sys/types.h>
  29. #ifdef HAVE_UNISTD_H
  30. #include <unistd.h>
  31. #endif
  32.  
  33. #include <iostream.h>
  34. #include <strstream.h>
  35. #include <string.h>
  36. #include <limits.h>
  37. #include <ctype.h>
  38. #include <stdio.h>
  39.  
  40. #include "variables.h"
  41. #include "user-prefs.h"
  42. #include "dynamic-ld.h"
  43. #include "help.h"
  44. #include "error.h"
  45. #include "gripes.h"
  46. #include "pager.h"
  47. #include "tree-base.h"
  48. #include "tree-expr.h"
  49. #include "tree-misc.h"
  50. #include "tree-const.h"
  51. #include "input.h"
  52. #include "symtab.h"
  53. #include "utils.h"
  54. #include "octave.h"
  55. #include "octave-hist.h"
  56. #include "unwind-prot.h"
  57. #include "parse.h"
  58. #include "lex.h"
  59. #include "defun.h"
  60.  
  61. // Nonzero means we're returning from a function.
  62. extern int returning;
  63.  
  64. // Nonzero means we're breaking out of a loop or function body.
  65. extern int breaking;
  66.  
  67. // But first, some extra functions used by the tree classes.
  68.  
  69. // We seem to have no use for this now.  Maybe it will be needed at
  70. // some future date, so here it is.
  71. #if 0
  72. // Convert a linked list of trees to a vector of pointers to trees.
  73.  
  74. static tree **
  75. list_to_vector (tree *list, int& len)
  76. {
  77.   len = list->length () + 1;
  78.  
  79.   tree **args = new tree * [len];
  80.  
  81. // args[0] may eventually hold something useful, like the function
  82. // name.
  83.   tree *tmp_list = list;
  84.   for (int k = 1; k < len; k++)
  85.     {
  86.       args[k] = tmp_list;
  87.       tmp_list = tmp_list->next_elem ();
  88.     }
  89.   return args;
  90. }
  91. #endif
  92.  
  93. static int
  94. any_element_less_than (const Matrix& a, double val)
  95. {
  96.   int nr = a.rows ();
  97.   int nc = a.columns ();
  98.   for (int j = 0; j < nc; j++)
  99.     for (int i = 0; i < nr; i++)
  100.       if (a.elem (i, j) < val)
  101.     return 1;
  102.   return 0;
  103. }
  104.  
  105. static int
  106. any_element_greater_than (const Matrix& a, double val)
  107. {
  108.   int nr = a.rows ();
  109.   int nc = a.columns ();
  110.   for (int j = 0; j < nc; j++)
  111.     for (int i = 0; i < nr; i++)
  112.       if (a.elem (i, j) > val)
  113.     return 1;
  114.   return 0;
  115. }
  116.  
  117. static int
  118. print_as_scalar (const tree_constant& val)
  119. {
  120.   int nr = val.rows ();
  121.   int nc = val.columns ();
  122.   return (val.is_scalar_type ()
  123.       || val.is_string ()
  124.       || (val.is_matrix_type ()
  125.           && ((nr == 1 && nc == 1)
  126.           || nr == 0
  127.           || nc == 0)));
  128. }
  129.  
  130. static void
  131. print_constant (tree_constant& tc, char *name)
  132. {
  133.   int pad_after = 0;
  134.   if (user_pref.print_answer_id_name)
  135.     {
  136.       if (print_as_scalar (tc))
  137.     {
  138.       ostrstream output_buf;
  139.       output_buf << name << " = " << ends;
  140.       maybe_page_output (output_buf);
  141.     }
  142.       else
  143.     {
  144.       pad_after = 1;
  145.       ostrstream output_buf;
  146.       output_buf << name << " =\n\n" << ends;
  147.       maybe_page_output (output_buf);
  148.     }
  149.     }
  150.  
  151.   tc.eval (1);
  152.  
  153.   if (pad_after)
  154.     {
  155.       ostrstream output_buf;
  156.       output_buf << "\n" << ends;
  157.       maybe_page_output (output_buf);
  158.     }
  159. }
  160.  
  161. // Make sure that all arguments have values.
  162.  
  163. static int
  164. all_args_defined (const Octave_object& args)
  165. {
  166.   int nargin = args.length ();
  167.  
  168.   for (int i = 0; i < nargin; i++)
  169.     if (args(i).is_undefined ())
  170.       return 0;
  171.  
  172.   return 1;
  173. }
  174.  
  175. // Are any of the arguments `:'?
  176.  
  177. static int
  178. any_arg_is_magic_colon (const Octave_object& args)
  179. {
  180.   int nargin = args.length ();
  181.  
  182.   for (int i = 0; i < nargin; i++)
  183.     if (args(i).is_magic_colon ())
  184.     return 1;
  185.  
  186.   return 0;
  187. }
  188.  
  189. // Expressions.
  190.  
  191. tree_constant
  192. tree_expression::eval (int print)
  193. {
  194.   panic ("invalid evaluation of generic expression");
  195.   return tree_constant ();
  196. }
  197.  
  198. // General matrices.  This list type is much more work to handle than
  199. // constant matrices, but it allows us to construct matrices from
  200. // other matrices, variables, and functions.
  201.  
  202. tree_matrix::~tree_matrix (void)
  203. {
  204.   delete element;
  205.   delete next;
  206. }
  207.  
  208. tree_matrix *
  209. tree_matrix::chain (tree_expression *t, tree_matrix::dir d)
  210. {
  211.   tree_matrix *tmp = new tree_matrix (t, d);
  212.   tmp->next = this;
  213.   return tmp;
  214. }
  215.  
  216. tree_matrix *
  217. tree_matrix::reverse (void)
  218. {
  219.   tree_matrix *list = this;
  220.   tree_matrix *next;
  221.   tree_matrix *prev = 0;
  222.  
  223.   while (list)
  224.     {
  225.       next = list->next;
  226.       list->next = prev;
  227.       prev = list;
  228.       list = next;
  229.     }
  230.   return prev;
  231. }
  232.  
  233. int
  234. tree_matrix::length (void)
  235. {
  236.   tree_matrix *list = this;
  237.   int len = 0;
  238.   while (list)
  239.     {
  240.       len++;
  241.       list = list->next;
  242.     }
  243.   return len;
  244. }
  245.  
  246. tree_return_list *
  247. tree_matrix::to_return_list (void)
  248. {
  249.   tree_return_list *retval = 0;
  250.  
  251.   tree_matrix *list;
  252.  
  253.   for (list = this; list; list = list->next)
  254.     {
  255.       tree_expression *elem = list->element;
  256.  
  257.       int is_id = elem->is_identifier ();
  258.  
  259.       int is_idx_expr = elem->is_index_expression ();
  260.  
  261.       if (is_id || is_idx_expr)
  262.     {
  263.       tree_index_expression *idx_expr;
  264.       if (is_id)
  265.         {
  266.           tree_identifier *id = (tree_identifier *) elem;
  267.           idx_expr = new tree_index_expression (id);
  268.         }
  269.       else
  270.         idx_expr = (tree_index_expression *) elem;
  271.  
  272.       if (list == this)
  273.         retval = new tree_return_list (idx_expr);
  274.       else
  275.         retval->append (idx_expr);
  276.     }
  277.       else
  278.     {
  279.       delete retval;
  280.       retval = 0;
  281.       break;
  282.     }
  283.     }
  284.  
  285.   return retval;
  286. }
  287.  
  288. // Just about as ugly as it gets.
  289.  
  290. struct const_matrix_list
  291. {
  292.   tree_matrix::dir direction;
  293.   tree_constant elem;
  294.   int nr;
  295.   int nc;
  296. };
  297.  
  298. // Less ugly than before, anyway.
  299.  
  300. tree_constant
  301. tree_matrix::eval (int print)
  302. {
  303.   tree_constant retval;
  304.  
  305.   if (error_state)
  306.     return retval;
  307.  
  308. // Just count the elements without looking at them.
  309.  
  310.   int total_len = length ();
  311.  
  312. // Easier to deal with this later instead of a tree_matrix structure.
  313.  
  314.   const_matrix_list *list = new const_matrix_list [total_len];
  315.  
  316. // Stats we want to keep track of.
  317.  
  318.   int all_strings = 1;
  319.  
  320.   int found_complex = 0;
  321.  
  322.   int row_total = 0;
  323.   int col_total = 0;
  324.  
  325.   int row_height = 0;
  326.  
  327.   int cols_this_row = 0;
  328.  
  329.   int first_row = 1;
  330.  
  331.   int empties_ok = user_pref.empty_list_elements_ok;
  332.  
  333.   tree_matrix *ptr = this;
  334.  
  335. // Stuff for the result matrix or string.  Declared here so that we
  336. // don't get warnings from gcc about the goto crossing the
  337. // initialization of these values.
  338.  
  339.   int put_row = 0;
  340.   int put_col = 0;
  341.  
  342.   int prev_nr = 0;
  343.   int prev_nc = 0;
  344.  
  345.   Matrix m;
  346.   ComplexMatrix cm;
  347.  
  348.   char *string = 0;
  349.   char *str_ptr = 0;
  350.  
  351. // Eliminate empties and gather stats.
  352.  
  353.   int found_new_row_in_empties = 0;
  354.  
  355.   int len = 0;
  356.   for (int i = 0; i < total_len; i++)
  357.     {
  358.       tree_expression *elem = ptr->element;
  359.       if (! elem)
  360.     {
  361.       retval = tree_constant (Matrix ());
  362.       goto done;
  363.     }
  364.  
  365.       tree_constant tmp = elem->eval (0);
  366.       if (error_state || tmp.is_undefined ())
  367.     {
  368.       retval = tree_constant ();
  369.       goto done;
  370.     }
  371.  
  372.       int nr = tmp.rows ();
  373.       int nc = tmp.columns ();
  374.  
  375.       dir direct = ptr->direction;
  376.  
  377.       if (nr == 0 || nc == 0)
  378.     {
  379.       if (empties_ok < 0)
  380.         warning ("empty matrix found in matrix list");
  381.       else if (empties_ok == 0)
  382.         {
  383.           ::error ("empty matrix found in matrix list");
  384.           retval = tree_constant ();
  385.           goto done;
  386.         }
  387.  
  388.       if (direct == md_down)
  389.         found_new_row_in_empties = 1;
  390.  
  391.       goto next;
  392.     }
  393.  
  394.       if (found_new_row_in_empties)
  395.     {
  396.       found_new_row_in_empties = 0;
  397.       list[len].direction = md_down;
  398.     }
  399.       else
  400.     list[len].direction = direct;
  401.  
  402.       list[len].elem = tmp;
  403.       list[len].nr = nr;
  404.       list[len].nc = nc;
  405.  
  406.       if (all_strings && ! tmp.is_string ())
  407.     all_strings = 0;
  408.  
  409.       if (! found_complex && tmp.is_complex_type ())
  410.     found_complex = 1;
  411.  
  412.       len++;
  413.  
  414.     next:
  415.  
  416.       ptr = ptr->next;
  417.     }
  418.  
  419. //  if (all_strings)
  420. //    cerr << "all strings\n";
  421.  
  422. // Compute size of result matrix, and check to see that the dimensions
  423. // of all the elements will match up properly.
  424.  
  425.   for (i = 0; i < len; i++)
  426.     {
  427.       dir direct = list[i].direction;
  428.  
  429.       int nr = list[i].nr;
  430.       int nc = list[i].nc;
  431.  
  432.       if (i == 0)
  433.     {
  434.       row_total = nr;
  435.       col_total = nc;
  436.  
  437.       row_height = nr;
  438.       cols_this_row = nc;
  439.     }
  440.       else
  441.     {
  442.       switch (direct)
  443.         {
  444.         case md_right:
  445.           {
  446.         if (nr != row_height)
  447.           {
  448.             ::error ("number of rows must match");
  449.             goto done;
  450.           }
  451.         else
  452.           {
  453.             cols_this_row += nc;
  454.             if (first_row)
  455.               col_total = cols_this_row;
  456.           }
  457.           }
  458.           break;
  459.  
  460.         case md_down:
  461.           {
  462.         if (cols_this_row != col_total)
  463.           {
  464.             ::error ("number of columns must match");
  465.             goto done;
  466.           }
  467.         first_row = 0;
  468.         row_total += nr;
  469.         row_height = nr;
  470.         cols_this_row = nc;
  471.           }
  472.           break;
  473.  
  474.         default:
  475.           panic_impossible ();
  476.           break;
  477.         }
  478.     }
  479.     }
  480.  
  481. // Don\'t forget to check to see if the last element will fit.
  482.  
  483.   if (cols_this_row != col_total)
  484.     {
  485.       ::error ("number of columns must match");
  486.       goto done;
  487.     }
  488.  
  489. // Now, extract the values from the individual elements and insert
  490. // them in the result matrix.
  491.  
  492.   if (all_strings && row_total == 1 && col_total > 0)
  493.     {
  494.       string = str_ptr = new char [col_total + 1];
  495.       string[col_total] = '\0';
  496.     }
  497.   else if (found_complex)
  498.     cm.resize (row_total, col_total, 0.0);
  499.   else
  500.     m.resize (row_total, col_total, 0.0);
  501.  
  502.   for (i = 0; i < len; i++)
  503.     {
  504.       tree_constant tmp = list[i].elem;
  505.  
  506.       int nr = list[i].nr;
  507.       int nc = list[i].nc;
  508.  
  509.       if (nr == 0 || nc == 0)
  510.     continue;
  511.  
  512.       if (i == 0)
  513.     {
  514.       put_row = 0;
  515.       put_col = 0;
  516.     }
  517.       else
  518.     {
  519.       switch (list[i].direction)
  520.         {
  521.         case md_right:
  522.           put_col += prev_nc;
  523.           break;
  524.  
  525.         case md_down:
  526.           put_row += prev_nr;
  527.           put_col = 0;
  528.           break;
  529.  
  530.         default:
  531.           panic_impossible ();
  532.           break;
  533.         }
  534.     }
  535.  
  536.       if (found_complex)
  537.     {
  538.       if (tmp.is_real_scalar ())
  539.         {
  540.           cm (put_row, put_col) = tmp.double_value ();
  541.         }
  542.       else if (tmp.is_real_matrix () || tmp.is_range ())
  543.         {
  544.           cm.insert (tmp.matrix_value (), put_row, put_col);
  545.         }
  546.       else if (tmp.is_complex_scalar ())
  547.         {
  548.           cm (put_row, put_col) = tmp.complex_value ();
  549.         }
  550.       else
  551.         {
  552.           ComplexMatrix cm_tmp = tmp.complex_matrix_value ();
  553.  
  554.           if (error_state)
  555.         goto done;
  556.  
  557.           cm.insert (cm_tmp, put_row, put_col);
  558.         }
  559.     }
  560.       else
  561.     {
  562.       if (tmp.is_real_scalar ())
  563.         {
  564.           m (put_row, put_col) = tmp.double_value ();
  565.         }
  566.       else if (tmp.is_string () && all_strings && str_ptr)
  567.         {
  568.           memcpy (str_ptr, tmp.string_value (), nc);
  569.           str_ptr += nc;
  570.         }
  571.       else
  572.         {
  573.           Matrix m_tmp = tmp.matrix_value ();
  574.  
  575.           if (error_state)
  576.         goto done;
  577.  
  578.           m.insert (m_tmp, put_row, put_col);
  579.         }
  580.     }
  581.  
  582.       prev_nr = nr;
  583.       prev_nc = nc;
  584.     }
  585.  
  586.   if (all_strings && string)
  587.     retval = tree_constant (string);
  588.   else if (found_complex)
  589.     retval = tree_constant (cm);
  590.   else
  591.     retval = tree_constant (m);
  592.  
  593.  done:
  594.   delete [] list;
  595.  
  596.   return retval;
  597. }
  598.  
  599. void
  600. tree_matrix::print_code (ostream& os)
  601. {
  602.   print_code_indent (os);
  603.  
  604.   if (in_parens)
  605.     os << "(";
  606.  
  607.   os << "[";
  608.  
  609.   tree_matrix *list = this;
  610.  
  611.   while (list)
  612.     {
  613.       list->element->print_code (os);
  614.  
  615.       list = list->next;
  616.  
  617.       if (list)
  618.     {
  619.       switch (list->direction)
  620.         {
  621.         case md_right:
  622.           os << ", ";
  623.           break;
  624.  
  625.         case md_down:
  626.           os << "; ";
  627.           break;
  628.  
  629.         default:
  630.           break;
  631.         }
  632.     }
  633.     }
  634.  
  635.   os << "]";
  636.  
  637.   if (in_parens)
  638.     os << ")";
  639. }
  640.  
  641. // A base class for objects that can be return multiple values
  642.  
  643. tree_constant
  644. tree_multi_val_ret::eval (int print)
  645. {
  646.   panic ("invalid evaluation of generic expression");
  647.   return tree_constant ();
  648. }
  649.  
  650. // A base class for objects that can be evaluated with argument lists.
  651.  
  652. tree_constant
  653. tree_fvc::assign (tree_constant& t, const Octave_object& args)
  654. {
  655.   panic_impossible ();
  656.   return tree_constant ();
  657. }
  658.  
  659. tree_constant
  660. tree_fvc::lookup_map_element (SLList<char*>& list)
  661. {
  662.   static tree_constant retval;
  663.   return retval;
  664. }
  665.  
  666. // Symbols from the symbol table.
  667.  
  668. char *
  669. tree_identifier::name (void) const
  670. {
  671.   return sym ? sym->name () : 0;
  672. }
  673.  
  674. tree_identifier *
  675. tree_identifier::define (tree_constant *t)
  676. {
  677.   int status = sym->define (t);
  678.   return status ? this : 0;
  679. }
  680.  
  681. tree_identifier *
  682. tree_identifier::define (tree_function *t)
  683. {
  684.   int status = sym->define (t);
  685.   return status ? this : 0;
  686. }
  687.  
  688. void
  689. tree_identifier::document (char *s)
  690. {
  691.   if (sym && s)
  692.     sym->document (strsave (s));
  693. }
  694.  
  695. tree_constant
  696. tree_identifier::assign (tree_constant& rhs)
  697. {
  698.   tree_constant retval;
  699.  
  700.   if (rhs.is_defined ())
  701.     {
  702.       if (! sym->is_defined ())
  703.     {
  704.       if (! (sym->is_formal_parameter ()
  705.          || sym->is_linked_to_global ()))
  706.         {
  707.           link_to_builtin_variable (sym);
  708.         }
  709.     }
  710.       else if (sym->is_function ())
  711.     {
  712.       sym->clear ();
  713.     }
  714.  
  715.       tree_constant *tmp = new tree_constant (rhs);
  716.  
  717.       if (sym->define (tmp))
  718.     retval = rhs;
  719.       else
  720.     delete tmp;
  721.     }
  722.  
  723.   return retval;
  724. }
  725.  
  726. tree_constant
  727. tree_identifier::assign (tree_constant& rhs, const Octave_object& args)
  728. {
  729.   tree_constant retval;
  730.  
  731.   if (rhs.is_defined ())
  732.     {
  733.       if (! sym->is_defined ())
  734.     {
  735.       if (! (sym->is_formal_parameter ()
  736.          || sym->is_linked_to_global ()))
  737.         {
  738.           link_to_builtin_variable (sym);
  739.         }
  740.     }
  741.       else if (sym->is_function ())
  742.     {
  743.       sym->clear ();
  744.     }
  745.  
  746.       if (sym->is_variable () && sym->is_defined ())
  747.     {
  748.       tree_fvc *tmp = sym->def ();
  749.       retval = tmp->assign (rhs, args);
  750.     }
  751.       else
  752.     {
  753.       assert (! sym->is_defined ());
  754.  
  755.       if (! user_pref.resize_on_range_error)
  756.         {
  757.           ::error ("indexed assignment to previously undefined variables");
  758.           ::error ("is only possible when resize_on_range_error is true");
  759.         }
  760.       else
  761.         {
  762.           tree_constant *tmp = new tree_constant ();
  763.           retval = tmp->assign (rhs, args);
  764.           if (retval.is_defined ())
  765.         sym->define (tmp);
  766.         }
  767.     }
  768.     }
  769.  
  770.   return retval;
  771. }
  772.  
  773. tree_constant
  774. tree_identifier::assign (SLList<char*> list, tree_constant& rhs)
  775. {
  776.   tree_constant retval;
  777.  
  778.   if (rhs.is_defined ())
  779.     {
  780.       if (sym->is_function ())
  781.     sym->clear ();
  782.  
  783.       tree_fvc *curr_val = sym->def ();
  784.  
  785.       tree_constant *tmp = 0;
  786.       if (curr_val && curr_val->is_constant ())
  787.     tmp = (tree_constant *) curr_val;
  788.       else
  789.     {
  790.       tmp = new tree_constant ();
  791.       if (! sym->define (tmp))
  792.         {
  793.           delete tmp;
  794.           tmp = 0;
  795.         }
  796.     }
  797.  
  798.       if (tmp)
  799.     retval = tmp->assign_map_element (list, rhs);
  800.     }
  801.  
  802.   return retval;
  803. }
  804.  
  805. tree_constant
  806. tree_identifier::assign (SLList<char*> list, tree_constant& rhs,
  807.              const Octave_object& args)
  808. {
  809.   tree_constant retval;
  810.  
  811.   if (rhs.is_defined ())
  812.     {
  813.       if (sym->is_function ())
  814.     sym->clear ();
  815.  
  816.       if (sym->is_variable () && sym->is_defined ())
  817.     {
  818.       tree_fvc *curr_val = sym->def ();
  819.  
  820.       tree_constant *tmp;
  821.       if (curr_val && curr_val->is_constant ())
  822.         tmp = (tree_constant *) curr_val;
  823.       else
  824.         panic_impossible ();
  825.  
  826.       retval = tmp->assign_map_element (list, rhs, args);
  827.     }
  828.       else
  829.     {
  830.       assert (! sym->is_defined ());
  831.  
  832.       if (! user_pref.resize_on_range_error)
  833.         {
  834.           ::error ("indexed assignment to previously undefined variables");
  835.           ::error ("is only possible when resize_on_range_error is true");
  836.         }
  837.       else
  838.         {
  839.           tree_constant *tmp = new tree_constant ();
  840.  
  841.           retval = tmp->assign_map_element (list, rhs, args);
  842.  
  843.           if (retval.is_defined ())
  844.         sym->define (tmp);
  845.         }
  846.     }
  847.     }
  848.  
  849.   return retval;
  850. }
  851.  
  852. int
  853. tree_identifier::is_defined (void)
  854. {
  855.   return (sym && sym->is_defined ());
  856. }
  857.  
  858. void
  859. tree_identifier::bump_value (tree_expression::type etype)
  860. {
  861.   if (sym)
  862.     {
  863.       if (sym->is_read_only ())
  864.     {
  865.       ::error ("can't redefined read-only variable `%s'", name ());
  866.     }
  867.       else
  868.     {
  869.       tree_fvc *tmp = sym->def ();
  870.       if (tmp)
  871.         tmp->bump_value (etype);
  872.     }
  873.     }
  874. }
  875.  
  876. void
  877. tree_identifier::eval_undefined_error (void)
  878. {
  879.   char *nm = name ();
  880.   int l = line ();
  881.   int c = column ();
  882.   if (l == -1 && c == -1)
  883.     ::error ("`%s' undefined", nm);
  884.   else
  885.     ::error ("`%s' undefined near line %d column %d", nm, l, c);
  886. }
  887.  
  888. // Try to find a definition for an identifier.  Here's how:
  889. //
  890. //   * If the identifier is already defined and is a function defined
  891. //     in an function file that has been modified since the last time 
  892. //     we parsed it, parse it again.
  893. //
  894. //   * If the identifier is not defined, try to find a builtin
  895. //     variable or an already compiled function with the same name.
  896. //
  897. //   * If the identifier is still undefined, try looking for an
  898. //     function file to parse.
  899. //
  900. //   * On systems that support dynamic linking, we prefer .oct files
  901. //     over .m files.
  902.  
  903. tree_fvc *
  904. tree_identifier::do_lookup (int& script_file_executed, int exec_script)
  905. {
  906.   script_file_executed = lookup (sym, exec_script);
  907.  
  908.   tree_fvc *retval = 0;
  909.  
  910.   if (! script_file_executed)
  911.     retval = sym->def ();
  912.  
  913.   return retval;
  914. }
  915.  
  916. void
  917. tree_identifier::link_to_global (void)
  918. {
  919.   if (sym)
  920.     link_to_global_variable (sym);
  921. }
  922.  
  923. void
  924. tree_identifier::mark_as_formal_parameter (void)
  925. {
  926.   if (sym)
  927.     sym->mark_as_formal_parameter ();
  928. }
  929.  
  930. tree_constant
  931. tree_identifier::eval (int print)
  932. {
  933.   tree_constant retval;
  934.  
  935.   if (error_state)
  936.     return retval;
  937.  
  938.   int script_file_executed = 0;
  939.  
  940.   tree_fvc *object_to_eval = do_lookup (script_file_executed);
  941.  
  942.   if (! script_file_executed)
  943.     {
  944.       if (object_to_eval)
  945.     {
  946.       int nargout = maybe_do_ans_assign ? 0 : 1;
  947.  
  948.       if (nargout)
  949.         {
  950.           Octave_object tmp_args;
  951.           Octave_object tmp = object_to_eval->eval (0, nargout, tmp_args);
  952.  
  953.           if (tmp.length () > 0)
  954.         retval = tmp(0);
  955.         }
  956.       else
  957.         retval = object_to_eval->eval (0);
  958.     }
  959.       else
  960.     eval_undefined_error ();
  961.     }
  962.  
  963.   if (! error_state && retval.is_defined ())
  964.     {
  965.       if (maybe_do_ans_assign && ! object_to_eval->is_constant ())
  966.     {
  967.  
  968. // XXX FIXME XXX -- need a procedure to do this, probably in
  969. // variables.cc, to isolate the code that does lookups...
  970.  
  971.       symbol_record *sr = global_sym_tab->lookup ("ans", 1, 0);
  972.  
  973.       assert (sr);
  974.  
  975.       tree_identifier *ans_id = new tree_identifier (sr);
  976.  
  977.       tree_constant *tmp = new tree_constant (retval);
  978.  
  979.       tree_simple_assignment_expression tmp_ass (ans_id, tmp, 0, 1);
  980.  
  981.       tmp_ass.eval (print);
  982.     }
  983.       else
  984.     {
  985.       if (print)
  986.         print_constant (retval, name ());
  987.     }
  988.     }
  989.   return retval;
  990. }
  991.  
  992. Octave_object
  993. tree_identifier::eval (int print, int nargout, const Octave_object& args)
  994. {
  995.   Octave_object retval;
  996.  
  997.   if (error_state)
  998.     return retval;
  999.  
  1000.   int script_file_executed = 0;
  1001.  
  1002.   tree_fvc *object_to_eval = do_lookup (script_file_executed);
  1003.  
  1004.   if (! script_file_executed)
  1005.     {
  1006.       if (object_to_eval)
  1007.     {
  1008.       if (maybe_do_ans_assign && nargout == 1)
  1009.         {
  1010.  
  1011. // Don't count the output arguments that we create automatically.
  1012.  
  1013.           nargout = 0;
  1014.  
  1015.           retval = object_to_eval->eval (0, nargout, args);
  1016.  
  1017.           if (retval.length () > 0 && retval(0).is_defined ())
  1018.         {
  1019.  
  1020. // XXX FIXME XXX -- need a procedure to do this, probably in
  1021. // variables.cc, to isolate the code that does lookups...
  1022.  
  1023.           symbol_record *sr = global_sym_tab->lookup ("ans", 1, 0);
  1024.  
  1025.           assert (sr);
  1026.       
  1027.           tree_identifier *ans_id = new tree_identifier (sr);
  1028.  
  1029.           tree_constant *tmp = new tree_constant (retval(0));
  1030.  
  1031.           tree_simple_assignment_expression tmp_ass (ans_id,
  1032.                                  tmp, 0, 1);
  1033.  
  1034.           tmp_ass.eval (print);
  1035.         }
  1036.         }
  1037.       else
  1038.         retval = object_to_eval->eval (print, nargout, args);
  1039.     }
  1040.       else
  1041.     eval_undefined_error ();
  1042.     }
  1043.  
  1044.   return retval;
  1045. }
  1046.  
  1047. void
  1048. tree_identifier::print_code (ostream& os)
  1049. {
  1050.   print_code_indent (os);
  1051.  
  1052.   if (in_parens)
  1053.     os << "(";
  1054.  
  1055.   char *nm = name ();
  1056.   os << (nm) ? nm : "(null)";
  1057.  
  1058.   if (in_parens)
  1059.     os << ")";
  1060. }
  1061.  
  1062. // Indirect references to values (structure elements).
  1063.  
  1064. tree_indirect_ref::~tree_indirect_ref (void)
  1065. {
  1066.   while (! refs.empty ())
  1067.     {
  1068.       char *t = refs.remove_front ();
  1069.       delete [] t;
  1070.     }
  1071.  
  1072.   if (! preserve_ident)
  1073.     delete id;
  1074. }
  1075.  
  1076. tree_indirect_ref *
  1077. tree_indirect_ref::chain (const char *elt)
  1078. {
  1079.   refs.append (strsave (elt));
  1080.   return this;
  1081. }
  1082.  
  1083. char *
  1084. tree_indirect_ref::name (void)
  1085. {
  1086.   char *id_nm = id->name ();
  1087.   if (refs.empty ())
  1088.     return id_nm;
  1089.   else
  1090.     {
  1091.       static char *nm = 0;
  1092.       delete [] nm;
  1093.  
  1094.       ostrstream tmp;
  1095.  
  1096.       tmp << id_nm;
  1097.  
  1098.       for (Pix p = refs.first (); p != 0; refs.next (p))
  1099.     {
  1100.       char *elt = refs (p);
  1101.  
  1102.       if (elt)
  1103.         tmp << "." << elt;
  1104.     }
  1105.  
  1106.       tmp << ends;
  1107.       nm = tmp.str ();
  1108.       return nm;
  1109.     }
  1110. }
  1111.  
  1112. tree_constant
  1113. tree_indirect_ref::assign (tree_constant& t)
  1114. {
  1115.   tree_constant retval;
  1116.  
  1117.   if (refs.empty ())
  1118.     retval = id->assign (t);
  1119.   else
  1120.     retval = id->assign (refs, t);
  1121.  
  1122.   return retval;
  1123. }
  1124.  
  1125. tree_constant
  1126. tree_indirect_ref::assign (tree_constant& t, const Octave_object& args)
  1127. {
  1128.   tree_constant retval;
  1129.  
  1130.   if (refs.empty ())
  1131.     retval = id->assign (t, args);
  1132.   else
  1133.     retval = id->assign (refs, t, args);
  1134.  
  1135.   return retval;
  1136. }
  1137.  
  1138. tree_constant
  1139. tree_indirect_ref::eval (int print)
  1140. {
  1141.   tree_constant retval;
  1142.  
  1143.   if (error_state)
  1144.     return retval;
  1145.  
  1146.   if (refs.empty ())
  1147.     {
  1148.       retval = id->eval (print);
  1149.     }
  1150.   else
  1151.     {
  1152.       int script_file_executed;
  1153.  
  1154.       tree_fvc *object_to_eval = id->do_lookup (script_file_executed, 0);
  1155.  
  1156.       if (object_to_eval)
  1157.     {
  1158.       retval = object_to_eval->lookup_map_element (refs);
  1159.  
  1160.       if (! error_state && print)
  1161.         print_constant (retval, name ());
  1162.     }
  1163.       else
  1164.     id->eval_undefined_error ();
  1165.     }
  1166.  
  1167.   return retval;
  1168. }
  1169.  
  1170. Octave_object
  1171. tree_indirect_ref::eval (int print, int nargout, const Octave_object& args)
  1172. {
  1173.   Octave_object retval;
  1174.  
  1175.   if (error_state)
  1176.     return retval;
  1177.  
  1178.   if (refs.empty ())
  1179.     {
  1180.       retval = id->eval (print, nargout, args);
  1181.     }
  1182.   else
  1183.     {
  1184.       int script_file_executed;
  1185.  
  1186.       tree_fvc *object_to_eval = id->do_lookup (script_file_executed, 0);
  1187.  
  1188.       if (object_to_eval)
  1189.     {
  1190.       tree_constant tmp = object_to_eval->lookup_map_element (refs);
  1191.  
  1192.       if (! error_state)
  1193.         {
  1194.           retval = tmp.eval (0, nargout, args);
  1195.  
  1196.           if (! error_state && print)
  1197.         {
  1198.           tmp = retval (0);
  1199.           if (tmp.is_defined ())
  1200.             print_constant (tmp, name ());
  1201.         }
  1202.         }
  1203.     }
  1204.       else
  1205.     id->eval_undefined_error ();
  1206.     }
  1207.  
  1208.   return retval;
  1209. }
  1210.  
  1211. void
  1212. tree_indirect_ref::print_code (ostream& os)
  1213. {
  1214.   print_code_indent (os);
  1215.  
  1216.   if (in_parens)
  1217.     os << "(";
  1218.  
  1219.   char *nm = id ? id->name () : "(null)";
  1220.   os << (nm) ? nm : "(null)";
  1221.  
  1222.   for (Pix p = refs.first (); p != 0; refs.next (p))
  1223.     {
  1224.       char *elt = refs (p);
  1225.  
  1226.       if (elt)
  1227.     os << "." << elt;
  1228.     }
  1229.  
  1230.   if (in_parens)
  1231.     os << ")";
  1232. }
  1233.  
  1234. // Index expressions.
  1235.  
  1236. tree_index_expression::~tree_index_expression (void)
  1237. {
  1238.   delete id;
  1239.   delete list;
  1240. }
  1241.  
  1242. tree_constant
  1243. tree_index_expression::eval (int print)
  1244. {
  1245.   tree_constant retval;
  1246.  
  1247.   if (error_state)
  1248.     return retval;
  1249.  
  1250.   if (list)
  1251.     {
  1252. // Extract the arguments into a simple vector.  Don't pass null args.
  1253.  
  1254.       Octave_object args = list->convert_to_const_vector ();
  1255.  
  1256.       if (error_state)
  1257.     eval_error ();
  1258.       else
  1259.     {
  1260.       int nargin = args.length ();
  1261.  
  1262.       if (error_state)
  1263.         eval_error ();
  1264.       else if (nargin > 0)
  1265.         {
  1266.           if (all_args_defined (args))
  1267.         {
  1268.           Octave_object tmp = id->eval (print, 1, args);
  1269.  
  1270.           if (error_state)
  1271.             eval_error ();
  1272.           else if (tmp.length () > 0)
  1273.             retval = tmp(0);
  1274.         }
  1275.           else
  1276.         {
  1277.           ::error ("undefined arguments found in index expression");
  1278.           eval_error ();
  1279.         }
  1280.         }
  1281.       else
  1282.         panic_impossible ();  // XXX FIXME XXX -- is this correct?
  1283.     }
  1284.     }
  1285.   else
  1286.     {
  1287.       retval = id->eval (print);
  1288.  
  1289.       if (error_state)
  1290.     eval_error ();
  1291.     }
  1292.  
  1293.   return retval;
  1294. }
  1295.  
  1296. Octave_object
  1297. tree_index_expression::eval (int print, int nargout, const Octave_object& args)
  1298. {
  1299.   Octave_object retval;
  1300.  
  1301.   if (error_state)
  1302.     return retval;
  1303.  
  1304.   if (list)
  1305.     {
  1306. // Extract the arguments into a simple vector.  Don't pass null args.
  1307.  
  1308.       Octave_object args = list->convert_to_const_vector ();
  1309.  
  1310.       if (error_state)
  1311.     eval_error ();
  1312.       else
  1313.     {
  1314.       int nargin = args.length ();
  1315.  
  1316.       if (error_state)
  1317.         eval_error ();
  1318.       else if (nargin > 0)
  1319.         {
  1320.           if (all_args_defined (args))
  1321.         {
  1322.           retval = id->eval (print, nargout, args);
  1323.  
  1324.           if (error_state)
  1325.             eval_error ();
  1326.         }
  1327.           else
  1328.         {
  1329.           ::error ("undefined arguments found in index expression");
  1330.           eval_error ();
  1331.         }
  1332.         }
  1333.       else
  1334.         panic_impossible ();  // XXX FIXME XXX -- is this correct?
  1335.     }
  1336.     }
  1337.   else
  1338.     {
  1339.       Octave_object tmp_args;
  1340.  
  1341.       retval = id->eval (print, nargout, tmp_args);
  1342.  
  1343.       if (error_state)
  1344.     eval_error ();
  1345.     }
  1346.  
  1347.   return retval;
  1348. }
  1349.  
  1350. void
  1351. tree_index_expression::eval_error (void)
  1352. {
  1353.   if (error_state > 0)
  1354.     {
  1355.       int l = line ();
  1356.       int c = column ();
  1357.       char *fmt;
  1358.       if (l != -1 && c != -1)
  1359.     {
  1360.       if (list)
  1361.         fmt = "evaluating index expression near line %d, column %d";
  1362.       else
  1363.         fmt = "evaluating expression near line %d, column %d";
  1364.  
  1365.       ::error (fmt, l, c);
  1366.     }
  1367.       else
  1368.     {
  1369.       if (list)
  1370.         ::error ("evaluating index expression");
  1371.       else
  1372.         ::error ("evaluating expression");
  1373.     }
  1374.     }
  1375. }
  1376.  
  1377. void
  1378. tree_index_expression::print_code (ostream& os)
  1379. {
  1380.   print_code_indent (os);
  1381.  
  1382.   if (in_parens)
  1383.     os << "(";
  1384.  
  1385.   if (id)
  1386.     id->print_code (os);
  1387.  
  1388.   if (list)
  1389.     {
  1390.       os << " (";
  1391.       list->print_code (os);
  1392.       os << ")";
  1393.     }
  1394.  
  1395.   if (in_parens)
  1396.     os << ")";
  1397. }
  1398.  
  1399. // Prefix expressions.
  1400.  
  1401. tree_constant
  1402. tree_prefix_expression::eval (int print)
  1403. {
  1404.   tree_constant retval;
  1405.  
  1406.   if (error_state)
  1407.     return retval;
  1408.  
  1409.   if (id)
  1410.     {
  1411.       id->bump_value (etype);
  1412.       if (error_state)
  1413.     eval_error ();
  1414.       else
  1415.     {
  1416.       retval = id->eval (print);
  1417.       if (error_state)
  1418.         {
  1419.           retval = tree_constant ();
  1420.           if (error_state)
  1421.         eval_error ();
  1422.         }
  1423.     }
  1424.     }
  1425.   return retval;
  1426. }
  1427.  
  1428. char *
  1429. tree_prefix_expression::oper (void) const
  1430. {
  1431.   static char *op;
  1432.   switch (etype)
  1433.     {
  1434.     case tree_expression::increment:
  1435.       op = "++";
  1436.       break;
  1437.  
  1438.     case tree_expression::decrement:
  1439.       op = "--";
  1440.       break;
  1441.  
  1442.     default:
  1443.       op = "<unknown>";
  1444.       break;
  1445.     }
  1446.   return op;
  1447. }
  1448.  
  1449. void
  1450. tree_prefix_expression::eval_error (void)
  1451. {
  1452.   if (error_state > 0)
  1453.     {
  1454.       char *op = oper ();
  1455.  
  1456.       ::error ("evaluating prefix operator `%s' near line %d, column %d",
  1457.            op, line (), column ());
  1458.     }
  1459. }
  1460.  
  1461. void
  1462. tree_prefix_expression::print_code (ostream& os)
  1463. {
  1464.   print_code_indent (os);
  1465.  
  1466.   if (in_parens)
  1467.     os << "(";
  1468.  
  1469.   os << oper ();
  1470.  
  1471.   if (id)
  1472.     id->print_code (os);
  1473.  
  1474.   if (in_parens)
  1475.     os << ")";
  1476. }
  1477.  
  1478. // Postfix expressions.
  1479.  
  1480. tree_constant
  1481. tree_postfix_expression::eval (int print)
  1482. {
  1483.   tree_constant retval;
  1484.  
  1485.   if (error_state)
  1486.     return retval;
  1487.  
  1488.   if (id)
  1489.     {
  1490.       retval = id->eval (print);
  1491.       id->bump_value (etype);
  1492.       if (error_state)
  1493.     {
  1494.       retval = tree_constant ();
  1495.       if (error_state)
  1496.         eval_error ();
  1497.     }
  1498.     }
  1499.   return retval;
  1500. }
  1501.  
  1502. char *
  1503. tree_postfix_expression::oper (void) const
  1504. {
  1505.   static char *op;
  1506.   switch (etype)
  1507.     {
  1508.     case tree_expression::increment:
  1509.       op = "++";
  1510.       break;
  1511.  
  1512.     case tree_expression::decrement:
  1513.       op = "--";
  1514.       break;
  1515.  
  1516.     default:
  1517.       op = "<unknown>";
  1518.       break;
  1519.     }
  1520.   return op;
  1521. }
  1522.  
  1523. void
  1524. tree_postfix_expression::eval_error (void)
  1525. {
  1526.   if (error_state > 0)
  1527.     {
  1528.       char *op = oper ();
  1529.  
  1530.       ::error ("evaluating postfix operator `%s' near line %d, column %d",
  1531.            op, line (), column ());
  1532.     }
  1533. }
  1534.  
  1535. void
  1536. tree_postfix_expression::print_code (ostream& os)
  1537. {
  1538.   print_code_indent (os);
  1539.  
  1540.   if (in_parens)
  1541.     os << "(";
  1542.  
  1543.   if (id)
  1544.     id->print_code (os);
  1545.  
  1546.   os << oper ();
  1547.  
  1548.   if (in_parens)
  1549.     os << ")";
  1550. }
  1551.  
  1552. // Unary expressions.
  1553.  
  1554. tree_constant
  1555. tree_unary_expression::eval (int print)
  1556. {
  1557.   if (error_state)
  1558.     return tree_constant ();
  1559.  
  1560.   tree_constant retval;
  1561.  
  1562.   switch (etype)
  1563.     {
  1564.     case tree_expression::not:
  1565.     case tree_expression::uminus:
  1566.     case tree_expression::hermitian:
  1567.     case tree_expression::transpose:
  1568.       if (op)
  1569.     {
  1570.       tree_constant u = op->eval (0);
  1571.       if (error_state)
  1572.         eval_error ();
  1573.       else if (u.is_defined ())
  1574.         {
  1575.           retval = do_unary_op (u, etype);
  1576.           if (error_state)
  1577.         {
  1578.           retval = tree_constant ();
  1579.           if (error_state)
  1580.             eval_error ();
  1581.         }
  1582.         }
  1583.     }
  1584.       break;
  1585.  
  1586.     default:
  1587.       ::error ("unary operator %d not implemented", etype);
  1588.       break;
  1589.     }
  1590.  
  1591.   return retval;
  1592. }
  1593.  
  1594. char *
  1595. tree_unary_expression::oper (void) const
  1596. {
  1597.   static char *op;
  1598.   switch (etype)
  1599.     {
  1600.     case tree_expression::not:
  1601.       op = "!";
  1602.       break;
  1603.  
  1604.     case tree_expression::uminus:
  1605.       op = "-";
  1606.       break;
  1607.  
  1608.     case tree_expression::hermitian:
  1609.       op = "'";
  1610.       break;
  1611.  
  1612.     case tree_expression::transpose:
  1613.       op = ".'";
  1614.       break;
  1615.  
  1616.     default:
  1617.       op = "<unknown>";
  1618.       break;
  1619.     }
  1620.   return op;
  1621. }
  1622.  
  1623. void
  1624. tree_unary_expression::eval_error (void)
  1625. {
  1626.   if (error_state > 0)
  1627.     {
  1628.       char *op = oper ();
  1629.  
  1630.       ::error ("evaluating unary operator `%s' near line %d, column %d",
  1631.            op, line (), column ());
  1632.     }
  1633. }
  1634.  
  1635. void
  1636. tree_unary_expression::print_code (ostream& os)
  1637. {
  1638.   print_code_indent (os);
  1639.  
  1640.   if (in_parens)
  1641.     os << "(";
  1642.  
  1643.   switch (etype)
  1644.     {
  1645.     case tree_expression::not:
  1646.     case tree_expression::uminus:
  1647.       os << oper ();
  1648.       if (op)
  1649.     op->print_code (os);
  1650.       break;
  1651.  
  1652.     case tree_expression::hermitian:
  1653.     case tree_expression::transpose:
  1654.       if (op)
  1655.     op->print_code (os);
  1656.       os << oper ();
  1657.       break;
  1658.  
  1659.     default:
  1660.       os << oper ();
  1661.       if (op)
  1662.     op->print_code (os);
  1663.       break;
  1664.     }
  1665.  
  1666.   if (in_parens)
  1667.     os << ")";
  1668. }
  1669.  
  1670. // Binary expressions.
  1671.  
  1672. tree_constant
  1673. tree_binary_expression::eval (int print)
  1674. {
  1675.   if (error_state)
  1676.     return tree_constant ();
  1677.  
  1678.   tree_constant retval;
  1679.  
  1680.   switch (etype)
  1681.     {
  1682.     case tree_expression::add:
  1683.     case tree_expression::subtract:
  1684.     case tree_expression::multiply:
  1685.     case tree_expression::el_mul:
  1686.     case tree_expression::divide:
  1687.     case tree_expression::el_div:
  1688.     case tree_expression::leftdiv:
  1689.     case tree_expression::el_leftdiv:
  1690.     case tree_expression::power:
  1691.     case tree_expression::elem_pow:
  1692.     case tree_expression::cmp_lt:
  1693.     case tree_expression::cmp_le:
  1694.     case tree_expression::cmp_eq:
  1695.     case tree_expression::cmp_ge:
  1696.     case tree_expression::cmp_gt:
  1697.     case tree_expression::cmp_ne:
  1698.     case tree_expression::and:
  1699.     case tree_expression::or:
  1700.       if (op1)
  1701.     {
  1702.       tree_constant a = op1->eval (0);
  1703.       if (error_state)
  1704.         eval_error ();
  1705.       else if (a.is_defined () && op2)
  1706.         {
  1707.           tree_constant b = op2->eval (0);
  1708.           if (error_state)
  1709.         eval_error ();
  1710.           else if (b.is_defined ())
  1711.         {
  1712.           retval = do_binary_op (a, b, etype);
  1713.           if (error_state)
  1714.             {
  1715.               retval = tree_constant ();
  1716.               if (error_state)
  1717.             eval_error ();
  1718.             }
  1719.         }
  1720.         }
  1721.     }
  1722.       break;
  1723.  
  1724.     case tree_expression::and_and:
  1725.     case tree_expression::or_or:
  1726.       {
  1727.     int result = 0;
  1728.     if (op1)
  1729.       {
  1730.         tree_constant a = op1->eval (0);
  1731.         if (error_state)
  1732.           {
  1733.         eval_error ();
  1734.         break;
  1735.           }
  1736.  
  1737.         int a_true = a.is_true ();
  1738.         if (error_state)
  1739.           {
  1740.         eval_error ();
  1741.         break;
  1742.           }
  1743.  
  1744.         if (a_true)
  1745.           {
  1746.         if (etype == tree_expression::or_or)
  1747.           {
  1748.             result = 1;
  1749.             goto done;
  1750.           }
  1751.           }
  1752.         else
  1753.           {
  1754.         if (etype == tree_expression::and_and)
  1755.           {
  1756.             result = 0;
  1757.             goto done;
  1758.           }
  1759.           }
  1760.  
  1761.         if (op2)
  1762.           {
  1763.         tree_constant b = op2->eval (0);
  1764.         if (error_state)
  1765.           {
  1766.             eval_error ();
  1767.             break;
  1768.           }
  1769.  
  1770.         result = b.is_true ();
  1771.         if (error_state)
  1772.           {
  1773.             eval_error ();
  1774.             break;
  1775.           }
  1776.           }
  1777.       }
  1778.       done:
  1779.     retval = tree_constant ((double) result);
  1780.       }
  1781.       break;
  1782.  
  1783.     default:
  1784.       ::error ("binary operator %d not implemented", etype);
  1785.       break;
  1786.     }
  1787.  
  1788.   return retval;
  1789. }
  1790.  
  1791. char *
  1792. tree_binary_expression::oper (void) const
  1793. {
  1794.   static char *op;
  1795.   switch (etype)
  1796.     {
  1797.     case tree_expression::add:
  1798.       op = "+";
  1799.       break;
  1800.  
  1801.     case tree_expression::subtract:
  1802.       op = "-";
  1803.       break;
  1804.  
  1805.     case tree_expression::multiply:
  1806.       op = "*";
  1807.       break;
  1808.  
  1809.     case tree_expression::el_mul:
  1810.       op = ".*";
  1811.       break;
  1812.  
  1813.     case tree_expression::divide:
  1814.       op = "/";
  1815.       break;
  1816.  
  1817.     case tree_expression::el_div:
  1818.       op = "./";
  1819.       break;
  1820.  
  1821.     case tree_expression::leftdiv:
  1822.       op = "\\";
  1823.       break;
  1824.  
  1825.     case tree_expression::el_leftdiv:
  1826.       op = ".\\";
  1827.       break;
  1828.  
  1829.     case tree_expression::power:
  1830.       op = "^";
  1831.       break;
  1832.  
  1833.     case tree_expression::elem_pow:
  1834.       op = ".^";
  1835.       break;
  1836.  
  1837.     case tree_expression::cmp_lt:
  1838.       op = "<";
  1839.       break;
  1840.  
  1841.     case tree_expression::cmp_le:
  1842.       op = "<=";
  1843.       break;
  1844.  
  1845.     case tree_expression::cmp_eq:
  1846.       op = "==";
  1847.       break;
  1848.  
  1849.     case tree_expression::cmp_ge:
  1850.       op = ">=";
  1851.       break;
  1852.  
  1853.     case tree_expression::cmp_gt:
  1854.       op = ">";
  1855.       break;
  1856.  
  1857.     case tree_expression::cmp_ne:
  1858.       op = "!=";
  1859.       break;
  1860.  
  1861.     case tree_expression::and_and:
  1862.       op = "&&";
  1863.       break;
  1864.  
  1865.     case tree_expression::or_or:
  1866.       op = "||";
  1867.       break;
  1868.  
  1869.     case tree_expression::and:
  1870.       op = "&";
  1871.       break;
  1872.  
  1873.     case tree_expression::or:
  1874.       op = "|";
  1875.       break;
  1876.  
  1877.     default:
  1878.       op = "<unknown>";
  1879.       break;
  1880.     }
  1881.   return op;
  1882. }
  1883.  
  1884. void
  1885. tree_binary_expression::eval_error (void)
  1886. {
  1887.   if (error_state > 0)
  1888.     {
  1889.       char *op = oper ();
  1890.  
  1891.       ::error ("evaluating binary operator `%s' near line %d, column %d",
  1892.          op, line (), column ());
  1893.     }
  1894. }
  1895.  
  1896. void
  1897. tree_binary_expression::print_code (ostream& os)
  1898. {
  1899.   print_code_indent (os);
  1900.  
  1901.   if (in_parens)
  1902.     os << "(";
  1903.  
  1904.   if (op1)
  1905.     op1->print_code (os);
  1906.  
  1907.   os << " " << oper () << " ";
  1908.  
  1909.   if (op2)
  1910.     op2->print_code (os);
  1911.  
  1912.   if (in_parens)
  1913.     os << ")";
  1914. }
  1915.  
  1916. // Simple assignment expressions.
  1917.  
  1918. tree_simple_assignment_expression::~tree_simple_assignment_expression (void)
  1919. {
  1920.   if (! preserve)
  1921.     {
  1922.       delete lhs;
  1923.       delete index;
  1924.     }
  1925.   delete rhs;
  1926. }
  1927.  
  1928. tree_constant
  1929. tree_simple_assignment_expression::eval (int print)
  1930. {
  1931.   assert (etype == tree_expression::assignment);
  1932.  
  1933.   tree_constant retval;
  1934.  
  1935.   if (error_state)
  1936.     return retval;
  1937.  
  1938.   if (rhs)
  1939.     {
  1940.       tree_constant rhs_val = rhs->eval (0);
  1941.       if (error_state)
  1942.     {
  1943.       eval_error ();
  1944.     }
  1945.       else if (rhs_val.is_undefined ())
  1946.     {
  1947.       error ("value on right hand side of assignment is undefined");
  1948.       eval_error ();
  1949.     }
  1950.       else if (! index)
  1951.     {
  1952.       retval = lhs->assign (rhs_val);
  1953.       if (error_state)
  1954.         eval_error ();
  1955.     }
  1956.       else
  1957.     {
  1958. // Extract the arguments into a simple vector.
  1959.  
  1960.       Octave_object args = index->convert_to_const_vector ();
  1961.  
  1962.       if (error_state)
  1963.         eval_error ();
  1964.       else
  1965.         {
  1966.           int nargin = args.length ();
  1967.  
  1968.           if (error_state)
  1969.         eval_error ();
  1970.           else if (nargin > 0)
  1971.         {
  1972.           retval = lhs->assign (rhs_val, args);
  1973.           if (error_state)
  1974.             eval_error ();
  1975.         }
  1976.         }
  1977.     }
  1978.     }
  1979.  
  1980.   if (! error_state && retval.is_defined ())
  1981.     {
  1982.       int pad_after = 0;
  1983.       if (print && user_pref.print_answer_id_name)
  1984.     {
  1985.       if (print_as_scalar (retval))
  1986.         {
  1987.           ostrstream output_buf;
  1988.           output_buf << lhs->name () << " = " << ends;
  1989.           maybe_page_output (output_buf);
  1990.         }
  1991.       else
  1992.         {
  1993.           pad_after = 1;
  1994.           ostrstream output_buf;
  1995.           output_buf << lhs->name () << " =\n\n" << ends;
  1996.           maybe_page_output (output_buf);
  1997.         }
  1998.     }
  1999.  
  2000.       retval.eval (print);
  2001.  
  2002.       if (print && pad_after)
  2003.     {
  2004.       ostrstream output_buf;
  2005.       output_buf << "\n" << ends;
  2006.       maybe_page_output (output_buf);
  2007.     }
  2008.     }
  2009.  
  2010.   return retval;
  2011. }
  2012.  
  2013. void
  2014. tree_simple_assignment_expression::eval_error (void)
  2015. {
  2016.   if (error_state > 0)
  2017.     {
  2018.       int l = line ();
  2019.       int c = column ();
  2020.       if (l != -1 && c != -1)
  2021.     ::error ("evaluating assignment expression near line %d, column %d",
  2022.          l, c);
  2023. //      else
  2024. //    ::error ("evaluating assignment expression");
  2025.     }
  2026. }
  2027.  
  2028. void
  2029. tree_simple_assignment_expression::print_code (ostream& os)
  2030. {
  2031.   print_code_indent (os);
  2032.  
  2033.   if (in_parens)
  2034.     os << "(";
  2035.  
  2036.   if (! is_ans_assign ())
  2037.     {
  2038.       if (lhs)
  2039.     lhs->print_code (os);
  2040.  
  2041.       if (index)
  2042.     {
  2043.       os << " (";
  2044.       index->print_code (os);
  2045.       os << ")";
  2046.     }
  2047.  
  2048.       os << " = ";
  2049.     }
  2050.  
  2051.   if (rhs)
  2052.     rhs->print_code (os);
  2053.  
  2054.   if (in_parens)
  2055.     os << ")";
  2056. }
  2057.  
  2058. // Multi-valued assignmnt expressions.
  2059.  
  2060. tree_multi_assignment_expression::~tree_multi_assignment_expression (void)
  2061. {
  2062.   delete lhs;
  2063.   delete rhs;
  2064. }
  2065.  
  2066. tree_constant
  2067. tree_multi_assignment_expression::eval (int print)
  2068. {
  2069.   tree_constant retval;
  2070.  
  2071.   if (error_state)
  2072.     return retval;
  2073.  
  2074.   Octave_object tmp_args;
  2075.   Octave_object result = eval (print, 1, tmp_args);
  2076.  
  2077.   if (result.length () > 0)
  2078.     retval = result(0);
  2079.  
  2080.   return retval;
  2081. }
  2082.  
  2083. Octave_object
  2084. tree_multi_assignment_expression::eval (int print, int nargout,
  2085.                     const Octave_object& args)
  2086. {
  2087.   assert (etype == tree_expression::multi_assignment);
  2088.  
  2089.   if (error_state || ! rhs)
  2090.     return Octave_object ();
  2091.  
  2092.   nargout = lhs->length ();
  2093.   Octave_object tmp_args;
  2094.   Octave_object results = rhs->eval (0, nargout, tmp_args);
  2095.  
  2096.   if (error_state)
  2097.     eval_error ();
  2098.  
  2099.   int ma_line = line ();
  2100.   int ma_column = column ();
  2101.  
  2102.   if (results.length () > 0)
  2103.     {
  2104.       int i = 0;
  2105.       int pad_after = 0;
  2106.       int last_was_scalar_type = 0;
  2107.       for (Pix p = lhs->first (); p != 0; lhs->next (p))
  2108.     {
  2109.       tree_index_expression *lhs_expr = (*lhs) (p);
  2110.  
  2111.       if (i < nargout)
  2112.         {
  2113. // XXX FIXME? XXX -- this is apparently the way Matlab works, but
  2114. // maybe we should have the option of skipping the assignment instead.
  2115.  
  2116.           tree_constant *tmp = 0;
  2117.           if (results(i).is_undefined ())
  2118.         {
  2119.           error ("element number %d undefined in return list", i+1);
  2120.           eval_error ();
  2121.           break;
  2122.         }
  2123.           else
  2124.         tmp = new tree_constant (results(i));
  2125.  
  2126.           tree_simple_assignment_expression tmp_expr
  2127.         (lhs_expr, tmp, 1, 0, ma_line, ma_column);
  2128.  
  2129.           results(i) = tmp_expr.eval (0); // May change
  2130.  
  2131.           if (error_state)
  2132.         break;
  2133.  
  2134.           if (print && pad_after)
  2135.         {
  2136.           ostrstream output_buf;
  2137.           output_buf << "\n" << '\0';
  2138.           maybe_page_output (output_buf);
  2139.         }
  2140.  
  2141.           if (print && user_pref.print_answer_id_name)
  2142.         {
  2143.           char *tmp_nm = lhs_expr->name ();
  2144.           
  2145.           if (print_as_scalar (results(i)))
  2146.             {
  2147.               ostrstream output_buf;
  2148.               output_buf << tmp_nm << " = " << '\0';
  2149.               maybe_page_output (output_buf);
  2150.               last_was_scalar_type = 1;
  2151.             }
  2152.           else
  2153.             {
  2154.               ostrstream output_buf;
  2155.               output_buf << tmp_nm << " =\n\n" << '\0';
  2156.               maybe_page_output (output_buf);
  2157.               last_was_scalar_type = 0;
  2158.             }
  2159.         }
  2160.  
  2161.           results(i).eval (print);
  2162.  
  2163.           pad_after++;
  2164.           i++;
  2165.         }
  2166.       else
  2167.         {
  2168.           tree_simple_assignment_expression tmp_expr
  2169.         (lhs_expr, 0, 1, 0, ma_line, ma_column);
  2170.  
  2171.           tmp_expr.eval (0);
  2172.  
  2173.           if (error_state)
  2174.         break;
  2175.  
  2176.           if (last_was_scalar_type && i == 1)
  2177.         pad_after = 0;
  2178.  
  2179.           break;
  2180.         }
  2181.     }
  2182.  
  2183.       if (print && pad_after)
  2184.     {
  2185.       ostrstream output_buf;
  2186.       output_buf << "\n" << '\0';
  2187.       maybe_page_output (output_buf);
  2188.     }
  2189.     }
  2190.  
  2191.   return results;
  2192. }
  2193.  
  2194. void
  2195. tree_multi_assignment_expression::eval_error (void)
  2196. {
  2197.   if (error_state > 0)
  2198.     ::error ("evaluating assignment expression near line %d, column %d",
  2199.          line (), column ());
  2200. }
  2201.  
  2202. void
  2203. tree_multi_assignment_expression::print_code (ostream& os)
  2204. {
  2205.   print_code_indent (os);
  2206.  
  2207.   if (in_parens)
  2208.     os << "(";
  2209.  
  2210.   if (lhs)
  2211.     {
  2212.       int len = lhs->length ();
  2213.  
  2214.       if (len > 1)
  2215.     os << "[";
  2216.  
  2217.       lhs->print_code (os);
  2218.  
  2219.       if (len > 1)
  2220.     os << "]";
  2221.     }
  2222.  
  2223.   os << " = ";
  2224.  
  2225.   if (rhs)
  2226.     rhs->print_code (os);
  2227.  
  2228.   if (in_parens)
  2229.     os << ")";
  2230. }
  2231.  
  2232. // Colon expressions.
  2233.  
  2234. tree_colon_expression *
  2235. tree_colon_expression::chain (tree_expression *t)
  2236. {
  2237.   tree_colon_expression *retval = 0;
  2238.   if (! op1 || op3)
  2239.     ::error ("invalid colon expression");
  2240.   else
  2241.     {
  2242.       op3 = op2;    // Stupid syntax.
  2243.       op2 = t;
  2244.  
  2245.       retval = this;
  2246.     }
  2247.   return retval;
  2248. }
  2249.  
  2250. tree_constant
  2251. tree_colon_expression::eval (int print)
  2252. {
  2253.   tree_constant retval;
  2254.  
  2255.   if (error_state || ! op1 || ! op2)
  2256.     return retval;
  2257.  
  2258.   tree_constant tmp = op1->eval (0);
  2259.  
  2260.   if (tmp.is_undefined ())
  2261.     {
  2262.       eval_error ("invalid null value in colon expression");
  2263.       return retval;
  2264.     }
  2265.  
  2266.   double base = tmp.double_value ();
  2267.  
  2268.   if (error_state)
  2269.     {
  2270.       error ("colon expression elements must be scalars");
  2271.       eval_error ("evaluating colon expression");
  2272.       return retval;
  2273.     }
  2274.  
  2275.   tmp = op2->eval (0);
  2276.  
  2277.   if (tmp.is_undefined ())
  2278.     {
  2279.       eval_error ("invalid null value in colon expression");
  2280.       return retval;
  2281.     }
  2282.  
  2283.   double limit = tmp.double_value ();
  2284.  
  2285.   if (error_state)
  2286.     {
  2287.       error ("colon expression elements must be scalars");
  2288.       eval_error ("evaluating colon expression");
  2289.       return retval;
  2290.     }
  2291.  
  2292.   double inc = 1.0;
  2293.   if (op3)
  2294.     {
  2295.       tmp = op3->eval (0);
  2296.  
  2297.       if (tmp.is_undefined ())
  2298.     {
  2299.       eval_error ("invalid null value in colon expression");
  2300.       return retval;
  2301.     }
  2302.  
  2303.       inc = tmp.double_value ();
  2304.  
  2305.       if (error_state)
  2306.     {
  2307.       error ("colon expression elements must be scalars");
  2308.       eval_error ("evaluating colon expression");
  2309.       return retval;
  2310.     }
  2311.     }
  2312.  
  2313.   retval = tree_constant (base, limit, inc);
  2314.  
  2315.   if (error_state)
  2316.     {
  2317.       if (error_state)
  2318.     eval_error ("evaluating colon expression");
  2319.       return tree_constant ();
  2320.     }
  2321.  
  2322.   return retval;
  2323. }
  2324.  
  2325. void
  2326. tree_colon_expression::eval_error (const char *s)
  2327. {
  2328.   if (error_state > 0)
  2329.     ::error ("%s near line %d column %d", s, line (), column ());
  2330. }
  2331.  
  2332. void
  2333. tree_colon_expression::print_code (ostream& os)
  2334. {
  2335.   print_code_indent (os);
  2336.  
  2337.   if (in_parens)
  2338.     os << "(";
  2339.  
  2340.   if (op1)
  2341.     op1->print_code (os);
  2342.  
  2343. // Stupid syntax.
  2344.  
  2345.   if (op3)
  2346.     {
  2347.       os << ":";
  2348.       op3->print_code (os);
  2349.     }
  2350.  
  2351.   if (op2)
  2352.     {
  2353.       os << ":";
  2354.       op2->print_code (os);
  2355.     }
  2356.  
  2357.   if (in_parens)
  2358.     os << ")";
  2359. }
  2360.  
  2361. // Builtin functions.
  2362.  
  2363. tree_builtin::tree_builtin (const char *nm)
  2364. {
  2365.   nargin_max = -1;
  2366.   nargout_max = -1;
  2367.   is_mapper = 0;
  2368.   fcn = 0;
  2369.   if (nm)
  2370.     my_name = strsave (nm);
  2371. }
  2372.  
  2373. tree_builtin::tree_builtin (int i_max, int o_max, Mapper_fcn& m_fcn,
  2374.                 const char *nm)
  2375. {
  2376.   nargin_max = i_max;
  2377.   nargout_max = o_max;
  2378.   mapper_fcn = m_fcn;
  2379.   is_mapper = 1;
  2380.   fcn = 0;
  2381.   my_name = nm ? strsave (nm) : 0;
  2382. }
  2383.  
  2384. tree_builtin::tree_builtin (int i_max, int o_max, Octave_builtin_fcn g_fcn,
  2385.                 const char *nm)
  2386. {
  2387.   nargin_max = i_max;
  2388.   nargout_max = o_max;
  2389.   is_mapper = 0;
  2390.   fcn = g_fcn;
  2391.   my_name = nm ? strsave (nm) : 0;
  2392. }
  2393.  
  2394. tree_constant
  2395. tree_builtin::eval (int print)
  2396. {
  2397.   tree_constant retval;
  2398.  
  2399.   if (error_state)
  2400.     return retval;
  2401.  
  2402.   if (fcn)
  2403.     {
  2404.     eval_fcn:
  2405.  
  2406.       Octave_object args;
  2407.       Octave_object tmp = (*fcn) (args, 0);
  2408.       if (tmp.length () > 0)
  2409.     retval = tmp(0);
  2410.     }
  2411.   else
  2412.     {
  2413.       fcn = load_octave_builtin (my_name);
  2414.  
  2415.       if (fcn)
  2416.     goto eval_fcn;
  2417.       else
  2418.     ::error ("unable to load builtin function %s", my_name);
  2419.     }
  2420.  
  2421.   return retval;
  2422. }
  2423.  
  2424. static tree_constant
  2425. apply_mapper_fcn (const tree_constant& arg, Mapper_fcn& m_fcn, int print)
  2426. {
  2427.   tree_constant retval;
  2428.  
  2429.   if (arg.is_real_type ())
  2430.     {
  2431.       if (arg.is_scalar_type ())
  2432.     {
  2433.       double d = arg.double_value ();
  2434.  
  2435.       if (m_fcn.can_return_complex_for_real_arg
  2436.           && (d < m_fcn.lower_limit || d > m_fcn.upper_limit))
  2437.         {
  2438.           if (m_fcn.c_c_mapper)
  2439.         retval = m_fcn.c_c_mapper (Complex (d));
  2440.           else
  2441.         error ("%s: unable to handle real arguments", m_fcn.name);
  2442.         }
  2443.       else if (m_fcn.d_d_mapper)
  2444.         retval = m_fcn.d_d_mapper (d);
  2445.       else
  2446.         error ("%s: unable to handle real arguments", m_fcn.name);
  2447.     }
  2448.       else
  2449.     {
  2450.       Matrix m = arg.matrix_value ();
  2451.  
  2452.       if (error_state)
  2453.         return retval;
  2454.  
  2455.       if (m_fcn.can_return_complex_for_real_arg
  2456.           && (any_element_less_than (m, m_fcn.lower_limit)
  2457.           || any_element_greater_than (m, m_fcn.upper_limit)))
  2458.         {
  2459.           if (m_fcn.c_c_mapper)
  2460.         retval = map (m_fcn.c_c_mapper, ComplexMatrix (m));
  2461.           else
  2462.         error ("%s: unable to handle real arguments", m_fcn.name);
  2463.         }
  2464.       else if (m_fcn.d_d_mapper)
  2465.         retval = map (m_fcn.d_d_mapper, m);
  2466.       else
  2467.         error ("%s: unable to handle real arguments", m_fcn.name);
  2468.     }
  2469.     }
  2470.   else if (arg.is_complex_type ())
  2471.     {
  2472.       if (arg.is_scalar_type ())
  2473.     {
  2474.       Complex c = arg.complex_value ();
  2475.  
  2476.       if (m_fcn.d_c_mapper)
  2477.         retval = m_fcn.d_c_mapper (c);
  2478.       else if (m_fcn.c_c_mapper)
  2479.         retval = m_fcn.c_c_mapper (c);
  2480.       else
  2481.         error ("%s: unable to handle complex arguments", m_fcn.name);
  2482.     }
  2483.       else
  2484.     {
  2485.       ComplexMatrix cm = arg.complex_matrix_value ();
  2486.  
  2487.       if (error_state)
  2488.         return retval;
  2489.  
  2490.       if (m_fcn.d_c_mapper)
  2491.         retval = map (m_fcn.d_c_mapper, cm);
  2492.       else if (m_fcn.c_c_mapper)
  2493.         retval = map (m_fcn.c_c_mapper, cm);
  2494.       else
  2495.         error ("%s: unable to handle complex arguments", m_fcn.name);
  2496.     }
  2497.     }
  2498.   else
  2499.     gripe_wrong_type_arg ("mapper", arg);
  2500.  
  2501.   return retval;
  2502. }
  2503.  
  2504. Octave_object
  2505. tree_builtin::eval (int print, int nargout, const Octave_object& args)
  2506. {
  2507.   Octave_object retval;
  2508.  
  2509.   if (error_state)
  2510.     return retval;
  2511.  
  2512.   int nargin = args.length ();
  2513.  
  2514.   if (fcn)
  2515.     {
  2516.     eval_fcn:
  2517.  
  2518.       if (any_arg_is_magic_colon (args))
  2519.     ::error ("invalid use of colon in function argument list");
  2520.       else
  2521.     retval = (*fcn) (args, nargout);
  2522.     }
  2523.   else if (is_mapper)
  2524.     {
  2525.       if (nargin > nargin_max)
  2526.     ::error ("%s: too many arguments", my_name);
  2527.       else if (nargin > 0 && args(0).is_defined ())
  2528.     {
  2529.       tree_constant tmp = apply_mapper_fcn (args(0), mapper_fcn, 0);
  2530.       retval(0) = tmp;
  2531.     }    
  2532.     }
  2533.   else
  2534.     {
  2535.       fcn = load_octave_builtin (my_name);
  2536.  
  2537.       if (fcn)
  2538.     goto eval_fcn;
  2539.       else
  2540.     ::error ("unable to load builtin function %s", my_name);
  2541.     }
  2542.  
  2543.   return retval;
  2544. }
  2545.  
  2546. int
  2547. tree_builtin::max_expected_args (void)
  2548. {
  2549.   int ea = nargin_max;
  2550.   if (nargin_max < 0)
  2551.     ea = INT_MAX;
  2552.   else
  2553.     ea = nargin_max;
  2554.   return ea;
  2555. }
  2556.  
  2557. // User defined functions.
  2558.  
  2559. #if 0
  2560. tree_function *
  2561. tree_function::define (tree statement_list *t)
  2562. {
  2563.   cmd_list = t;
  2564.   return this;
  2565. }
  2566. #endif
  2567.  
  2568. tree_function *
  2569. tree_function::define_param_list (tree_parameter_list *t)
  2570. {
  2571.   param_list = t;
  2572.  
  2573.   if (param_list)
  2574.     {
  2575.       num_named_args = param_list->length ();
  2576.       curr_va_arg_number = num_named_args;
  2577.     }
  2578.  
  2579.   return this;
  2580. }
  2581.  
  2582. tree_function *
  2583. tree_function::define_ret_list (tree_parameter_list *t)
  2584. {
  2585.   ret_list = t;
  2586.  
  2587.   if (ret_list && ret_list->takes_varargs ())
  2588.     vr_list = new tree_va_return_list;
  2589.  
  2590.   return this;
  2591. }
  2592.  
  2593. void
  2594. tree_function::stash_fcn_file_name (void)
  2595. {
  2596.   delete [] file_name;
  2597.   file_name = fcn_name ? fcn_file_in_path (fcn_name) : 0;
  2598. }
  2599.  
  2600. void
  2601. tree_function::mark_as_system_fcn_file (void)
  2602. {
  2603.   if (file_name)
  2604.     {
  2605. // We really should stash the whole path to the file we found, when we
  2606. // looked it up, to avoid possible race conditions...  XXX FIXME XXX
  2607. //
  2608. // We probably also don't need to get the library directory every
  2609. // time, but since this function is only called when the function file
  2610. // is parsed, it probably doesn't matter that much.
  2611.  
  2612.       char *oct_lib = octave_lib_dir ();
  2613.       int len = strlen (oct_lib);
  2614.  
  2615.       char *ff_name = fcn_file_in_path (file_name);
  2616.  
  2617.       if (strncmp (oct_lib, ff_name, len) == 0)
  2618.     system_fcn_file = 1;
  2619.  
  2620.       delete [] ff_name;
  2621.     }
  2622.   else
  2623.     system_fcn_file = 0;
  2624. }
  2625.  
  2626. int
  2627. tree_function::takes_varargs (void) const
  2628. {
  2629.   return (param_list && param_list->takes_varargs ());
  2630. }
  2631.  
  2632. tree_constant
  2633. tree_function::octave_va_arg (void)
  2634. {
  2635.   tree_constant retval;
  2636.  
  2637.   if (curr_va_arg_number < num_args_passed)
  2638.     retval = args_passed (curr_va_arg_number++);
  2639.   else
  2640.     ::error ("va_arg: error getting arg number %d -- only %d provided",
  2641.          curr_va_arg_number + 1, num_args_passed);
  2642.  
  2643.   return retval;
  2644. }
  2645.  
  2646. Octave_object
  2647. tree_function::octave_all_va_args (void)
  2648. {
  2649.   Octave_object retval;
  2650.  
  2651.   retval.resize (num_args_passed - num_named_args);
  2652.  
  2653.   int k = 0;
  2654.   for (int i = num_named_args; i < num_args_passed; i++)
  2655.     retval(k++) = args_passed(i);
  2656.  
  2657.   return retval;
  2658. }
  2659.  
  2660. int
  2661. tree_function::takes_var_return (void) const
  2662. {
  2663.   return (ret_list && ret_list->takes_varargs ());
  2664. }
  2665.  
  2666. void
  2667. tree_function::octave_vr_val (const tree_constant& val)
  2668. {
  2669.   assert (vr_list);
  2670.  
  2671.   vr_list->append (val);
  2672. }
  2673.  
  2674. void
  2675. tree_function::stash_function_name (char *s)
  2676. {
  2677.   delete [] fcn_name;
  2678.   fcn_name = strsave (s);
  2679. }
  2680.  
  2681. tree_constant
  2682. tree_function::eval (int print)
  2683. {
  2684.   tree_constant retval;
  2685.  
  2686.   if (error_state || ! cmd_list)
  2687.     return retval;
  2688.  
  2689.   Octave_object tmp_args;
  2690.   Octave_object tmp = eval (print, 0, tmp_args);
  2691.  
  2692.   if (! error_state && tmp.length () > 0)
  2693.     retval = tmp(0);
  2694.  
  2695.   return retval;
  2696. }
  2697.  
  2698. // For unwind protect.
  2699.  
  2700. static void
  2701. pop_symbol_table_context (void *table)
  2702. {
  2703.   symbol_table *tmp = (symbol_table *) table;
  2704.   tmp->pop_context ();
  2705. }
  2706.  
  2707. static void
  2708. delete_vr_list (void *list)
  2709. {
  2710.   tree_va_return_list *tmp = (tree_va_return_list *) list;
  2711.   tmp->clear ();
  2712.   delete tmp;
  2713. }
  2714.  
  2715. static void
  2716. clear_symbol_table (void *table)
  2717. {
  2718.   symbol_table *tmp = (symbol_table *) table;
  2719.   tmp->clear ();
  2720. }
  2721.  
  2722. Octave_object
  2723. tree_function::eval (int print, int nargout, const Octave_object& args)
  2724. {
  2725.   Octave_object retval;
  2726.  
  2727.   if (error_state)
  2728.     return retval;
  2729.  
  2730.   if (! cmd_list)
  2731.     return retval;
  2732.  
  2733.   int nargin = args.length ();
  2734.  
  2735.   begin_unwind_frame ("func_eval");
  2736.  
  2737.   unwind_protect_int (call_depth);
  2738.   call_depth++;
  2739.  
  2740.   if (call_depth > 1)
  2741.     {
  2742.       sym_tab->push_context ();
  2743.       add_unwind_protect (pop_symbol_table_context, (void *) sym_tab);
  2744.  
  2745.       if (vr_list)
  2746.     {
  2747. // Push new vr_list.
  2748.       unwind_protect_ptr (vr_list);
  2749.       vr_list = new tree_va_return_list;
  2750.  
  2751. // Clear and delete the new one before restoring the old one.
  2752.       add_unwind_protect (delete_vr_list, (void *) vr_list);
  2753.     }
  2754.     }
  2755.  
  2756.   if (vr_list)
  2757.     vr_list->clear ();
  2758.  
  2759. // Force symbols to be undefined again when this function exits.
  2760.  
  2761.   add_unwind_protect (clear_symbol_table, (void *) sym_tab);
  2762.  
  2763. // Save old and set current symbol table context, for eval_undefined_error().
  2764.  
  2765.   unwind_protect_ptr (curr_sym_tab);
  2766.   curr_sym_tab = sym_tab;
  2767.  
  2768.   unwind_protect_ptr (curr_function);
  2769.   curr_function = this;
  2770.  
  2771. //  unwind_protect_ptr (args_passed);
  2772.   args_passed = args;
  2773.  
  2774.   unwind_protect_int (num_args_passed);
  2775.   num_args_passed = nargin;
  2776.  
  2777.   unwind_protect_int (num_named_args);
  2778.   unwind_protect_int (curr_va_arg_number);
  2779.  
  2780.   if (param_list && ! param_list->varargs_only ())
  2781.     {
  2782.       param_list->define_from_arg_vector (args);
  2783.       if (error_state)
  2784.     goto abort;
  2785.     }
  2786.  
  2787. // The following code is in a separate scope to avoid warnings from
  2788. // G++ about `goto abort' crossing the initialization of some
  2789. // variables.
  2790.  
  2791.   {
  2792.     bind_nargin_and_nargout (sym_tab, nargin, nargout);
  2793.       
  2794. // Evaluate the commands that make up the function.  Always turn on
  2795. // printing for commands inside functions.   Maybe this should be
  2796. // toggled by a user-leval variable?
  2797.  
  2798.     int pf = ! user_pref.silent_functions;
  2799.     tree_constant last_computed_value = cmd_list->eval (pf);
  2800.  
  2801.     if (returning)
  2802.       returning = 0;
  2803.  
  2804.     if (breaking)
  2805.       breaking--;
  2806.  
  2807.     if (error_state)
  2808.       {
  2809.     traceback_error ();
  2810.     goto abort;
  2811.       }
  2812.     
  2813. // Copy return values out.
  2814.  
  2815.     if (ret_list)
  2816.       {
  2817.     if (nargout > 0 && user_pref.define_all_return_values)
  2818.       {
  2819.         tree_constant tmp = builtin_any_variable ("default_return_value");
  2820.         if (tmp.is_defined ())
  2821.           ret_list->initialize_undefined_elements (tmp);
  2822.       }
  2823.  
  2824.     retval = ret_list->convert_to_const_vector (vr_list);
  2825.       }
  2826.     else if (user_pref.return_last_computed_value)
  2827.       retval(0) = last_computed_value;
  2828.   }
  2829.  
  2830.  abort:
  2831.   run_unwind_frame ("func_eval");
  2832.  
  2833.   return retval;
  2834. }
  2835.  
  2836. int
  2837. tree_function::max_expected_args (void)
  2838. {
  2839.   if (param_list)
  2840.     {
  2841.       if (param_list->takes_varargs ())
  2842.     return -1;
  2843.       else
  2844.     return param_list->length ();
  2845.     }
  2846.   else
  2847.     return 1;
  2848. }
  2849.  
  2850. void
  2851. tree_function::traceback_error (void)
  2852. {
  2853.   if (error_state >= 0)
  2854.     error_state = -1;
  2855.  
  2856.   if (fcn_name)
  2857.     {
  2858.       if (file_name)
  2859.     ::error ("called from `%s' in file `%s'", fcn_name, file_name);
  2860.       else 
  2861.     ::error ("called from `%s'", fcn_name);
  2862.     }
  2863.   else
  2864.     {
  2865.       if (file_name)
  2866.     ::error ("called from file `%s'", file_name);
  2867.       else
  2868.     ::error ("called from `?unknown?'");
  2869.     }
  2870. }
  2871.  
  2872. void
  2873. tree_function::print_code (ostream& os)
  2874. {
  2875.   print_code_reset ();
  2876.  
  2877.   print_code_indent (os);
  2878.  
  2879.   os << "function ";
  2880.  
  2881.   if (ret_list)
  2882.     {
  2883.       int len = ret_list->length ();
  2884.  
  2885.       if (len > 1)
  2886.     os << "[";
  2887.  
  2888.       ret_list->print_code (os);
  2889.  
  2890.       if (len > 1)
  2891.     os << "]";
  2892.  
  2893.       os << " = ";
  2894.     }
  2895.  
  2896.   os << (fcn_name ? fcn_name : "(null)") << " ";
  2897.  
  2898.   if (param_list)
  2899.     {
  2900.       int len = param_list->length ();
  2901.       if (len > 0)
  2902.     os << "(";
  2903.  
  2904.       param_list->print_code (os);
  2905.  
  2906.       if (len > 0)
  2907.     {
  2908.       os << ")";
  2909.       print_code_new_line (os);
  2910.     }
  2911.     }
  2912.   else
  2913.     {
  2914.       os << "()";
  2915.       print_code_new_line (os);
  2916.     }
  2917.  
  2918.   if (cmd_list)
  2919.     {
  2920.       increment_indent_level ();
  2921.       cmd_list->print_code (os);
  2922.     }
  2923.  
  2924.   os << "endfunction";
  2925.  
  2926.   print_code_new_line (os);
  2927. }
  2928.  
  2929. DEFUN ("va_arg", Fva_arg, Sva_arg, 0, 1,
  2930.   "va_arg (): return next argument in a function that takes a\n\
  2931. variable number of parameters")
  2932. {
  2933.   Octave_object retval;
  2934.  
  2935.   int nargin = args.length ();
  2936.  
  2937.   if (nargin == 0)
  2938.     {
  2939.       if (curr_function)
  2940.     {
  2941.       if (curr_function->takes_varargs ())
  2942.         retval = curr_function->octave_va_arg ();
  2943.       else
  2944.         {
  2945.           ::error ("va_arg only valid within function taking variable");
  2946.           ::error ("number of arguments");
  2947.         }
  2948.     }
  2949.       else
  2950.     ::error ("va_arg only valid within function body");
  2951.     }
  2952.   else
  2953.     print_usage ("va_arg");
  2954.  
  2955.   return retval;
  2956. }
  2957.  
  2958. DEFUN ("va_start", Fva_start, Sva_start, 0, 0,
  2959.   "va_start (): reset the pointer to the list of optional arguments\n\
  2960. to the beginning")
  2961. {
  2962.   Octave_object retval;
  2963.  
  2964.   int nargin = args.length ();
  2965.  
  2966.   if (nargin == 0)
  2967.     {
  2968.       if (curr_function)
  2969.     {
  2970.       if (curr_function->takes_varargs ())
  2971.         curr_function->octave_va_start ();
  2972.       else
  2973.         {
  2974.           ::error ("va_start only valid within function taking variable");
  2975.           ::error ("number of arguments");
  2976.         }
  2977.     }
  2978.       else
  2979.     ::error ("va_start only valid within function body");
  2980.     }
  2981.   else
  2982.     print_usage ("va_start");
  2983.  
  2984.   return retval;
  2985. }
  2986.  
  2987. DEFUN ("vr_val", Fvr_val, Svr_val, 1, 0,
  2988.   "vr_val (X): append X to the list of optional return values for a
  2989. function that allows a variable number of return values")
  2990. {
  2991.   Octave_object retval;
  2992.  
  2993.   int nargin = args.length ();
  2994.  
  2995.   if (nargin == 1)
  2996.     {
  2997.       if (curr_function)
  2998.     {
  2999.       if (curr_function->takes_var_return ())
  3000.         curr_function->octave_vr_val (args(0));
  3001.       else
  3002.         {
  3003.           ::error ("vr_val only valid within function declared to");
  3004.           ::error ("produce a variable number of values");
  3005.         }
  3006.     }
  3007.       else
  3008.     ::error ("vr_val only valid within function body");
  3009.     }
  3010.   else
  3011.     print_usage ("vr_val");
  3012.  
  3013.   return retval;
  3014. }
  3015.  
  3016. /*
  3017. ;;; Local Variables: ***
  3018. ;;; mode: C++ ***
  3019. ;;; page-delimiter: "^/\\*" ***
  3020. ;;; End: ***
  3021. */
  3022.