note description: "[ Objects representing delayed calls to a routine, with some operands possibly still open ]" library: "Free implementation of ELKS library" status: "See notice at end of class." legal: "See notice at end of class." date: "$Date: 2017-06-01 07:24:49 +0000 (Thu, 01 Jun 2017) $" revision: "$Revision: 100440 $" deferred class ROUTINE [OPEN_ARGS -> detachable TUPLE create default_create end] feature -- Initialization adapt (other: like Current) -- Initialize from other. -- Useful in descendants. require other_exists: other /= Void conforming: conforms_to (other) do rout_disp := other.rout_disp encaps_rout_disp := other.encaps_rout_disp calc_rout_addr := other.calc_rout_addr closed_operands := other.closed_operands operands := other.operands routine_id := other.routine_id is_basic := other.is_basic is_target_closed := other.is_target_closed written_type_id_inline_agent := other.written_type_id_inline_agent open_count := other.open_count end feature {NONE} -- Initialization default_create -- Process instances of classes with no creation clause. -- (Default: do nothing.) -- (from ANY) do end feature -- Access attached_type (type_id: INTEGER_32): INTEGER_32 -- Attached version of type_id. -- (from REFLECTOR) require -- from REFLECTOR type_id_nonnegative: type_id >= 0 do Result := {ISE_RUNTIME}.attached_type (type_id) ensure -- from REFLECTOR instance_free: class unchanged_if_attached: is_attached_type (type_id) implies type_id = Result end Bit_type: INTEGER_32 = 8 -- This type is obsolete and is not used anymore. -- (from REFLECTOR_CONSTANTS) Boolean_type: INTEGER_32 = 3 -- Abstract type ID for predefined type BOOLEAN. -- (from REFLECTOR_CONSTANTS) Character_32_type: INTEGER_32 = 12 -- Abstract type ID for predefined type CHARACTER_32. -- Was declared in REFLECTOR_CONSTANTS as synonym of Wide_character_type. -- (from REFLECTOR_CONSTANTS) Character_8_type: INTEGER_32 = 2 -- Abstract type ID for predefined type CHARACTER_8. -- Was declared in REFLECTOR_CONSTANTS as synonym of Character_type. -- (from REFLECTOR_CONSTANTS) Character_type: INTEGER_32 = 2 -- Abstract type ID for predefined type CHARACTER_8. -- Was declared in REFLECTOR_CONSTANTS as synonym of Character_8_type. -- (from REFLECTOR_CONSTANTS) class_name_8_of_type (type_id: INTEGER_32): STRING_8 -- Name of class associated with dynamic type type_id. -- (from REFLECTOR) require -- from REFLECTOR type_id_nonnegative: type_id >= 0 do Result := {ISE_RUNTIME}.generator_8_of_type (type_id) ensure -- from REFLECTOR instance_free: class end class_name_of_type (type_id: INTEGER_32): STRING_8 -- Name of class associated with dynamic type type_id. -- (from REFLECTOR) require -- from REFLECTOR type_id_nonnegative: type_id >= 0 do Result := {ISE_RUNTIME}.generator_of_type (type_id) ensure -- from REFLECTOR instance_free: class end detachable_type (type_id: INTEGER_32): INTEGER_32 -- Detachable version of type_id. -- (from REFLECTOR) require -- from REFLECTOR type_id_nonnegative: type_id >= 0 do Result := {ISE_RUNTIME}.detachable_type (type_id) ensure -- from REFLECTOR instance_free: class unchanged_if_detachable: not is_attached_type (type_id) implies type_id = Result end Double_type: INTEGER_32 = 6 -- Abstract type ID for predefined type REAL_64. -- Was declared in REFLECTOR_CONSTANTS as synonym of Real_64_type. -- (from REFLECTOR_CONSTANTS) empty_operands: attached OPEN_ARGS obsolete "This function will be removed as non-void-safe. [2017-05-31]" -- Empty tuple matching open operands. do create Result ensure empty_operands_not_void: Result /= Void end Expanded_type: INTEGER_32 = 7 -- Abstract type ID for a non-predefined expanded type. -- (from REFLECTOR_CONSTANTS) field_name_8_of_type (i: INTEGER_32; type_id: INTEGER_32): STRING_8 -- Name of i-th field of dynamic type type_id. -- (from REFLECTOR) require -- from REFLECTOR type_id_nonnegative: type_id >= 0 index_large_enough: i >= 1 index_small_enought: i <= field_count_of_type (type_id) do create Result.make_from_c ({ISE_RUNTIME}.field_name_of_type (i, type_id)) ensure -- from REFLECTOR instance_free: class end field_name_of_type (i: INTEGER_32; type_id: INTEGER_32): STRING_8 -- Name of i-th field of dynamic type type_id. -- (from REFLECTOR) require -- from REFLECTOR type_id_nonnegative: type_id >= 0 index_large_enough: i >= 1 index_small_enought: i <= field_count_of_type (type_id) do create Result.make_from_c ({ISE_RUNTIME}.field_name_of_type (i, type_id)) ensure -- from REFLECTOR instance_free: class end field_static_type_of_type (i: INTEGER_32; type_id: INTEGER_32): INTEGER_32 -- Static type of declared i-th field of dynamic type type_id -- (from REFLECTOR) require -- from REFLECTOR type_id_nonnegative: type_id >= 0 index_large_enough: i >= 1 index_small_enough: i <= field_count_of_type (type_id) do Result := {ISE_RUNTIME}.field_static_type_of_type (i, type_id) ensure -- from REFLECTOR instance_free: class field_type_nonnegative: Result >= 0 end field_type_of_type (i: INTEGER_32; type_id: INTEGER_32): INTEGER_32 -- Abstract type of i-th field of dynamic type type_id -- (from REFLECTOR) require -- from REFLECTOR type_id_nonnegative: type_id >= 0 index_large_enough: i >= 1 index_small_enough: i <= field_count_of_type (type_id) do Result := {ISE_RUNTIME}.field_type_of_type (i, type_id) ensure -- from REFLECTOR instance_free: class field_type_nonnegative: Result >= 0 end generating_type: TYPE [detachable ROUTINE [OPEN_ARGS]] -- Type of current object -- (type of which it is a direct instance) -- (from ANY) external "built_in" ensure -- from ANY generating_type_not_void: Result /= Void end generator: STRING_8 -- Name of current object's generating class -- (base class of the type of which it is a direct instance) -- (from ANY) external "built_in" ensure -- from ANY generator_not_void: Result /= Void generator_not_empty: not Result.is_empty end generic_count_of_type (type_id: INTEGER_32): INTEGER_32 -- Number of generic parameter in type_id. -- (from REFLECTOR) require -- from REFLECTOR type_id_nonnegative: type_id >= 0 do Result := {ISE_RUNTIME}.generic_parameter_count (type_id) ensure -- from REFLECTOR instance_free: class end generic_dynamic_type_of_type (type_id: INTEGER_32; i: INTEGER_32): INTEGER_32 -- Dynamic type of generic parameter of type_id at position i. -- (from REFLECTOR) require -- from REFLECTOR type_id_nonnegative: type_id >= 0 type_id_generic: generic_count_of_type (type_id) > 0 i_valid: i > 0 and i <= generic_count_of_type (type_id) do Result := {ISE_RUNTIME}.eif_gen_param_id (type_id, i) ensure -- from REFLECTOR instance_free: class dynamic_type_nonnegative: Result >= 0 end hash_code: INTEGER_32 -- Hash code value. do Result := rout_disp.hash_code.bit_xor (routine_id.hash_code) ensure -- from HASHABLE good_hash_value: Result >= 0 end Integer_16_type: INTEGER_32 = 10 -- Abstract type ID for predefined type INTEGER_16. -- (from REFLECTOR_CONSTANTS) Integer_32_type: INTEGER_32 = 4 -- Abstract type ID for predefined type INTEGER_32. -- Was declared in REFLECTOR_CONSTANTS as synonym of Integer_type. -- (from REFLECTOR_CONSTANTS) Integer_64_type: INTEGER_32 = 11 -- Abstract type ID for predefined type INTEGER_64. -- (from REFLECTOR_CONSTANTS) Integer_8_type: INTEGER_32 = 9 -- Abstract type ID for predefined type INTEGER_8. -- (from REFLECTOR_CONSTANTS) Integer_type: INTEGER_32 = 4 -- Abstract type ID for predefined type INTEGER_32. -- Was declared in REFLECTOR_CONSTANTS as synonym of Integer_32_type. -- (from REFLECTOR_CONSTANTS) Max_predefined_type: INTEGER_32 = 16 -- (from REFLECTOR_CONSTANTS) Min_predefined_type: INTEGER_32 = -2 -- (from REFLECTOR_CONSTANTS) Natural_16_type: INTEGER_32 = 14 -- Abstract type ID for predefined type NATURAL_16. -- (from REFLECTOR_CONSTANTS) Natural_32_type: INTEGER_32 = 15 -- Abstract type ID for predefined type NATURAL_32. -- (from REFLECTOR_CONSTANTS) Natural_64_type: INTEGER_32 = 16 -- Abstract type ID for predefined type NATURAL_64. -- (from REFLECTOR_CONSTANTS) Natural_8_type: INTEGER_32 = 13 -- Abstract type ID for predefined type NATURAL_8. -- (from REFLECTOR_CONSTANTS) None_type: INTEGER_32 = -2 -- Type ID representation for NONE. -- (from REFLECTOR_CONSTANTS) frozen operands: detachable OPEN_ARGS Pointer_type: INTEGER_32 = 0 -- Abstract type ID for predefined type POINTER. -- (from REFLECTOR_CONSTANTS) postcondition (args: like operands): BOOLEAN -- Does current state satisfy routine's -- postcondition for args? do Result := True end precondition (args: like operands): BOOLEAN -- Do args satisfy routine's precondition -- in current state? do Result := True end Real_32_type: INTEGER_32 = 5 -- Abstract type ID for predefined type REAL_32. -- Was declared in REFLECTOR_CONSTANTS as synonym of Real_type. -- (from REFLECTOR_CONSTANTS) Real_64_type: INTEGER_32 = 6 -- Abstract type ID for predefined type REAL_64. -- Was declared in REFLECTOR_CONSTANTS as synonym of Double_type. -- (from REFLECTOR_CONSTANTS) Real_type: INTEGER_32 = 5 -- Abstract type ID for predefined type REAL_32. -- Was declared in REFLECTOR_CONSTANTS as synonym of Real_32_type. -- (from REFLECTOR_CONSTANTS) Reference_type: INTEGER_32 = 1 -- Abstract type ID for a reference type. -- (from REFLECTOR_CONSTANTS) storable_version_of_type (a_type_id: INTEGER_32): detachable IMMUTABLE_STRING_8 -- Storable version if any specified. -- (from REFLECTOR) require -- from REFLECTOR a_type_id_nonnegative: a_type_id >= 0 local l_result: detachable STRING_8 do Id_to_storable_version.search (a_type_id) if Id_to_storable_version.found then Result := Id_to_storable_version.found_item else l_result := {ISE_RUNTIME}.storable_version_of_type (a_type_id) if l_result /= Void then create Result.make_from_string (l_result) end; Id_to_storable_version.put (Result, a_type_id) end ensure -- from REFLECTOR instance_free: class end target: detachable ANY -- Target of call, if already known local c: like closed_operands do if is_target_closed then c := closed_operands if c /= Void and then c.count > 0 and then attached {ANY} c.item (1) as r then Result := r end elseif attached {TUPLE} operands as o and then o.count > 0 and then attached {ANY} o.item (1) as r then Result := r end end type_name_8_of_type (type_id: INTEGER_32): STRING_8 -- Name of type_id's generating type (type of which type_id -- is a direct instance). -- (from REFLECTOR) require -- from REFLECTOR type_id_nonnegative: type_id >= 0 do Result := {ISE_RUNTIME}.generating_type_8_of_type (type_id) ensure -- from REFLECTOR instance_free: class end type_name_of_type (type_id: INTEGER_32): STRING_8 -- Name of type_id's generating type (type of which type_id -- is a direct instance). -- (from REFLECTOR) require -- from REFLECTOR type_id_nonnegative: type_id >= 0 do Result := {ISE_RUNTIME}.generating_type_of_type (type_id) ensure -- from REFLECTOR instance_free: class end Wide_character_type: INTEGER_32 = 12 -- Abstract type ID for predefined type CHARACTER_32. -- Was declared in REFLECTOR_CONSTANTS as synonym of Character_32_type. -- (from REFLECTOR_CONSTANTS) feature -- Measurement field_count_of_type (type_id: INTEGER_32): INTEGER_32 -- Number of logical fields in dynamic type type_id. -- (from REFLECTOR) require -- from REFLECTOR type_id_nonnegative: type_id >= 0 do Result := {ISE_RUNTIME}.field_count_of_type (type_id) ensure -- from REFLECTOR instance_free: class end open_count: INTEGER_32 -- Number of open operands. persistent_field_count_of_type (a_type_id: INTEGER_32): INTEGER_32 -- Number of logical fields in dynamic type type_id that are not transient. -- (from REFLECTOR) require -- from REFLECTOR a_type_non_negative: a_type_id >= 0 do Result := {ISE_RUNTIME}.persistent_field_count_of_type (a_type_id) ensure -- from REFLECTOR instance_free: class end feature -- Comparison frozen deep_equal (a: detachable ANY; b: like arg #1): BOOLEAN -- Are a and b either both void -- or attached to isomorphic object structures? -- (from ANY) do if a = Void then Result := b = Void else Result := b /= Void and then a.is_deep_equal (b) end ensure -- from ANY instance_free: class shallow_implies_deep: standard_equal (a, b) implies Result both_or_none_void: (a = Void) implies (Result = (b = Void)) same_type: (Result and (a /= Void)) implies (b /= Void and then a.same_type (b)) symmetric: Result implies deep_equal (b, a) end frozen equal (a: detachable ANY; b: like arg #1): BOOLEAN -- Are a and b either both void or attached -- to objects considered equal? -- (from ANY) do if a = Void then Result := b = Void else Result := b /= Void and then a.is_equal (b) end ensure -- from ANY instance_free: class definition: Result = (a = Void and b = Void) or else ((a /= Void and b /= Void) and then a.is_equal (b)) end frozen is_deep_equal alias "≡≡≡" (other: ROUTINE [OPEN_ARGS]): BOOLEAN -- Are Current and other attached to isomorphic object structures? -- (from ANY) require -- from ANY other_not_void: other /= Void external "built_in" ensure -- from ANY shallow_implies_deep: standard_is_equal (other) implies Result same_type: Result implies same_type (other) symmetric: Result implies other.is_deep_equal (Current) end frozen standard_equal (a: detachable ANY; b: like arg #1): BOOLEAN -- Are a and b either both void or attached to -- field-by-field identical objects of the same type? -- Always uses default object comparison criterion. -- (from ANY) do if a = Void then Result := b = Void else Result := b /= Void and then a.standard_is_equal (b) end ensure -- from ANY instance_free: class definition: Result = (a = Void and b = Void) or else ((a /= Void and b /= Void) and then a.standard_is_equal (b)) end frozen standard_is_equal alias "≜" (other: ROUTINE [OPEN_ARGS]): BOOLEAN -- Is other attached to an object of the same type -- as current object, and field-by-field identical to it? -- (from ANY) require -- from ANY other_not_void: other /= Void external "built_in" ensure -- from ANY same_type: Result implies same_type (other) symmetric: Result implies other.standard_is_equal (Current) end feature -- Status report Callable: BOOLEAN = True -- Can routine be called on current object? conforms_to (other: ANY): BOOLEAN -- Does type of current object conform to type -- of other (as per Eiffel: The Language, chapter 13)? -- (from ANY) require -- from ANY other_not_void: other /= Void external "built_in" end is_attached_type (a_type_id: INTEGER_32): BOOLEAN -- Is a_type_id an attached type? -- (from REFLECTOR) require -- from REFLECTOR a_type_non_negative: a_type_id >= 0 do Result := {ISE_RUNTIME}.is_attached_type (a_type_id) ensure -- from REFLECTOR instance_free: class end is_equal (other: like Current): BOOLEAN -- Is associated routine the same as the one -- associated with other. require -- from ANY other_not_void: other /= Void do Result := closed_operands ~ other.closed_operands and then operands ~ other.operands and then open_map ~ other.open_map and then (rout_disp = other.rout_disp) and then (routine_id = other.routine_id) and then (written_type_id_inline_agent = other.written_type_id_inline_agent) and then (encaps_rout_disp = other.encaps_rout_disp) and then (calc_rout_addr = other.calc_rout_addr) ensure -- from ANY symmetric: Result implies other ~ Current consistent: standard_is_equal (other) implies Result end is_field_expanded_of_type (i: INTEGER_32; a_type_id: INTEGER_32): BOOLEAN -- Is i-th field of type a_type_id a user-defined expanded attribute? -- (from REFLECTOR) require -- from REFLECTOR a_type_non_negative: a_type_id >= 0 index_large_enough: i >= 1 index_small_enough: i <= field_count_of_type (a_type_id) do Result := {ISE_RUNTIME}.is_field_expanded_of_type (i, a_type_id) ensure -- from REFLECTOR instance_free: class end is_field_transient_of_type (i: INTEGER_32; a_type_id: INTEGER_32): BOOLEAN -- Is i-th field of object a transient attribute? -- I.e. an attribute that does not need to be stored? -- (from REFLECTOR) require -- from REFLECTOR a_type_non_negative: a_type_id >= 0 index_large_enough: i >= 1 index_small_enough: i <= field_count_of_type (a_type_id) do Result := {ISE_RUNTIME}.is_field_transient_of_type (i, a_type_id) ensure -- from REFLECTOR instance_free: class end is_hashable: BOOLEAN -- May current object be hashed? -- (True by default.) -- (from HASHABLE) do Result := True end is_pre_ecma_mapping_disabled: BOOLEAN -- Are we mapping old names to new ECMA names? -- False means mapping STRING to STRING_8, INTEGER to INTEGER_32,... -- Redefine in descendants of REFLECTOR to modify the behavior of inspection queries of REFLECTOR. -- (from REFLECTOR_HELPER) do Result := False ensure -- from REFLECTOR_HELPER instance_free: class end is_special_any_type (type_id: INTEGER_32): BOOLEAN -- Is type represented by type_id represent -- a SPECIAL [XX] where XX is a reference type. -- (from REFLECTOR) require -- from REFLECTOR type_id_nonnegative: type_id >= 0 do Result := {ISE_RUNTIME}.is_special_of_reference_type (type_id) ensure -- from REFLECTOR instance_free: class end is_special_type (type_id: INTEGER_32): BOOLEAN -- Is type represented by type_id represent -- a SPECIAL [XX] where XX is a reference type -- or a basic expanded type (note that user-defined -- expanded types are excluded). -- (from REFLECTOR) require -- from REFLECTOR type_id_nonnegative: type_id >= 0 do Result := {ISE_RUNTIME}.is_special_of_reference_or_basic_type (type_id) ensure -- from REFLECTOR instance_free: class end is_target_closed: BOOLEAN -- Is target for current agent closed, i.e. specified at creation time? is_tuple_type (type_id: INTEGER_32): BOOLEAN -- Is type represented by type_id represent a TUPLE? -- (from REFLECTOR) require -- from REFLECTOR type_id_nonnegative: type_id >= 0 do Result := {ISE_RUNTIME}.is_tuple_type (type_id) ensure -- from REFLECTOR instance_free: class end is_valid_type_string (s: READABLE_STRING_GENERAL): BOOLEAN -- Is s a valid string representation for a TYPE. -- (from REFLECTOR_HELPER) local l_type_name: STRING_32 l_start_pos, l_end_pos: INTEGER_32 l_class_type_name: STRING_32 l_parameters: like parameters_decomposition do if s /= Void and then not s.is_empty then create l_class_type_name.make_from_string_general (s); l_class_type_name.adjust l_start_pos := l_class_type_name.index_of ('['.to_character_32, 1) if l_start_pos > 1 then l_end_pos := l_class_type_name.count if l_class_type_name.item (l_end_pos) /= ']'.to_character_32 then l_end_pos := 0 end if l_end_pos = l_class_type_name.count and l_start_pos < l_end_pos and l_class_type_name.occurrences ('['.to_character_32) = l_class_type_name.occurrences (']'.to_character_32) then l_type_name := l_class_type_name.substring (1, l_start_pos - 1); l_type_name.adjust if is_valid_identifier (l_type_name) then l_parameters := parameters_decomposition (l_class_type_name.substring (l_start_pos + 1, l_end_pos - 1)) if l_parameters /= Void then from Result := True; l_parameters.start until l_parameters.after or not Result loop Result := is_valid_type_string (l_parameters.item); l_parameters.forth end end end end else Result := is_valid_identifier (l_class_type_name) end end ensure -- from REFLECTOR_HELPER instance_free: class end mapped_type (a_type: READABLE_STRING_GENERAL): READABLE_STRING_GENERAL -- If is_pre_ecma_mapping_disabled a_type, otherwise -- the mapped typed. -- (from REFLECTOR_HELPER) require -- from REFLECTOR_HELPER a_type_not_void: a_type /= Void local l_table: like Pre_ecma_type_mapping do if not is_pre_ecma_mapping_disabled then l_table := Pre_ecma_type_mapping; l_table.search (a_type) if l_table.found then Result := l_table.found_item end end if Result = Void then Result := a_type end ensure -- from REFLECTOR_HELPER instance_free: class mapped_type_not_void: Result /= Void end same_type (other: ANY): BOOLEAN -- Is type of current object identical to type of other? -- (from ANY) require -- from ANY other_not_void: other /= Void external "built_in" ensure -- from ANY definition: Result = (conforms_to (other) and other.conforms_to (Current)) end valid_operands (args: detachable separate TUPLE): BOOLEAN -- Are args valid operands for this routine? local i, arg_type_code: INTEGER_32 arg: like {TUPLE}.item l_type: INTEGER_32 do if args = Void then Result := open_count = 0 elseif args.count >= open_count then from Result := True i := 1 until i > open_count or not Result loop arg_type_code := args.item_code (i).to_integer_32 l_type := open_operand_type (i) inspect arg_type_code when {TUPLE}.boolean_code then Result := l_type = ({BOOLEAN}).type_id when {TUPLE}.character_8_code then Result := l_type = ({CHARACTER_8}).type_id when {TUPLE}.character_32_code then Result := l_type = ({CHARACTER_32}).type_id when {TUPLE}.integer_8_code then Result := l_type = ({INTEGER_8}).type_id when {TUPLE}.integer_16_code then Result := l_type = ({INTEGER_16}).type_id when {TUPLE}.integer_32_code then Result := l_type = ({INTEGER_32}).type_id when {TUPLE}.integer_64_code then Result := l_type = ({INTEGER_64}).type_id when {TUPLE}.natural_8_code then Result := l_type = ({NATURAL_8}).type_id when {TUPLE}.natural_16_code then Result := l_type = ({NATURAL_16}).type_id when {TUPLE}.natural_32_code then Result := l_type = ({NATURAL_32}).type_id when {TUPLE}.natural_64_code then Result := l_type = ({NATURAL_64}).type_id when {TUPLE}.pointer_code then Result := l_type = ({POINTER}).type_id when {TUPLE}.real_32_code then Result := l_type = ({REAL_32}).type_id when {TUPLE}.real_64_code then Result := l_type = ({REAL_64}).type_id when {TUPLE}.reference_code then arg := args.item (i) if is_attached_type (l_type) then Result := arg /= Void and then field_conforms_to ({ISE_RUNTIME}.dynamic_type (arg), l_type) else Result := arg = Void or else field_conforms_to ({ISE_RUNTIME}.dynamic_type (arg), l_type) end else Result := False end i := i + 1 end end if Result and then not is_target_closed then Result := args /= Void and then not args.is_empty and then args.item (1) /= Void end end valid_target (args: detachable TUPLE): BOOLEAN -- Is the first element of tuple args a valid target do if args /= Void and then args.count > 0 then if args.is_reference_item (1) then Result := args.reference_item (1) /= Void else Result := True end end end feature -- Duplication frozen clone (other: detachable ANY): like other obsolete "Use `twin' instead. [2017-05-31]" -- Void if other is void; otherwise new object -- equal to other -- -- For non-void other, clone calls copy; -- to change copying/cloning semantics, redefine copy. -- (from ANY) do if other /= Void then Result := other.twin end ensure -- from ANY instance_free: class equal: Result ~ other end copy (other: like Current) -- Use same routine as other. require -- from ANY other_not_void: other /= Void type_identity: same_type (other) do if other /= Current then standard_copy (other) if attached operands as l_operands then operands := l_operands.twin end end ensure -- from ANY is_equal: Current ~ other ensure then same_call_status: other.Callable implies Callable end frozen deep_clone (other: detachable ANY): like other obsolete "Use `deep_twin' instead. [2017-05-31]" -- Void if other is void: otherwise, new object structure -- recursively duplicated from the one attached to other -- (from ANY) do if other /= Void then Result := other.deep_twin end ensure -- from ANY instance_free: class deep_equal: deep_equal (other, Result) end frozen deep_copy (other: ROUTINE [OPEN_ARGS]) -- Effect equivalent to that of: -- copy (other . deep_twin) -- (from ANY) require -- from ANY other_not_void: other /= Void do copy (other.deep_twin) ensure -- from ANY deep_equal: deep_equal (Current, other) end frozen deep_twin: ROUTINE [OPEN_ARGS] -- New object structure recursively duplicated from Current. -- (from ANY) external "built_in" ensure -- from ANY deep_twin_not_void: Result /= Void deep_equal: deep_equal (Current, Result) end frozen standard_clone (other: detachable ANY): like other obsolete "Use `standard_twin' instead. [2017-05-31]" -- Void if other is void; otherwise new object -- field-by-field identical to other. -- Always uses default copying semantics. -- (from ANY) do if other /= Void then Result := other.standard_twin end ensure -- from ANY instance_free: class equal: standard_equal (Result, other) end frozen standard_copy (other: ROUTINE [OPEN_ARGS]) -- Copy every field of other onto corresponding field -- of current object. -- (from ANY) require -- from ANY other_not_void: other /= Void type_identity: same_type (other) external "built_in" ensure -- from ANY is_standard_equal: standard_is_equal (other) end frozen standard_twin: ROUTINE [OPEN_ARGS] -- New object field-by-field identical to other. -- Always uses default copying semantics. -- (from ANY) external "built_in" ensure -- from ANY standard_twin_not_void: Result /= Void equal: standard_equal (Result, Current) end frozen twin: ROUTINE [OPEN_ARGS] -- New object equal to Current -- twin calls copy; to change copying/twinning semantics, redefine copy. -- (from ANY) external "built_in" ensure -- from ANY twin_not_void: Result /= Void is_equal: Result ~ Current end feature -- Basic operations apply -- Call routine with operands as last set. require valid_operands: valid_operands (operands) deferred end frozen as_attached: attached ROUTINE [OPEN_ARGS] obsolete "Remove calls to this feature. [2017-05-31]" -- Attached version of Current. -- (Can be used during transitional period to convert -- non-void-safe classes to void-safe ones.) -- (from ANY) do Result := Current end call (args: detachable separate OPEN_ARGS) -- Call routine with args. require valid_operands: valid_operands (args) deferred end frozen default: detachable ROUTINE [OPEN_ARGS] -- Default value of object's type -- (from ANY) do end frozen default_pointer: POINTER -- Default value of type POINTER -- (Avoid the need to write p.default for -- some p of type POINTER.) -- (from ANY) do ensure -- from ANY instance_free: class end default_rescue -- Process exception for routines with no Rescue clause. -- (Default: do nothing.) -- (from ANY) do end frozen do_nothing -- Execute a null action. -- (from ANY) do ensure -- from ANY instance_free: class end feature -- Obsolete adapt_from (other: like Current) obsolete "Please use `adapt' instead (it's also a creation procedure). [2017-05-31]" -- Adapt from other. Useful in descendants. require other_exists: other /= Void conforming: conforms_to (other) do adapt (other) end arguments: detachable OPEN_ARGS obsolete "Use `operands`. [2017-05-31]" do Result := operands end set_arguments (args: detachable OPEN_ARGS) obsolete "Use `set_operands`. [2017-05-31]" do set_operands (args) end valid_arguments (args: detachable OPEN_ARGS): BOOLEAN obsolete "Use `valid_operands`. [2017-05-31]" do Result := valid_operands (args) end feature {ROUTINE} -- Implementation frozen calc_rout_addr: POINTER -- Address of the final routine closed_count: INTEGER_32 -- The number of closed operands (including the target if it is closed) local c: detachable TUPLE do c := closed_operands if c /= Void then Result := c.count end end frozen closed_operands: detachable TUPLE -- All closed arguments provided at creation time frozen encaps_rout_disp: POINTER -- Eiffel routine dispatcher frozen is_basic: BOOLEAN frozen open_map: detachable ARRAY [INTEGER_32] -- Index map for open arguments frozen rout_disp: POINTER -- Routine dispatcher frozen routine_id: INTEGER_32 frozen set_rout_disp (a_rout_disp, a_encaps_rout_disp, a_calc_rout_addr: POINTER; a_routine_id: INTEGER_32; a_open_map: like open_map; a_is_basic, a_is_target_closed: BOOLEAN; a_written_type_id_inline_agent: INTEGER_32; a_closed_operands: TUPLE; a_open_count: INTEGER_32) -- Initialize object in workbench mode. require a_routine_id_valid: a_routine_id > -1 target_valid: a_is_target_closed implies valid_target (a_closed_operands) do set_rout_disp_int (a_rout_disp, a_encaps_rout_disp, a_calc_rout_addr, a_routine_id, a_open_map, a_is_basic, a_is_target_closed, a_written_type_id_inline_agent, a_closed_operands, a_open_count) end frozen set_rout_disp_final (a_rout_disp, a_encaps_rout_disp, a_calc_rout_addr: POINTER; a_closed_operands: TUPLE; a_is_target_closed: BOOLEAN; a_open_count: INTEGER_32) -- Initialize object in finalized mode. require target_valid: a_is_target_closed implies valid_target (a_closed_operands) do rout_disp := a_rout_disp encaps_rout_disp := a_encaps_rout_disp calc_rout_addr := a_calc_rout_addr closed_operands := a_closed_operands is_target_closed := a_is_target_closed open_count := a_open_count end frozen set_rout_disp_int (a_rout_disp, a_encaps_rout_disp, a_calc_rout_addr: POINTER; a_routine_id: INTEGER_32; a_open_map: like open_map; a_is_basic, a_is_target_closed: BOOLEAN; a_written_type_id_inline_agent: INTEGER_32; a_closed_operands: TUPLE; a_open_count: INTEGER_32) -- Initialize object in workbench mode. require a_routine_id_valid: a_routine_id > -1 target_valid: a_is_target_closed implies valid_target (a_closed_operands) do rout_disp := a_rout_disp encaps_rout_disp := a_encaps_rout_disp calc_rout_addr := a_calc_rout_addr routine_id := a_routine_id open_map := a_open_map is_basic := a_is_basic is_target_closed := a_is_target_closed written_type_id_inline_agent := a_written_type_id_inline_agent closed_operands := a_closed_operands open_count := a_open_count ensure rout_disp_set: rout_disp = a_rout_disp encaps_rout_disp_set: encaps_rout_disp = a_encaps_rout_disp calc_rout_addr_set: calc_rout_addr = a_calc_rout_addr routine_id_set: routine_id = a_routine_id open_map_set: open_map = a_open_map is_target_closed_set: is_target_closed = a_is_target_closed is_basic_set: is_basic = a_is_basic written_type_id_inline_agent_set: written_type_id_inline_agent = a_written_type_id_inline_agent closed_operands_set: closed_operands = a_closed_operands open_count_set: open_count = a_open_count end frozen written_type_id_inline_agent: INTEGER_32 feature {NONE} -- Implementation Id_to_storable_version: HASH_TABLE [detachable IMMUTABLE_STRING_8, INTEGER_32] -- Buffer for storable_version_of_type lookups index by type_id. -- (from REFLECTOR) once create Result.make (100) ensure -- from REFLECTOR instance_free: class id_to_storable_version_not_void: Result /= Void end Internal_dynamic_type_string_table: STRING_TABLE [INTEGER_32] -- Table of dynamic type indexed by type name -- (from REFLECTOR) once create Result.make (100) ensure -- from REFLECTOR instance_free: class internal_dynamic_type_string_table_not_void: Result /= Void end open_operand_type (i: INTEGER_32): INTEGER_32 -- Type of ith open operand. require positive: i >= 1 within_bounds: i <= open_count local o: like open_types do o := open_types if o = Void then create o.make_filled (-1, 1, open_count) open_types := o end Result := o.item (i) if Result = -1 then Result := ({OPEN_ARGS}).generic_parameter_type (i).type_id; o.put (Result, i) end end frozen open_types: detachable ARRAY [INTEGER_32] -- Types of open operands type_id_of (a: separate ANY): INTEGER_32 -- Type ID of an object a. require False do Result := a.generating_type.type_id end feature -- Conformance field_conforms_to (a_source_type, a_field_type: INTEGER_32): BOOLEAN -- Does a_source_type conform to a_field_type? -- (from REFLECTOR) require -- from REFLECTOR a_source_type_non_negative: a_source_type >= 0 a_field_type_non_negative: a_field_type >= 0 do Result := {ISE_RUNTIME}.type_conforms_to (a_source_type, {ISE_RUNTIME}.detachable_type (a_field_type)) ensure -- from REFLECTOR instance_free: class end type_conforms_to (type1, type2: INTEGER_32): BOOLEAN -- Does type1 conform to type2? -- (from REFLECTOR) require -- from REFLECTOR type1_nonnegative: type1 >= 0 type2_nonnegative: type2 >= 0 do Result := {ISE_RUNTIME}.type_conforms_to (type1, type2) ensure -- from REFLECTOR instance_free: class end feature -- Correction correct_mismatch -- Attempt to correct object mismatch using Mismatch_information. do end Mismatch_information: MISMATCH_INFORMATION -- Original attribute values of mismatched object -- (from MISMATCH_CORRECTOR) once create Result end feature -- Creation dynamic_type_from_string (class_type: READABLE_STRING_GENERAL): INTEGER_32 -- Dynamic type corresponding to class_type. -- If no dynamic type available, returns -1. -- (from REFLECTOR) require -- from REFLECTOR class_type_not_void: class_type /= Void class_type_not_empty: not class_type.is_empty is_valid_type_string: is_valid_type_string (class_type) local l_cstr: C_STRING l_table: like Internal_dynamic_type_string_table l_pre_ecma_status: BOOLEAN do l_table := Internal_dynamic_type_string_table; l_table.search (class_type) if l_table.found then Result := l_table.found_item else create l_cstr.make (class_type) l_pre_ecma_status := {ISE_RUNTIME}.pre_ecma_mapping_status {ISE_RUNTIME}.set_pre_ecma_mapping (not is_pre_ecma_mapping_disabled) Result := {ISE_RUNTIME}.type_id_from_name (l_cstr.item) {ISE_RUNTIME}.set_pre_ecma_mapping (l_pre_ecma_status); l_table.put (Result, class_type) end ensure -- from REFLECTOR instance_free: class dynamic_type_from_string_valid: Result = -1 or Result = None_type or Result >= 0 end new_instance_of (type_id: INTEGER_32): ANY -- New instance of dynamic type_id. -- Note: returned object is not initialized and may -- hence violate its invariant. -- type_id cannot represent a SPECIAL type, use -- new_special_any_instance instead. -- (from REFLECTOR) require -- from REFLECTOR type_id_nonnegative: type_id >= 0 not_special_type: not is_special_type (type_id) not_deferred: not type_of_type (type_id).is_deferred do Result := {ISE_RUNTIME}.new_instance_of (type_id) ensure -- from REFLECTOR instance_free: class not_special_type: not attached {SPECIAL [detachable ANY]} Result dynamic_type_set: attached_type (Result.generating_type.type_id) = attached_type (type_id) end new_special_any_instance (type_id, a_capacity: INTEGER_32): SPECIAL [detachable ANY] -- New instance of dynamic type_id that represents -- a SPECIAL which can contain a_capacity elements of reference type. -- To create a SPECIAL of basic type, use class SPECIAL directly. -- (from REFLECTOR) require -- from REFLECTOR a_capacity_valid: a_capacity >= 0 type_id_nonnegative: type_id >= 0 special_type: is_special_any_type (type_id) do Result := {ISE_RUNTIME}.new_special_of_reference_instance_of (type_id, a_capacity) ensure -- from REFLECTOR instance_free: class dynamic_type_set: Result.generating_type.type_id = type_id count_set: Result.count = 0 capacity_set: Result.capacity = a_capacity end new_tuple_from_special (type_id: INTEGER_32; values: SPECIAL [detachable separate ANY]): detachable TUPLE -- New instance of a tuple of type type_id filled with values if all types of items are suitable. -- Void if some items from values are inappropriate for a tuple of type type_id. -- (from REFLECTOR) require -- from REFLECTOR type_id_nonnegative: type_id >= 0 is_tuple_type: is_tuple_type (type_id) local i: INTEGER_32 v: detachable separate ANY do Result := {ISE_RUNTIME}.new_tuple_instance_of (type_id) i := Result.count if i <= values.count then from until i <= 0 or else not attached Result loop v := values [i - 1] if Result.valid_type_for_index (v, i) then Result [i] := v else Result := Void end i := i - 1 end else Result := Void end ensure -- from REFLECTOR instance_free: class dynamic_type_set: attached Result implies Result.generating_type.type_id = type_id values_set: attached Result implies ∀ k: 1 |..| Result.count ¦ Result.item (k) = values [k - 1] end new_tuple_from_tuple (type_id: INTEGER_32; source: separate TUPLE): detachable TUPLE -- New instance of a tuple of type type_id filled with values fom source if all value types are suitable. -- Void if some values from source are inappropriate for a tuple of type type_id. -- (from REFLECTOR) require -- from REFLECTOR type_id_nonnegative: type_id >= 0 is_tuple_type: is_tuple_type (type_id) local i: INTEGER_32 v: detachable separate ANY do Result := {ISE_RUNTIME}.new_tuple_instance_of (type_id) i := Result.count if i <= source.count then if source.object_comparison then Result.compare_objects end from until i <= 0 or else not attached Result loop v := source [i] if Result.valid_type_for_index (v, i) then Result [i] := v else Result := Void end i := i - 1 end else Result := Void end ensure -- from REFLECTOR instance_free: class dynamic_type_set: attached Result implies Result.generating_type.type_id = type_id object_comparison_set: attached Result implies Result.object_comparison = source.object_comparison values_set: attached Result implies ∀ k: 1 |..| Result.count ¦ Result.item (k) = source [k] end type_of_type (type_id: INTEGER_32): TYPE [detachable ANY] -- Associated TYPE instance for an object of type id type_id -- (from REFLECTOR) require -- from REFLECTOR type_id_nonnegative: type_id >= 0 do Result := {ISE_RUNTIME}.new_type_instance_of (type_id) ensure -- from REFLECTOR instance_free: class result_not_void: Result /= Void end feature {NONE} -- Decompose string type parameters_decomposition (a_str: READABLE_STRING_32): detachable ARRAYED_LIST [READABLE_STRING_32] -- Decompose a_str which should be of the form "A, B, D [G], H [E ,F]" -- into a list of strings "A", "B", "D [G]", "H [E, F]" -- If decomposition is not possible, Void. -- (from REFLECTOR_HELPER) require -- from REFLECTOR_HELPER a_str_not_void: a_str /= Void local i, nb: INTEGER_32 l_invalid: BOOLEAN l_first_pos: INTEGER_32 l_nesting: INTEGER_32 do from create Result.make (5) i := 1 l_first_pos := 1 nb := a_str.count until i > nb or l_invalid loop inspect a_str.item (i) when ',' then if l_nesting = 0 then Result.extend (a_str.substring (l_first_pos, i - 1)) l_first_pos := i + 1 end when '[' then l_nesting := l_nesting + 1 when ']' then l_nesting := l_nesting - 1 l_invalid := l_nesting < 0 else end i := i + 1 end if not l_invalid and then l_nesting = 0 then Result.extend (a_str.substring (l_first_pos, i - 1)) else Result := Void end ensure -- from REFLECTOR_HELPER instance_free: class end feature {NONE} -- ECMA mapping helper Attached_keyword: STRING_8 = "attached" -- (from REFLECTOR_HELPER) Attached_mark: CHARACTER_32 = '!' -- (from REFLECTOR_HELPER) Detachable_keyword: STRING_8 = "detachable" -- (from REFLECTOR_HELPER) Detachable_mark: CHARACTER_32 = '?' -- (from REFLECTOR_HELPER) Expanded_keyword: STRING_8 = "expanded" -- Symbols use for attachment marks. -- (from REFLECTOR_HELPER) Pre_ecma_type_mapping: STRING_TABLE [STRING_8] -- Mapping between pre-ECMA type naming and new names. -- (from REFLECTOR_HELPER) once create Result.make (12); Result.put ("STRING_8", "STRING"); Result.put ("INTEGER_32", "INTEGER"); Result.put ("INTEGER_32_REF", "INTEGER_REF"); Result.put ("CHARACTER_8", "CHARACTER"); Result.put ("CHARACTER_8_REF", "CHARACTER_REF"); Result.put ("CHARACTER_32", "WIDE_CHARACTER"); Result.put ("CHARACTER_32_REF", "WIDE_CHARACTER_REF"); Result.put ("REAL_32", "REAL"); Result.put ("REAL_32_REF", "REAL_REF"); Result.put ("REAL_64", "DOUBLE"); Result.put ("REAL_64_REF", "DOUBLE_REF") ensure -- from REFLECTOR_HELPER instance_free: class pre_ecma_type_mapping_not_void: Result /= Void end feature -- Extended operations flexible_call (a: detachable separate TUPLE) -- Call routine with arguments a. -- Compared to call the type of a may be different from {OPEN_ARGS}. require valid_operands: valid_operands (a) local default_arguments: detachable OPEN_ARGS do if not attached a then call (default_arguments) else check from_precondition: attached {OPEN_ARGS} new_tuple_from_tuple (({OPEN_ARGS}).type_id, a) as x then call (x) end end end feature {NONE} -- Implementation: status report is_valid_identifier (s: READABLE_STRING_GENERAL): BOOLEAN -- Is s a valid Eiffel identifier? -- (from REFLECTOR_HELPER) require -- from REFLECTOR_HELPER name_not_void: s /= Void local i, nb: INTEGER_32 cc: CHARACTER_32 do if not s.is_empty then cc := s.item (1) nb := s.count + 1 if cc = Attached_mark or cc = Detachable_mark then i := 2 elseif s.substring_index (Attached_keyword, 1) = 1 then i := Attached_keyword.count + 1 elseif s.substring_index (Detachable_keyword, 1) = 1 then i := Detachable_keyword.count + 1 elseif s.substring_index (Expanded_keyword, 1) = 1 then i := Expanded_keyword.count + 1 else i := 1 end if i > 1 then from until i = nb or not s.item (i).is_space loop i := i + 1 end end if s.item (i).is_alpha then from Result := True until i = nb loop cc := s.item (i) if not (cc.is_alpha or cc.is_digit or cc = '_'.to_character_32) then Result := False i := nb - 1 end i := i + 1 end end end ensure -- from REFLECTOR_HELPER instance_free: class end feature -- Output Io: STD_FILES -- Handle to standard file setup -- (from ANY) once create Result; Result.set_output_default ensure -- from ANY instance_free: class io_not_void: Result /= Void end out: STRING_8 -- New string containing terse printable representation -- of current object -- (from ANY) do Result := tagged_out ensure -- from ANY out_not_void: Result /= Void end print (o: detachable ANY) -- Write terse external representation of o -- on standard output. -- (from ANY) local s: READABLE_STRING_8 do if attached o then s := o.out if attached {READABLE_STRING_32} s as s32 then Io.put_string_32 (s32) elseif attached {READABLE_STRING_8} s as s8 then Io.put_string (s8) else Io.put_string_32 (s.as_string_32) end end ensure -- from ANY instance_free: class end frozen tagged_out: STRING_8 -- New string containing terse printable representation -- of current object -- (from ANY) external "built_in" ensure -- from ANY tagged_out_not_void: Result /= Void end feature -- Platform Operating_environment: OPERATING_ENVIRONMENT -- Objects available from the operating system -- (from ANY) once create Result ensure -- from ANY instance_free: class operating_environment_not_void: Result /= Void end feature {NONE} -- Retrieval frozen internal_correct_mismatch -- Called from runtime to perform a proper dynamic dispatch on correct_mismatch -- from MISMATCH_CORRECTOR. -- (from ANY) local l_msg: STRING_32 l_exc: EXCEPTIONS do if attached {MISMATCH_CORRECTOR} Current as l_corrector then l_corrector.correct_mismatch else create l_msg.make_from_string ("Mismatch: ".as_string_32) create l_exc; l_msg.append (generating_type.name_32); l_exc.raise_retrieval_exception (l_msg) end end feature -- Settings frozen set_operands (args: detachable OPEN_ARGS) -- Use args as operands for next call. require valid_operands: valid_operands (args) do operands := args ensure operands_set: (operands /= Void implies (operands ~ args)) or (operands = Void implies (args = Void or else args.is_empty)) end set_target (a_target: like target) -- Set a_target as the next target for remaining calls to Current. require a_target_not_void: a_target /= Void is_target_closed: is_target_closed target_not_void: target /= Void same_target_type: attached target as t and then t.same_type (a_target) local c: like closed_operands do c := closed_operands if c /= Void then c.put (a_target, 1) end ensure target_set: target = a_target end feature {NONE} -- Type creation Type_keyword: STRING_8 = "TYPE" -- Used for creating type objects. -- (from REFLECTOR_HELPER) feature -- Version compiler_version: INTEGER_32 -- (from REFLECTOR) do Result := 0 ensure -- from REFLECTOR instance_free: class end invariant -- from ANY reflexive_equality: standard_is_equal (Current) reflexive_conformance: conforms_to (Current) note copyright: "Copyright (c) 1984-2017, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software 5949 Hollister Ave., Goleta, CA 93117 USA Telephone 805-685-1006, Fax 805-685-6869 Website http://www.eiffel.com Customer support http://support.eiffel.com ]" end -- class ROUTINE
Generated by ISE EiffelStudio