-- 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