pt-misc.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1994-2012 John W. Eaton
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, see
00019 <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026 
00027 #include "Cell.h"
00028 
00029 #include "defun.h"
00030 #include "error.h"
00031 #include "ov.h"
00032 #include "oct-lvalue.h"
00033 #include "pt-id.h"
00034 #include "pt-idx.h"
00035 #include "pt-misc.h"
00036 #include "pt-walk.h"
00037 #include "utils.h"
00038 
00039 // Parameter lists.
00040 
00041 tree_parameter_list::~tree_parameter_list (void)
00042 {
00043   while (! empty ())
00044     {
00045       iterator p = begin ();
00046       delete *p;
00047       erase (p);
00048     }
00049 }
00050 
00051 void
00052 tree_parameter_list::mark_as_formal_parameters (void)
00053 {
00054   for (iterator p = begin (); p != end (); p++)
00055     {
00056       tree_decl_elt *elt = *p;
00057       elt->mark_as_formal_parameter ();
00058     }
00059 }
00060 
00061 bool
00062 tree_parameter_list::validate (in_or_out type)
00063 {
00064   bool retval = true;
00065 
00066   std::set<std::string> dict;
00067 
00068   for (iterator p = begin (); p != end (); p++)
00069     {
00070       tree_decl_elt *elt = *p;
00071 
00072       tree_identifier *id = elt->ident ();
00073 
00074       if (id)
00075         {
00076           std::string name = id->name ();
00077 
00078           if (id->is_black_hole ())
00079             {
00080               if (type != in)
00081                 error ("invalid use of ~ in output list");
00082             }
00083           else if (dict.find (name) != dict.end ())
00084             {
00085               retval = false;
00086               error ("'%s' appears more than once in parameter list",
00087                      name.c_str ());
00088               break;
00089             }
00090           else
00091             dict.insert (name);
00092         }
00093     }
00094 
00095   if (! error_state)
00096     {
00097       std::string va_type = (type == in ? "varargin" : "varargout");
00098 
00099       size_t len = length ();
00100 
00101       if (len > 0)
00102         {
00103           tree_decl_elt *elt = back ();
00104 
00105           tree_identifier *id = elt->ident ();
00106 
00107           if (id && id->name () == va_type)
00108             {
00109               if (len == 1)
00110                 mark_varargs_only ();
00111               else
00112                 mark_varargs ();
00113 
00114               iterator p = end ();
00115               --p;
00116               delete *p;
00117               erase (p);
00118             }
00119         }
00120     }
00121 
00122   return retval;
00123 }
00124 
00125 void
00126 tree_parameter_list::initialize_undefined_elements (const std::string& warnfor,
00127                                                     int nargout, const octave_value& val)
00128 {
00129   bool warned = false;
00130 
00131   int count = 0;
00132 
00133   octave_value tmp = symbol_table::varval (".ignored.");
00134   const Matrix ignored = tmp.is_defined () ? tmp.matrix_value () : Matrix ();
00135 
00136   octave_idx_type k = 0;
00137 
00138   for (iterator p = begin (); p != end (); p++)
00139     {
00140       if (++count > nargout)
00141         break;
00142 
00143       tree_decl_elt *elt = *p;
00144 
00145       if (! elt->is_variable ())
00146         {
00147           if (! warned)
00148             {
00149               warned = true;
00150 
00151               while (k < ignored.numel ())
00152                 {
00153                   octave_idx_type l = ignored (k);
00154                   if (l == count)
00155                     {
00156                       warned = false;
00157                       break;
00158                     }
00159                   else if (l > count)
00160                     break;
00161                   else
00162                     k++;
00163                 }
00164 
00165               if (warned)
00166                 {
00167                   warning_with_id
00168                     ("Octave:undefined-return-values",
00169                      "%s: some elements in list of return values are undefined",
00170                      warnfor.c_str ());
00171                 }
00172             }
00173 
00174           octave_lvalue lval = elt->lvalue ();
00175 
00176           lval.assign (octave_value::op_asn_eq, val);
00177         }
00178     }
00179 }
00180 
00181 void
00182 tree_parameter_list::define_from_arg_vector (const octave_value_list& args)
00183 {
00184   int nargin = args.length ();
00185 
00186   int expected_nargin = length ();
00187 
00188   iterator p = begin ();
00189 
00190   for (int i = 0; i < expected_nargin; i++)
00191     {
00192       tree_decl_elt *elt = *p++;
00193 
00194       octave_lvalue ref = elt->lvalue ();
00195 
00196       if (i < nargin)
00197         {
00198           if (args(i).is_defined () && args(i).is_magic_colon ())
00199             {
00200               if (! elt->eval ())
00201                 {
00202                   ::error ("no default value for argument %d\n", i+1);
00203                   return;
00204                 }
00205             }
00206           else
00207             ref.define (args(i));
00208         }
00209       else
00210         elt->eval ();
00211     }
00212 }
00213 
00214 void
00215 tree_parameter_list::undefine (void)
00216 {
00217   int len = length ();
00218 
00219   iterator p = begin ();
00220 
00221   for (int i = 0; i < len; i++)
00222     {
00223       tree_decl_elt *elt = *p++;
00224 
00225       octave_lvalue ref = elt->lvalue ();
00226 
00227       ref.assign (octave_value::op_asn_eq, octave_value ());
00228     }
00229 }
00230 
00231 octave_value_list
00232 tree_parameter_list::convert_to_const_vector (int nargout,
00233                                               const Cell& varargout)
00234 {
00235   octave_idx_type vlen = varargout.numel ();
00236   int len = length ();
00237 
00238   // Special case. Will do a shallow copy.
00239   if (len == 0)
00240     return varargout;
00241   else if (nargout <= len)
00242     {
00243       octave_value_list retval (nargout);
00244 
00245       int i = 0;
00246 
00247       for (iterator p = begin (); p != end (); p++)
00248         {
00249           tree_decl_elt *elt = *p;
00250           if (elt->is_defined ())
00251             retval(i++) = elt->rvalue1 ();
00252           else
00253             break;
00254         }
00255 
00256       return retval;
00257     }
00258   else
00259     {
00260       octave_value_list retval (len + vlen);
00261 
00262       int i = 0;
00263 
00264       for (iterator p = begin (); p != end (); p++)
00265         {
00266           tree_decl_elt *elt = *p;
00267           retval(i++) = elt->rvalue1 ();
00268         }
00269 
00270       for (octave_idx_type j = 0; j < vlen; j++)
00271         retval(i++) = varargout(j);
00272 
00273       return retval;
00274     }
00275 }
00276 
00277 bool
00278 tree_parameter_list::is_defined (void)
00279 {
00280   bool status = true;
00281 
00282   for (iterator p = begin (); p != end (); p++)
00283     {
00284       tree_decl_elt *elt = *p;
00285 
00286       if (! elt->is_variable ())
00287         {
00288           status = false;
00289           break;
00290         }
00291     }
00292 
00293   return status;
00294 }
00295 
00296 tree_parameter_list *
00297 tree_parameter_list::dup (symbol_table::scope_id scope,
00298                           symbol_table::context_id context) const
00299 {
00300   tree_parameter_list *new_list = new tree_parameter_list ();
00301 
00302   if (takes_varargs ())
00303     new_list->mark_varargs ();
00304 
00305   for (const_iterator p = begin (); p != end (); p++)
00306     {
00307       const tree_decl_elt *elt = *p;
00308 
00309       new_list->append (elt->dup (scope, context));
00310     }
00311 
00312   return new_list;
00313 }
00314 
00315 void
00316 tree_parameter_list::accept (tree_walker& tw)
00317 {
00318   tw.visit_parameter_list (*this);
00319 }
00320 
00321 // Return lists.
00322 
00323 tree_return_list::~tree_return_list (void)
00324 {
00325   while (! empty ())
00326     {
00327       iterator p = begin ();
00328       delete *p;
00329       erase (p);
00330     }
00331 }
00332 
00333 tree_return_list *
00334 tree_return_list::dup (symbol_table::scope_id scope,
00335                        symbol_table::context_id context) const
00336 {
00337   tree_return_list *new_list = new tree_return_list ();
00338 
00339   for (const_iterator p = begin (); p != end (); p++)
00340     {
00341       const tree_index_expression *elt = *p;
00342 
00343       new_list->append (elt->dup (scope, context));
00344     }
00345 
00346   return new_list;
00347 }
00348 
00349 void
00350 tree_return_list::accept (tree_walker& tw)
00351 {
00352   tw.visit_return_list (*this);
00353 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines