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