home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / AACD / Programming / sofa / archive / SmallEiffel.lha / SmallEiffel / lib_se / reverse_assignment.e < prev    next >
Text File  |  1999-06-05  |  7KB  |  249 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 REVERSE_ASSIGNMENT
  17.    --
  18.    -- For instructions like :
  19.    --                          foo ?= bar;
  20.    --                          foo ?= bar + 1;
  21.    --
  22.  
  23. inherit INSTRUCTION;
  24.  
  25. creation make
  26.  
  27. feature
  28.  
  29.    left_side: EXPRESSION;
  30.  
  31.    right_side: EXPRESSION;
  32.  
  33. feature {NONE}
  34.  
  35.    current_type: TYPE;
  36.  
  37. feature
  38.  
  39.    make(ls: like left_side; rs: like right_side) is
  40.       require
  41.          ls /= Void;
  42.          rs /= Void
  43.       do
  44.          left_side := ls;
  45.          right_side := rs;
  46.       end;
  47.  
  48. feature
  49.  
  50.    end_mark_comment: BOOLEAN is false;
  51.  
  52. feature
  53.  
  54.    use_current: BOOLEAN is
  55.       do
  56.          if left_side.use_current then
  57.             Result := true;
  58.          else
  59.             Result := right_side.use_current;
  60.          end;
  61.       end;
  62.  
  63.    afd_check is
  64.       do
  65.          right_side.afd_check;
  66.       end;
  67.  
  68.    collect_c_tmp is
  69.       do
  70.          right_side.collect_c_tmp;
  71.       end;
  72.  
  73.    compile_to_c is
  74.       local
  75.          run: ARRAY[RUN_CLASS];
  76.          i: INTEGER;
  77.       do
  78.          if right_type.run_type.is_expanded then
  79.             eh.add_position(start_position);
  80.             fatal_error("Right-hand side expanded Not Yet Implemented.");
  81.          end;
  82.          run := left_type.run_class.running;
  83.          if run = Void then
  84.             if not right_side.can_be_dropped then
  85.                right_side.compile_to_c;
  86.                cpp.put_string(fz_00);
  87.             end;
  88.             left_side.compile_to_c;
  89.             cpp.put_string(fz_30);
  90.          elseif right_side.is_current then
  91.             if run.fast_has(right_side.result_type.run_class) then
  92.                left_side.compile_to_c;
  93.                cpp.put_string("=((void*)");
  94.                right_side.compile_to_c;
  95.                cpp.put_string(fz_14);
  96.             else
  97.                left_side.compile_to_c;
  98.                cpp.put_string(fz_30);
  99.             end;
  100.          else
  101.             left_side.compile_to_c;
  102.             cpp.put_character('=');
  103.             if right_side.is_current then
  104.                cpp.put_string(fz_cast_t0_star);
  105.             end;
  106.             right_side.compile_to_c;
  107.             cpp.put_string(";%Nif(NULL!=(");
  108.             left_side.compile_to_c;
  109.             cpp.put_string(")){%Nswitch(((T0*)");
  110.             left_side.compile_to_c;
  111.             cpp.put_string(")->");
  112.             cpp.put_string("id){%N");
  113.             from
  114.                i := run.lower;
  115.             until
  116.                i > run.upper
  117.             loop
  118.                cpp.put_string("case ");
  119.                cpp.put_integer(run.item(i).id);
  120.                cpp.put_character(':');
  121.                i := i + 1;
  122.             end;
  123.             cpp.put_string("%Nbreak;%Ndefault:%N");
  124.             left_side.compile_to_c;
  125.             cpp.put_string("=NULL;%N}%N}");
  126.          end;
  127.       end;
  128.  
  129.    compile_to_jvm is
  130.       local
  131.          run: ARRAY[RUN_CLASS];
  132.          rc: RUN_CLASS;
  133.          point1, i: INTEGER;
  134.          ca: like code_attribute;
  135.       do
  136.          ca := code_attribute;
  137.          if right_type.run_type.is_expanded then
  138.             eh.add_position(start_position);
  139.             fatal_error("Right-hand side expanded Not Yet Implemented.");
  140.          end;
  141.          run := left_type.run_class.running;
  142.          if run = Void or else run.empty then
  143.             right_side.compile_to_jvm;
  144.             ca.opcode_pop;
  145.             ca.opcode_aconst_null;
  146.             left_side.jvm_assign;
  147.          else
  148.             right_side.compile_to_jvm;
  149.             ca.opcode_dup;
  150.             point1 := ca.opcode_ifnull;
  151.             from
  152.                ca.branches.clear;
  153.                i := run.upper;
  154.             until
  155.                i = 0
  156.             loop
  157.                ca.opcode_dup;
  158.                rc := run.item(i);
  159.                rc.opcode_instanceof;
  160.                ca.branches.add_last(ca.opcode_ifne);
  161.                i := i - 1;
  162.             end;
  163.             ca.opcode_pop;
  164.             ca.opcode_aconst_null;
  165.             ca.resolve_u2_branch(point1);
  166.             ca.resolve_branches;
  167.             left_side.jvm_assign;
  168.          end;
  169.       end;
  170.  
  171.    is_pre_computable: BOOLEAN is false;
  172.  
  173.    start_position: POSITION is
  174.       do
  175.          Result := left_side.start_position;
  176.       end;
  177.  
  178.    to_runnable(ct: TYPE): like Current is
  179.       local
  180.          e: EXPRESSION;
  181.       do
  182.          if current_type = Void then
  183.             current_type := ct;
  184.             e := left_side.to_runnable(ct);
  185.             if e = Void then
  186.                error(left_side.start_position,fz_blhsoa);
  187.             else
  188.                left_side := e;
  189.             end;
  190.             if nb_errors = 0  then
  191.                e := right_side.to_runnable(ct);
  192.                if e = Void then
  193.                   error(right_side.start_position,fz_brhsoa);
  194.                else
  195.                   right_side := e;
  196.                end;
  197.             end;
  198.             if nb_errors = 0 and then
  199.                right_type.run_type.is_a(left_type.run_type) then
  200.                if not right_side.is_current and then
  201.                   not left_type.is_like_current
  202.                 then
  203.                   eh.add_type(right_type," is a ");
  204.                   eh.add_type(left_type,". Simple assignment is allowed");
  205.                   warning(start_position," (%"?=%" is not necessary).");
  206.                end;
  207.             end;
  208.             eh.cancel;
  209.             if not left_type.run_type.is_reference then
  210.                eh.add_type(left_type.run_type," is not a reference Type.");
  211.                error(start_position," Invalid reverse assignment (VJRV).");
  212.             end;
  213.             if nb_errors = 0 then
  214.                Result := Current;
  215.             end;
  216.          else
  217.             !!Result.make(left_side,right_side);
  218.             Result := Result.to_runnable(ct);
  219.          end;
  220.       end;
  221.  
  222.    right_type: TYPE is
  223.       do
  224.          Result := right_side.result_type;
  225.       ensure
  226.          Result /= Void
  227.       end;
  228.  
  229.    left_type: TYPE is
  230.       do
  231.          Result := left_side.result_type;
  232.       ensure
  233.          Result /= Void
  234.       end;
  235.  
  236.    pretty_print is
  237.       do
  238.          pretty_print_assignment(left_side,"?=",right_side);
  239.       end;
  240.  
  241. invariant
  242.  
  243.    left_side.is_writable;
  244.  
  245.    right_side /= Void;
  246.  
  247. end -- REVERSE_ASSIGNMENT
  248.  
  249.