home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #4 / amigaacscoverdisc1998-041998.iso / utilities / shareware / dev / ppcsmalleiffel / lib_se / e_loop.e < prev    next >
Encoding:
Text File  |  1998-01-16  |  7.1 KB  |  275 lines

  1. --          This file is part of SmallEiffel The GNU Eiffel Compiler.
  2. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  3. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr 
  4. --                       http://www.loria.fr/SmallEiffel
  5. -- SmallEiffel is  free  software;  you can  redistribute it and/or modify it 
  6. -- under the terms of the GNU General Public License as published by the Free
  7. -- Software  Foundation;  either  version  2, or (at your option)  any  later 
  8. -- version. SmallEiffel is distributed in the hope that it will be useful,but
  9. -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. -- or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU General Public License 
  11. -- for  more  details.  You  should  have  received a copy of the GNU General 
  12. -- Public  License  along  with  SmallEiffel;  see the file COPYING.  If not,
  13. -- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  14. -- Boston, MA 02111-1307, USA.
  15. --
  16. class E_LOOP
  17.    --   
  18.    -- The Eiffel instruction : "from ... until ... loop ... end".
  19.    --
  20.  
  21. inherit INSTRUCTION;
  22.       
  23. creation make
  24.  
  25. feature 
  26.  
  27.    start_position: POSITION;
  28.      -- Of letter 'f' of "from".
  29.    
  30.    initialize: COMPOUND;
  31.  
  32.    invariant_clause: LOOP_INVARIANT;
  33.  
  34.    variant_clause: LOOP_VARIANT;
  35.  
  36.    until_expression: EXPRESSION;
  37.  
  38.    loop_body: COMPOUND;
  39.  
  40. feature {NONE}
  41.  
  42.    make(sp: like start_position;
  43.     i: like initialize; 
  44.     ic : like invariant_clause; 
  45.     vc: like variant_clause; 
  46.     ue : like until_expression;
  47.     lb : like loop_body) is
  48.       require
  49.      sp /= Void;
  50.      ue /= Void;
  51.       do
  52.      start_position := sp;
  53.      initialize := i; 
  54.      invariant_clause := ic; 
  55.      variant_clause := vc; 
  56.      until_expression := ue;
  57.      loop_body := lb;
  58.       ensure
  59.      start_position = sp;
  60.      initialize = i; 
  61.      invariant_clause = ic; 
  62.      variant_clause = vc; 
  63.      until_expression = ue;
  64.      loop_body = lb;
  65.       end;
  66.  
  67. feature
  68.  
  69.    is_pre_computable: BOOLEAN is false;
  70.  
  71.    end_mark_comment: BOOLEAN is true;
  72.    
  73. feature
  74.  
  75.    afd_check is
  76.       do
  77.      if run_control.loop_check then
  78.         if variant_clause /= Void then
  79.            variant_clause.afd_check;
  80.         end;
  81.         if invariant_clause /= Void then
  82.            invariant_clause.afd_check;
  83.         end;
  84.      end;
  85.      if initialize /= Void then
  86.         initialize.afd_check;
  87.      end;
  88.      until_expression.afd_check;
  89.      if loop_body /= Void then
  90.         loop_body.afd_check;
  91.      end;
  92.       end;
  93.    
  94.    compile_to_c is
  95.       local
  96.      loop_check, variant_flag, invariant_flag: BOOLEAN;
  97.       do
  98.      loop_check := run_control.loop_check; 
  99.      if loop_check and then variant_clause /= Void then
  100.         cpp.put_string("{int c=0;int v=0;%N");
  101.         variant_flag := true;
  102.      end;
  103.      if initialize /= Void then
  104.         initialize.compile_to_c;
  105.      end;
  106.      if loop_check and then invariant_clause /= Void then
  107.         invariant_clause.compile_to_c;
  108.         invariant_flag := true;
  109.      end;
  110.      cpp.put_string("while (!(");
  111.      if run_control.no_check then
  112.         cpp.trace_boolean_expression(until_expression);
  113.      else
  114.         until_expression.compile_to_c;
  115.      end;
  116.      cpp.put_string(")) {%N");
  117.      if variant_flag then
  118.         cpp.variant_check(variant_clause.expression);
  119.      end;
  120.      if loop_body /= Void then
  121.         loop_body.compile_to_c;
  122.      end;
  123.      if invariant_flag then
  124.         invariant_clause.compile_to_c;
  125.      end;
  126.      cpp.put_string(fz_12);
  127.      if variant_flag then
  128.         cpp.put_string(fz_12);
  129.      end;
  130.       end;
  131.    
  132.    compile_to_jvm is
  133.       local
  134.      point1, point2: INTEGER
  135.       do
  136.      if initialize /= Void then
  137.         initialize.compile_to_jvm;
  138.      end;
  139.      point1 := code_attribute.program_counter;
  140.      if invariant_clause /= Void then
  141.         if run_control.loop_check then
  142.            invariant_clause.compile_to_jvm(true);
  143.         end;
  144.      end;     
  145.      point2 := until_expression.jvm_branch_if_true;
  146.      if loop_body /= Void then
  147.         loop_body.compile_to_jvm;
  148.      end;
  149.      code_attribute.opcode_goto_backward(point1);
  150.      code_attribute.resolve_u2_branch(point2);
  151.       end;
  152.    
  153.    use_current: BOOLEAN is   
  154.       local
  155.      loop_check: BOOLEAN;
  156.       do
  157.      loop_check := run_control.loop_check; 
  158.      if loop_check and then variant_clause /= Void then
  159.         Result := Result or else variant_clause.use_current;
  160.      end;
  161.      if initialize /= Void then
  162.         Result := Result or else initialize.use_current;
  163.      end;
  164.      Result := Result or else until_expression.use_current;
  165.      if loop_check and then invariant_clause /= Void then
  166.         Result := Result or else invariant_clause.use_current;
  167.      end;
  168.      if loop_body /= Void then
  169.         Result := Result or else loop_body.use_current;
  170.      end;
  171.       end;
  172.    
  173.    to_runnable(rc: like run_compound): like Current is
  174.       local
  175.      ue : like until_expression;
  176.      loop_check: BOOLEAN;
  177.       do
  178.      loop_check := run_control.loop_check; 
  179.      if run_compound = Void then
  180.         run_compound := rc;
  181.         if initialize /= Void then
  182.            initialize := initialize.to_runnable(current_type);
  183.            if initialize = Void then
  184.           error(start_position,"Bad initialisation part.");
  185.            end;
  186.         end;
  187.         if loop_check and then invariant_clause /= Void then
  188.            invariant_clause := invariant_clause.to_runnable(rc.current_type);
  189.            if invariant_clause = Void then
  190.           error(start_position,"Bad invariant.");
  191.            end;
  192.         end;
  193.         if loop_check and then variant_clause /= Void then
  194.            variant_clause := variant_clause.to_runnable(current_type);
  195.            if variant_clause = Void then
  196.           error(start_position,"Bad variant for this loop.");
  197.            end;
  198.         end;
  199.         ue := until_expression.to_runnable(current_type);
  200.         if ue /= Void then
  201.            if not ue.result_type.is_boolean then
  202.           error(ue.start_position,
  203.             "Expression of until must be BOOLEAN.");
  204.           eh.add_type(ue.result_type,fz_is_not_boolean);
  205.           eh.print_as_error;
  206.            end;
  207.            until_expression := ue;
  208.         else
  209.            error(start_position, "This loop has an invalid expression.");
  210.         end;
  211.         if loop_body /= Void then
  212.            loop_body := loop_body.to_runnable(current_type);
  213.            if loop_body = Void then
  214.           error(start_position,"Invalid loop body.");
  215.            end;
  216.         end;
  217.         if nb_errors = 0 then
  218.            Result := Current;
  219.         end;
  220.      else
  221.         !!Result.make(start_position,initialize,invariant_clause,
  222.               variant_clause,until_expression,loop_body); 
  223.         Result := Result.to_runnable(rc);
  224.      end;
  225.       end;
  226.    
  227.    pretty_print is
  228.       local
  229.      semi_colon_flag: BOOLEAN;
  230.       do
  231.      fmt.indent;
  232.      fmt.keyword(fz_from);
  233.         if initialize /= Void then
  234.            initialize.pretty_print;
  235.         end;
  236.      if invariant_clause /= Void then
  237.         invariant_clause.pretty_print;
  238.      end;
  239.      if variant_clause /= Void then
  240.         fmt.indent;
  241.         fmt.keyword(fz_variant);
  242.         semi_colon_flag := fmt.semi_colon_flag;
  243.         fmt.set_semi_colon_flag(false);
  244.         variant_clause.pretty_print;
  245.         fmt.set_semi_colon_flag(semi_colon_flag);
  246.      end;
  247.      fmt.indent;
  248.      fmt.keyword(fz_until);
  249.      fmt.level_incr;
  250.      fmt.indent;
  251.      fmt.set_semi_colon_flag(false);
  252.      until_expression.pretty_print;
  253.      fmt.level_decr;
  254.      fmt.indent;
  255.      fmt.keyword(fz_loop);
  256.      fmt.indent;
  257.      if loop_body /= Void then
  258.         loop_body.pretty_print;
  259.      end;
  260.      fmt.indent;
  261.      fmt.keyword("end;");
  262.      if fmt.print_end_loop then
  263.         fmt.put_end(fz_loop);
  264.      end;
  265.       end;
  266.  
  267. invariant
  268.    
  269.    start_position /= Void;
  270.    
  271.    until_expression /= Void;
  272.    
  273. end -- E_LOOP
  274.  
  275.