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] inherit HASHABLE redefine copy, is_equal end REFLECTOR export {NONE} all redefine copy, is_equal end MISMATCH_CORRECTOR redefine correct_mismatch, copy, is_equal 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 -- Access frozen operands: detachable OPEN_ARGS 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 hash_code: INTEGER_32 -- Hash code value. do Result := rout_disp.hash_code.bit_xor (routine_id.hash_code) end precondition (args: like operands): BOOLEAN -- Do args satisfy routine's precondition -- in current state? do Result := True end postcondition (args: like operands): BOOLEAN -- Does current state satisfy routine's -- postcondition for args? do Result := True end 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 feature -- Status report Callable: BOOLEAN = True -- Can routine be called on current object? is_equal (other: like Current): BOOLEAN -- Is associated routine the same as the one -- associated with other. 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) 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 is_target_closed: BOOLEAN -- Is target for current agent closed, i.e. specified at creation time? feature -- Measurement open_count: INTEGER_32 -- Number of open operands. 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 -- Duplication copy (other: like Current) -- Use same routine as other. do if other /= Current then standard_copy (other) if attached operands as l_operands then operands := l_operands.twin end end ensure then same_call_status: other.Callable implies Callable end feature -- Basic operations call (args: detachable separate OPEN_ARGS) -- Call routine with args. require valid_operands: valid_operands (args) deferred end apply -- Call routine with operands as last set. require valid_operands: valid_operands (operands) deferred 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 -- Correction correct_mismatch -- Attempt to correct object mismatch using Mismatch_information. do end feature {ROUTINE} -- Implementation frozen closed_operands: detachable TUPLE -- All closed arguments provided at creation time 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 rout_disp: POINTER -- Routine dispatcher frozen calc_rout_addr: POINTER -- Address of the final routine frozen open_map: detachable ARRAY [INTEGER_32] -- Index map for open arguments frozen encaps_rout_disp: POINTER -- Eiffel routine dispatcher frozen routine_id: INTEGER_32 frozen is_basic: BOOLEAN frozen written_type_id_inline_agent: 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 feature {NONE} -- Implementation frozen open_types: detachable ARRAY [INTEGER_32] -- Types of open operands 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 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 -- 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 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