Mercurial > hg > octave-lyh
annotate src/pt-pr-code.cc @ 7922:935be827eaf8
error for NaN values in & and | expressions
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 11 Jul 2008 14:56:30 -0400 |
parents | 5b4d278ec828 |
children | 73c4516fae10 |
rev | line source |
---|---|
2123 | 1 /* |
2 | |
7017 | 3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, |
4 2005, 2006, 2007 John W. Eaton | |
2123 | 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. | |
2123 | 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/>. | |
2123 | 21 |
22 */ | |
23 | |
24 #ifdef HAVE_CONFIG_H | |
25 #include <config.h> | |
26 #endif | |
27 | |
3665 | 28 #include <cctype> |
29 | |
3503 | 30 #include <iostream> |
2123 | 31 |
3665 | 32 #include "comment-list.h" |
2123 | 33 #include "error.h" |
2969 | 34 #include "ov-usr-fcn.h" |
2123 | 35 #include "pr-output.h" |
2988 | 36 #include "pt-all.h" |
2123 | 37 |
38 void | |
5861 | 39 tree_print_code::visit_anon_fcn_handle (tree_anon_fcn_handle& afh) |
40 { | |
41 indent (); | |
42 | |
43 print_parens (afh, "("); | |
44 | |
45 os << "@("; | |
46 | |
47 tree_parameter_list *param_list = afh.parameter_list (); | |
48 | |
49 if (param_list) | |
50 param_list->accept (*this); | |
51 | |
52 os << ") "; | |
53 | |
54 tree_statement_list *body = afh.body (); | |
55 | |
56 if (body) | |
57 body->accept (*this); | |
58 | |
59 print_parens (afh, ")"); | |
60 } | |
61 | |
62 void | |
2123 | 63 tree_print_code::visit_argument_list (tree_argument_list& lst) |
64 { | |
4219 | 65 tree_argument_list::iterator p = lst.begin (); |
2123 | 66 |
4219 | 67 while (p != lst.end ()) |
2123 | 68 { |
4219 | 69 tree_expression *elt = *p++; |
2123 | 70 |
71 if (elt) | |
72 { | |
73 elt->accept (*this); | |
74 | |
4219 | 75 if (p != lst.end ()) |
2123 | 76 os << ", "; |
77 } | |
78 } | |
79 } | |
80 | |
81 void | |
82 tree_print_code::visit_binary_expression (tree_binary_expression& expr) | |
83 { | |
84 indent (); | |
85 | |
2961 | 86 print_parens (expr, "("); |
2123 | 87 |
88 tree_expression *op1 = expr.lhs (); | |
89 | |
90 if (op1) | |
91 op1->accept (*this); | |
92 | |
93 os << " " << expr.oper () << " "; | |
94 | |
95 tree_expression *op2 = expr.rhs (); | |
96 | |
97 if (op2) | |
98 op2->accept (*this); | |
99 | |
2961 | 100 print_parens (expr, ")"); |
2123 | 101 } |
102 | |
103 void | |
4207 | 104 tree_print_code::visit_break_command (tree_break_command&) |
2123 | 105 { |
106 indent (); | |
107 | |
108 os << "break"; | |
109 } | |
110 | |
111 void | |
112 tree_print_code::visit_colon_expression (tree_colon_expression& expr) | |
113 { | |
114 indent (); | |
115 | |
2961 | 116 print_parens (expr, "("); |
2123 | 117 |
118 tree_expression *op1 = expr.base (); | |
119 | |
120 if (op1) | |
121 op1->accept (*this); | |
122 | |
123 // Stupid syntax. | |
124 | |
125 tree_expression *op3 = expr.increment (); | |
126 | |
127 if (op3) | |
128 { | |
129 os << ":"; | |
130 op3->accept (*this); | |
131 } | |
132 | |
133 tree_expression *op2 = expr.limit (); | |
134 | |
135 if (op2) | |
136 { | |
137 os << ":"; | |
138 op2->accept (*this); | |
139 } | |
140 | |
2961 | 141 print_parens (expr, ")"); |
2123 | 142 } |
143 | |
144 void | |
4207 | 145 tree_print_code::visit_continue_command (tree_continue_command&) |
2123 | 146 { |
147 indent (); | |
148 | |
149 os << "continue"; | |
150 } | |
151 | |
152 void | |
2846 | 153 tree_print_code::visit_decl_command (tree_decl_command& cmd) |
154 { | |
155 indent (); | |
156 | |
157 os << cmd.name () << " "; | |
158 | |
159 tree_decl_init_list *init_list = cmd.initializer_list (); | |
160 | |
161 if (init_list) | |
162 init_list->accept (*this); | |
163 } | |
164 | |
165 void | |
166 tree_print_code::visit_decl_elt (tree_decl_elt& cmd) | |
167 { | |
168 tree_identifier *id = cmd.ident (); | |
169 | |
170 if (id) | |
171 id->accept (*this); | |
172 | |
2969 | 173 tree_expression *expr = cmd.expression (); |
2846 | 174 |
2969 | 175 if (expr) |
176 { | |
177 os << " = "; | |
178 | |
179 expr->accept (*this); | |
180 } | |
2846 | 181 } |
182 | |
183 void | |
184 tree_print_code::visit_decl_init_list (tree_decl_init_list& lst) | |
185 { | |
4219 | 186 tree_decl_init_list::iterator p = lst.begin (); |
2846 | 187 |
4219 | 188 while (p != lst.end ()) |
2846 | 189 { |
4219 | 190 tree_decl_elt *elt = *p++; |
2846 | 191 |
192 if (elt) | |
193 { | |
194 elt->accept (*this); | |
195 | |
4219 | 196 if (p != lst.end ()) |
2846 | 197 os << ", "; |
198 } | |
199 } | |
200 } | |
201 | |
202 void | |
2969 | 203 tree_print_code::visit_simple_for_command (tree_simple_for_command& cmd) |
2123 | 204 { |
3665 | 205 print_comment_list (cmd.leading_comment ()); |
206 | |
2123 | 207 indent (); |
208 | |
209 os << "for "; | |
210 | |
2969 | 211 tree_expression *lhs = cmd.left_hand_side (); |
2123 | 212 |
2969 | 213 if (lhs) |
214 lhs->accept (*this); | |
2123 | 215 |
216 os << " = "; | |
217 | |
218 tree_expression *expr = cmd.control_expr (); | |
219 | |
220 if (expr) | |
221 expr->accept (*this); | |
222 | |
223 newline (); | |
224 | |
225 tree_statement_list *list = cmd.body (); | |
226 | |
227 if (list) | |
228 { | |
229 increment_indent_level (); | |
3665 | 230 |
2123 | 231 list->accept (*this); |
3665 | 232 |
2123 | 233 decrement_indent_level (); |
234 } | |
235 | |
3665 | 236 print_indented_comment (cmd.trailing_comment ()); |
237 | |
2123 | 238 indent (); |
239 | |
240 os << "endfor"; | |
241 } | |
242 | |
243 void | |
2969 | 244 tree_print_code::visit_complex_for_command (tree_complex_for_command& cmd) |
245 { | |
3665 | 246 print_comment_list (cmd.leading_comment ()); |
247 | |
2969 | 248 indent (); |
249 | |
250 os << "for ["; | |
4676 | 251 nesting.push ('['); |
2969 | 252 |
253 tree_argument_list *lhs = cmd.left_hand_side (); | |
254 | |
255 if (lhs) | |
256 lhs->accept (*this); | |
257 | |
4676 | 258 nesting.pop (); |
2969 | 259 os << "] = "; |
260 | |
261 tree_expression *expr = cmd.control_expr (); | |
262 | |
263 if (expr) | |
264 expr->accept (*this); | |
265 | |
266 newline (); | |
267 | |
268 tree_statement_list *list = cmd.body (); | |
269 | |
270 if (list) | |
271 { | |
272 increment_indent_level (); | |
3665 | 273 |
2969 | 274 list->accept (*this); |
3665 | 275 |
2969 | 276 decrement_indent_level (); |
277 } | |
278 | |
3665 | 279 print_indented_comment (cmd.trailing_comment ()); |
280 | |
2969 | 281 indent (); |
282 | |
283 os << "endfor"; | |
284 } | |
285 | |
286 void | |
7715
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
287 tree_print_code::visit_octave_user_script (octave_user_script& fcn) |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
288 { |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
289 reset (); |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
290 |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
291 tree_statement_list *cmd_list = fcn.body (); |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
292 |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
293 if (cmd_list) |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
294 cmd_list->accept (*this); |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
295 } |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
296 |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
297 void |
2891 | 298 tree_print_code::visit_octave_user_function (octave_user_function& fcn) |
2123 | 299 { |
300 reset (); | |
301 | |
2891 | 302 visit_octave_user_function_header (fcn); |
2123 | 303 |
304 tree_statement_list *cmd_list = fcn.body (); | |
305 | |
306 if (cmd_list) | |
307 { | |
308 increment_indent_level (); | |
3665 | 309 |
2123 | 310 cmd_list->accept (*this); |
3665 | 311 |
2123 | 312 decrement_indent_level (); |
313 } | |
314 | |
2891 | 315 visit_octave_user_function_trailer (fcn); |
2123 | 316 } |
317 | |
318 void | |
2891 | 319 tree_print_code::visit_octave_user_function_header (octave_user_function& fcn) |
2123 | 320 { |
3665 | 321 octave_comment_list *leading_comment = fcn.leading_comment (); |
322 | |
323 if (leading_comment) | |
324 { | |
325 print_comment_list (leading_comment); | |
326 newline (); | |
327 } | |
328 | |
2123 | 329 indent (); |
330 | |
331 os << "function "; | |
332 | |
333 tree_parameter_list *ret_list = fcn.return_list (); | |
334 | |
335 if (ret_list) | |
336 { | |
337 bool takes_var_return = fcn.takes_var_return (); | |
338 | |
339 int len = ret_list->length (); | |
340 | |
341 if (len > 1 || takes_var_return) | |
4676 | 342 { |
343 os << "["; | |
344 nesting.push ('['); | |
345 } | |
2123 | 346 |
347 ret_list->accept (*this); | |
348 | |
349 if (takes_var_return) | |
350 { | |
351 if (len > 0) | |
352 os << ", "; | |
353 | |
5848 | 354 os << "varargout"; |
2123 | 355 } |
356 | |
357 if (len > 1 || takes_var_return) | |
4676 | 358 { |
359 nesting.pop (); | |
360 os << "]"; | |
361 } | |
2123 | 362 |
363 os << " = "; | |
364 } | |
365 | |
4748 | 366 std::string fcn_name = fcn.name (); |
2123 | 367 |
3523 | 368 os << (fcn_name.empty () ? std::string ("(empty)") : fcn_name) << " "; |
2123 | 369 |
370 tree_parameter_list *param_list = fcn.parameter_list (); | |
371 | |
372 if (param_list) | |
373 { | |
374 bool takes_varargs = fcn.takes_varargs (); | |
375 | |
376 int len = param_list->length (); | |
377 | |
378 if (len > 0 || takes_varargs) | |
4676 | 379 { |
380 os << "("; | |
381 nesting.push ('('); | |
382 } | |
2123 | 383 |
384 param_list->accept (*this); | |
385 | |
386 if (takes_varargs) | |
387 { | |
388 if (len > 0) | |
389 os << ", "; | |
390 | |
5848 | 391 os << "varargin"; |
2123 | 392 } |
393 | |
394 if (len > 0 || takes_varargs) | |
395 { | |
4676 | 396 nesting.pop (); |
2123 | 397 os << ")"; |
398 newline (); | |
399 } | |
400 } | |
401 else | |
402 { | |
403 os << "()"; | |
404 newline (); | |
405 } | |
406 } | |
407 | |
408 void | |
3665 | 409 tree_print_code::visit_octave_user_function_trailer (octave_user_function& fcn) |
2123 | 410 { |
3665 | 411 print_indented_comment (fcn.trailing_comment ()); |
412 | |
2123 | 413 indent (); |
414 | |
415 os << "endfunction"; | |
416 | |
417 newline (); | |
418 } | |
419 | |
420 void | |
7715
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
421 tree_print_code::visit_function_def (tree_function_def& fdef) |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
422 { |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
423 indent (); |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
424 |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
425 octave_function *fcn = fdef.function (); |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
426 |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
427 if (fcn) |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
428 fcn->accept (*this); |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
429 } |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
430 |
5b4d278ec828
parse scripts completely before executing
John W. Eaton <jwe@octave.org>
parents:
7017
diff
changeset
|
431 void |
2123 | 432 tree_print_code::visit_identifier (tree_identifier& id) |
433 { | |
434 indent (); | |
435 | |
2961 | 436 print_parens (id, "("); |
2123 | 437 |
3523 | 438 std::string nm = id.name (); |
439 os << (nm.empty () ? std::string ("(empty)") : nm); | |
2123 | 440 |
2961 | 441 print_parens (id, ")"); |
2123 | 442 } |
443 | |
444 void | |
445 tree_print_code::visit_if_clause (tree_if_clause& cmd) | |
446 { | |
447 tree_expression *expr = cmd.condition (); | |
448 | |
449 if (expr) | |
450 expr->accept (*this); | |
451 | |
452 newline (); | |
453 | |
454 tree_statement_list *list = cmd.commands (); | |
455 | |
456 if (list) | |
457 { | |
3665 | 458 increment_indent_level (); |
459 | |
2123 | 460 list->accept (*this); |
461 | |
462 decrement_indent_level (); | |
463 } | |
464 } | |
465 | |
466 void | |
467 tree_print_code::visit_if_command (tree_if_command& cmd) | |
468 { | |
3665 | 469 print_comment_list (cmd.leading_comment ()); |
470 | |
2123 | 471 indent (); |
472 | |
473 os << "if "; | |
474 | |
475 tree_if_command_list *list = cmd.cmd_list (); | |
476 | |
477 if (list) | |
478 list->accept (*this); | |
479 | |
3665 | 480 print_indented_comment (cmd.trailing_comment ()); |
481 | |
2123 | 482 indent (); |
483 | |
484 os << "endif"; | |
485 } | |
486 | |
487 void | |
488 tree_print_code::visit_if_command_list (tree_if_command_list& lst) | |
489 { | |
4219 | 490 tree_if_command_list::iterator p = lst.begin (); |
2123 | 491 |
492 bool first_elt = true; | |
493 | |
4219 | 494 while (p != lst.end ()) |
2123 | 495 { |
4219 | 496 tree_if_clause *elt = *p++; |
2123 | 497 |
498 if (elt) | |
499 { | |
500 if (! first_elt) | |
501 { | |
3665 | 502 print_indented_comment (elt->leading_comment ()); |
503 | |
2123 | 504 indent (); |
505 | |
506 if (elt->is_else_clause ()) | |
507 os << "else"; | |
508 else | |
509 os << "elseif "; | |
510 } | |
511 | |
512 elt->accept (*this); | |
513 } | |
514 | |
515 first_elt = false; | |
516 } | |
517 } | |
518 | |
519 void | |
520 tree_print_code::visit_index_expression (tree_index_expression& expr) | |
521 { | |
522 indent (); | |
523 | |
2961 | 524 print_parens (expr, "("); |
2123 | 525 |
3665 | 526 bool expr_has_parens = false; |
527 | |
3010 | 528 tree_expression *e = expr.expression (); |
2123 | 529 |
2969 | 530 if (e) |
3665 | 531 { |
532 e->accept (*this); | |
533 | |
534 expr_has_parens = e->is_postfix_indexed (); | |
535 } | |
2123 | 536 |
4219 | 537 std::list<tree_argument_list *> arg_lists = expr.arg_lists (); |
3933 | 538 std::string type_tags = expr.type_tags (); |
4219 | 539 std::list<string_vector> arg_names = expr.arg_names (); |
2123 | 540 |
3933 | 541 int n = type_tags.length (); |
542 | |
4219 | 543 std::list<tree_argument_list *>::iterator p_arg_lists = arg_lists.begin (); |
544 std::list<string_vector>::iterator p_arg_names = arg_names.begin (); | |
3933 | 545 |
546 for (int i = 0; i < n; i++) | |
2123 | 547 { |
3933 | 548 switch (type_tags[i]) |
549 { | |
550 case '(': | |
551 { | |
4676 | 552 char nc = nesting.top (); |
553 if ((nc == '[' || nc == '{') && expr.paren_count () == 0) | |
554 os << "("; | |
555 else | |
556 os << " ("; | |
557 nesting.push ('('); | |
558 | |
4219 | 559 tree_argument_list *l = *p_arg_lists; |
3933 | 560 if (l) |
561 l->accept (*this); | |
4676 | 562 |
563 nesting.pop (); | |
3933 | 564 os << ")"; |
565 } | |
566 break; | |
567 | |
568 case '{': | |
569 { | |
4676 | 570 char nc = nesting.top (); |
571 if ((nc == '[' || nc == '{') && expr.paren_count () == 0) | |
572 os << "{"; | |
573 else | |
574 os << " {"; | |
575 // We only care about whitespace inside [] and {} when we | |
576 // are defining matrix and cell objects, not when indexing. | |
577 nesting.push ('('); | |
578 | |
4219 | 579 tree_argument_list *l = *p_arg_lists; |
3933 | 580 if (l) |
581 l->accept (*this); | |
4676 | 582 |
583 nesting.pop (); | |
3933 | 584 os << "}"; |
585 } | |
586 break; | |
587 | |
588 case '.': | |
589 { | |
4219 | 590 string_vector nm = *p_arg_names; |
3933 | 591 assert (nm.length () == 1); |
592 os << "." << nm(0); | |
593 } | |
594 break; | |
595 | |
596 default: | |
597 panic_impossible (); | |
598 } | |
599 | |
4219 | 600 p_arg_lists++; |
601 p_arg_names++; | |
3930 | 602 } |
2123 | 603 |
2961 | 604 print_parens (expr, ")"); |
2123 | 605 } |
606 | |
607 void | |
608 tree_print_code::visit_matrix (tree_matrix& lst) | |
609 { | |
610 indent (); | |
611 | |
2961 | 612 print_parens (lst, "("); |
2123 | 613 |
614 os << "["; | |
4676 | 615 nesting.push ('['); |
2123 | 616 |
4219 | 617 tree_matrix::iterator p = lst.begin (); |
2123 | 618 |
4219 | 619 while (p != lst.end ()) |
2123 | 620 { |
4219 | 621 tree_argument_list *elt = *p++; |
2123 | 622 |
623 if (elt) | |
624 { | |
625 elt->accept (*this); | |
626 | |
4219 | 627 if (p != lst.end ()) |
2123 | 628 os << "; "; |
629 } | |
630 } | |
631 | |
4676 | 632 nesting.pop (); |
2123 | 633 os << "]"; |
634 | |
2961 | 635 print_parens (lst, ")"); |
2123 | 636 } |
637 | |
638 void | |
3351 | 639 tree_print_code::visit_cell (tree_cell& lst) |
640 { | |
641 indent (); | |
642 | |
643 print_parens (lst, "("); | |
644 | |
645 os << "{"; | |
4676 | 646 nesting.push ('{'); |
3351 | 647 |
4219 | 648 tree_cell::iterator p = lst.begin (); |
3351 | 649 |
4219 | 650 while (p != lst.end ()) |
3351 | 651 { |
4219 | 652 tree_argument_list *elt = *p++; |
3351 | 653 |
654 if (elt) | |
655 { | |
656 elt->accept (*this); | |
657 | |
4219 | 658 if (p != lst.end ()) |
3351 | 659 os << "; "; |
660 } | |
661 } | |
662 | |
4676 | 663 nesting.pop (); |
3351 | 664 os << "}"; |
665 | |
666 print_parens (lst, ")"); | |
667 } | |
668 | |
669 void | |
2969 | 670 tree_print_code::visit_multi_assignment (tree_multi_assignment& expr) |
2123 | 671 { |
672 indent (); | |
673 | |
2961 | 674 print_parens (expr, "("); |
2123 | 675 |
2969 | 676 tree_argument_list *lhs = expr.left_hand_side (); |
2123 | 677 |
678 if (lhs) | |
679 { | |
680 int len = lhs->length (); | |
681 | |
682 if (len > 1) | |
4676 | 683 { |
684 os << "["; | |
685 nesting.push ('['); | |
686 } | |
2123 | 687 |
688 lhs->accept (*this); | |
689 | |
690 if (len > 1) | |
4676 | 691 { |
692 nesting.pop (); | |
693 os << "]"; | |
694 } | |
2123 | 695 } |
696 | |
3208 | 697 os << " " << expr.oper () << " "; |
2123 | 698 |
2969 | 699 tree_expression *rhs = expr.right_hand_side (); |
2123 | 700 |
701 if (rhs) | |
702 rhs->accept (*this); | |
703 | |
2961 | 704 print_parens (expr, ")"); |
2123 | 705 } |
706 | |
707 void | |
2620 | 708 tree_print_code::visit_no_op_command (tree_no_op_command& cmd) |
709 { | |
710 indent (); | |
711 | |
712 os << cmd.original_command (); | |
713 } | |
714 | |
715 void | |
2372 | 716 tree_print_code::visit_constant (tree_constant& val) |
2123 | 717 { |
718 indent (); | |
719 | |
2961 | 720 print_parens (val, "("); |
2123 | 721 |
2942 | 722 val.print_raw (os, true, print_original_text); |
2123 | 723 |
2961 | 724 print_parens (val, ")"); |
2123 | 725 } |
726 | |
727 void | |
4342 | 728 tree_print_code::visit_fcn_handle (tree_fcn_handle& fh) |
729 { | |
730 indent (); | |
731 | |
732 print_parens (fh, "("); | |
733 | |
734 fh.print_raw (os, true, print_original_text); | |
735 | |
736 print_parens (fh, ")"); | |
737 } | |
738 | |
739 void | |
2123 | 740 tree_print_code::visit_parameter_list (tree_parameter_list& lst) |
741 { | |
4219 | 742 tree_parameter_list::iterator p = lst.begin (); |
2123 | 743 |
4219 | 744 while (p != lst.end ()) |
2123 | 745 { |
6215 | 746 tree_decl_elt *elt = *p++; |
2123 | 747 |
748 if (elt) | |
749 { | |
750 elt->accept (*this); | |
751 | |
4219 | 752 if (p != lst.end ()) |
2123 | 753 os << ", "; |
754 } | |
755 } | |
756 } | |
757 | |
758 void | |
759 tree_print_code::visit_postfix_expression (tree_postfix_expression& expr) | |
760 { | |
761 indent (); | |
762 | |
2961 | 763 print_parens (expr, "("); |
2123 | 764 |
2960 | 765 tree_expression *e = expr.operand (); |
2123 | 766 |
2960 | 767 if (e) |
768 e->accept (*this); | |
2123 | 769 |
770 os << expr.oper (); | |
771 | |
2961 | 772 print_parens (expr, ")"); |
2123 | 773 } |
774 | |
775 void | |
776 tree_print_code::visit_prefix_expression (tree_prefix_expression& expr) | |
777 { | |
778 indent (); | |
779 | |
2961 | 780 print_parens (expr, "("); |
2123 | 781 |
782 os << expr.oper (); | |
783 | |
2960 | 784 tree_expression *e = expr.operand (); |
2123 | 785 |
2960 | 786 if (e) |
787 e->accept (*this); | |
2123 | 788 |
2961 | 789 print_parens (expr, ")"); |
2123 | 790 } |
791 | |
792 void | |
4207 | 793 tree_print_code::visit_return_command (tree_return_command&) |
2123 | 794 { |
795 indent (); | |
796 | |
797 os << "return"; | |
798 } | |
799 | |
800 void | |
801 tree_print_code::visit_return_list (tree_return_list& lst) | |
802 { | |
4219 | 803 tree_return_list::iterator p = lst.begin (); |
2123 | 804 |
4219 | 805 while (p != lst.end ()) |
2123 | 806 { |
4219 | 807 tree_index_expression *elt = *p++; |
2123 | 808 |
809 if (elt) | |
810 { | |
811 elt->accept (*this); | |
812 | |
4219 | 813 if (p != lst.end ()) |
2123 | 814 os << ", "; |
815 } | |
816 } | |
817 } | |
818 | |
819 void | |
2969 | 820 tree_print_code::visit_simple_assignment (tree_simple_assignment& expr) |
2123 | 821 { |
822 indent (); | |
823 | |
2961 | 824 print_parens (expr, "("); |
2123 | 825 |
2969 | 826 tree_expression *lhs = expr.left_hand_side (); |
2123 | 827 |
2969 | 828 if (lhs) |
829 lhs->accept (*this); | |
2123 | 830 |
2969 | 831 os << " " << expr.oper () << " "; |
2123 | 832 |
833 tree_expression *rhs = expr.right_hand_side (); | |
834 | |
835 if (rhs) | |
836 rhs->accept (*this); | |
837 | |
2961 | 838 print_parens (expr, ")"); |
2123 | 839 } |
840 | |
841 void | |
842 tree_print_code::visit_statement (tree_statement& stmt) | |
843 { | |
3665 | 844 print_comment_list (stmt.comment_text ()); |
845 | |
2123 | 846 tree_command *cmd = stmt.command (); |
847 | |
848 if (cmd) | |
849 { | |
850 cmd->accept (*this); | |
851 | |
852 if (! stmt.print_result ()) | |
4980 | 853 { |
854 os << ";"; | |
855 newline (" "); | |
856 } | |
857 else | |
858 newline (); | |
2123 | 859 } |
860 else | |
861 { | |
862 tree_expression *expr = stmt.expression (); | |
863 | |
864 if (expr) | |
865 { | |
866 expr->accept (*this); | |
867 | |
868 if (! stmt.print_result ()) | |
4980 | 869 { |
870 os << ";"; | |
871 newline (" "); | |
872 } | |
873 else | |
874 newline (); | |
2123 | 875 } |
876 } | |
877 } | |
878 | |
879 void | |
880 tree_print_code::visit_statement_list (tree_statement_list& lst) | |
881 { | |
4219 | 882 for (tree_statement_list::iterator p = lst.begin (); p != lst.end (); p++) |
2123 | 883 { |
4219 | 884 tree_statement *elt = *p; |
2123 | 885 |
886 if (elt) | |
887 elt->accept (*this); | |
888 } | |
889 } | |
890 | |
891 void | |
2846 | 892 tree_print_code::visit_switch_case (tree_switch_case& cs) |
893 { | |
3665 | 894 print_comment_list (cs.leading_comment ()); |
895 | |
2846 | 896 indent (); |
897 | |
898 if (cs.is_default_case ()) | |
899 os << "otherwise"; | |
900 else | |
901 os << "case "; | |
902 | |
903 tree_expression *label = cs.case_label (); | |
904 | |
905 if (label) | |
906 label->accept (*this); | |
907 | |
908 newline (); | |
909 | |
910 tree_statement_list *list = cs.commands (); | |
911 | |
912 if (list) | |
913 { | |
3665 | 914 increment_indent_level (); |
915 | |
2846 | 916 list->accept (*this); |
917 | |
3665 | 918 newline (); |
919 | |
2846 | 920 decrement_indent_level (); |
921 } | |
922 } | |
923 | |
924 void | |
925 tree_print_code::visit_switch_case_list (tree_switch_case_list& lst) | |
926 { | |
4219 | 927 tree_switch_case_list::iterator p = lst.begin (); |
2846 | 928 |
4219 | 929 while (p != lst.end ()) |
2846 | 930 { |
4219 | 931 tree_switch_case *elt = *p++; |
2846 | 932 |
933 if (elt) | |
934 elt->accept (*this); | |
935 } | |
936 } | |
937 | |
938 void | |
939 tree_print_code::visit_switch_command (tree_switch_command& cmd) | |
940 { | |
3665 | 941 print_comment_list (cmd.leading_comment ()); |
942 | |
2846 | 943 indent (); |
944 | |
945 os << "switch "; | |
946 | |
947 tree_expression *expr = cmd.switch_value (); | |
948 | |
949 if (expr) | |
950 expr->accept (*this); | |
951 | |
952 newline (); | |
953 | |
954 tree_switch_case_list *list = cmd.case_list (); | |
955 | |
956 if (list) | |
3665 | 957 { |
958 increment_indent_level (); | |
959 | |
960 list->accept (*this); | |
961 | |
962 decrement_indent_level (); | |
963 } | |
964 | |
965 print_indented_comment (cmd.leading_comment ()); | |
2846 | 966 |
967 indent (); | |
968 | |
969 os << "endswitch"; | |
970 } | |
971 | |
972 void | |
2123 | 973 tree_print_code::visit_try_catch_command (tree_try_catch_command& cmd) |
974 { | |
3665 | 975 print_comment_list (cmd.leading_comment ()); |
976 | |
2123 | 977 indent (); |
978 | |
3665 | 979 os << "try"; |
2123 | 980 |
981 newline (); | |
982 | |
983 tree_statement_list *try_code = cmd.body (); | |
984 | |
985 if (try_code) | |
986 { | |
987 increment_indent_level (); | |
3665 | 988 |
2123 | 989 try_code->accept (*this); |
3665 | 990 |
2123 | 991 decrement_indent_level (); |
992 } | |
993 | |
3665 | 994 print_indented_comment (cmd.middle_comment ()); |
995 | |
2123 | 996 indent (); |
997 | |
998 os << "catch"; | |
999 | |
1000 newline (); | |
1001 | |
1002 tree_statement_list *catch_code = cmd.cleanup (); | |
1003 | |
1004 if (catch_code) | |
1005 { | |
1006 increment_indent_level (); | |
3665 | 1007 |
2123 | 1008 catch_code->accept (*this); |
3665 | 1009 |
2123 | 1010 decrement_indent_level (); |
1011 } | |
1012 | |
3665 | 1013 print_indented_comment (cmd.trailing_comment ()); |
1014 | |
2123 | 1015 indent (); |
1016 | |
1017 os << "end_try_catch"; | |
1018 } | |
1019 | |
1020 void | |
1021 tree_print_code::visit_unwind_protect_command | |
1022 (tree_unwind_protect_command& cmd) | |
1023 { | |
3665 | 1024 print_comment_list (cmd.leading_comment ()); |
1025 | |
2123 | 1026 indent (); |
1027 | |
1028 os << "unwind_protect"; | |
1029 | |
1030 newline (); | |
1031 | |
1032 tree_statement_list *unwind_protect_code = cmd.body (); | |
1033 | |
1034 if (unwind_protect_code) | |
1035 { | |
1036 increment_indent_level (); | |
3665 | 1037 |
2123 | 1038 unwind_protect_code->accept (*this); |
3665 | 1039 |
2123 | 1040 decrement_indent_level (); |
1041 } | |
1042 | |
3665 | 1043 print_indented_comment (cmd.middle_comment ()); |
1044 | |
2123 | 1045 indent (); |
1046 | |
3478 | 1047 os << "unwind_protect_cleanup"; |
2123 | 1048 |
1049 newline (); | |
1050 | |
1051 tree_statement_list *cleanup_code = cmd.cleanup (); | |
1052 | |
1053 if (cleanup_code) | |
1054 { | |
1055 increment_indent_level (); | |
3665 | 1056 |
2123 | 1057 cleanup_code->accept (*this); |
3665 | 1058 |
2123 | 1059 decrement_indent_level (); |
1060 } | |
1061 | |
3665 | 1062 print_indented_comment (cmd.trailing_comment ()); |
1063 | |
2123 | 1064 indent (); |
1065 | |
1066 os << "end_unwind_protect"; | |
1067 } | |
1068 | |
1069 void | |
1070 tree_print_code::visit_while_command (tree_while_command& cmd) | |
1071 { | |
3665 | 1072 print_comment_list (cmd.leading_comment ()); |
1073 | |
2123 | 1074 indent (); |
1075 | |
1076 os << "while "; | |
1077 | |
1078 tree_expression *expr = cmd.condition (); | |
1079 | |
1080 if (expr) | |
1081 expr->accept (*this); | |
1082 | |
1083 newline (); | |
1084 | |
1085 tree_statement_list *list = cmd.body (); | |
1086 | |
1087 if (list) | |
1088 { | |
1089 increment_indent_level (); | |
3665 | 1090 |
2123 | 1091 list->accept (*this); |
3665 | 1092 |
2123 | 1093 decrement_indent_level (); |
1094 } | |
1095 | |
3665 | 1096 print_indented_comment (cmd.trailing_comment ()); |
1097 | |
2123 | 1098 indent (); |
1099 | |
1100 os << "endwhile"; | |
1101 } | |
1102 | |
3484 | 1103 void |
1104 tree_print_code::visit_do_until_command (tree_do_until_command& cmd) | |
1105 { | |
3665 | 1106 print_comment_list (cmd.leading_comment ()); |
1107 | |
3484 | 1108 indent (); |
1109 | |
1110 os << "do"; | |
1111 | |
1112 newline (); | |
1113 | |
1114 tree_statement_list *list = cmd.body (); | |
1115 | |
1116 if (list) | |
1117 { | |
1118 increment_indent_level (); | |
3665 | 1119 |
3484 | 1120 list->accept (*this); |
3665 | 1121 |
3484 | 1122 decrement_indent_level (); |
1123 } | |
1124 | |
3665 | 1125 print_indented_comment (cmd.trailing_comment ()); |
1126 | |
3484 | 1127 indent (); |
1128 | |
1129 os << "until"; | |
1130 | |
1131 tree_expression *expr = cmd.condition (); | |
1132 | |
1133 if (expr) | |
1134 expr->accept (*this); | |
1135 | |
1136 newline (); | |
1137 } | |
1138 | |
2123 | 1139 // Each print_code() function should call this before printing |
1140 // anything. | |
1141 // | |
1142 // This doesn't need to be fast, but isn't there a better way? | |
1143 | |
1144 void | |
1145 tree_print_code::indent (void) | |
1146 { | |
1147 assert (curr_print_indent_level >= 0); | |
2900 | 1148 |
4980 | 1149 if (printing_newlines) |
1150 { | |
1151 if (beginning_of_line) | |
1152 { | |
1153 os << prefix; | |
2900 | 1154 |
4980 | 1155 for (int i = 0; i < curr_print_indent_level; i++) |
1156 os << " "; | |
1157 | |
1158 beginning_of_line = false; | |
1159 } | |
2123 | 1160 } |
1161 } | |
1162 | |
1163 // All print_code() functions should use this to print new lines. | |
1164 | |
1165 void | |
4980 | 1166 tree_print_code::newline (const char *alt_txt) |
2123 | 1167 { |
4980 | 1168 os << (printing_newlines ? "\n" : alt_txt); |
2123 | 1169 |
1170 beginning_of_line = true; | |
1171 } | |
1172 | |
1173 // For ressetting print_code state. | |
1174 | |
1175 void | |
1176 tree_print_code::reset (void) | |
1177 { | |
1178 beginning_of_line = true; | |
1179 curr_print_indent_level = 0; | |
4676 | 1180 while (nesting.top () != 'n') |
1181 nesting.pop (); | |
2123 | 1182 } |
1183 | |
2961 | 1184 void |
1185 tree_print_code::print_parens (const tree_expression& expr, const char *txt) | |
1186 { | |
1187 int n = expr.paren_count (); | |
1188 | |
1189 for (int i = 0; i < n; i++) | |
1190 os << txt; | |
1191 } | |
1192 | |
3665 | 1193 void |
1194 tree_print_code::print_comment_elt (const octave_comment_elt& elt) | |
1195 { | |
1196 bool printed_something = false; | |
1197 | |
1198 bool prev_char_was_newline = false; | |
1199 | |
3769 | 1200 std::string comment = elt.text (); |
3665 | 1201 |
1202 size_t len = comment.length (); | |
1203 | |
1204 size_t i = 0; | |
1205 | |
1206 while (i < len && comment[i++] == '\n') | |
1207 ; /* Skip leading new lines. */ | |
1208 i--; | |
1209 | |
1210 while (i < len) | |
1211 { | |
1212 char c = comment[i++]; | |
1213 | |
1214 if (c == '\n') | |
1215 { | |
1216 if (prev_char_was_newline) | |
1217 os << "##"; | |
1218 | |
1219 newline (); | |
1220 | |
1221 prev_char_was_newline = true; | |
1222 } | |
1223 else | |
1224 { | |
1225 if (beginning_of_line) | |
1226 { | |
1227 printed_something = true; | |
1228 | |
1229 indent (); | |
1230 | |
1231 os << "##"; | |
1232 | |
1233 if (! (isspace (c) || c == '!')) | |
1234 os << " "; | |
1235 } | |
1236 | |
5760 | 1237 os << static_cast<char> (c); |
3665 | 1238 |
1239 prev_char_was_newline = false; | |
1240 } | |
1241 } | |
1242 | |
1243 if (printed_something && ! beginning_of_line) | |
1244 newline (); | |
1245 } | |
1246 | |
1247 void | |
1248 tree_print_code::print_comment_list (octave_comment_list *comment_list) | |
1249 { | |
1250 if (comment_list) | |
1251 { | |
4219 | 1252 octave_comment_list::iterator p = comment_list->begin (); |
3665 | 1253 |
4219 | 1254 while (p != comment_list->end ()) |
3665 | 1255 { |
4219 | 1256 octave_comment_elt elt = *p++; |
3665 | 1257 |
1258 print_comment_elt (elt); | |
1259 | |
4219 | 1260 if (p != comment_list->end ()) |
3665 | 1261 newline (); |
1262 } | |
1263 } | |
1264 } | |
1265 | |
1266 void | |
1267 tree_print_code::print_indented_comment (octave_comment_list *comment_list) | |
1268 { | |
1269 increment_indent_level (); | |
1270 | |
1271 print_comment_list (comment_list); | |
1272 | |
1273 decrement_indent_level (); | |
1274 } | |
1275 | |
2123 | 1276 /* |
1277 ;;; Local Variables: *** | |
1278 ;;; mode: C++ *** | |
1279 ;;; End: *** | |
1280 */ |