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