pt-pr-code.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1996-2012 John W. Eaton
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, see
00019 <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026 
00027 #include <cctype>
00028 
00029 #include <iostream>
00030 
00031 #include "comment-list.h"
00032 #include "error.h"
00033 #include "ov-usr-fcn.h"
00034 #include "pr-output.h"
00035 #include "pt-all.h"
00036 
00037 void
00038 tree_print_code::visit_anon_fcn_handle (tree_anon_fcn_handle& afh)
00039 {
00040   indent ();
00041 
00042   print_parens (afh, "(");
00043 
00044   os << "@(";
00045 
00046   tree_parameter_list *param_list = afh.parameter_list ();
00047 
00048   if (param_list)
00049     param_list->accept (*this);
00050 
00051   os << ") ";
00052 
00053   print_fcn_handle_body (afh.body ());
00054 
00055   print_parens (afh, ")");
00056 }
00057 
00058 void
00059 tree_print_code::visit_argument_list (tree_argument_list& lst)
00060 {
00061   tree_argument_list::iterator p = lst.begin ();
00062 
00063   while (p != lst.end ())
00064     {
00065       tree_expression *elt = *p++;
00066 
00067       if (elt)
00068         {
00069           elt->accept (*this);
00070 
00071           if (p != lst.end ())
00072             os << ", ";
00073         }
00074     }
00075 }
00076 
00077 void
00078 tree_print_code::visit_binary_expression (tree_binary_expression& expr)
00079 {
00080   indent ();
00081 
00082   print_parens (expr, "(");
00083 
00084   tree_expression *op1 = expr.lhs ();
00085 
00086   if (op1)
00087     op1->accept (*this);
00088 
00089   os << " " << expr.oper () << " ";
00090 
00091   tree_expression *op2 = expr.rhs ();
00092 
00093   if (op2)
00094     op2->accept (*this);
00095 
00096   print_parens (expr, ")");
00097 }
00098 
00099 void
00100 tree_print_code::visit_break_command (tree_break_command&)
00101 {
00102   indent ();
00103 
00104   os << "break";
00105 }
00106 
00107 void
00108 tree_print_code::visit_colon_expression (tree_colon_expression& expr)
00109 {
00110   indent ();
00111 
00112   print_parens (expr, "(");
00113 
00114   tree_expression *op1 = expr.base ();
00115 
00116   if (op1)
00117     op1->accept (*this);
00118 
00119   // Stupid syntax.
00120 
00121   tree_expression *op3 = expr.increment ();
00122 
00123   if (op3)
00124     {
00125       os << ":";
00126       op3->accept (*this);
00127     }
00128 
00129   tree_expression *op2 = expr.limit ();
00130 
00131   if (op2)
00132     {
00133       os << ":";
00134       op2->accept (*this);
00135     }
00136 
00137   print_parens (expr, ")");
00138 }
00139 
00140 void
00141 tree_print_code::visit_continue_command (tree_continue_command&)
00142 {
00143   indent ();
00144 
00145   os << "continue";
00146 }
00147 
00148 void
00149 tree_print_code::do_decl_command (tree_decl_command& cmd)
00150 {
00151   indent ();
00152 
00153   os << cmd.name () << " ";
00154 
00155   tree_decl_init_list *init_list = cmd.initializer_list ();
00156 
00157   if (init_list)
00158     init_list->accept (*this);
00159 }
00160 
00161 void
00162 tree_print_code::visit_global_command (tree_global_command& cmd)
00163 {
00164   do_decl_command (cmd);
00165 }
00166 
00167 void
00168 tree_print_code::visit_static_command (tree_static_command& cmd)
00169 {
00170   do_decl_command (cmd);
00171 }
00172 
00173 void
00174 tree_print_code::visit_decl_elt (tree_decl_elt& cmd)
00175 {
00176   tree_identifier *id = cmd.ident ();
00177 
00178   if (id)
00179     id->accept (*this);
00180 
00181   tree_expression *expr = cmd.expression ();
00182 
00183   if (expr)
00184     {
00185       os << " = ";
00186 
00187       expr->accept (*this);
00188     }
00189 }
00190 
00191 void
00192 tree_print_code::visit_decl_init_list (tree_decl_init_list& lst)
00193 {
00194   tree_decl_init_list::iterator p = lst.begin ();
00195 
00196   while (p != lst.end ())
00197     {
00198       tree_decl_elt *elt = *p++;
00199 
00200       if (elt)
00201         {
00202           elt->accept (*this);
00203 
00204           if (p != lst.end ())
00205             os << ", ";
00206         }
00207     }
00208 }
00209 
00210 void
00211 tree_print_code::visit_simple_for_command (tree_simple_for_command& cmd)
00212 {
00213   print_comment_list (cmd.leading_comment ());
00214 
00215   indent ();
00216 
00217   os << (cmd.in_parallel () ? "parfor " : "for ");
00218 
00219   tree_expression *lhs = cmd.left_hand_side ();
00220 
00221   tree_expression *maxproc = cmd.maxproc_expr ();
00222 
00223   if (maxproc)
00224     os << "(";
00225 
00226   if (lhs)
00227     lhs->accept (*this);
00228 
00229   os << " = ";
00230 
00231   tree_expression *expr = cmd.control_expr ();
00232 
00233   if (expr)
00234     expr->accept (*this);
00235 
00236   if (maxproc)
00237     {
00238       os << ", ";
00239       maxproc->accept (*this);
00240       os << ")";
00241     }
00242 
00243   newline ();
00244 
00245   tree_statement_list *list = cmd.body ();
00246 
00247   if (list)
00248     {
00249       increment_indent_level ();
00250 
00251       list->accept (*this);
00252 
00253       decrement_indent_level ();
00254     }
00255 
00256   print_indented_comment (cmd.trailing_comment ());
00257 
00258   indent ();
00259 
00260   os << (cmd.in_parallel () ? "endparfor" : "endfor");
00261 }
00262 
00263 void
00264 tree_print_code::visit_complex_for_command (tree_complex_for_command& cmd)
00265 {
00266   print_comment_list (cmd.leading_comment ());
00267 
00268   indent ();
00269 
00270   os << "for [";
00271   nesting.push ('[');
00272 
00273   tree_argument_list *lhs = cmd.left_hand_side ();
00274 
00275   if (lhs)
00276     lhs->accept (*this);
00277 
00278   nesting.pop ();
00279   os << "] = ";
00280 
00281   tree_expression *expr = cmd.control_expr ();
00282 
00283   if (expr)
00284     expr->accept (*this);
00285 
00286   newline ();
00287 
00288   tree_statement_list *list = cmd.body ();
00289 
00290   if (list)
00291     {
00292       increment_indent_level ();
00293 
00294       list->accept (*this);
00295 
00296       decrement_indent_level ();
00297     }
00298 
00299   print_indented_comment (cmd.trailing_comment ());
00300 
00301   indent ();
00302 
00303   os << "endfor";
00304 }
00305 
00306 void
00307 tree_print_code::visit_octave_user_script (octave_user_script& fcn)
00308 {
00309   reset ();
00310 
00311   tree_statement_list *cmd_list = fcn.body ();
00312 
00313   if (cmd_list)
00314     cmd_list->accept (*this);
00315 }
00316 
00317 void
00318 tree_print_code::visit_octave_user_function (octave_user_function& fcn)
00319 {
00320   reset ();
00321 
00322   visit_octave_user_function_header (fcn);
00323 
00324   tree_statement_list *cmd_list = fcn.body ();
00325 
00326   if (cmd_list)
00327     {
00328       increment_indent_level ();
00329 
00330       cmd_list->accept (*this);
00331 
00332       decrement_indent_level ();
00333     }
00334 
00335   visit_octave_user_function_trailer (fcn);
00336 }
00337 
00338 void
00339 tree_print_code::visit_octave_user_function_header (octave_user_function& fcn)
00340 {
00341   octave_comment_list *leading_comment = fcn.leading_comment ();
00342 
00343   if (leading_comment)
00344     {
00345       print_comment_list (leading_comment);
00346       newline ();
00347     }
00348 
00349   indent ();
00350 
00351   os << "function ";
00352 
00353   tree_parameter_list *ret_list = fcn.return_list ();
00354 
00355   if (ret_list)
00356     {
00357       bool takes_var_return = fcn.takes_var_return ();
00358 
00359       int len = ret_list->length ();
00360 
00361       if (len > 1 || takes_var_return)
00362         {
00363           os << "[";
00364           nesting.push ('[');
00365         }
00366 
00367       ret_list->accept (*this);
00368 
00369       if (takes_var_return)
00370         {
00371           if (len > 0)
00372             os << ", ";
00373 
00374           os << "varargout";
00375         }
00376 
00377       if (len > 1 || takes_var_return)
00378         {
00379           nesting.pop ();
00380           os << "]";
00381         }
00382 
00383       os << " = ";
00384     }
00385 
00386   std::string fcn_name = fcn.name ();
00387 
00388   os << (fcn_name.empty () ? std::string ("(empty)") : fcn_name) << " ";
00389 
00390   tree_parameter_list *param_list = fcn.parameter_list ();
00391 
00392   if (param_list)
00393     {
00394       bool takes_varargs = fcn.takes_varargs ();
00395 
00396       int len = param_list->length ();
00397 
00398       if (len > 0 || takes_varargs)
00399         {
00400           os << "(";
00401           nesting.push ('(');
00402         }
00403 
00404       param_list->accept (*this);
00405 
00406       if (takes_varargs)
00407         {
00408           if (len > 0)
00409             os << ", ";
00410 
00411           os << "varargin";
00412         }
00413 
00414       if (len > 0 || takes_varargs)
00415         {
00416           nesting.pop ();
00417           os << ")";
00418           newline ();
00419         }
00420     }
00421   else
00422     {
00423       os << "()";
00424       newline ();
00425     }
00426 }
00427 
00428 void
00429 tree_print_code::visit_octave_user_function_trailer (octave_user_function& fcn)
00430 {
00431   print_indented_comment (fcn.trailing_comment ());
00432 
00433   newline ();
00434 }
00435 
00436 void
00437 tree_print_code::visit_function_def (tree_function_def& fdef)
00438 {
00439   indent ();
00440 
00441   octave_value fcn = fdef.function ();
00442 
00443   octave_function *f = fcn.function_value ();
00444 
00445   if (f)
00446     f->accept (*this);
00447 }
00448 
00449 void
00450 tree_print_code::visit_identifier (tree_identifier& id)
00451 {
00452   indent ();
00453 
00454   print_parens (id, "(");
00455 
00456   std::string nm = id.name ();
00457   os << (nm.empty () ? std::string ("(empty)") : nm);
00458 
00459   print_parens (id, ")");
00460 }
00461 
00462 void
00463 tree_print_code::visit_if_clause (tree_if_clause& cmd)
00464 {
00465   tree_expression *expr = cmd.condition ();
00466 
00467   if (expr)
00468     expr->accept (*this);
00469 
00470   newline ();
00471 
00472   tree_statement_list *list = cmd.commands ();
00473 
00474   if (list)
00475     {
00476       increment_indent_level ();
00477 
00478       list->accept (*this);
00479 
00480       decrement_indent_level ();
00481     }
00482 }
00483 
00484 void
00485 tree_print_code::visit_if_command (tree_if_command& cmd)
00486 {
00487   print_comment_list (cmd.leading_comment ());
00488 
00489   indent ();
00490 
00491   os << "if ";
00492 
00493   tree_if_command_list *list = cmd.cmd_list ();
00494 
00495   if (list)
00496     list->accept (*this);
00497 
00498   print_indented_comment (cmd.trailing_comment ());
00499 
00500   indent ();
00501 
00502   os << "endif";
00503 }
00504 
00505 void
00506 tree_print_code::visit_if_command_list (tree_if_command_list& lst)
00507 {
00508   tree_if_command_list::iterator p = lst.begin ();
00509 
00510   bool first_elt = true;
00511 
00512   while (p != lst.end ())
00513     {
00514       tree_if_clause *elt = *p++;
00515 
00516       if (elt)
00517         {
00518           if (! first_elt)
00519             {
00520               print_indented_comment (elt->leading_comment ());
00521 
00522               indent ();
00523 
00524               if (elt->is_else_clause ())
00525                 os << "else";
00526               else
00527                 os << "elseif ";
00528             }
00529 
00530           elt->accept (*this);
00531         }
00532 
00533       first_elt = false;
00534     }
00535 }
00536 
00537 void
00538 tree_print_code::visit_index_expression (tree_index_expression& expr)
00539 {
00540   indent ();
00541 
00542   print_parens (expr, "(");
00543 
00544   tree_expression *e = expr.expression ();
00545 
00546   if (e)
00547     e->accept (*this);
00548 
00549   std::list<tree_argument_list *> arg_lists = expr.arg_lists ();
00550   std::string type_tags = expr.type_tags ();
00551   std::list<string_vector> arg_names = expr.arg_names ();
00552 
00553   int n = type_tags.length ();
00554 
00555   std::list<tree_argument_list *>::iterator p_arg_lists = arg_lists.begin ();
00556   std::list<string_vector>::iterator p_arg_names = arg_names.begin ();
00557 
00558   for (int i = 0; i < n; i++)
00559     {
00560       switch (type_tags[i])
00561         {
00562         case '(':
00563           {
00564             char nc = nesting.top ();
00565             if ((nc == '[' || nc == '{') && expr.paren_count () == 0)
00566               os << "(";
00567             else
00568               os << " (";
00569             nesting.push ('(');
00570 
00571             tree_argument_list *l = *p_arg_lists;
00572             if (l)
00573               l->accept (*this);
00574 
00575             nesting.pop ();
00576             os << ")";
00577           }
00578           break;
00579 
00580         case '{':
00581           {
00582             char nc = nesting.top ();
00583             if ((nc == '[' || nc == '{') && expr.paren_count () == 0)
00584               os << "{";
00585             else
00586               os << " {";
00587             // We only care about whitespace inside [] and {} when we
00588             // are defining matrix and cell objects, not when indexing.
00589             nesting.push ('(');
00590 
00591             tree_argument_list *l = *p_arg_lists;
00592             if (l)
00593               l->accept (*this);
00594 
00595             nesting.pop ();
00596             os << "}";
00597           }
00598           break;
00599 
00600         case '.':
00601           {
00602             string_vector nm = *p_arg_names;
00603             assert (nm.length () == 1);
00604             os << "." << nm(0);
00605           }
00606           break;
00607 
00608         default:
00609           panic_impossible ();
00610         }
00611 
00612       p_arg_lists++;
00613       p_arg_names++;
00614     }
00615 
00616   print_parens (expr, ")");
00617 }
00618 
00619 void
00620 tree_print_code::visit_matrix (tree_matrix& lst)
00621 {
00622   indent ();
00623 
00624   print_parens (lst, "(");
00625 
00626   os << "[";
00627   nesting.push ('[');
00628 
00629   tree_matrix::iterator p = lst.begin ();
00630 
00631   while (p != lst.end ())
00632     {
00633       tree_argument_list *elt = *p++;
00634 
00635       if (elt)
00636         {
00637           elt->accept (*this);
00638 
00639           if (p != lst.end ())
00640             os << "; ";
00641         }
00642     }
00643 
00644   nesting.pop ();
00645   os << "]";
00646 
00647   print_parens (lst, ")");
00648 }
00649 
00650 void
00651 tree_print_code::visit_cell (tree_cell& lst)
00652 {
00653   indent ();
00654 
00655   print_parens (lst, "(");
00656 
00657   os << "{";
00658   nesting.push ('{');
00659 
00660   tree_cell::iterator p = lst.begin ();
00661 
00662   while (p != lst.end ())
00663     {
00664       tree_argument_list *elt = *p++;
00665 
00666       if (elt)
00667         {
00668           elt->accept (*this);
00669 
00670           if (p != lst.end ())
00671             os << "; ";
00672         }
00673     }
00674 
00675   nesting.pop ();
00676   os << "}";
00677 
00678   print_parens (lst, ")");
00679 }
00680 
00681 void
00682 tree_print_code::visit_multi_assignment (tree_multi_assignment& expr)
00683 {
00684   indent ();
00685 
00686   print_parens (expr, "(");
00687 
00688   tree_argument_list *lhs = expr.left_hand_side ();
00689 
00690   if (lhs)
00691     {
00692       int len = lhs->length ();
00693 
00694       if (len > 1)
00695         {
00696           os << "[";
00697           nesting.push ('[');
00698         }
00699 
00700       lhs->accept (*this);
00701 
00702       if (len > 1)
00703         {
00704           nesting.pop ();
00705           os << "]";
00706         }
00707     }
00708 
00709   os << " " << expr.oper () << " ";
00710 
00711   tree_expression *rhs = expr.right_hand_side ();
00712 
00713   if (rhs)
00714     rhs->accept (*this);
00715 
00716   print_parens (expr, ")");
00717 }
00718 
00719 void
00720 tree_print_code::visit_no_op_command (tree_no_op_command& cmd)
00721 {
00722   indent ();
00723 
00724   os << cmd.original_command ();
00725 }
00726 
00727 void
00728 tree_print_code::visit_constant (tree_constant& val)
00729 {
00730   indent ();
00731 
00732   print_parens (val, "(");
00733 
00734   val.print_raw (os, true, print_original_text);
00735 
00736   print_parens (val, ")");
00737 }
00738 
00739 void
00740 tree_print_code::visit_fcn_handle (tree_fcn_handle& fh)
00741 {
00742   indent ();
00743 
00744   print_parens (fh, "(");
00745 
00746   fh.print_raw (os, true, print_original_text);
00747 
00748   print_parens (fh, ")");
00749 }
00750 
00751 void
00752 tree_print_code::visit_parameter_list (tree_parameter_list& lst)
00753 {
00754   tree_parameter_list::iterator p = lst.begin ();
00755 
00756   while (p != lst.end ())
00757     {
00758       tree_decl_elt *elt = *p++;
00759 
00760       if (elt)
00761         {
00762           elt->accept (*this);
00763 
00764           if (p != lst.end ())
00765             os << ", ";
00766         }
00767     }
00768 }
00769 
00770 void
00771 tree_print_code::visit_postfix_expression (tree_postfix_expression& expr)
00772 {
00773   indent ();
00774 
00775   print_parens (expr, "(");
00776 
00777   tree_expression *e = expr.operand ();
00778 
00779   if (e)
00780     e->accept (*this);
00781 
00782   os << expr.oper ();
00783 
00784   print_parens (expr, ")");
00785 }
00786 
00787 void
00788 tree_print_code::visit_prefix_expression (tree_prefix_expression& expr)
00789 {
00790   indent ();
00791 
00792   print_parens (expr, "(");
00793 
00794   os << expr.oper ();
00795 
00796   tree_expression *e = expr.operand ();
00797 
00798   if (e)
00799     e->accept (*this);
00800 
00801   print_parens (expr, ")");
00802 }
00803 
00804 void
00805 tree_print_code::visit_return_command (tree_return_command&)
00806 {
00807   indent ();
00808 
00809   os << "return";
00810 }
00811 
00812 void
00813 tree_print_code::visit_return_list (tree_return_list& lst)
00814 {
00815   tree_return_list::iterator p = lst.begin ();
00816 
00817   while (p != lst.end ())
00818     {
00819       tree_index_expression *elt = *p++;
00820 
00821       if (elt)
00822         {
00823           elt->accept (*this);
00824 
00825           if (p != lst.end ())
00826             os << ", ";
00827         }
00828     }
00829 }
00830 
00831 void
00832 tree_print_code::visit_simple_assignment (tree_simple_assignment& expr)
00833 {
00834   indent ();
00835 
00836   print_parens (expr, "(");
00837 
00838   tree_expression *lhs = expr.left_hand_side ();
00839 
00840   if (lhs)
00841     lhs->accept (*this);
00842 
00843   os << " " << expr.oper () << " ";
00844 
00845   tree_expression *rhs = expr.right_hand_side ();
00846 
00847   if (rhs)
00848     rhs->accept (*this);
00849 
00850   print_parens (expr, ")");
00851 }
00852 
00853 void
00854 tree_print_code::visit_statement (tree_statement& stmt)
00855 {
00856   print_comment_list (stmt.comment_text ());
00857 
00858   tree_command *cmd = stmt.command ();
00859 
00860   if (cmd)
00861     {
00862       cmd->accept (*this);
00863 
00864       if (! stmt.print_result ())
00865         {
00866           os << ";";
00867           newline (" ");
00868         }
00869       else
00870         newline ();
00871     }
00872   else
00873     {
00874       tree_expression *expr = stmt.expression ();
00875 
00876       if (expr)
00877         {
00878           expr->accept (*this);
00879 
00880           if (! stmt.print_result ())
00881             {
00882               os << ";";
00883               newline (" ");
00884             }
00885           else
00886             newline ();
00887         }
00888     }
00889 }
00890 
00891 void
00892 tree_print_code::visit_statement_list (tree_statement_list& lst)
00893 {
00894   for (tree_statement_list::iterator p = lst.begin (); p != lst.end (); p++)
00895     {
00896       tree_statement *elt = *p;
00897 
00898       if (elt)
00899         elt->accept (*this);
00900     }
00901 }
00902 
00903 void
00904 tree_print_code::visit_switch_case (tree_switch_case& cs)
00905 {
00906   print_comment_list (cs.leading_comment ());
00907 
00908   indent ();
00909 
00910   if (cs.is_default_case ())
00911     os << "otherwise";
00912   else
00913     os << "case ";
00914 
00915   tree_expression *label = cs.case_label ();
00916 
00917   if (label)
00918     label->accept (*this);
00919 
00920   newline ();
00921 
00922   tree_statement_list *list = cs.commands ();
00923 
00924   if (list)
00925     {
00926       increment_indent_level ();
00927 
00928       list->accept (*this);
00929 
00930       newline ();
00931 
00932       decrement_indent_level ();
00933     }
00934 }
00935 
00936 void
00937 tree_print_code::visit_switch_case_list (tree_switch_case_list& lst)
00938 {
00939   tree_switch_case_list::iterator p = lst.begin ();
00940 
00941   while (p != lst.end ())
00942     {
00943       tree_switch_case *elt = *p++;
00944 
00945       if (elt)
00946         elt->accept (*this);
00947     }
00948 }
00949 
00950 void
00951 tree_print_code::visit_switch_command (tree_switch_command& cmd)
00952 {
00953   print_comment_list (cmd.leading_comment ());
00954 
00955   indent ();
00956 
00957   os << "switch ";
00958 
00959   tree_expression *expr = cmd.switch_value ();
00960 
00961   if (expr)
00962     expr->accept (*this);
00963 
00964   newline ();
00965 
00966   tree_switch_case_list *list = cmd.case_list ();
00967 
00968   if (list)
00969     {
00970       increment_indent_level ();
00971 
00972       list->accept (*this);
00973 
00974       decrement_indent_level ();
00975     }
00976 
00977   print_indented_comment (cmd.leading_comment ());
00978 
00979   indent ();
00980 
00981   os << "endswitch";
00982 }
00983 
00984 void
00985 tree_print_code::visit_try_catch_command (tree_try_catch_command& cmd)
00986 {
00987   print_comment_list (cmd.leading_comment ());
00988 
00989   indent ();
00990 
00991   os << "try";
00992 
00993   newline ();
00994 
00995   tree_statement_list *try_code = cmd.body ();
00996 
00997   if (try_code)
00998     {
00999       increment_indent_level ();
01000 
01001       try_code->accept (*this);
01002 
01003       decrement_indent_level ();
01004     }
01005 
01006   print_indented_comment (cmd.middle_comment ());
01007 
01008   indent ();
01009 
01010   os << "catch";
01011 
01012   newline ();
01013 
01014   tree_statement_list *catch_code = cmd.cleanup ();
01015 
01016   if (catch_code)
01017     {
01018       increment_indent_level ();
01019 
01020       catch_code->accept (*this);
01021 
01022       decrement_indent_level ();
01023     }
01024 
01025   print_indented_comment (cmd.trailing_comment ());
01026 
01027   indent ();
01028 
01029   os << "end_try_catch";
01030 }
01031 
01032 void
01033 tree_print_code::visit_unwind_protect_command
01034   (tree_unwind_protect_command& cmd)
01035 {
01036   print_comment_list (cmd.leading_comment ());
01037 
01038   indent ();
01039 
01040   os << "unwind_protect";
01041 
01042   newline ();
01043 
01044   tree_statement_list *unwind_protect_code = cmd.body ();
01045 
01046   if (unwind_protect_code)
01047     {
01048       increment_indent_level ();
01049 
01050       unwind_protect_code->accept (*this);
01051 
01052       decrement_indent_level ();
01053     }
01054 
01055   print_indented_comment (cmd.middle_comment ());
01056 
01057   indent ();
01058 
01059   os << "unwind_protect_cleanup";
01060 
01061   newline ();
01062 
01063   tree_statement_list *cleanup_code = cmd.cleanup ();
01064 
01065   if (cleanup_code)
01066     {
01067       increment_indent_level ();
01068 
01069       cleanup_code->accept (*this);
01070 
01071       decrement_indent_level ();
01072     }
01073 
01074   print_indented_comment (cmd.trailing_comment ());
01075 
01076   indent ();
01077 
01078   os << "end_unwind_protect";
01079 }
01080 
01081 void
01082 tree_print_code::visit_while_command (tree_while_command& cmd)
01083 {
01084   print_comment_list (cmd.leading_comment ());
01085 
01086   indent ();
01087 
01088   os << "while ";
01089 
01090   tree_expression *expr = cmd.condition ();
01091 
01092   if (expr)
01093     expr->accept (*this);
01094 
01095   newline ();
01096 
01097   tree_statement_list *list = cmd.body ();
01098 
01099   if (list)
01100     {
01101       increment_indent_level ();
01102 
01103       list->accept (*this);
01104 
01105       decrement_indent_level ();
01106     }
01107 
01108   print_indented_comment (cmd.trailing_comment ());
01109 
01110   indent ();
01111 
01112   os << "endwhile";
01113 }
01114 
01115 void
01116 tree_print_code::visit_do_until_command (tree_do_until_command& cmd)
01117 {
01118   print_comment_list (cmd.leading_comment ());
01119 
01120   indent ();
01121 
01122   os << "do";
01123 
01124   newline ();
01125 
01126   tree_statement_list *list = cmd.body ();
01127 
01128   if (list)
01129     {
01130       increment_indent_level ();
01131 
01132       list->accept (*this);
01133 
01134       decrement_indent_level ();
01135     }
01136 
01137   print_indented_comment (cmd.trailing_comment ());
01138 
01139   indent ();
01140 
01141   os << "until";
01142 
01143   tree_expression *expr = cmd.condition ();
01144 
01145   if (expr)
01146     expr->accept (*this);
01147 
01148   newline ();
01149 }
01150 
01151 void
01152 tree_print_code::print_fcn_handle_body (tree_statement_list *b)
01153 {
01154   if (b)
01155     {
01156       assert (b->length () == 1);
01157 
01158       tree_statement *s = b->front ();
01159 
01160       if (s)
01161         {
01162           if (s->is_expression ())
01163             {
01164               tree_expression *e = s->expression ();
01165 
01166               if (e)
01167                 {
01168                   suppress_newlines++;
01169                   e->accept (*this);
01170                   suppress_newlines--;
01171                 }
01172             }
01173           else
01174             {
01175               tree_command *c = s->command ();
01176 
01177               suppress_newlines++;
01178               c->accept (*this);
01179               suppress_newlines--;
01180             }
01181         }
01182     }
01183 }
01184 
01185 // Each print_code() function should call this before printing
01186 // anything.
01187 //
01188 // This doesn't need to be fast, but isn't there a better way?
01189 
01190 void
01191 tree_print_code::indent (void)
01192 {
01193   assert (curr_print_indent_level >= 0);
01194 
01195   if (beginning_of_line)
01196     {
01197       os << prefix;
01198 
01199       for (int i = 0; i < curr_print_indent_level; i++)
01200         os << " ";
01201 
01202       beginning_of_line = false;
01203     }
01204 }
01205 
01206 // All print_code() functions should use this to print new lines.
01207 
01208 void
01209 tree_print_code::newline (const char *alt_txt)
01210 {
01211   if (suppress_newlines)
01212     os << alt_txt;
01213   else
01214     {
01215       os << "\n";
01216 
01217       beginning_of_line = true;
01218     }
01219 }
01220 
01221 // For ressetting print_code state.
01222 
01223 void
01224 tree_print_code::reset (void)
01225 {
01226   beginning_of_line = true;
01227   curr_print_indent_level = 0;
01228   while (nesting.top () != 'n')
01229     nesting.pop ();
01230 }
01231 
01232 void
01233 tree_print_code::print_parens (const tree_expression& expr, const char *txt)
01234 {
01235   int n = expr.paren_count ();
01236 
01237   for (int i = 0; i < n; i++)
01238     os << txt;
01239 }
01240 
01241 void
01242 tree_print_code::print_comment_elt (const octave_comment_elt& elt)
01243 {
01244   bool printed_something = false;
01245 
01246   bool prev_char_was_newline = false;
01247 
01248   std::string comment = elt.text ();
01249 
01250   size_t len = comment.length ();
01251 
01252   size_t i = 0;
01253 
01254   while (i < len && comment[i++] == '\n')
01255     ; /* Skip leading new lines. */
01256   i--;
01257 
01258   while (i < len)
01259     {
01260       char c = comment[i++];
01261 
01262       if (c == '\n')
01263         {
01264           if (prev_char_was_newline)
01265             os << "##";
01266 
01267           newline ();
01268 
01269           prev_char_was_newline = true;
01270         }
01271       else
01272         {
01273           if (beginning_of_line)
01274             {
01275               printed_something = true;
01276 
01277               indent ();
01278 
01279               os << "##";
01280 
01281               if (! (isspace (c) || c == '!'))
01282                 os << " ";
01283             }
01284 
01285           os << static_cast<char> (c);
01286 
01287           prev_char_was_newline = false;
01288         }
01289     }
01290 
01291   if (printed_something && ! beginning_of_line)
01292     newline ();
01293 }
01294 
01295 void
01296 tree_print_code::print_comment_list (octave_comment_list *comment_list)
01297 {
01298   if (comment_list)
01299     {
01300       octave_comment_list::iterator p = comment_list->begin ();
01301 
01302       while (p != comment_list->end ())
01303         {
01304           octave_comment_elt elt = *p++;
01305 
01306           print_comment_elt (elt);
01307 
01308           if (p != comment_list->end ())
01309             newline ();
01310         }
01311     }
01312 }
01313 
01314 void
01315 tree_print_code::print_indented_comment (octave_comment_list *comment_list)
01316 {
01317   increment_indent_level ();
01318 
01319   print_comment_list (comment_list);
01320 
01321   decrement_indent_level ();
01322 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines