-- This file is part of SmartEiffel The GNU Eiffel Compiler. -- Copyright (C) 1994-2002 LORIA - INRIA - U.H.P. Nancy 1 - FRANCE -- Dominique COLNET and Suzanne COLLIN - SmartEiffel@loria.fr -- http://SmartEiffel.loria.fr -- SmartEiffel 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. SmartEiffel 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 SmartEiffel; see the file COPYING. If not, -- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -- Boston, MA 02111-1307, USA. -- deferred class CALL_INFIX2 -- -- Root for CALL_INFIX_EQ and CALL_INFIX_NEQ. -- inherit CALL_INFIX redefine start_lookup_class, use_current, verify_scoop end feature precedence: INTEGER is 6 left_brackets: BOOLEAN is false start_lookup_class: BASE_CLASS is local cn: CLASS_NAME once create cn.unknown_position(as_boolean) Result := smart_eiffel.base_class(cn) end frozen result_type: E_TYPE is do Result := type_boolean end frozen to_runnable(ct: E_TYPE): like Current is require ct /= Void do if current_type = Void then current_type := ct runnable_target(ct) arguments := runnable_arguments(ct) Result := Current debug debug_info_update end if nb_errors = 0 then Result.check_comparison(ct) end else create Result.with(target,feature_name,arguments) Result := Result.to_runnable(ct) end end frozen assertion_check(tag: CHARACTER) is do target.assertion_check(tag) arg1.assertion_check(tag) end frozen use_current: BOOLEAN is do Result := target.use_current or else arg1.use_current end frozen isa_dca_inline_argument: INTEGER is do end frozen dca_inline_argument(formal_arg_type: E_TYPE) is do end verify_scoop(allowed: FORMAL_ARG_LIST): BOOLEAN is do Result := Precursor(allowed) Result := false; -- = and /= never can be guards end feature {RUN_FEATURE_4} frozen dca_inline(formal_arg_type: E_TYPE) is do cpp.put_character('(') cpp.put_target_as_value cpp.put_character(')') if operator.first = '=' then cpp.put_string(fz_c_eq) else cpp.put_string(fz_c_neq) end cpp.put_character('(') arg1.dca_inline_argument(formal_arg_type) cpp.put_character(')') end feature {RUN_FEATURE_3, RUN_FEATURE_4} finalize is do end feature {CALL_INFIX2} frozen check_comparison(ct: E_TYPE) is local t1, t2: E_TYPE; do_warning: BOOLEAN bcw1, bcw2: BASE_CLASS do t1 := target.result_type t2 := arg1.result_type if t1.is_a(t2) then else error_handler.cancel if t2.is_a(t1) then else if smart_eiffel.short_flag then bcw1 := ct.base_class bcw2 := feature_name.start_position.base_class do_warning := bcw1 = bcw2 else do_warning := true end error_handler.cancel error_handler.add_position(feature_name.start_position) if t1.is_expanded or else t2.is_expanded then error_handler.append( "Comparison not allowed (more details below).") error_handler.print_as_error error_handler.add_type(t1," cannot be compared with ") error_handler.add_type(t2," (comparison not allowed).") error_handler.print_as_fatal_error elseif do_warning then error_handler.append( "Strange (or invalid ?) comparison of ") error_handler.append(t1.run_time_mark) error_handler.append(" with ") error_handler.append(t2.run_time_mark) error_handler.append(". (This will be always ") if feature_name.to_string = as_eq then error_handler.append("False") else error_handler.append("True") end error_handler.append( ".) Note: the context of types interpretation (i.e. % %the type of Current) is ") error_handler.append(ct.run_time_mark) error_handler.append(".") error_handler.print_as_warning end end end end afd_check_hook is local t1, t2: E_TYPE do t1 := target.result_type t2 := arg1.result_type if t1.is_bit then if t2.is_bit then bit_limitation(t1, t2) end end -- *** Do not know what to do yet... -- sept 20 of 2002, D.Colnet if target.is_void then -- *** void_with_expanded_comparison_warning(arg1) elseif arg1.is_void then -- *** void_with_expanded_comparison_warning(target) end end void_with_expanded_comparison_warning(e: EXPRESSION) is local tfg: TYPE_FORMAL_GENERIC; rt: E_TYPE do rt := e.result_type tfg ?= rt if tfg = Void and then not rt.is_anchored then if rt.is_expanded then error_handler.add_position(feature_name.start_position) error_handler.append( "Strange comparison of an expanded with Void. (An expanded % %type is never Void.) Note: the context of types interpreta% %tion (i.e. the type of Current) is ") error_handler.append(current_type.run_time_mark) error_handler.append(".") error_handler.print_as_warning end end end bit_limitation(t1, t2: E_TYPE) is require t1.is_bit; t2.is_bit local b1, b2: TYPE_BIT do b1 ?= t1.run_type; b2 ?= t2.run_type if b1.nb /= b2.nb then error_handler.add_position(feature_name.start_position) error_handler.append("Comparison between ") error_handler.add_type(b1," and ") error_handler.add_type(b2, " is not yet implemented (you can work arround by % %doing an assignment in a local variable).") error_handler.print_as_fatal_error end end cmp_bit(equal_test: BOOLEAN; t: E_TYPE) is require t.is_bit local tb: TYPE_BIT do tb ?= t if tb.is_c_unsigned_ptr then if equal_test then cpp.put_character('!') end cpp.put_string(once "memcmp((") target.mapping_c_target(t) cpp.put_string(fz_20) arg1.mapping_c_target(t) cpp.put_string(fz_84) cpp.put_integer(tb.id) cpp.put_string(fz_13) else cpp.put_character('(') target.compile_to_c cpp.put_character(')') if equal_test then cpp.put_string(fz_c_eq) else cpp.put_string(fz_c_neq) end cpp.put_character('(') arg1.compile_to_c cpp.put_character(')') end end cmp_user_expanded(equal_test: BOOLEAN; t: E_TYPE) is require t.is_user_expanded local mem_id: INTEGER do if t.is_dummy_expanded then cpp.put_character('(') target.compile_to_c cpp.put_character(',') arg1.compile_to_c cpp.put_character(',') if equal_test then cpp.put_character('1') else cpp.put_character('0') end cpp.put_character(')') else mem_id := t.id if equal_test then cpp.put_character('!') end cpp.put_string(fz_se_cmpt) cpp.put_integer(mem_id) cpp.put_string(fz_17) target.compile_to_c cpp.put_string(fz_20) arg1.compile_to_c cpp.put_string(fz_13) end end cmp_basic_eiffel_expanded(equal_test: BOOLEAN; t1, t2: E_TYPE) is require t1.is_basic_eiffel_expanded t2.is_basic_eiffel_expanded local cast: STRING do if t1.is_double or else t2.is_double then cast := fz_43 elseif t1.is_real or else t2.is_real then cast := fz_45 end if cast /= Void then cpp.put_string(cast) end cpp.put_character('(') target.compile_to_c if cast /= Void then cpp.put_string(fz_13) end cpp.put_character(')') if equal_test then cpp.put_string(fz_c_eq) else cpp.put_string(fz_c_neq) end cpp.put_character('(') if cast /= Void then cpp.put_string(cast) end arg1.compile_to_c cpp.put_character(')') if cast /= Void then cpp.put_string(fz_13) end end cmp_basic_ref(equal_test: BOOLEAN) is do if target.result_type.is_separate or else arg1.result_type.is_separate then if not equal_test then cpp.put_character('!') end cpp.put_string(once "scoop_cmp((T0*)(") target.compile_to_c cpp.put_string(once "),(T0*)(") arg1.compile_to_c cpp.put_string(once "))") else cpp.put_character('(') target.compile_to_c cpp.put_character(')') if equal_test then cpp.put_string(fz_c_eq) else cpp.put_string(fz_c_neq) end cpp.put_string(once "((void*)(") arg1.compile_to_c cpp.put_string(once "))") end end is_manifest_array(e: EXPRESSION): BOOLEAN is local manifest_array: MANIFEST_ARRAY do manifest_array ?= e Result := manifest_array /= Void end frozen make(lp: like target; operator_position: POSITION; rp: like arg1) is require lp /= Void not operator_position.is_unknown rp /= Void do target := lp create feature_name.infix_name(operator,operator_position) create arguments.make_1(rp) ensure target = lp start_position = operator_position arguments.first = rp end frozen with(t: like target; fn: like feature_name; a: like arguments) is require t /= Void fn /= Void a.count = 1 do target := t feature_name := fn arguments := a ensure target = t feature_name = fn arguments = a end feature {NONE} c2c_exp_ref(exp: EXPRESSION; ref: EXPRESSION; eq_flag: BOOLEAN) is -- Generic (= /=) implementation of `compile_to_c' for an expanded -- expression compared with some reference expression. require exp.result_type.is_expanded ref.result_type.is_reference local type_reference: TYPE_REFERENCE; exp_type: E_TYPE; skip_tag: BOOLEAN do type_reference ?= ref.result_type.run_type if ref.is_void or else type_reference = Void then cpp.put_character('(') if not ref.is_void then ref.compile_to_c cpp.put_character(',') end exp.compile_to_c cpp.put_character(',') if eq_flag then cpp.put_character('0') else cpp.put_character('1') end cpp.put_character(')') else exp_type := exp.result_type.run_type if exp_type.is_basic_eiffel_expanded then cpp.put_character('(') exp.compile_to_c cpp.put_character(')') if eq_flag then cpp.put_string(fz_c_eq) else cpp.put_string(fz_c_neq) end cpp.put_string(once "((") ref.mapping_c_target(type_reference) cpp.put_string(once ")->_item)") else if eq_flag then cpp.put_character('!') end cpp.put_string(once "memcmp(&(") exp.compile_to_c cpp.put_string(once "),") if type_reference.run_class.is_tagged then skip_tag := True cpp.put_string(once "((Tid*)(") end ref.compile_to_c if skip_tag then cpp.put_string(once "))+1") end cpp.put_string(once ",sizeof(T") cpp.put_integer(exp_type.id) cpp.put_string(once "))") end end end invariant run_feature = Void end -- CALL_INFIX2