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