home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / octa21fs.zip / octave / octave-2.1.23 / src / pt-pr-code.cc < prev    next >
C/C++ Source or Header  |  2000-01-15  |  18KB  |  1,164 lines

  1. /*
  2.  
  3. Copyright (C) 1996, 1997 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 2, or (at your option) any
  10. 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, write to the Free
  19. Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. */
  22.  
  23. #if defined (__GNUG__)
  24. #pragma implementation
  25. #endif
  26.  
  27. #ifdef HAVE_CONFIG_H
  28. #include <config.h>
  29. #endif
  30.  
  31. #include <iostream.h>
  32.  
  33. #include "error.h"
  34. #include "ov-usr-fcn.h"
  35. #include "pr-output.h"
  36. #include "pt-all.h"
  37.  
  38. void
  39. tree_print_code::visit_argument_list (tree_argument_list& lst)
  40. {
  41.   Pix p = lst.first ();
  42.  
  43.   while (p)
  44.     {
  45.       tree_expression *elt = lst (p);
  46.  
  47.       lst.next (p);
  48.  
  49.       if (elt)
  50.     {
  51.       elt->accept (*this);
  52.  
  53.       if (p)
  54.         os << ", ";
  55.     }
  56.     }
  57. }
  58.  
  59. void
  60. tree_print_code::visit_binary_expression (tree_binary_expression& expr)
  61. {
  62.   indent ();
  63.  
  64.   print_parens (expr, "(");
  65.  
  66.   tree_expression *op1 = expr.lhs ();
  67.  
  68.   if (op1)
  69.     op1->accept (*this);
  70.  
  71.   os << " " << expr.oper () << " ";
  72.  
  73.   tree_expression *op2 = expr.rhs ();
  74.  
  75.   if (op2)
  76.     op2->accept (*this);
  77.  
  78.   print_parens (expr, ")");
  79. }
  80.  
  81. void
  82. tree_print_code::visit_break_command (tree_break_command&)
  83. {
  84.   indent ();
  85.  
  86.   os << "break";
  87. }
  88.  
  89. void
  90. tree_print_code::visit_colon_expression (tree_colon_expression& expr)
  91. {
  92.   indent ();
  93.  
  94.   print_parens (expr, "(");
  95.  
  96.   tree_expression *op1 = expr.base ();
  97.  
  98.   if (op1)
  99.     op1->accept (*this);
  100.  
  101.   // Stupid syntax.
  102.  
  103.   tree_expression *op3 = expr.increment ();
  104.  
  105.   if (op3)
  106.     {
  107.       os << ":";
  108.       op3->accept (*this);
  109.     }
  110.  
  111.   tree_expression *op2 = expr.limit ();
  112.  
  113.   if (op2)
  114.     {
  115.       os << ":";
  116.       op2->accept (*this);
  117.     }
  118.  
  119.   print_parens (expr, ")");
  120. }
  121.  
  122. void
  123. tree_print_code::visit_continue_command (tree_continue_command&)
  124. {
  125.   indent ();
  126.  
  127.   os << "continue";
  128. }
  129.  
  130. void
  131. tree_print_code::visit_decl_command (tree_decl_command& cmd)
  132. {
  133.   indent ();
  134.  
  135.   os << cmd.name () << " ";
  136.  
  137.   tree_decl_init_list *init_list = cmd.initializer_list ();
  138.  
  139.   if (init_list)
  140.     init_list->accept (*this);
  141. }
  142.  
  143. void
  144. tree_print_code::visit_decl_elt (tree_decl_elt& cmd)
  145. {
  146.   tree_identifier *id = cmd.ident ();
  147.  
  148.   if (id)
  149.     id->accept (*this);
  150.  
  151.   tree_expression *expr = cmd.expression ();
  152.  
  153.   if (expr)
  154.     {
  155.       os << " = ";
  156.  
  157.       expr->accept (*this);
  158.     }
  159. }
  160.  
  161. void
  162. tree_print_code::visit_decl_init_list (tree_decl_init_list& lst)
  163. {
  164.   Pix p = lst.first ();
  165.  
  166.   while (p)
  167.     {
  168.       tree_decl_elt *elt = lst (p);
  169.  
  170.       lst.next (p);
  171.  
  172.       if (elt)
  173.     {
  174.       elt->accept (*this);
  175.  
  176.       if (p)
  177.         os << ", ";
  178.     }
  179.     }
  180. }
  181.  
  182. void
  183. tree_print_code::visit_simple_for_command (tree_simple_for_command& cmd)
  184. {
  185.   indent ();
  186.  
  187.   os << "for ";
  188.  
  189.   tree_expression *lhs = cmd.left_hand_side ();
  190.  
  191.   if (lhs)
  192.     lhs->accept (*this);
  193.  
  194.   os << " = ";
  195.  
  196.   tree_expression *expr = cmd.control_expr ();
  197.  
  198.   if (expr)
  199.     expr->accept (*this);
  200.  
  201.   newline ();
  202.  
  203.   tree_statement_list *list = cmd.body ();
  204.  
  205.   if (list)
  206.     {
  207.       increment_indent_level ();
  208.       list->accept (*this);
  209.       decrement_indent_level ();
  210.     }
  211.  
  212.   indent ();
  213.  
  214.   os << "endfor";
  215. }
  216.  
  217. void
  218. tree_print_code::visit_complex_for_command (tree_complex_for_command& cmd)
  219. {
  220.   indent ();
  221.  
  222.   os << "for [";
  223.  
  224.   tree_argument_list *lhs = cmd.left_hand_side ();
  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.   newline ();
  237.  
  238.   tree_statement_list *list = cmd.body ();
  239.  
  240.   if (list)
  241.     {
  242.       increment_indent_level ();
  243.       list->accept (*this);
  244.       decrement_indent_level ();
  245.     }
  246.  
  247.   indent ();
  248.  
  249.   os << "endfor";
  250. }
  251.  
  252. void
  253. tree_print_code::visit_octave_user_function (octave_user_function& fcn)
  254. {
  255.   reset ();
  256.  
  257.   visit_octave_user_function_header (fcn);
  258.  
  259.   tree_statement_list *cmd_list = fcn.body ();
  260.  
  261.   if (cmd_list)
  262.     {
  263.       increment_indent_level ();
  264.       cmd_list->accept (*this);
  265.       decrement_indent_level ();
  266.     }
  267.  
  268.   visit_octave_user_function_trailer (fcn);
  269. }
  270.  
  271. void
  272. tree_print_code::visit_octave_user_function_header (octave_user_function& fcn)
  273. {
  274.   indent ();
  275.  
  276.   os << "function ";
  277.  
  278.   tree_parameter_list *ret_list = fcn.return_list ();
  279.  
  280.   if (ret_list)
  281.     {
  282.       bool takes_var_return = fcn.takes_var_return ();
  283.  
  284.       int len = ret_list->length ();
  285.  
  286.       if (len > 1 || takes_var_return)
  287.     os << "[";
  288.  
  289.       ret_list->accept (*this);
  290.  
  291.       if (takes_var_return)
  292.     {
  293.       if (len > 0)
  294.         os << ", ";
  295.  
  296.       os << "...";
  297.     }
  298.  
  299.       if (len > 1 || takes_var_return)
  300.     os << "]";
  301.  
  302.       os << " = ";
  303.     }
  304.  
  305.   string fcn_name = fcn.function_name ();
  306.  
  307.   os << (fcn_name.empty () ? string ("(empty)") : fcn_name) << " ";
  308.  
  309.   tree_parameter_list *param_list = fcn.parameter_list ();
  310.  
  311.   if (param_list)
  312.     {
  313.       bool takes_varargs = fcn.takes_varargs ();
  314.  
  315.       int len = param_list->length ();
  316.  
  317.       if (len > 0 || takes_varargs)
  318.     os << "(";
  319.  
  320.       param_list->accept (*this);
  321.  
  322.       if (takes_varargs)
  323.     {
  324.       if (len > 0)
  325.         os << ", ";
  326.  
  327.       os << "...";
  328.     }
  329.  
  330.       if (len > 0 || takes_varargs)
  331.     {
  332.       os << ")";
  333.       newline ();
  334.     }
  335.     }
  336.   else
  337.     {
  338.       os << "()";
  339.       newline ();
  340.     }
  341. }
  342.  
  343. void
  344. tree_print_code::visit_octave_user_function_trailer (octave_user_function&)
  345. {
  346.   indent ();
  347.  
  348.   os << "endfunction";
  349.  
  350.   newline ();
  351. }
  352.  
  353. void
  354. tree_print_code::visit_identifier (tree_identifier& id)
  355. {
  356.   indent ();
  357.  
  358.   print_parens (id, "(");
  359.  
  360.   string nm = id.name ();
  361.   os << (nm.empty () ? string ("(empty)") : nm);
  362.  
  363.   print_parens (id, ")");
  364. }
  365.  
  366. void
  367. tree_print_code::visit_if_clause (tree_if_clause& cmd)
  368. {
  369.   tree_expression *expr = cmd.condition ();
  370.  
  371.   if (expr)
  372.     expr->accept (*this);
  373.  
  374.   newline ();
  375.  
  376.   increment_indent_level ();
  377.  
  378.   tree_statement_list *list = cmd.commands ();
  379.  
  380.   if (list)
  381.     {
  382.       list->accept (*this);
  383.  
  384.       decrement_indent_level ();
  385.     }
  386. }
  387.  
  388. void
  389. tree_print_code::visit_if_command (tree_if_command& cmd)
  390. {
  391.   indent ();
  392.  
  393.   os << "if ";
  394.  
  395.   tree_if_command_list *list = cmd.cmd_list ();
  396.  
  397.   if (list)
  398.     list->accept (*this);
  399.  
  400.   indent ();
  401.  
  402.   os << "endif";
  403. }
  404.  
  405. void
  406. tree_print_code::visit_if_command_list (tree_if_command_list& lst)
  407. {
  408.   Pix p = lst.first ();
  409.  
  410.   bool first_elt = true;
  411.  
  412.   while (p)
  413.     {
  414.       tree_if_clause *elt = lst (p);
  415.  
  416.       if (elt)
  417.     {
  418.       if (! first_elt)
  419.         {
  420.           indent ();
  421.  
  422.           if (elt->is_else_clause ())
  423.         os << "else";
  424.           else
  425.         os << "elseif ";
  426.         }
  427.  
  428.       elt->accept (*this);
  429.     }
  430.  
  431.       first_elt = false;
  432.       lst.next (p);
  433.     }
  434. }
  435.  
  436. void
  437. tree_print_code::visit_index_expression (tree_index_expression& expr)
  438. {
  439.   indent ();
  440.  
  441.   print_parens (expr, "(");
  442.  
  443.   tree_expression *e = expr.expression ();
  444.  
  445.   if (e)
  446.     e->accept (*this);
  447.  
  448.   tree_argument_list *list = expr.arg_list ();
  449.  
  450.   if (list)
  451.     {
  452.       os << " (";
  453.       list->accept (*this);
  454.       os << ")";
  455.     }
  456.  
  457.   print_parens (expr, ")");
  458. }
  459.  
  460. void
  461. tree_print_code::visit_indirect_ref (tree_indirect_ref& expr)
  462. {
  463.   indent ();
  464.  
  465.   print_parens (expr, "(");
  466.  
  467.   tree_expression *e = expr.expression ();
  468.  
  469.   if (e)
  470.     e->accept (*this);
  471.  
  472.   os << "." << expr.elt_name ();
  473.  
  474.   print_parens (expr, ")");
  475. }
  476.  
  477. void
  478. tree_print_code::visit_matrix (tree_matrix& lst)
  479. {
  480.   indent ();
  481.  
  482.   print_parens (lst, "(");
  483.  
  484.   os << "[";
  485.  
  486.   Pix p = lst.first ();
  487.  
  488.   while (p)
  489.     {
  490.       tree_argument_list *elt = lst (p);
  491.  
  492.       lst.next (p);
  493.  
  494.       if (elt)
  495.     {
  496.       elt->accept (*this);
  497.  
  498.       if (p)
  499.         os << "; ";
  500.     }
  501.     }
  502.  
  503.   os << "]";
  504.  
  505.   print_parens (lst, ")");
  506. }
  507.  
  508. void
  509. tree_print_code::visit_cell (tree_cell& lst)
  510. {
  511.   indent ();
  512.  
  513.   print_parens (lst, "(");
  514.  
  515.   os << "{";
  516.  
  517.   Pix p = lst.first ();
  518.  
  519.   while (p)
  520.     {
  521.       tree_argument_list *elt = lst (p);
  522.  
  523.       lst.next (p);
  524.  
  525.       if (elt)
  526.     {
  527.       elt->accept (*this);
  528.  
  529.       if (p)
  530.         os << "; ";
  531.     }
  532.     }
  533.  
  534.   os << "}";
  535.  
  536.   print_parens (lst, ")");
  537. }
  538.  
  539. void
  540. tree_print_code::visit_multi_assignment (tree_multi_assignment& expr)
  541. {
  542.   indent ();
  543.  
  544.   print_parens (expr, "(");
  545.  
  546.   tree_argument_list *lhs = expr.left_hand_side ();
  547.  
  548.   if (lhs)
  549.     {
  550.       int len = lhs->length ();
  551.  
  552.       if (len > 1)
  553.     os << "[";
  554.  
  555.       lhs->accept (*this);
  556.  
  557.       if (len > 1)
  558.     os << "]";
  559.     }
  560.  
  561.   os << " " << expr.oper () << " ";
  562.  
  563.   tree_expression *rhs = expr.right_hand_side ();
  564.  
  565.   if (rhs)
  566.     rhs->accept (*this);
  567.  
  568.   print_parens (expr, ")");
  569. }
  570.  
  571. void
  572. tree_print_code::visit_no_op_command (tree_no_op_command& cmd)
  573. {
  574.   indent ();
  575.  
  576.   os << cmd.original_command ();
  577. }
  578.  
  579. void
  580. tree_print_code::visit_constant (tree_constant& val)
  581. {
  582.   indent ();
  583.  
  584.   print_parens (val, "(");
  585.  
  586.   val.print_raw (os, true, print_original_text);
  587.  
  588.   print_parens (val, ")");
  589. }
  590.  
  591. void
  592. tree_print_code::visit_parameter_list (tree_parameter_list& lst)
  593. {
  594.   Pix p = lst.first ();
  595.  
  596.   while (p)
  597.     {
  598.       tree_identifier *elt = lst (p);
  599.  
  600.       lst.next (p);
  601.  
  602.       if (elt)
  603.     {
  604.       elt->accept (*this);
  605.  
  606.       if (p)
  607.         os << ", ";
  608.     }
  609.     }
  610. }
  611.  
  612. void
  613. tree_print_code::visit_plot_command (tree_plot_command& cmd)
  614. {
  615.   indent ();
  616.  
  617.   int ndim = cmd.num_dimensions ();
  618.  
  619.   switch (ndim)
  620.     {
  621.     case 1:
  622.       os << "replot";
  623.       break;
  624.  
  625.     case 2:
  626.       os << "gplot";
  627.       break;
  628.  
  629.     case 3:
  630.       os << "gsplot";
  631.       break;
  632.  
  633.     default:
  634.       os << "<unkown plot command>";
  635.       break;
  636.     }
  637.  
  638.   plot_limits *range = cmd.limits ();
  639.  
  640.   if (range)
  641.     range->accept (*this);
  642.  
  643.   subplot_list *plot_list = cmd.subplots ();
  644.  
  645.   if (plot_list)
  646.     plot_list->accept (*this);
  647. }
  648.  
  649. void
  650. tree_print_code::visit_plot_limits (plot_limits& cmd)
  651. {
  652.   plot_range *x_range = cmd.x_limits ();
  653.  
  654.   if (x_range)
  655.     x_range->accept (*this);
  656.  
  657.   plot_range *y_range = cmd.y_limits ();
  658.  
  659.   if (y_range)
  660.     y_range->accept (*this);
  661.  
  662.   plot_range *z_range = cmd.z_limits ();
  663.  
  664.   if (z_range)
  665.     z_range->accept (*this);
  666. }
  667.  
  668. void
  669. tree_print_code::visit_plot_range (plot_range& cmd)
  670. {
  671.   os << " [";
  672.  
  673.   tree_expression *lower = cmd.lower_bound ();
  674.  
  675.   if (lower)
  676.     lower->accept (*this);
  677.  
  678.   os << ":";
  679.  
  680.   tree_expression *upper = cmd.upper_bound ();
  681.  
  682.   if (upper)
  683.     upper->accept (*this);
  684.  
  685.   os << "]";
  686. }
  687.  
  688. void
  689. tree_print_code::visit_postfix_expression (tree_postfix_expression& expr)
  690. {
  691.   indent ();
  692.  
  693.   print_parens (expr, "(");
  694.  
  695.   tree_expression *e = expr.operand ();
  696.  
  697.   if (e)
  698.     e->accept (*this);
  699.  
  700.   os << expr.oper ();
  701.  
  702.   print_parens (expr, ")");
  703. }
  704.  
  705. void
  706. tree_print_code::visit_prefix_expression (tree_prefix_expression& expr)
  707. {
  708.   indent ();
  709.  
  710.   print_parens (expr, "(");
  711.  
  712.   os << expr.oper ();
  713.  
  714.   tree_expression *e = expr.operand ();
  715.  
  716.   if (e)
  717.     e->accept (*this);
  718.  
  719.   print_parens (expr, ")");
  720. }
  721.  
  722. void
  723. tree_print_code::visit_return_command (tree_return_command&)
  724. {
  725.   indent ();
  726.  
  727.   os << "return";
  728. }
  729.  
  730. void
  731. tree_print_code::visit_return_list (tree_return_list& lst)
  732. {
  733.   Pix p = lst.first ();
  734.  
  735.   while (p)
  736.     {
  737.       tree_index_expression *elt = lst (p);
  738.  
  739.       lst.next (p);
  740.  
  741.       if (elt)
  742.     {
  743.       elt->accept (*this);
  744.  
  745.       if (p)
  746.         os << ", ";
  747.     }
  748.     }
  749. }
  750.  
  751. void
  752. tree_print_code::visit_simple_assignment (tree_simple_assignment& expr)
  753. {
  754.   indent ();
  755.  
  756.   print_parens (expr, "(");
  757.  
  758.   tree_expression *lhs = expr.left_hand_side ();
  759.  
  760.   if (lhs)
  761.     lhs->accept (*this);
  762.  
  763.   os << " " << expr.oper () << " ";
  764.  
  765.   tree_expression *rhs = expr.right_hand_side ();
  766.  
  767.   if (rhs)
  768.     rhs->accept (*this);
  769.  
  770.   print_parens (expr, ")");
  771. }
  772.  
  773. void
  774. tree_print_code::visit_statement (tree_statement& stmt)
  775. {
  776.   tree_command *cmd = stmt.command ();
  777.  
  778.   if (cmd)
  779.     {
  780.       cmd->accept (*this);
  781.  
  782.       if (! stmt.print_result ())
  783.     os << ";";
  784.  
  785.       newline ();
  786.     }
  787.   else
  788.     {
  789.       tree_expression *expr = stmt.expression ();
  790.  
  791.       if (expr)
  792.     {
  793.       expr->accept (*this);
  794.  
  795.       if (! stmt.print_result ())
  796.         os << ";";
  797.  
  798.       newline ();
  799.     }
  800.     }
  801. }
  802.  
  803. void
  804. tree_print_code::visit_statement_list (tree_statement_list& lst)
  805. {
  806.   for (Pix p = lst.first (); p != 0; lst.next (p))
  807.     {
  808.       tree_statement *elt = lst (p);
  809.  
  810.       if (elt)
  811.     elt->accept (*this);
  812.     }
  813. }
  814.  
  815. void
  816. tree_print_code::visit_subplot (subplot& cmd)
  817. {
  818.   tree_expression *sp_plot_data = cmd.plot_data ();
  819.  
  820.   if (sp_plot_data)
  821.     {
  822.       os << " ";
  823.  
  824.       sp_plot_data->accept (*this);
  825.     }
  826.  
  827.   subplot_axes *sp_axes_clause = cmd.axes_clause ();
  828.  
  829.   if (sp_axes_clause)
  830.     sp_axes_clause->accept (*this);
  831.  
  832.   subplot_using *sp_using_clause = cmd.using_clause ();
  833.  
  834.   if (sp_using_clause)
  835.     sp_using_clause->accept (*this);
  836.  
  837.   tree_expression *sp_title_clause = cmd.title_clause ();
  838.  
  839.   if (sp_title_clause)
  840.     sp_title_clause->accept (*this);
  841.  
  842.   subplot_style *sp_style_clause = cmd.style_clause ();
  843.  
  844.   if (sp_style_clause)
  845.     sp_style_clause->accept (*this);
  846. }
  847.  
  848. void
  849. tree_print_code::visit_subplot_axes (subplot_axes& cmd)
  850. {
  851.   os << " axes " << cmd.axes ();
  852. }
  853.  
  854. void
  855. tree_print_code::visit_subplot_list (subplot_list& lst)
  856. {
  857.   Pix p = lst.first ();
  858.  
  859.   while (p)
  860.     {
  861.       subplot *elt = lst (p);
  862.  
  863.       lst.next (p);
  864.  
  865.       if (elt)
  866.     {
  867.       elt->accept (*this);
  868.  
  869.       if (p)
  870.         os << ",";
  871.     }
  872.     }
  873. }
  874.  
  875. void
  876. tree_print_code::visit_subplot_style (subplot_style& cmd)
  877. {
  878.   os << " with " << cmd.style ();
  879.  
  880.   tree_expression *sp_linetype = cmd.linetype ();
  881.  
  882.   if (sp_linetype)
  883.     {
  884.       os << " ";
  885.  
  886.       sp_linetype->accept (*this);
  887.     }
  888.  
  889.   tree_expression *sp_pointtype = cmd.pointtype ();
  890.  
  891.   if (sp_pointtype)
  892.     {
  893.       os << " ";
  894.  
  895.       sp_pointtype->accept (*this);
  896.     }
  897. }
  898.  
  899. void
  900. tree_print_code::visit_subplot_using (subplot_using& cmd)
  901. {
  902.   os << " using ";
  903.  
  904.   int qual_count = cmd.qualifier_count ();
  905.  
  906.   if (qual_count > 0)
  907.     {
  908.       tree_expression **x = cmd.qualifiers ();
  909.  
  910.       for (int i = 0; i < qual_count; i++)
  911.     {
  912.       if (i > 0)
  913.         os << ":";
  914.  
  915.       if (x[i])
  916.         x[i]->accept (*this);
  917.     }
  918.     }
  919.   else
  920.     {
  921.       tree_expression *scanf_fmt = cmd.scanf_format ();
  922.  
  923.       if (scanf_fmt)
  924.     scanf_fmt->accept (*this);
  925.     }
  926. }
  927.  
  928. void
  929. tree_print_code::visit_switch_case (tree_switch_case& cs)
  930. {
  931.   indent ();
  932.  
  933.   if (cs.is_default_case ())
  934.     os << "otherwise";
  935.   else
  936.     os << "case ";
  937.  
  938.   tree_expression *label = cs.case_label ();
  939.  
  940.   if (label)
  941.     label->accept (*this);
  942.  
  943.   newline ();
  944.  
  945.   increment_indent_level ();
  946.  
  947.   tree_statement_list *list = cs.commands ();
  948.  
  949.   if (list)
  950.     {
  951.       list->accept (*this);
  952.  
  953.       decrement_indent_level ();
  954.     }
  955. }
  956.  
  957. void
  958. tree_print_code::visit_switch_case_list (tree_switch_case_list& lst)
  959. {
  960.   Pix p = lst.first ();
  961.  
  962.   while (p)
  963.     {
  964.       tree_switch_case *elt = lst (p);
  965.  
  966.       if (elt)
  967.     elt->accept (*this);
  968.  
  969.       lst.next (p);
  970.     }
  971. }
  972.  
  973. void
  974. tree_print_code::visit_switch_command (tree_switch_command& cmd)
  975. {
  976.   indent ();
  977.  
  978.   os << "switch ";
  979.  
  980.   tree_expression *expr = cmd.switch_value ();
  981.  
  982.   if (expr)
  983.     expr->accept (*this);
  984.  
  985.   newline ();
  986.  
  987.   increment_indent_level ();
  988.  
  989.   tree_switch_case_list *list = cmd.case_list ();
  990.  
  991.   if (list)
  992.     list->accept (*this);
  993.  
  994.   indent ();
  995.  
  996.   os << "endswitch";
  997. }
  998.  
  999. void
  1000. tree_print_code::visit_try_catch_command (tree_try_catch_command& cmd)
  1001. {
  1002.   indent ();
  1003.  
  1004.   os << "try_catch";
  1005.  
  1006.   newline ();
  1007.  
  1008.   tree_statement_list *try_code = cmd.body ();
  1009.  
  1010.   if (try_code)
  1011.     {
  1012.       increment_indent_level ();
  1013.       try_code->accept (*this);
  1014.       decrement_indent_level ();
  1015.     }
  1016.  
  1017.   indent ();
  1018.  
  1019.   os << "catch";
  1020.  
  1021.   newline ();
  1022.  
  1023.   tree_statement_list *catch_code = cmd.cleanup ();
  1024.  
  1025.   if (catch_code)
  1026.     {
  1027.       increment_indent_level ();
  1028.       catch_code->accept (*this);
  1029.       decrement_indent_level ();
  1030.     }
  1031.  
  1032.   indent ();
  1033.  
  1034.   os << "end_try_catch";
  1035. }
  1036.  
  1037. void
  1038. tree_print_code::visit_unwind_protect_command
  1039.   (tree_unwind_protect_command& cmd)
  1040. {
  1041.   indent ();
  1042.  
  1043.   os << "unwind_protect";
  1044.  
  1045.   newline ();
  1046.  
  1047.   tree_statement_list *unwind_protect_code = cmd.body ();
  1048.  
  1049.   if (unwind_protect_code)
  1050.     {
  1051.       increment_indent_level ();
  1052.       unwind_protect_code->accept (*this);
  1053.       decrement_indent_level ();
  1054.     }
  1055.  
  1056.   indent ();
  1057.  
  1058.   os << "cleanup_code";
  1059.  
  1060.   newline ();
  1061.  
  1062.   tree_statement_list *cleanup_code = cmd.cleanup ();
  1063.  
  1064.   if (cleanup_code)
  1065.     {
  1066.       increment_indent_level ();
  1067.       cleanup_code->accept (*this);
  1068.       decrement_indent_level ();
  1069.     }
  1070.  
  1071.   indent ();
  1072.  
  1073.   os << "end_unwind_protect";
  1074. }
  1075.  
  1076. void
  1077. tree_print_code::visit_while_command (tree_while_command& cmd)
  1078. {
  1079.   indent ();
  1080.  
  1081.   os << "while ";
  1082.  
  1083.   tree_expression *expr = cmd.condition ();
  1084.  
  1085.   if (expr)
  1086.     expr->accept (*this);
  1087.  
  1088.   newline ();
  1089.  
  1090.   tree_statement_list *list = cmd.body ();
  1091.  
  1092.   if (list)
  1093.     {
  1094.       increment_indent_level ();
  1095.       list->accept (*this);
  1096.       decrement_indent_level ();
  1097.     }
  1098.  
  1099.   indent ();
  1100.  
  1101.   os << "endwhile";
  1102. }
  1103.  
  1104. // Current indentation.
  1105. int tree_print_code::curr_print_indent_level = 0;
  1106.  
  1107. // TRUE means we are at the beginning of a line.
  1108. bool tree_print_code::beginning_of_line = true;
  1109.  
  1110. // Each print_code() function should call this before printing
  1111. // anything.
  1112. //
  1113. // This doesn't need to be fast, but isn't there a better way?
  1114.  
  1115. void
  1116. tree_print_code::indent (void)
  1117. {
  1118.   assert (curr_print_indent_level >= 0);
  1119.  
  1120.   if (beginning_of_line)
  1121.     {
  1122.       os << prefix;
  1123.  
  1124.       for (int i = 0; i < curr_print_indent_level; i++)
  1125.     os << " ";
  1126.  
  1127.       beginning_of_line = false;
  1128.     }
  1129. }
  1130.  
  1131. // All print_code() functions should use this to print new lines.
  1132.  
  1133. void
  1134. tree_print_code::newline (void)
  1135. {
  1136.   os << "\n";
  1137.  
  1138.   beginning_of_line = true;
  1139. }
  1140.  
  1141. // For ressetting print_code state.
  1142.  
  1143. void
  1144. tree_print_code::reset (void)
  1145. {
  1146.   beginning_of_line = true;
  1147.   curr_print_indent_level = 0;
  1148. }
  1149.  
  1150. void
  1151. tree_print_code::print_parens (const tree_expression& expr, const char *txt)
  1152. {
  1153.   int n = expr.paren_count ();
  1154.  
  1155.   for (int i = 0; i < n; i++)
  1156.     os << txt;
  1157. }
  1158.  
  1159. /*
  1160. ;;; Local Variables: ***
  1161. ;;; mode: C++ ***
  1162. ;;; End: ***
  1163. */
  1164.