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 }