home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / sofa / archive / SmallEiffel.lha / SmallEiffel / lib_se / compound.e < prev    next >
Text File  |  1999-06-05  |  8KB  |  316 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://SmallEiffel.loria.fr
  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 COMPOUND
  17.    --
  18.    -- A list of Eiffel instructions.
  19.    --
  20.  
  21. inherit GLOBALS;
  22.  
  23. creation make, from_compound
  24.  
  25. feature
  26.  
  27.    header_comment: COMMENT;
  28.  
  29. feature {NONE}
  30.  
  31.    current_type: TYPE;
  32.          -- Not Void when checked.
  33.  
  34. feature {COMPOUND}
  35.  
  36.    first_one: INSTRUCTION;
  37.          -- The `first_one' if any.
  38.  
  39.    remainder: FIXED_ARRAY[INSTRUCTION];
  40.          -- Non Void when the list has more than one element.
  41.  
  42. feature {NONE}
  43.  
  44.    make(hc: like header_comment; fo: like first_one; r: like remainder) is
  45.       require
  46.          hc /= Void or else fo /= Void;
  47.          r /= Void implies fo /= Void
  48.       do
  49.          header_comment := hc;
  50.          first_one := fo;
  51.          remainder := r;
  52.       ensure
  53.          header_comment = hc;
  54.          first_one = fo;
  55.          remainder = r
  56.       end;
  57.  
  58. feature {NONE}
  59.  
  60.    from_compound(c: like Current) is
  61.       require
  62.          c /= Void
  63.       do
  64.          header_comment := c.header_comment;
  65.          first_one := c.first_one;
  66.          remainder := c.remainder;
  67.          if remainder /= Void then
  68.             remainder := remainder.twin;
  69.          end;
  70.       ensure
  71.          header_comment = c.header_comment;
  72.          count = c.count
  73.       end;
  74.  
  75. feature
  76.  
  77.    count: INTEGER is
  78.       do
  79.          if first_one = Void then
  80.          elseif remainder /= Void then
  81.             Result := remainder.upper + 2;
  82.          else
  83.             Result := 1;
  84.          end;
  85.       end;
  86.  
  87.    first: INSTRUCTION is
  88.       require
  89.          count >= 1
  90.       do
  91.          Result := first_one;
  92.       ensure
  93.          Result /= Void
  94.       end;
  95.  
  96.    item(i: INTEGER): INSTRUCTION is
  97.       require
  98.          i.in_range(1,count)
  99.       do
  100.          if i = 1 then
  101.             Result := first_one;
  102.          else
  103.             Result := remainder.item(i - 2);
  104.          end;
  105.       end;
  106.  
  107.    start_position: POSITION is
  108.       do
  109.          if count > 0 then
  110.             Result := first_one.start_position;
  111.          end;
  112.       end;
  113.  
  114.    run_class: RUN_CLASS is
  115.       do
  116.          Result := current_type.run_class;
  117.       end;
  118.  
  119.    afd_check is
  120.       local
  121.          i: INTEGER;
  122.       do
  123.          from
  124.             i := count;
  125.          until
  126.             i = 0
  127.          loop
  128.             item(i).afd_check;
  129.             i := i - 1;
  130.          end;
  131.       end;
  132.  
  133.    compile_to_c is
  134.       local
  135.          i, c: INTEGER;
  136.          instruction: INSTRUCTION;
  137.          need_se_tmp: BOOLEAN;
  138.          no_check: BOOLEAN;
  139.       do
  140.          from
  141.             no_check := run_control.no_check;
  142.             i := 1;
  143.             c := count;
  144.          until
  145.             i > c
  146.          loop
  147.             instruction := item(i);
  148.             instruction.collect_c_tmp;
  149.             need_se_tmp := cpp.se_tmp_open_declaration;
  150.             instruction.compile_to_c;
  151.             if need_se_tmp then
  152.                cpp.se_tmp_close_declaration;
  153.             end;
  154.             i := i + 1;
  155.          end;
  156.       end;
  157.  
  158.    c2jvm: BOOLEAN is
  159.          -- Result is false when no byte code is produced.
  160.       local
  161.          pc: INTEGER;
  162.       do
  163.          pc := code_attribute.program_counter;
  164.          compile_to_jvm;
  165.          Result := pc /= code_attribute.program_counter;
  166.       end;
  167.  
  168.    compile_to_jvm is
  169.       local
  170.          i, c: INTEGER;
  171.          instruction: INSTRUCTION;
  172.          trace: BOOLEAN;
  173.          ca: like code_attribute;
  174.       do
  175.          from
  176.             c := count;
  177.             ca := code_attribute;
  178.             trace := run_control.trace;
  179.             i := 1;
  180.          until
  181.             i > c
  182.          loop
  183.             instruction := item(i);
  184.             if trace then
  185.                ca.se_trace(current_type,instruction.start_position);
  186.             end;
  187.             instruction.compile_to_jvm;
  188.             i := i + 1;
  189.          end;
  190.       end;
  191.  
  192.    use_current: BOOLEAN is
  193.       local
  194.          i: INTEGER;
  195.       do
  196.          from
  197.             i := count;
  198.          until
  199.             Result or else i = 0
  200.          loop
  201.             Result := item(i).use_current;
  202.             i := i - 1;
  203.          end;
  204.       end;
  205.  
  206.    is_pre_computable: BOOLEAN is
  207.       local
  208.          i: INTEGER;
  209.       do
  210.          from
  211.             i := count;
  212.             Result := true;
  213.          until
  214.             not Result or else i = 0
  215.          loop
  216.             Result := item(i).is_pre_computable;
  217.             i := i - 1;
  218.          end;
  219.       end;
  220.  
  221.    to_runnable(ct: TYPE): like Current is
  222.       require
  223.          ct.run_type = ct;
  224.          nb_errors = 0
  225.       local
  226.          i: INTEGER;
  227.          i1, i2: INSTRUCTION;
  228.       do
  229.          if first_one = Void then
  230.             Result := Current;
  231.          elseif current_type = Void then
  232.             current_type := ct;
  233.             from
  234.                i := count;
  235.             until
  236.                i = 0
  237.             loop
  238.                i1 := item(i);
  239.                i2 := i1.to_runnable(ct);
  240.                if nb_errors > 0 then
  241.                   eh.append("Bad instruction (when interpreted in ");
  242.                   eh.append(current_type.written_mark);
  243.                   eh.add_position(i1.start_position);
  244.                   fatal_error(").");
  245.                else
  246.                   put(i2,i);
  247.                end;
  248.                i := i - 1;
  249.             end;
  250.             Result := Current;
  251.          else
  252.             !!Result.from_compound(Current);
  253.             Result := Result.to_runnable(ct);
  254.          end;
  255.       ensure
  256.          Result /= Void
  257.       end;
  258.  
  259.    pretty_print is
  260.       require
  261.          fmt.indent_level >= 2;
  262.       local
  263.          i, c: INTEGER;
  264.       do
  265.          c := count
  266.          fmt.level_incr;
  267.          fmt.indent;
  268.          if header_comment /= Void then
  269.             header_comment.pretty_print;
  270.          end;
  271.          from
  272.             i := 1;
  273.          until
  274.             i > c
  275.          loop
  276.             fmt.set_semi_colon_flag(true);
  277.             if fmt.zen_mode and then i = c then
  278.                fmt.set_semi_colon_flag(false);
  279.             end;
  280.             fmt.indent;
  281.             item(i).pretty_print;
  282.             i := i + 1;
  283.          end;
  284.          fmt.level_decr;
  285.       ensure
  286.          fmt.indent_level = old fmt.indent_level;
  287.       end;
  288.  
  289.    empty_or_null_body: BOOLEAN is
  290.       do
  291.          Result := first_one = Void;
  292.       end;
  293.  
  294. feature {NONE}
  295.  
  296.    put(i: INSTRUCTION; idx: INTEGER) is
  297.       require
  298.          i /= Void;
  299.          idx.in_range(1,count)
  300.       do
  301.          if idx = 1 then
  302.             first_one := i;
  303.          else
  304.             remainder.put(i,idx - 2);
  305.          end;
  306.       end;
  307.  
  308. invariant
  309.  
  310.    header_comment /= Void or else first_one /= Void;
  311.  
  312.    remainder /= Void implies first_one /= Void;
  313.  
  314. end -- COMPOUND
  315.  
  316.