home *** CD-ROM | disk | FTP | other *** search
- -- This file is part of SmallEiffel The GNU Eiffel Compiler.
- -- Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
- -- Dominique COLNET and Suzanne COLLIN - colnet@loria.fr
- -- http://www.loria.fr/SmallEiffel
- -- SmallEiffel is free software; you can redistribute it and/or modify it
- -- under the terms of the GNU General Public License as published by the Free
- -- Software Foundation; either version 2, or (at your option) any later
- -- version. SmallEiffel is distributed in the hope that it will be useful,but
- -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- -- for more details. You should have received a copy of the GNU General
- -- Public License along with SmallEiffel; see the file COPYING. If not,
- -- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- -- Boston, MA 02111-1307, USA.
- --
- class REVERSE_ASSIGNMENT
- --
- -- For instructions like :
- -- foo ?= bar;
- -- foo ?= bar + 1;
- --
-
- inherit INSTRUCTION;
-
- creation make
-
- feature
-
- left_side: EXPRESSION;
-
- right_side: EXPRESSION;
-
- feature
-
- make(ls: like left_side; rs: like right_side) is
- require
- ls /= Void;
- rs /= Void
- do
- left_side := ls;
- right_side := rs;
- end;
-
- feature
-
- end_mark_comment: BOOLEAN is false;
-
- feature
-
- use_current: BOOLEAN is
- do
- if left_side.use_current then
- Result := true;
- else
- Result := right_side.use_current;
- end;
- end;
-
- afd_check is
- do
- right_side.afd_check;
- end;
-
- compile_to_c is
- local
- run: ARRAY[RUN_CLASS];
- i: INTEGER;
- do
- if right_type.run_type.is_expanded then
- eh.add_position(start_position);
- fatal_error("Right-hand side expanded Not Yet Implemented.");
- end;
- run := left_type.run_class.running;
- if run = Void or else run.empty then
- left_side.compile_to_c;
- cpp.put_string("=NULL;%N");
- else
- left_side.compile_to_c;
- cpp.put_character('=');
- if right_side.is_current then
- cpp.put_string(fz_cast_t0_star);
- end;
- right_side.compile_to_c;
- cpp.put_string(";%Nif(NULL!=(");
- left_side.compile_to_c;
- cpp.put_string("))switch(((T0*)");
- left_side.compile_to_c;
- cpp.put_string(")->");
- cpp.put_string("id) {%N");
- from
- i := run.lower;
- until
- i > run.upper
- loop
- cpp.put_string("case ");
- cpp.put_integer(run.item(i).id);
- cpp.put_string(": ");
- i := i + 1;
- end;
- cpp.put_string("%Nbreak;%Ndefault:%N");
- left_side.compile_to_c;
- cpp.put_string("=NULL;%N};");
- end;
- end;
-
- compile_to_jvm is
- local
- run: ARRAY[RUN_CLASS];
- rc: RUN_CLASS;
- point1, idx, i: INTEGER;
- ca: like code_attribute;
- do
- ca := code_attribute;
- if right_type.run_type.is_expanded then
- eh.add_position(start_position);
- fatal_error("Right-hand side expanded Not Yet Implemented.");
- end;
- run := left_type.run_class.running;
- if run = Void or else run.empty then
- right_side.compile_to_jvm;
- ca.opcode_pop;
- ca.opcode_aconst_null;
- left_side.jvm_assign;
- else
- right_side.compile_to_jvm;
- ca.opcode_dup;
- point1 := ca.opcode_ifnull;
- from
- ca.branches.clear;
- i := run.upper;
- until
- i = 0
- loop
- ca.opcode_dup;
- rc := run.item(i);
- idx := rc.fully_qualified_constant_pool_index;
- ca.opcode_instanceof(idx);
- ca.branches.add_last(ca.opcode_ifne);
- i := i - 1;
- end;
- ca.opcode_pop;
- ca.opcode_aconst_null;
- ca.resolve_u2_branch(point1);
- ca.resolve_branches;
- left_side.jvm_assign;
- end;
- end;
-
- is_pre_computable: BOOLEAN is false;
-
- start_position: POSITION is
- do
- Result := left_side.start_position;
- end;
-
- to_runnable(rc: like run_compound): like Current is
- local
- e: EXPRESSION;
- do
- if run_compound = Void then
- run_compound := rc;
- e := left_side.to_runnable(current_type);
- if e = Void then
- error(left_side.start_position,fz_blhsoa);
- else
- left_side := e;
- end;
- if nb_errors = 0 then
- e := right_side.to_runnable(current_type);
- if e = Void then
- error(right_side.start_position,fz_brhsoa);
- else
- right_side := e;
- end;
- end;
- if nb_errors = 0 and then
- right_type.run_type.is_a(left_type.run_type) then
- if not right_side.is_current and then
- not left_type.is_like_current
- then
- eh.add_type(right_type," is a ");
- eh.add_type(left_type,". Simple assignment is allowed");
- warning(start_position," (%"?=%" is not necessary).");
- end;
- end;
- eh.cancel;
- if not left_type.run_type.is_reference then
- eh.add_type(left_type.run_type," is not a reference Type.");
- error(start_position," Invalid reverse assignment (VJRV).");
- end;
- if nb_errors = 0 then
- Result := Current;
- end;
- else
- !!Result.make(left_side,right_side);
- Result := Result.to_runnable(rc);
- end;
- end;
-
- right_type: TYPE is
- require
- right_side.is_checked
- do
- Result := right_side.result_type;
- ensure
- Result /= Void
- end;
-
- left_type: TYPE is
- do
- Result := left_side.result_type;
- ensure
- Result /= Void
- end;
-
- pretty_print is
- do
- pretty_print_assignment(left_side,"?=",right_side);
- end;
-
- invariant
-
- left_side.is_writable;
-
- right_side /= Void;
-
- end -- REVERSE_ASSIGNMENT
-
-