comparison libinterp/parse-tree/pt-arg-list.cc @ 15195:2fc554ffbc28

split libinterp from src * libinterp: New directory. Move all files from src directory here except Makefile.am, main.cc, main-cli.cc, mkoctfile.in.cc, mkoctfilr.in.sh, octave-config.in.cc, octave-config.in.sh. * libinterp/Makefile.am: New file, extracted from src/Makefile.am. * src/Makefile.am: Delete everything except targets and definitions needed to build and link main and utility programs. * Makefile.am (SUBDIRS): Include libinterp in the list. * autogen.sh: Run config-module.sh in libinterp/dldfcn directory, not src/dldfcn directory. * configure.ac (AC_CONFIG_SRCDIR): Use libinterp/octave.cc, not src/octave.cc. (DL_LDFLAGS, LIBOCTINTERP): Use libinterp, not src. (AC_CONFIG_FILES): Include libinterp/Makefile in the list. * find-docstring-files.sh: Look in libinterp, not src. * gui/src/Makefile.am (liboctgui_la_CPPFLAGS): Find header files in libinterp, not src.
author John W. Eaton <jwe@octave.org>
date Sat, 18 Aug 2012 16:23:39 -0400
parents src/parse-tree/pt-arg-list.cc@46b19589b593
children 3389152014ca
comparison
equal deleted inserted replaced
15194:0f0b795044c3 15195:2fc554ffbc28
1 /*
2
3 Copyright (C) 1996-2012 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 <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 "oct-obj.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 "toplev.h"
45 #include "unwind-prot.h"
46
47 // Argument lists.
48
49 tree_argument_list::~tree_argument_list (void)
50 {
51 while (! empty ())
52 {
53 iterator p = begin ();
54 delete *p;
55 erase (p);
56 }
57 }
58
59 bool
60 tree_argument_list::has_magic_end (void) const
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
74 tree_argument_list::append (const element_type& s)
75 {
76 octave_base_list<tree_expression *>::append (s);
77
78 if (! list_includes_magic_end && s && s->has_magic_end ())
79 list_includes_magic_end = true;
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
89 tree_argument_list::all_elements_are_constant (void) const
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 static const octave_value *indexed_object = 0;
103 static int index_position = 0;
104 static int num_indices = 0;
105
106 DEFCONSTFUN (__end__, , ,
107 "internal function")
108 {
109 octave_value retval;
110
111 if (indexed_object)
112 {
113 if (indexed_object->is_object ())
114 {
115 octave_value_list args;
116
117 args(2) = num_indices;
118 args(1) = index_position + 1;
119 args(0) = *indexed_object;
120
121 std::string class_name = indexed_object->class_name ();
122
123 octave_value meth = symbol_table::find_method ("end", class_name);
124
125 if (meth.is_defined ())
126 return feval (meth.function_value (), args, 1);
127 }
128
129 dim_vector dv = indexed_object->dims ();
130 int ndims = dv.length ();
131
132 if (num_indices < ndims)
133 {
134 for (int i = num_indices; i < ndims; i++)
135 dv(num_indices-1) *= dv(i);
136
137 if (num_indices == 1)
138 {
139 ndims = 2;
140 dv.resize (ndims);
141 dv(1) = 1;
142 }
143 else
144 {
145 ndims = num_indices;
146 dv.resize (ndims);
147 }
148 }
149
150 if (index_position < ndims)
151 retval = dv(index_position);
152 else
153 retval = 1;
154 }
155 else
156 ::error ("invalid use of end");
157
158 return retval;
159 }
160
161 octave_value_list
162 tree_argument_list::convert_to_const_vector (const octave_value *object)
163 {
164 // END doesn't make sense for functions. Maybe we need a different
165 // way of asking an octave_value object this question?
166
167 bool stash_object = (list_includes_magic_end
168 && object
169 && ! (object->is_function ()
170 || object->is_function_handle ()));
171
172 unwind_protect frame;
173
174 if (stash_object)
175 {
176 frame.protect_var (indexed_object);
177
178 indexed_object = object;
179 }
180
181 int len = length ();
182
183 std::list<octave_value_list> args;
184
185 iterator p = begin ();
186 for (int k = 0; k < len; k++)
187 {
188 if (stash_object)
189 {
190 frame.protect_var (index_position);
191 frame.protect_var (num_indices);
192
193 index_position = k;
194 num_indices = len;
195 }
196
197 tree_expression *elt = *p++;
198
199 if (elt)
200 {
201 octave_value tmp = elt->rvalue1 ();
202
203 if (error_state)
204 {
205 ::error ("evaluating argument list element number %d", k+1);
206 args.clear ();
207 break;
208 }
209 else
210 {
211 if (tmp.is_cs_list ())
212 args.push_back (tmp.list_value ());
213 else if (tmp.is_defined ())
214 args.push_back (tmp);
215 }
216 }
217 else
218 {
219 args.push_back (octave_value ());
220 break;
221 }
222 }
223
224 return args;
225 }
226
227 std::list<octave_lvalue>
228 tree_argument_list::lvalue_list (void)
229 {
230 std::list<octave_lvalue> retval;
231
232 for (tree_argument_list::iterator p = begin ();
233 p != end ();
234 p++)
235 {
236 tree_expression *elt = *p;
237
238 retval.push_back (elt->lvalue ());
239 }
240
241 return retval;
242 }
243
244 string_vector
245 tree_argument_list::get_arg_names (void) const
246 {
247 int len = length ();
248
249 string_vector retval (len);
250
251 int k = 0;
252
253 for (const_iterator p = begin (); p != end (); p++)
254 {
255 tree_expression *elt = *p;
256
257 retval(k++) = elt->str_print_code ();
258 }
259
260 return retval;
261 }
262
263 tree_argument_list *
264 tree_argument_list::dup (symbol_table::scope_id scope,
265 symbol_table::context_id context) const
266 {
267 tree_argument_list *new_list = new tree_argument_list ();
268
269 new_list->list_includes_magic_end = list_includes_magic_end;
270 new_list->simple_assign_lhs = simple_assign_lhs;
271
272 for (const_iterator p = begin (); p != end (); p++)
273 {
274 const tree_expression *elt = *p;
275
276 new_list->append (elt ? elt->dup (scope, context) : 0);
277 }
278
279 return new_list;
280 }
281
282 void
283 tree_argument_list::accept (tree_walker& tw)
284 {
285 tw.visit_argument_list (*this);
286 }