GNU Octave  4.2.1
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-arg-list.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 1996-2017 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 #if defined (HAVE_CONFIG_H)
24 # include "config.h"
25 #endif
26 
27 #include <iostream>
28 #include <string>
29 
30 #include "str-vec.h"
31 
32 #include "defun.h"
33 #include "error.h"
34 #include "oct-lvalue.h"
35 #include "ovl.h"
36 #include "ov.h"
37 #include "ov-usr-fcn.h"
38 #include "parse.h"
39 #include "pt-arg-list.h"
40 #include "pt-exp.h"
41 #include "pt-id.h"
42 #include "pt-pr-code.h"
43 #include "pt-walk.h"
44 #include "interpreter.h"
45 #include "unwind-prot.h"
46 
47 // Argument lists.
48 
50 {
51  while (! empty ())
52  {
53  iterator p = begin ();
54  delete *p;
55  erase (p);
56  }
57 }
58 
59 bool
61 {
62  for (const_iterator p = begin (); p != end (); p++)
63  {
64  tree_expression *elt = *p;
65 
66  if (elt && elt->has_magic_end ())
67  return true;
68  }
69 
70  return false;
71 }
72 
73 void
75 {
77 
78  if (! list_includes_magic_end && s && s->has_magic_end ())
80 
81  if (! list_includes_magic_tilde && s && s->is_identifier ())
82  {
83  tree_identifier *id = dynamic_cast<tree_identifier *> (s);
84  list_includes_magic_tilde = id && id->is_black_hole ();
85  }
86 }
87 
88 bool
90 {
91  for (const_iterator p = begin (); p != end (); p++)
92  {
93  tree_expression *elt = *p;
94 
95  if (! elt->is_constant ())
96  return false;
97  }
98 
99  return true;
100 }
101 
102 bool
104 {
105  bool retval = true;
106 
107  for (const_iterator p = begin (); p != end (); p++)
108  {
109  tree_expression *elt = *p;
110 
111  // There is no need for a separate check for the magic "~" because
112  // it represented by tree_black_hole, and that is derived from
113  // tree_identifier.
114 
115  if (! (elt->is_identifier () || elt->is_index_expression ()))
116  {
117  retval = false;
118  break;
119  }
120  }
121 
122  return retval;
123 }
124 
125 static const octave_value *indexed_object = 0;
126 static int index_position = 0;
127 static int num_indices = 0;
128 
129 // END is documented in op-kw-docs.
130 DEFCONSTFUN (end, , ,
131  doc: /* -*- texinfo -*-
132 @deftypefn {} {} end
133 Last element of an array or the end of any @code{for}, @code{parfor},
134 @code{if}, @code{do}, @code{while}, @code{function}, @code{switch},
135 @code{try}, or @code{unwind_protect} block.
136 
137 As an index of an array, the magic index @qcode{"end"} refers to the
138 last valid entry in an indexing operation.
139 
140 Example:
141 
142 @example
143 @group
144 @var{x} = [ 1 2 3
145  4 5 6 ];
146 @var{x}(1,end)
147  @result{} 3
148 @var{x}(end,1)
149  @result{} 4
150 @var{x}(end,end)
151  @result{} 6
152 @end group
153 @end example
154 @seealso{for, parfor, if, do, while, function, switch, try, unwind_protect}
155 @end deftypefn */)
156 {
158 
159  if (! indexed_object)
160  error ("invalid use of end");
161 
162  if (indexed_object->is_object ())
163  {
165 
166  args(2) = num_indices;
167  args(1) = index_position + 1;
168  args(0) = *indexed_object;
169 
170  std::string class_name = indexed_object->class_name ();
171 
172  octave_value meth = symbol_table::find_method ("end", class_name);
173 
174  if (meth.is_defined ())
175  return feval (meth.function_value (), args, 1);
176  }
177 
178  dim_vector dv = indexed_object->dims ();
179  int ndims = dv.ndims ();
180 
181  if (num_indices < ndims)
182  {
183  for (int i = num_indices; i < ndims; i++)
184  dv(num_indices-1) *= dv(i);
185 
186  if (num_indices == 1)
187  {
188  ndims = 2;
189  dv.resize (ndims);
190  dv(1) = 1;
191  }
192  else
193  {
194  ndims = num_indices;
195  dv.resize (ndims);
196  }
197  }
198 
199  if (index_position < ndims)
200  retval = dv(index_position);
201  else
202  retval = 1;
203 
204  return retval;
205 }
206 
209 {
210  // END doesn't make sense for functions. Maybe we need a different
211  // way of asking an octave_value object this question?
212 
213  bool stash_object = (list_includes_magic_end
214  && object
215  && ! (object->is_function ()
216  || object->is_function_handle ()));
217 
219 
220  if (stash_object)
221  {
222  frame.protect_var (indexed_object);
223 
224  indexed_object = object;
225  }
226 
227  int len = length ();
228 
229  std::list<octave_value_list> args;
230 
231  iterator p = begin ();
232  for (int k = 0; k < len; k++)
233  {
234  if (stash_object)
235  {
236  frame.protect_var (index_position);
237  frame.protect_var (num_indices);
238 
239  index_position = k;
240  num_indices = len;
241  }
242 
243  tree_expression *elt = *p++;
244 
245  if (elt)
246  {
247  octave_value tmp = elt->rvalue1 ();
248 
249  if (tmp.is_cs_list ())
250  args.push_back (tmp.list_value ());
251  else if (tmp.is_defined ())
252  args.push_back (tmp);
253  }
254  else
255  {
256  args.push_back (octave_value ());
257  break;
258  }
259  }
260 
261  return args;
262 }
263 
264 std::list<octave_lvalue>
266 {
267  std::list<octave_lvalue> retval;
268 
270  p != end ();
271  p++)
272  {
273  tree_expression *elt = *p;
274 
275  retval.push_back (elt->lvalue ());
276  }
277 
278  return retval;
279 }
280 
283 {
284  int len = length ();
285 
286  string_vector retval (len);
287 
288  int k = 0;
289 
290  for (const_iterator p = begin (); p != end (); p++)
291  {
292  tree_expression *elt = *p;
293 
294  retval(k++) = elt->str_print_code ();
295  }
296 
297  return retval;
298 }
299 
300 std::list<std::string>
302 {
303  std::list<std::string> retval;
304 
305  for (const_iterator p = begin (); p != end (); p++)
306  {
307  tree_expression *elt = *p;
308 
309  if (elt->is_identifier ())
310  {
311  tree_identifier *id = dynamic_cast<tree_identifier *> (elt);
312 
313  retval.push_back (id->name ());
314  }
315  else if (elt->is_index_expression ())
316  {
317  tree_index_expression *idx_expr
318  = dynamic_cast<tree_index_expression *> (elt);
319 
320  retval.push_back (idx_expr->name ());
321  }
322  }
323 
324  return retval;
325 }
326 
330 {
331  tree_argument_list *new_list = new tree_argument_list ();
332 
335 
336  for (const_iterator p = begin (); p != end (); p++)
337  {
338  const tree_expression *elt = *p;
339 
340  new_list->append (elt ? elt->dup (scope, context) : 0);
341  }
342 
343  return new_list;
344 }
345 
346 void
348 {
349  tw.visit_argument_list (*this);
350 }
std::list< octave_lvalue > lvalue_list(void)
bool is_object(void) const
Definition: ov.h:593
virtual bool has_magic_end(void) const =0
virtual bool is_constant(void) const
Definition: pt-exp.h:55
static int num_indices
Definition: pt-arg-list.cc:127
static octave_value find_method(const std::string &name, const std::string &dispatch_type)
Definition: symtab.h:1495
bool all_elements_are_constant(void) const
Definition: pt-arg-list.cc:89
octave_value_list convert_to_const_vector(const octave_value *object=0)
bool is_defined(void) const
Definition: ov.h:536
bool list_includes_magic_tilde
Definition: pt-arg-list.h:101
for large enough k
Definition: lu.cc:606
void resize(int n, int fill_value=0)
Definition: dim-vector.h:316
void protect_var(T &var)
virtual tree_expression * dup(symbol_table::scope_id, symbol_table::context_id context) const =0
void error(const char *fmt,...)
Definition: error.cc:570
std::list< tree_expression * >::iterator iterator
Definition: base-list.h:40
static int index_position
Definition: pt-arg-list.cc:126
iterator erase(iterator pos)
Definition: base-list.h:52
s
Definition: file-io.cc:2682
std::string name(void) const
Definition: pt-idx.cc:145
JNIEnv void * args
Definition: ov-java.cc:67
bool has_magic_end(void) const
Definition: pt-arg-list.cc:60
string_vector get_arg_names(void) const
bool list_includes_magic_end
Definition: pt-arg-list.h:99
static llvm::LLVMContext & context
Definition: jit-typeinfo.cc:76
void append(const element_type &s)
Definition: pt-arg-list.cc:74
std::string name(void) const
Definition: pt-id.h:67
virtual bool is_index_expression(void) const
Definition: pt-exp.h:63
virtual void visit_argument_list(tree_argument_list &)=0
tree_argument_list(void)
Definition: pt-arg-list.h:50
double tmp
Definition: data.cc:6300
#define DEFCONSTFUN(name, args_name, nargout_name, doc)
Definition: defun.h:58
octave_value retval
Definition: data.cc:6294
bool is_valid_lvalue_list(void) const
Definition: pt-arg-list.cc:103
dim_vector dims(void) const
Definition: ov.h:486
feval(ar{f}, 1) esult
Definition: oct-parse.cc:8829
octave_function * function_value(bool silent=false) const
Definition: ov.cc:1705
void accept(tree_walker &tw)
octave::unwind_protect frame
Definition: graphics.cc:11584
static const octave_value * indexed_object
Definition: pt-arg-list.cc:125
std::string str_print_code(void)
Definition: pt.cc:40
virtual octave_value rvalue1(int nargout=1)
Definition: pt-exp.cc:54
std::list< tree_expression * >::const_iterator const_iterator
Definition: base-list.h:41
tree_argument_list * dup(symbol_table::scope_id scope, symbol_table::context_id context) const
=val(i)}if ode{val(i)}occurs in table i
Definition: lookup.cc:239
p
Definition: lu.cc:138
std::list< std::string > variable_names(void) const
bool is_cs_list(void) const
Definition: ov.h:602
virtual octave_lvalue lvalue(void)
Definition: pt-exp.cc:72
octave_idx_type ndims(void) const
Number of dimensions.
Definition: dim-vector.h:301
std::string class_name(void) const
Definition: ov.h:1234
ots The first example below creates an uninitialized object
Definition: ov-java.cc:2837
octave_value_list list_value(void) const
Definition: ov.cc:1741
void append(const elt_type &s)
Definition: base-list.h:110
Vector representing the dimensions (size) of an Array.
Definition: dim-vector.h:87
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:854
dim_vector dv
Definition: sub2ind.cc:263
virtual bool is_identifier(void) const
Definition: pt-exp.h:61