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