GNU Octave
3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
Main Page
Namespaces
Classes
Files
File List
File Members
•
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Pages
libinterp
parse-tree
pt-check.cc
Go to the documentation of this file.
1
/*
2
3
Copyright (C) 1996-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 "
error.h
"
28
#include "
input.h
"
29
#include "
ov-usr-fcn.h
"
30
#include "
pt-all.h
"
31
32
void
33
tree_checker::visit_argument_list
(
tree_argument_list
& lst)
34
{
35
tree_argument_list::iterator
p = lst.
begin
();
36
37
while
(p != lst.
end
())
38
{
39
tree_expression
*elt = *p++;
40
41
if
(elt)
42
{
43
if
(
do_lvalue_check
&& ! elt->
lvalue_ok
())
44
gripe
(
"invalid lvalue in multiple assignment"
, elt->
line
());
45
}
46
}
47
}
48
49
void
50
tree_checker::visit_binary_expression
(
tree_binary_expression
& expr)
51
{
52
tree_expression
*op1 = expr.
lhs
();
53
54
if
(op1)
55
op1->
accept
(*
this
);
56
57
tree_expression
*op2 = expr.
rhs
();
58
59
if
(op2)
60
op2->
accept
(*
this
);
61
}
62
63
void
64
tree_checker::visit_break_command
(
tree_break_command
&)
65
{
66
}
67
68
void
69
tree_checker::visit_colon_expression
(
tree_colon_expression
& expr)
70
{
71
tree_expression
*op1 = expr.
base
();
72
73
if
(op1)
74
op1->
accept
(*
this
);
75
76
tree_expression
*op3 = expr.
increment
();
77
78
if
(op3)
79
op3->
accept
(*
this
);
80
81
tree_expression
*op2 = expr.
limit
();
82
83
if
(op2)
84
op2->
accept
(*
this
);
85
}
86
87
void
88
tree_checker::visit_continue_command
(
tree_continue_command
&)
89
{
90
}
91
92
void
93
tree_checker::do_decl_command
(
tree_decl_command
& cmd)
94
{
95
tree_decl_init_list
*init_list = cmd.
initializer_list
();
96
97
if
(init_list)
98
init_list->
accept
(*
this
);
99
}
100
101
void
102
tree_checker::visit_global_command
(
tree_global_command
& cmd)
103
{
104
do_decl_command
(cmd);
105
}
106
107
void
108
tree_checker::visit_persistent_command
(
tree_persistent_command
& cmd)
109
{
110
do_decl_command
(cmd);
111
}
112
113
void
114
tree_checker::visit_decl_elt
(
tree_decl_elt
& cmd)
115
{
116
tree_identifier
*
id
= cmd.
ident
();
117
118
if
(
id
)
119
id
->
accept
(*
this
);
120
121
tree_expression
*expr = cmd.
expression
();
122
123
if
(expr)
124
expr->
accept
(*
this
);
125
}
126
127
void
128
tree_checker::visit_decl_init_list
(
tree_decl_init_list
& lst)
129
{
130
tree_decl_init_list::iterator
p = lst.
begin
();
131
132
while
(p != lst.
end
())
133
{
134
tree_decl_elt
*elt = *p++;
135
136
if
(elt)
137
elt->
accept
(*
this
);
138
}
139
}
140
141
void
142
tree_checker::visit_simple_for_command
(
tree_simple_for_command
& cmd)
143
{
144
tree_expression
*lhs = cmd.
left_hand_side
();
145
146
if
(lhs)
147
{
148
if
(! lhs->
lvalue_ok
())
149
gripe
(
"invalid lvalue in for command"
, cmd.
line
());
150
}
151
152
tree_expression
*expr = cmd.
control_expr
();
153
154
if
(expr)
155
expr->
accept
(*
this
);
156
157
tree_expression
*maxproc = cmd.
maxproc_expr
();
158
159
if
(maxproc)
160
maxproc->
accept
(*
this
);
161
162
tree_statement_list
*list = cmd.
body
();
163
164
if
(list)
165
list->
accept
(*
this
);
166
}
167
168
void
169
tree_checker::visit_complex_for_command
(
tree_complex_for_command
& cmd)
170
{
171
tree_argument_list
*lhs = cmd.
left_hand_side
();
172
173
if
(lhs)
174
{
175
int
len = lhs->
length
();
176
177
if
(len == 0 || len > 2)
178
gripe
(
"invalid number of output arguments in for command"
,
179
cmd.
line
());
180
181
do_lvalue_check
=
true
;
182
183
lhs->
accept
(*
this
);
184
185
do_lvalue_check =
false
;
186
}
187
188
tree_expression
*expr = cmd.
control_expr
();
189
190
if
(expr)
191
expr->
accept
(*
this
);
192
193
tree_statement_list
*list = cmd.
body
();
194
195
if
(list)
196
list->
accept
(*
this
);
197
}
198
199
void
200
tree_checker::visit_octave_user_script
(
octave_user_script
& fcn)
201
{
202
tree_statement_list
*cmd_list = fcn.
body
();
203
204
if
(cmd_list)
205
cmd_list->
accept
(*
this
);
206
}
207
208
void
209
tree_checker::visit_octave_user_function
(
octave_user_function
& fcn)
210
{
211
tree_statement_list
*cmd_list = fcn.
body
();
212
213
if
(cmd_list)
214
cmd_list->
accept
(*
this
);
215
}
216
217
void
218
tree_checker::visit_function_def
(
tree_function_def
& fdef)
219
{
220
octave_value
fcn = fdef.
function
();
221
222
octave_function
*
f
= fcn.
function_value
();
223
224
if
(f)
225
f->
accept
(*
this
);
226
}
227
228
void
229
tree_checker::visit_identifier
(
tree_identifier
&
/* id */
)
230
{
231
}
232
233
void
234
tree_checker::visit_if_clause
(
tree_if_clause
& cmd)
235
{
236
tree_expression
*expr = cmd.
condition
();
237
238
if
(expr)
239
expr->
accept
(*
this
);
240
241
tree_statement_list
*list = cmd.
commands
();
242
243
if
(list)
244
list->
accept
(*
this
);
245
}
246
247
void
248
tree_checker::visit_if_command
(
tree_if_command
& cmd)
249
{
250
tree_if_command_list
*list = cmd.
cmd_list
();
251
252
if
(list)
253
list->
accept
(*
this
);
254
}
255
256
void
257
tree_checker::visit_if_command_list
(
tree_if_command_list
& lst)
258
{
259
tree_if_command_list::iterator
p = lst.
begin
();
260
261
while
(p != lst.
end
())
262
{
263
tree_if_clause
*elt = *p++;
264
265
if
(elt)
266
elt->
accept
(*
this
);
267
}
268
}
269
270
void
271
tree_checker::visit_index_expression
(
tree_index_expression
& expr)
272
{
273
tree_expression
*e = expr.
expression
();
274
275
if
(e)
276
e->
accept
(*
this
);
277
278
std::list<tree_argument_list *> lst = expr.
arg_lists
();
279
280
std::list<tree_argument_list *>::iterator p = lst.begin ();
281
282
while
(p != lst.end ())
283
{
284
tree_argument_list
*elt = *p++;
285
286
if
(elt)
287
elt->
accept
(*
this
);
288
}
289
}
290
291
void
292
tree_checker::visit_matrix
(
tree_matrix
& lst)
293
{
294
tree_matrix::iterator
p = lst.
begin
();
295
296
while
(p != lst.
end
())
297
{
298
tree_argument_list
*elt = *p++;
299
300
if
(elt)
301
elt->
accept
(*
this
);
302
}
303
}
304
305
void
306
tree_checker::visit_cell
(
tree_cell
& lst)
307
{
308
tree_matrix::iterator
p = lst.
begin
();
309
310
while
(p != lst.
end
())
311
{
312
tree_argument_list
*elt = *p++;
313
314
if
(elt)
315
elt->
accept
(*
this
);
316
}
317
}
318
319
void
320
tree_checker::visit_multi_assignment
(
tree_multi_assignment
& expr)
321
{
322
tree_argument_list
*lhs = expr.
left_hand_side
();
323
324
if
(lhs)
325
{
326
do_lvalue_check
=
true
;
327
328
lhs->
accept
(*
this
);
329
330
do_lvalue_check
=
false
;
331
}
332
333
tree_expression
*rhs = expr.
right_hand_side
();
334
335
if
(rhs)
336
rhs->
accept
(*
this
);
337
}
338
339
void
340
tree_checker::visit_no_op_command
(
tree_no_op_command
&
/* cmd */
)
341
{
342
}
343
344
void
345
tree_checker::visit_anon_fcn_handle
(
tree_anon_fcn_handle
&
/* afh */
)
346
{
347
}
348
349
void
350
tree_checker::visit_constant
(
tree_constant
&
/* val */
)
351
{
352
}
353
354
void
355
tree_checker::visit_fcn_handle
(
tree_fcn_handle
&
/* fh */
)
356
{
357
}
358
359
void
360
tree_checker::visit_parameter_list
(
tree_parameter_list
& lst)
361
{
362
tree_parameter_list::iterator
p = lst.
begin
();
363
364
while
(p != lst.
end
())
365
{
366
tree_decl_elt
*elt = *p++;
367
368
if
(elt)
369
elt->
accept
(*
this
);
370
}
371
}
372
373
void
374
tree_checker::visit_postfix_expression
(
tree_postfix_expression
& expr)
375
{
376
tree_expression
*e = expr.
operand
();
377
378
if
(e)
379
e->
accept
(*
this
);
380
}
381
382
void
383
tree_checker::visit_prefix_expression
(
tree_prefix_expression
& expr)
384
{
385
tree_expression
*e = expr.
operand
();
386
387
if
(e)
388
e->
accept
(*
this
);
389
}
390
391
void
392
tree_checker::visit_return_command
(
tree_return_command
&)
393
{
394
}
395
396
void
397
tree_checker::visit_return_list
(
tree_return_list
& lst)
398
{
399
tree_return_list::iterator
p = lst.
begin
();
400
401
while
(p != lst.
end
())
402
{
403
tree_index_expression
*elt = *p++;
404
405
if
(elt)
406
elt->
accept
(*
this
);
407
}
408
}
409
410
void
411
tree_checker::visit_simple_assignment
(
tree_simple_assignment
& expr)
412
{
413
tree_expression
*lhs = expr.
left_hand_side
();
414
415
if
(lhs)
416
{
417
if
(! lhs->
lvalue_ok
())
418
gripe
(
"invalid lvalue in assignment"
, expr.
line
());
419
}
420
421
tree_expression
*rhs = expr.
right_hand_side
();
422
423
if
(rhs)
424
rhs->
accept
(*
this
);
425
}
426
427
void
428
tree_checker::visit_statement
(
tree_statement
& stmt)
429
{
430
tree_command
*cmd = stmt.
command
();
431
432
if
(cmd)
433
cmd->
accept
(*
this
);
434
else
435
{
436
tree_expression
*expr = stmt.
expression
();
437
438
if
(expr)
439
expr->
accept
(*
this
);
440
}
441
}
442
443
void
444
tree_checker::visit_statement_list
(
tree_statement_list
& lst)
445
{
446
for
(
tree_statement_list::iterator
p = lst.
begin
(); p != lst.
end
(); p++)
447
{
448
tree_statement
*elt = *p;
449
450
if
(elt)
451
elt->
accept
(*
this
);
452
}
453
}
454
455
void
456
tree_checker::visit_switch_case
(
tree_switch_case
& cs)
457
{
458
tree_expression
*label = cs.
case_label
();
459
460
if
(label)
461
label->
accept
(*
this
);
462
463
tree_statement_list
*list = cs.
commands
();
464
465
if
(list)
466
list->
accept
(*
this
);
467
}
468
469
void
470
tree_checker::visit_switch_case_list
(
tree_switch_case_list
& lst)
471
{
472
tree_switch_case_list::iterator
p = lst.
begin
();
473
474
while
(p != lst.
end
())
475
{
476
tree_switch_case
*elt = *p++;
477
478
if
(elt)
479
elt->
accept
(*
this
);
480
}
481
}
482
483
void
484
tree_checker::visit_switch_command
(
tree_switch_command
& cmd)
485
{
486
tree_expression
*expr = cmd.
switch_value
();
487
488
if
(expr)
489
expr->
accept
(*
this
);
490
491
tree_switch_case_list
*list = cmd.
case_list
();
492
493
if
(list)
494
list->
accept
(*
this
);
495
}
496
497
void
498
tree_checker::visit_try_catch_command
(
tree_try_catch_command
& cmd)
499
{
500
tree_statement_list
*try_code = cmd.
body
();
501
502
tree_identifier
*expr_id = cmd.
identifier
();
503
504
if
(expr_id)
505
{
506
if
(! expr_id->
lvalue_ok
())
507
gripe
(
"invalid lvalue used for identifier in try-catch command"
,
508
cmd.
line
());
509
}
510
511
if
(try_code)
512
try_code->
accept
(*
this
);
513
514
tree_statement_list
*catch_code = cmd.
cleanup
();
515
516
if
(catch_code)
517
catch_code->
accept
(*
this
);
518
}
519
520
void
521
tree_checker::visit_unwind_protect_command
(
tree_unwind_protect_command
& cmd)
522
{
523
tree_statement_list
*unwind_protect_code = cmd.
body
();
524
525
if
(unwind_protect_code)
526
unwind_protect_code->
accept
(*
this
);
527
528
tree_statement_list
*cleanup_code = cmd.
cleanup
();
529
530
if
(cleanup_code)
531
cleanup_code->
accept
(*
this
);
532
}
533
534
void
535
tree_checker::visit_while_command
(
tree_while_command
& cmd)
536
{
537
tree_expression
*expr = cmd.
condition
();
538
539
if
(expr)
540
expr->
accept
(*
this
);
541
542
tree_statement_list
*list = cmd.
body
();
543
544
if
(list)
545
list->
accept
(*
this
);
546
}
547
548
void
549
tree_checker::visit_do_until_command
(
tree_do_until_command
& cmd)
550
{
551
tree_statement_list
*list = cmd.
body
();
552
553
if
(list)
554
list->
accept
(*
this
);
555
556
tree_expression
*expr = cmd.
condition
();
557
558
if
(expr)
559
expr->
accept
(*
this
);
560
}
561
562
void
563
tree_checker::gripe
(
const
std::string& msg,
int
line
)
564
{
565
if
(
file_name
.empty ())
566
error
(
"%s"
, msg.c_str ());
567
else
568
error
(
"%s: %d: %s"
,
file_name
.c_str (), line, msg.c_str ());
569
}
Generated on Mon Dec 30 2013 03:04:37 for GNU Octave by
1.8.1.2