Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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
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
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 }