GNU Octave  3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
pt-misc.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1994-2013 John W. Eaton
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 #include "Cell.h"
28 
29 #include "defun.h"
30 #include "error.h"
31 #include "ov.h"
32 #include "oct-lvalue.h"
33 #include "pt-id.h"
34 #include "pt-idx.h"
35 #include "pt-misc.h"
36 #include "pt-walk.h"
37 #include "utils.h"
38 
39 // Parameter lists.
40 
42 {
43  while (! empty ())
44  {
45  iterator p = begin ();
46  delete *p;
47  erase (p);
48  }
49 }
50 
51 void
53 {
54  for (iterator p = begin (); p != end (); p++)
55  {
56  tree_decl_elt *elt = *p;
58  }
59 }
60 
61 bool
63 {
64  bool retval = true;
65 
66  std::set<std::string> dict;
67 
68  for (iterator p = begin (); p != end (); p++)
69  {
70  tree_decl_elt *elt = *p;
71 
72  tree_identifier *id = elt->ident ();
73 
74  if (id)
75  {
76  std::string name = id->name ();
77 
78  if (id->is_black_hole ())
79  {
80  if (type != in)
81  error ("invalid use of ~ in output list");
82  }
83  else if (dict.find (name) != dict.end ())
84  {
85  retval = false;
86  error ("'%s' appears more than once in parameter list",
87  name.c_str ());
88  break;
89  }
90  else
91  dict.insert (name);
92  }
93  }
94 
95  if (! error_state)
96  {
97  std::string va_type = (type == in ? "varargin" : "varargout");
98 
99  size_t len = length ();
100 
101  if (len > 0)
102  {
103  tree_decl_elt *elt = back ();
104 
105  tree_identifier *id = elt->ident ();
106 
107  if (id && id->name () == va_type)
108  {
109  if (len == 1)
111  else
112  mark_varargs ();
113 
114  iterator p = end ();
115  --p;
116  delete *p;
117  erase (p);
118  }
119  }
120  }
121 
122  return retval;
123 }
124 
125 void
127  int nargout,
128  const octave_value& val)
129 {
130  bool warned = false;
131 
132  int count = 0;
133 
134  octave_value tmp = symbol_table::varval (".ignored.");
135  const Matrix ignored = tmp.is_defined () ? tmp.matrix_value () : Matrix ();
136 
137  octave_idx_type k = 0;
138 
139  for (iterator p = begin (); p != end (); p++)
140  {
141  if (++count > nargout)
142  break;
143 
144  tree_decl_elt *elt = *p;
145 
146  if (! elt->is_variable ())
147  {
148  if (! warned)
149  {
150  warned = true;
151 
152  while (k < ignored.numel ())
153  {
154  octave_idx_type l = ignored (k);
155  if (l == count)
156  {
157  warned = false;
158  break;
159  }
160  else if (l > count)
161  break;
162  else
163  k++;
164  }
165 
166  if (warned)
167  {
169  ("Octave:undefined-return-values",
170  "%s: some elements in list of return values are undefined",
171  warnfor.c_str ());
172  }
173  }
174 
175  octave_lvalue lval = elt->lvalue ();
176 
177  lval.assign (octave_value::op_asn_eq, val);
178  }
179  }
180 }
181 
182 void
184 {
185  int nargin = args.length ();
186 
187  int expected_nargin = length ();
188 
189  iterator p = begin ();
190 
191  for (int i = 0; i < expected_nargin; i++)
192  {
193  tree_decl_elt *elt = *p++;
194 
195  octave_lvalue ref = elt->lvalue ();
196 
197  if (i < nargin)
198  {
199  if (args(i).is_defined () && args(i).is_magic_colon ())
200  {
201  if (! elt->eval ())
202  {
203  ::error ("no default value for argument %d\n", i+1);
204  return;
205  }
206  }
207  else
208  ref.define (args(i));
209  }
210  else
211  elt->eval ();
212  }
213 }
214 
215 void
217 {
218  int len = length ();
219 
220  iterator p = begin ();
221 
222  for (int i = 0; i < len; i++)
223  {
224  tree_decl_elt *elt = *p++;
225 
226  octave_lvalue ref = elt->lvalue ();
227 
229  }
230 }
231 
232 std::list<std::string>
234 {
235  std::list<std::string> retval;
236 
237  for (const_iterator p = begin (); p != end (); p++)
238  {
239  tree_decl_elt *elt = *p;
240 
241  retval.push_back (elt->name ());
242  }
243 
244  return retval;
245 }
246 
249  const Cell& varargout)
250 {
251  octave_idx_type vlen = varargout.numel ();
252  int len = length ();
253 
254  // Special case. Will do a shallow copy.
255  if (len == 0)
256  return varargout;
257  else if (nargout <= len)
258  {
259  octave_value_list retval (nargout);
260 
261  int i = 0;
262 
263  for (iterator p = begin (); p != end (); p++)
264  {
265  tree_decl_elt *elt = *p;
266  if (elt->is_defined ())
267  retval(i++) = elt->rvalue1 ();
268  else
269  break;
270  }
271 
272  return retval;
273  }
274  else
275  {
276  octave_value_list retval (len + vlen);
277 
278  int i = 0;
279 
280  for (iterator p = begin (); p != end (); p++)
281  {
282  tree_decl_elt *elt = *p;
283  retval(i++) = elt->rvalue1 ();
284  }
285 
286  for (octave_idx_type j = 0; j < vlen; j++)
287  retval(i++) = varargout(j);
288 
289  return retval;
290  }
291 }
292 
293 bool
295 {
296  bool status = true;
297 
298  for (iterator p = begin (); p != end (); p++)
299  {
300  tree_decl_elt *elt = *p;
301 
302  if (! elt->is_variable ())
303  {
304  status = false;
305  break;
306  }
307  }
308 
309  return status;
310 }
311 
315 {
316  tree_parameter_list *new_list = new tree_parameter_list ();
317 
318  if (takes_varargs ())
319  new_list->mark_varargs ();
320 
321  for (const_iterator p = begin (); p != end (); p++)
322  {
323  const tree_decl_elt *elt = *p;
324 
325  new_list->append (elt->dup (scope, context));
326  }
327 
328  return new_list;
329 }
330 
331 void
333 {
334  tw.visit_parameter_list (*this);
335 }
336 
337 // Return lists.
338 
340 {
341  while (! empty ())
342  {
343  iterator p = begin ();
344  delete *p;
345  erase (p);
346  }
347 }
348 
352 {
353  tree_return_list *new_list = new tree_return_list ();
354 
355  for (const_iterator p = begin (); p != end (); p++)
356  {
357  const tree_index_expression *elt = *p;
358 
359  new_list->append (elt->dup (scope, context));
360  }
361 
362  return new_list;
363 }
364 
365 void
367 {
368  tw.visit_return_list (*this);
369 }