Mercurial > hg > octave-lyh
annotate src/pt-select.cc @ 7767:71f068b22fcc
scope and context fixes for function handles
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 07 May 2008 13:45:30 -0400 |
parents | 745a8299c2b5 |
children | 3100283874d7 |
rev | line source |
---|---|
2982 | 1 /* |
2 | |
7017 | 3 Copyright (C) 1996, 1997, 2000, 2002, 2004, 2005, 2006, 2007 |
4 John W. Eaton | |
2982 | 5 |
6 This file is part of Octave. | |
7 | |
8 Octave is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
7016 | 10 Free Software Foundation; either version 3 of the License, or (at your |
11 option) any later version. | |
2982 | 12 |
13 Octave is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
7016 | 19 along with Octave; see the file COPYING. If not, see |
20 <http://www.gnu.org/licenses/>. | |
2982 | 21 |
22 */ | |
23 | |
24 #ifdef HAVE_CONFIG_H | |
25 #include <config.h> | |
26 #endif | |
27 | |
28 #include "error.h" | |
29 #include "oct-obj.h" | |
30 #include "ov.h" | |
31 #include "pt-cmd.h" | |
32 #include "pt-exp.h" | |
33 #include "pt-select.h" | |
34 #include "pt-stmt.h" | |
35 #include "pt-walk.h" | |
3724 | 36 #include "Cell.h" |
37 #include "ov-typeinfo.h" | |
2982 | 38 |
39 // If clauses. | |
40 | |
41 tree_if_clause::~tree_if_clause (void) | |
42 { | |
43 delete expr; | |
44 delete list; | |
3665 | 45 delete lead_comm; |
2982 | 46 } |
47 | |
48 int | |
49 tree_if_clause::eval (void) | |
50 { | |
51 if (is_else_clause () || expr->is_logically_true ("if")) | |
52 { | |
53 if (list) | |
54 list->eval (); | |
55 | |
56 return 1; | |
57 } | |
58 | |
59 return 0; | |
60 } | |
61 | |
5861 | 62 tree_if_clause * |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
63 tree_if_clause::dup (symbol_table::scope_id scope, |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
64 symbol_table::context_id context) |
5861 | 65 { |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
66 return new tree_if_clause (expr ? expr->dup (scope, context) : 0, |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
67 list ? list->dup (scope, context) : 0, |
5861 | 68 lead_comm ? lead_comm->dup () : 0); |
69 } | |
70 | |
2982 | 71 void |
72 tree_if_clause::accept (tree_walker& tw) | |
73 { | |
74 tw.visit_if_clause (*this); | |
75 } | |
76 | |
77 // List of if commands. | |
78 | |
79 void | |
80 tree_if_command_list::eval (void) | |
81 { | |
4219 | 82 for (iterator p = begin (); p != end (); p++) |
2982 | 83 { |
4219 | 84 tree_if_clause *t = *p; |
2982 | 85 |
86 if (t->eval () || error_state) | |
87 break; | |
88 } | |
89 } | |
90 | |
5861 | 91 tree_if_command_list * |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
92 tree_if_command_list::dup (symbol_table::scope_id scope, |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
93 symbol_table::context_id context) |
5861 | 94 { |
95 tree_if_command_list *new_icl = new tree_if_command_list (); | |
96 | |
97 for (iterator p = begin (); p != end (); p++) | |
98 { | |
99 tree_if_clause *elt = *p; | |
100 | |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
101 new_icl->append (elt ? elt->dup (scope, context) : 0); |
5861 | 102 } |
103 | |
104 return new_icl; | |
105 } | |
106 | |
2982 | 107 void |
108 tree_if_command_list::accept (tree_walker& tw) | |
109 { | |
110 tw.visit_if_command_list (*this); | |
111 } | |
112 | |
113 // If. | |
114 | |
115 tree_if_command::~tree_if_command (void) | |
116 { | |
117 delete list; | |
3665 | 118 delete lead_comm; |
119 delete trail_comm; | |
2982 | 120 } |
121 | |
122 void | |
123 tree_if_command::eval (void) | |
124 { | |
125 if (list) | |
126 list->eval (); | |
127 | |
3965 | 128 if (error_state) |
2982 | 129 ::error ("evaluating if command near line %d, column %d", |
130 line (), column ()); | |
131 } | |
132 | |
5861 | 133 tree_command * |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
134 tree_if_command::dup (symbol_table::scope_id scope, |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
135 symbol_table::context_id context) |
5861 | 136 { |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
137 return new tree_if_command (list ? list->dup (scope, context) : 0, |
5861 | 138 lead_comm ? lead_comm->dup () : 0, |
139 trail_comm ? trail_comm->dup () : 0, | |
140 line (), column ()); | |
141 } | |
142 | |
2982 | 143 void |
144 tree_if_command::accept (tree_walker& tw) | |
145 { | |
146 tw.visit_if_command (*this); | |
147 } | |
148 | |
149 // Switch cases. | |
150 | |
151 tree_switch_case::~tree_switch_case (void) | |
152 { | |
153 delete label; | |
154 delete list; | |
3665 | 155 delete lead_comm; |
2982 | 156 } |
157 | |
3724 | 158 |
159 // Compare two octave values, returning true if equal, false if not | |
5775 | 160 // FIXME --- should be member or friend of octave_value class. |
3724 | 161 |
162 static bool | |
163 equal (const octave_value& val, const octave_value& test) | |
2982 | 164 { |
165 bool retval = false; | |
166 | |
3724 | 167 // If there is no op_eq for these types, we can't compare values. |
168 | |
4223 | 169 if (val.rows () == test.rows () && val.columns () == test.columns ()) |
3724 | 170 { |
171 octave_value tmp = do_binary_op (octave_value::op_eq, val, test); | |
172 | |
173 if (! error_state && tmp.is_defined ()) | |
174 retval = tmp.is_true (); | |
175 } | |
176 | |
177 return retval; | |
178 } | |
179 | |
180 bool | |
181 tree_switch_case::label_matches (const octave_value& val) | |
182 { | |
2982 | 183 octave_value label_value = label->rvalue (); |
184 | |
3724 | 185 if (! error_state && label_value.is_defined() ) |
2982 | 186 { |
3724 | 187 if (label_value.is_cell ()) |
2982 | 188 { |
3724 | 189 Cell cell (label_value.cell_value ()); |
190 | |
5275 | 191 for (octave_idx_type i = 0; i < cell.rows (); i++) |
3724 | 192 { |
5275 | 193 for (octave_idx_type j = 0; j < cell.columns (); j++) |
3724 | 194 { |
195 bool match = equal (val, cell(i,j)); | |
2982 | 196 |
3724 | 197 if (error_state) |
198 { | |
199 eval_error (); | |
200 return false; | |
201 } | |
202 else if (match) | |
203 return true; | |
204 } | |
205 } | |
206 } | |
207 else | |
208 { | |
209 bool match = equal (val, label_value); | |
210 | |
211 if (error_state) | |
2982 | 212 { |
3724 | 213 eval_error (); |
214 return false; | |
2982 | 215 } |
216 else | |
3724 | 217 return match; |
2982 | 218 } |
219 } | |
220 else | |
221 eval_error (); | |
222 | |
3724 | 223 return false; |
2982 | 224 } |
225 | |
226 int | |
227 tree_switch_case::eval (const octave_value& val) | |
228 { | |
229 int retval = 0; | |
230 | |
231 if (is_default_case () || label_matches (val)) | |
232 { | |
233 if (list) | |
234 list->eval (); | |
235 | |
236 retval = 1; | |
237 } | |
238 | |
239 return retval; | |
240 } | |
241 | |
242 void | |
243 tree_switch_case::eval_error (void) | |
244 { | |
245 ::error ("evaluating switch case label"); | |
246 } | |
247 | |
5861 | 248 tree_switch_case * |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
249 tree_switch_case::dup (symbol_table::scope_id scope, |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
250 symbol_table::context_id context) |
5861 | 251 { |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
252 return new tree_switch_case (label ? label->dup (scope, context) : 0, |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
253 list ? list->dup (scope, context) : 0, |
5861 | 254 lead_comm ? lead_comm->dup () : 0); |
255 } | |
256 | |
2982 | 257 void |
258 tree_switch_case::accept (tree_walker& tw) | |
259 { | |
260 tw.visit_switch_case (*this); | |
261 } | |
262 | |
263 // List of switch cases. | |
264 | |
265 void | |
266 tree_switch_case_list::eval (const octave_value& val) | |
267 { | |
4219 | 268 for (iterator p = begin (); p != end (); p++) |
2982 | 269 { |
4219 | 270 tree_switch_case *t = *p; |
2982 | 271 |
272 if (t->eval (val) || error_state) | |
273 break; | |
274 } | |
275 } | |
276 | |
5861 | 277 tree_switch_case_list * |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
278 tree_switch_case_list::dup (symbol_table::scope_id scope, |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
279 symbol_table::context_id context) |
5861 | 280 { |
281 tree_switch_case_list *new_scl = new tree_switch_case_list (); | |
282 | |
283 for (iterator p = begin (); p != end (); p++) | |
284 { | |
285 tree_switch_case *elt = *p; | |
286 | |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
287 new_scl->append (elt ? elt->dup (scope, context) : 0); |
5861 | 288 } |
289 | |
290 return new_scl; | |
291 } | |
292 | |
2982 | 293 void |
294 tree_switch_case_list::accept (tree_walker& tw) | |
295 { | |
296 tw.visit_switch_case_list (*this); | |
297 } | |
298 | |
299 // Switch. | |
300 | |
301 tree_switch_command::~tree_switch_command (void) | |
302 { | |
303 delete expr; | |
304 delete list; | |
3665 | 305 delete lead_comm; |
306 delete trail_comm; | |
2982 | 307 } |
308 | |
309 void | |
310 tree_switch_command::eval (void) | |
311 { | |
312 if (expr) | |
313 { | |
314 octave_value val = expr->rvalue (); | |
315 | |
316 if (! error_state) | |
317 { | |
318 if (list) | |
319 list->eval (val); | |
320 | |
321 if (error_state) | |
322 eval_error (); | |
323 } | |
324 else | |
325 eval_error (); | |
326 } | |
327 else | |
328 ::error ("missing value in switch command near line %d, column %d", | |
329 line (), column ()); | |
330 } | |
331 | |
332 void | |
333 tree_switch_command::eval_error (void) | |
334 { | |
335 ::error ("evaluating switch command near line %d, column %d", | |
336 line (), column ()); | |
337 } | |
338 | |
5861 | 339 tree_command * |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
340 tree_switch_command::dup (symbol_table::scope_id scope, |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
341 symbol_table::context_id context) |
5861 | 342 { |
7767
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
343 return new tree_switch_command (expr ? expr->dup (scope, context) : 0, |
71f068b22fcc
scope and context fixes for function handles
John W. Eaton <jwe@octave.org>
parents:
7336
diff
changeset
|
344 list ? list->dup (scope, context) : 0, |
5861 | 345 lead_comm ? lead_comm->dup () : 0, |
346 trail_comm ? trail_comm->dup () : 0, | |
347 line (), column ()); | |
348 } | |
349 | |
2982 | 350 void |
351 tree_switch_command::accept (tree_walker& tw) | |
352 { | |
353 tw.visit_switch_command (*this); | |
354 } | |
355 | |
356 /* | |
357 ;;; Local Variables: *** | |
358 ;;; mode: C++ *** | |
359 ;;; End: *** | |
360 */ |