# HG changeset patch # User jwe # Date 775944414 0 # Node ID 91e2164fb1b2125a909af60ed96df7c1926b836e # Parent 33d622a12de84af5a4dcb433739bf35a72e4d1bf [project @ 1994-08-03 20:06:54 by jwe] Initial revision diff -r 33d622a12de8 -r 91e2164fb1b2 src/pt-misc.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pt-misc.cc Wed Aug 03 20:06:54 1994 +0000 @@ -0,0 +1,328 @@ +// tree-misc.cc -*- C++ -*- +/* + +Copyright (C) 1992, 1993, 1994 John W. Eaton + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, write to the Free +Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#if defined (__GNUG__) +#pragma implementation +#endif + +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "error.h" +#include "tree.h" +#include "tree-misc.h" +#include "tree-expr.h" +#include "tree-const.h" +#include "user-prefs.h" +#include "oct-obj.h" + +// Nonzero means we're breaking out of a loop. +extern int breaking; + +// Nonzero means we're jumping to the end of a loop. +extern int continuing; + +// Nonzero means we're returning from a function. +extern int returning; + +// A list of commands to be executed. + +tree_statement::~tree_statement (void) +{ + delete command; + delete expression; +} + +tree_constant +tree_statement_list::eval (int print) +{ + int pf; + tree_constant retval; + + if (error_state) + return retval; + + for (Pix p = first (); p != 0; next (p)) + { + tree_statement *elt = this->operator () (p); + + if (print == 0) + pf = 0; + else + pf = elt->print_flag; + + tree_command *cmd = elt->command; + tree_expression *expr = elt->expression; + + if (cmd || expr) + { + if (cmd) + cmd->eval (); + else + retval = expr->eval (pf); + + if (error_state) + return tree_constant (); + + if (breaking || continuing) + break; + + if (returning) + break; + } + else + retval = tree_constant (); + } + return retval; +} + +Octave_object +tree_argument_list::convert_to_const_vector (void) +{ + int len = length () + 1; + + Octave_object args; + args.resize (len); + +// args[0] may eventually hold something useful, like the function +// name. + Pix p = first (); + for (int k = 1; k < len; k++) + { + tree_expression *elt = this->operator () (p); + if (elt) + { + args(k) = elt->eval (0); + if (error_state) + { + ::error ("evaluating argument list element number %d", k); + break; + } + next (p); + } + else + { + args(k) = tree_constant (); + break; + } + } + return args; +} + +// Parameter lists. + +void +tree_parameter_list::mark_as_formal_parameters (void) +{ + for (Pix p = first (); p != 0; next (p)) + { + tree_identifier *elt = this->operator () (p); + elt->mark_as_formal_parameter (); + } +} + +void +tree_parameter_list::define_from_arg_vector (const Octave_object& args) +{ + if (args.length () <= 0) + return; + + int nargin = args.length (); + + int expected_nargin = length () + 1; + + Pix p = first (); + + for (int i = 1; i < expected_nargin; i++) + { + tree_identifier *elt = this->operator () (p); + + tree_constant *tmp = 0; + + if (i < nargin) + { + if (args(i).is_defined () + && (args(i).const_type () == tree_constant_rep::magic_colon)) + { + ::error ("invalid use of colon in function argument list"); + return; + } + tmp = new tree_constant (args(i)); + } + + elt->define (tmp); + + next (p); + } +} + +Octave_object +tree_parameter_list::convert_to_const_vector (void) +{ + int nout = length (); + + Octave_object retval; + retval.resize (nout); + + int i = 0; + + for (Pix p = first (); p != 0; next (p)) + { + tree_identifier *elt = this->operator () (p); + + if (elt->is_defined ()) + retval(i) = elt->eval (0); + + i++; + } + + return retval; +} + +int +tree_parameter_list::is_defined (void) +{ + int status = 1; + + for (Pix p = first (); p != 0; next (p)) + { + tree_identifier *elt = this->operator () (p); + + if (! elt->is_defined ()) + { + status = 0; + break; + } + } + + return status; +} + +void +tree_global::eval (void) +{ + if (ident) + { + ident->link_to_global (); + } + else if (assign_expr) + { + tree_identifier *id = assign_expr->left_hand_side (); + + if (id) + id->link_to_global (); + + assign_expr->eval (0); + } +} + +void +tree_global_init_list::eval (void) +{ + for (Pix p = first (); p != 0; next (p)) + { + tree_global *t = this->operator () (p); + t->eval (); + } +} + +int +tree_if_clause::eval (void) +{ + if (expr) + { + tree_constant t1 = expr->eval (0); + + if (error_state || t1.is_undefined ()) + return 0; + + if (t1.rows () == 0 || t1.columns () == 0) + { + int flag = user_pref.propagate_empty_matrices; + if (flag < 0) + warning ("if: empty matrix used in conditional"); + else if (flag == 0) + { + ::error ("if: empty matrix used in conditional"); + return 0; + } + t1 = tree_constant (0.0); + } + else if (! t1.is_scalar_type ()) + { + tree_constant t2 = t1.all (); + t1 = t2.all (); + } + + int expr_value = 0; + tree_constant_rep::constant_type t = t1.const_type (); + if (t == tree_constant_rep::scalar_constant) + expr_value = (int) t1.double_value (); + else if (t == tree_constant_rep::complex_scalar_constant) + expr_value = t1.complex_value () != 0.0; + else + panic_impossible (); + + if (expr_value) + { + if (list) + list->eval (1); + + return 1; + } + } + else + { + if (list) + list->eval (1); + + return 1; + } + + return 0; +} + +void +tree_if_command_list::eval (void) +{ + for (Pix p = first (); p != 0; next (p)) + { + tree_if_clause *t = this->operator () (p); + + if (t->eval () || error_state) + break; + } +} + +/* +;;; Local Variables: *** +;;; mode: C++ *** +;;; page-delimiter: "^/\\*" *** +;;; End: *** +*/ diff -r 33d622a12de8 -r 91e2164fb1b2 src/pt-misc.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pt-misc.h Wed Aug 03 20:06:54 1994 +0000 @@ -0,0 +1,325 @@ +// tree-misc.h -*- C++ -*- +/* + +Copyright (C) 1992, 1993, 1994 John W. Eaton + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, write to the Free +Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#if !defined (octave_tree_misc_h) +#define octave_tree_misc_h 1 + +#if defined (__GNUG__) +#pragma interface +#endif + +class Octave_object; +class tree_constant; +class tree_command; +class tree_expression; +class tree_simple_assignment_expression; +class tree_identifier; +class symbol_record; +class symbol_table; + +class tree_statement; +class tree_statement_list; +class tree_argument_list; +class tree_parameter_list; +class tree_return_list; +class tree_global; +class tree_global_init_list; + +#include + +#include "tree-base.h" +#include "tree-expr.h" +#include "tree-cmd.h" + +// A list of expressions and commands to be executed. + +class +tree_statement +{ +friend class tree_statement_list; + +public: + tree_statement (void) + { + command = 0; + expression = 0; + print_flag = 1; + } + + tree_statement (tree_command *c) + { + command = c; + expression = 0; + print_flag = 1; + } + + tree_statement (tree_expression *e) + { + command = 0; + expression = e; + print_flag = 1; + } + + ~tree_statement (void); + + void set_print_flag (int print) + { print_flag = print; } + +private: + tree_command *command; // Command to execute. + tree_expression *expression; // Command to execute. + int print_flag; // Print result of eval for this command? +}; + +class +tree_statement_list : public SLList +{ +public: + tree_statement_list (void) : SLList () { } + tree_statement_list (tree_statement *s) : SLList () + { append (s); } + + ~tree_statement_list (void) + { + while (! empty ()) + { + tree_statement *t = remove_front (); + delete t; + } + } + + tree_constant eval (int print); +}; + +// Argument lists. Used to hold the list of expressions that are the +// arguments in a function call or index expression. + +class +tree_argument_list : public SLList +{ +public: + tree_argument_list (void) : SLList () { } + tree_argument_list (tree_expression *t) : SLList () + { append (t); } + + ~tree_argument_list (void) + { + while (! empty ()) + { + tree_expression *t = remove_front (); + delete t; + } + } + + Octave_object convert_to_const_vector (void); +}; + +// Parameter lists. Used to hold the list of input and output +// parameters in a function definition. Elements are identifiers +// only. + +class +tree_parameter_list : public SLList +{ +public: + tree_parameter_list (void) : SLList () { } + tree_parameter_list (tree_identifier *t) : SLList () + { append (t); } + + ~tree_parameter_list (void) + { + while (! empty ()) + { + tree_identifier *t = remove_front (); + delete t; + } + } + +// char *name (void) const; + + void mark_as_formal_parameters (void); + + void mark_varargs (void) + { marked_for_varargs = 1; } + + int takes_varargs (void) const + { return marked_for_varargs; } + + void mark_varargs_only (void) + { marked_for_varargs = -1; } + + int varargs_only (void) + { return (marked_for_varargs < 0); } + + void define_from_arg_vector (const Octave_object& args); + + int is_defined (void); + + Octave_object convert_to_const_vector (void); + +private: + int marked_for_varargs; +}; + +// Return lists. Used to hold the right hand sides of multiple +// assignment expressions. + +class +tree_return_list : public SLList +{ +public: + tree_return_list (void) : SLList () { } + tree_return_list (tree_index_expression *t) + : SLList () + { append (t); } + + ~tree_return_list (void) + { + while (! empty ()) + { + tree_index_expression *t = remove_front (); + delete t; + } + } +}; + +// List of expressions that make up a global statement. + +class +tree_global +{ +public: + tree_global (void) + { + ident = 0; + assign_expr = 0; + } + + tree_global (tree_identifier *id) + { + ident = id; + assign_expr = 0; + } + + tree_global (tree_simple_assignment_expression *ass) + { + ident = 0; + assign_expr = ass; + } + + ~tree_global (void) + { + delete ident; + delete assign_expr; + } + + void eval (void); + +private: + tree_identifier *ident; + tree_simple_assignment_expression *assign_expr; +}; + +class +tree_global_init_list : public SLList +{ +public: + tree_global_init_list (void) : SLList () { } + tree_global_init_list (tree_global *t) : SLList () + { append (t); } + + ~tree_global_init_list (void) + { + while (! empty ()) + { + tree_global *t = remove_front (); + delete t; + } + } + + void eval (void); +}; + +class +tree_if_clause +{ +public: + tree_if_clause (void) + { + expr = 0; + list = 0; + } + + tree_if_clause (tree_statement_list *l) + { + expr = 0; + list = l; + } + + tree_if_clause (tree_expression *e, tree_statement_list *l) + { + expr = e; + list = l; + } + + ~tree_if_clause (void) + { + delete expr; + delete list; + } + + int eval (void); + +private: + tree_expression *expr; + tree_statement_list *list; +}; + +class +tree_if_command_list : public SLList +{ +public: + tree_if_command_list (void) : SLList () { } + tree_if_command_list (tree_if_clause *t) : SLList () + { append (t); } + + ~tree_if_command_list (void) + { + while (! empty ()) + { + tree_if_clause *t = remove_front (); + delete t; + } + } + + void eval (void); +}; + +#endif + +/* +;;; Local Variables: *** +;;; mode: C++ *** +;;; page-delimiter: "^/\\*" *** +;;; End: *** +*/