def add_state(self, StateIndex, OnSuccessDoorId, OnFailureDoorId, BeforeReload=None): """Adds a state from where the reload state is entered. When reload is done it jumps to 'OnFailureDoorId' if the reload failed and to 'OnSuccessDoorId' if the reload succeeded. RETURNS: DoorID into the reload state. Jump to this DoorID in order to trigger the reload for the state given by 'StateIndex'. """ assert BeforeReload is None or isinstance(BeforeReload, CommandList) # Before reload: prepare after reload, the jump back to the reloading state. before_cl = CommandList(PrepareAfterReload(OnSuccessDoorId, OnFailureDoorId)) if BeforeReload is not None: # May be, add additional commands before_cl = before_cl.concatinate(BeforeReload) # No two transitions into the reload state have the same CommandList! # No two transitions can have the same DoorID! # => it is safe to assign a new DoorID withouth .categorize() ta = TransitionAction(before_cl) # Assign a DoorID (without categorization) knowing that no such entry # into this state existed before. ta.door_id = dial_db.new_door_id(self.index) assert not self.entry.has_transition(self.index, StateIndex) # Cannot be in there twice! self.entry.enter(self.index, StateIndex, ta) return ta.door_id
def add_state(self, StateIndex, OnSuccessDoorId, OnFailureDoorId, BeforeReload=None): """Adds a state from where the reload state is entered. When reload is done it jumps to 'OnFailureDoorId' if the reload failed and to 'OnSuccessDoorId' if the reload succeeded. RETURNS: DoorID into the reload state. Jump to this DoorID in order to trigger the reload for the state given by 'StateIndex'. """ assert BeforeReload is None or isinstance(BeforeReload, CommandList) # Before reload: prepare after reload, the jump back to the reloading state. before_cl = CommandList( PrepareAfterReload(OnSuccessDoorId, OnFailureDoorId)) if BeforeReload is not None: # May be, add additional commands before_cl = before_cl.concatinate(BeforeReload) # No two transitions into the reload state have the same CommandList! # No two transitions can have the same DoorID! # => it is safe to assign a new DoorID withouth .categorize() ta = TransitionAction(before_cl) # Assign a DoorID (without categorization) knowing that no such entry # into this state existed before. ta.door_id = dial_db.new_door_id(self.index) assert not self.entry.has_transition( self.index, StateIndex) # Cannot be in there twice! self.entry.enter(self.index, StateIndex, ta) return ta.door_id
def _prepare_entry_and_reentry(analyzer, OnBegin, OnStep): """Prepare the entry and re-entry doors into the initial state of the loop-implementing initial state. .----------. | on_entry | '----------' | .------------. |<--------| on_reentry |<-----. | '------------' | .----------------. | | +-----> Terminal ----+----> Exit | ... | | +-----> Terminal - - '----------------' RETURNS: DoorID of the re-entry door which is used to iterate in the loop. """ # Entry into state machine entry = analyzer.init_state().entry init_state_index = analyzer.init_state_index # OnEntry ta_on_entry = entry.get_action(init_state_index, E_StateIndices.NONE) ta_on_entry.command_list = CommandList.concatinate( ta_on_entry.command_list, OnBegin) # OnReEntry tid_reentry = entry.enter_CommandList(init_state_index, index.get(), CommandList.from_iterable(OnStep)) entry.categorize(init_state_index) return entry.get(tid_reentry).door_id
def _prepare_entry_and_reentry(analyzer, OnBegin, OnStep): """Prepare the entry and re-entry doors into the initial state of the loop-implementing initial state. .----------. | on_entry | '----------' | .------------. |<--------| on_reentry |<-----. | '------------' | .----------------. | | +-----> Terminal ----+----> Exit | ... | | +-----> Terminal - - '----------------' RETURNS: DoorID of the re-entry door which is used to iterate in the loop. """ # Entry into state machine entry = analyzer.init_state().entry init_state_index = analyzer.init_state_index # OnEntry ta_on_entry = entry.get_action(init_state_index, E_StateIndices.NONE) ta_on_entry.command_list = CommandList.concatinate(ta_on_entry.command_list, OnBegin) # OnReEntry tid_reentry = entry.enter_CommandList(init_state_index, index.get(), CommandList.from_iterable(OnStep)) entry.categorize(init_state_index) return entry.get(tid_reentry).door_id
def create_DropOut(self, SM_State): if SM_State.is_acceptance(): incidence_id = self.__incidence_id_of_bipd return CommandList( QuexDebug('pattern %i: backward input position detected\\n' % incidence_id), InputPIncrement(), GotoDoorId(DoorID.bipd_return(incidence_id))) else: return CommandList(QuexAssertNoPassage())
def __init__(self, InitCommandList=None): # NOTE: 'DoorId' is not accepted as argument. Is needs to be assigned # by '.categorize()' in the action_db. Then, transition actions # with the same CommandList-s share the same DoorID. assert InitCommandList is None or isinstance( InitCommandList, CommandList), "%s: %s" % (InitCommandList.__class__, InitCommandList) self.door_id = None if InitCommandList is None: self._command_list = CommandList() else: self._command_list = InitCommandList
def prepare_state(self, OldState, StateIndex): """REQUIRES: 'self.init_state_forward_f', 'self.engine_type', 'self.__from_db'. """ state = AnalyzerState.from_State(OldState, StateIndex, self.engine_type) cmd_list = [] if self.engine_type.is_BACKWARD_PRE_CONTEXT(): cmd_list.extend( PreContextOK(origin.acceptance_id()) for origin in OldState.origins() \ if origin.is_acceptance() ) if state.transition_map is None and False: # NOTE: We need a way to disable this exception for PathWalkerState-s(!) # It's safe, not to allow it, in general. #------------------------------------------------------------------------ # If the state has no further transitions then the input character does # not have to be read. This is so, since without a transition map, the # state immediately drops out. The drop out transits to a terminal. # Then, the next action will happen from the init state where we work # on the same position. If required the reload happens at that moment, # NOT before the empty transition block. # # This is not true for Path Walker States, so we offer the option # 'ForceInputDereferencingF' assert StateIndex != self.init_state_index # Empty state machine! --> impossible if self.engine_type.is_FORWARD(): cmd_list.append(InputPIncrement()) else: cmd_list.append(InputPDecrement()) else: if self.engine_type.is_FORWARD(): cmd_list.extend([InputPIncrement(), InputPDereference()]) else: cmd_list.extend([InputPDecrement(), InputPDereference()]) ta = TransitionAction(CommandList.from_iterable(cmd_list)) # NOTE: The 'from reload transition' is implemented by 'prepare_for_reload()' for source_state_index in self.__from_db[StateIndex]: assert source_state_index != E_StateIndices.NONE state.entry.enter(StateIndex, source_state_index, ta.clone()) if StateIndex == self.init_state_index: if self.engine_type.is_FORWARD(): ta = TransitionAction(CommandList(InputPDereference())) state.entry.enter_state_machine_entry(self.__state_machine_id, StateIndex, ta) return state
def __init__(self, InitCommandList=None): # NOTE: 'DoorId' is not accepted as argument. Is needs to be assigned # by '.categorize()' in the action_db. Then, transition actions # with the same CommandList-s share the same DoorID. assert InitCommandList is None or isinstance(InitCommandList, CommandList), "%s: %s" % (InitCommandList.__class__, InitCommandList) self.door_id = None if InitCommandList is None: self._command_list = CommandList() else: self._command_list = InitCommandList
def get_CommandList(TheAccepter, TheTerminalRouter): """If there is no stored acceptance involved, then one can directly conclude from the pre-contexts to the acceptance_id. Then the drop- out action can be described as a sequence of checks # [0] Check [1] Position and Goto Terminal if pre_context_32: input_p = x; goto terminal_893; elif pre_context_32: goto terminal_893; elif pre_context_32: input_p = x; goto terminal_893; elif pre_context_32: goto terminal_893; Such a configuration is considered trivial. No restore is involved. RETURNS: None -- if not trivial list((pre_context_id, TerminalRouterElement)) -- if trivial """ # If the 'last_acceptance' is not determined in this state, then it # must bee derived from previous storages. We cannot simplify here. if TheAccepter is None: return CommandList(TheTerminalRouter) elif not TheAccepter.content.has_acceptance_without_pre_context(): # If no pre-context is met, then 'last_acceptance' needs to be # considered. return CommandList(TheAccepter, TheTerminalRouter) def router_element(TerminalRouter, AcceptanceId): for x in TerminalRouter: if x.acceptance_id == AcceptanceId: return x assert False # There MUST be an element for each acceptance_id! router = TheTerminalRouter.content return CommandList.from_iterable( IfPreContextSetPositionAndGoto( check.pre_context_id, router_element(router, check.acceptance_id)) for check in TheAccepter.content)
class TransitionAction(object): """Object containing information about commands to be executed upon transition into a state. .command_list --> list of commands to be executed upon the transition. .door_id --> An 'id' which is supposed to be unique for a command list. It is (re-)assigned during the process of 'EntryActionDB.categorize()'. """ __slots__ = ("door_id", "_command_list") def __init__(self, InitCommandList=None): # NOTE: 'DoorId' is not accepted as argument. Is needs to be assigned # by '.categorize()' in the action_db. Then, transition actions # with the same CommandList-s share the same DoorID. assert InitCommandList is None or isinstance( InitCommandList, CommandList), "%s: %s" % (InitCommandList.__class__, InitCommandList) self.door_id = None if InitCommandList is None: self._command_list = CommandList() else: self._command_list = InitCommandList @property def command_list(self): return self._command_list @command_list.setter def command_list(self, CL): assert isinstance(CL, CommandList) or CL is None self._command_list = CL def clone(self): result = TransitionAction(self._command_list.clone()) result.door_id = self.door_id # DoorID-s are immutable return result # Make TransitionAction usable for dictionary and set def __hash__(self): return hash(self._command_list) def __eq__(self, Other): return self._command_list == Other._command_list def __repr__(self): return "(%s: [%s])" % (self.door_id, self._command_list)
class TransitionAction(object): """Object containing information about commands to be executed upon transition into a state. .command_list --> list of commands to be executed upon the transition. .door_id --> An 'id' which is supposed to be unique for a command list. It is (re-)assigned during the process of 'EntryActionDB.categorize()'. """ __slots__ = ("door_id", "_command_list") def __init__(self, InitCommandList=None): # NOTE: 'DoorId' is not accepted as argument. Is needs to be assigned # by '.categorize()' in the action_db. Then, transition actions # with the same CommandList-s share the same DoorID. assert InitCommandList is None or isinstance(InitCommandList, CommandList), "%s: %s" % (InitCommandList.__class__, InitCommandList) self.door_id = None if InitCommandList is None: self._command_list = CommandList() else: self._command_list = InitCommandList @property def command_list(self): return self._command_list @command_list.setter def command_list(self, CL): assert isinstance(CL, CommandList) or CL is None self._command_list = CL def clone(self): result = TransitionAction(self._command_list.clone()) result.door_id = self.door_id # DoorID-s are immutable return result # Make TransitionAction usable for dictionary and set def __hash__(self): return hash(self._command_list) def __eq__(self, Other): return self._command_list == Other._command_list def __repr__(self): return "(%s: [%s])" % (self.door_id, self._command_list)
def get_CommandList(TheAccepter, TheTerminalRouter): """If there is no stored acceptance involved, then one can directly conclude from the pre-contexts to the acceptance_id. Then the drop- out action can be described as a sequence of checks # [0] Check [1] Position and Goto Terminal if pre_context_32: input_p = x; goto terminal_893; elif pre_context_32: goto terminal_893; elif pre_context_32: input_p = x; goto terminal_893; elif pre_context_32: goto terminal_893; Such a configuration is considered trivial. No restore is involved. RETURNS: None -- if not trivial list((pre_context_id, TerminalRouterElement)) -- if trivial """ # If the 'last_acceptance' is not determined in this state, then it # must bee derived from previous storages. We cannot simplify here. if TheAccepter is None: return CommandList(TheTerminalRouter) elif not TheAccepter.content.has_acceptance_without_pre_context(): # If no pre-context is met, then 'last_acceptance' needs to be # considered. return CommandList(TheAccepter, TheTerminalRouter) def router_element(TerminalRouter, AcceptanceId): for x in TerminalRouter: if x.acceptance_id == AcceptanceId: return x assert False # There MUST be an element for each acceptance_id! router = TheTerminalRouter.content return CommandList.from_iterable( IfPreContextSetPositionAndGoto(check.pre_context_id, router_element(router, check.acceptance_id)) for check in TheAccepter.content )
def add_mega_state(self, MegaStateIndex, StateKeyRegister, Iterable_StateKey_Index_Pairs, TheAnalyzer): """Implement a router from the MegaState-s door into the Reloader to the doors of the implemented states. Reload State .--------------------------------- - - - .--------------. on state-key reload --->| MegaState's | .---. | Reload Door |------>| 0 |-----> Reload Door of state[0] '--------------' | 1 |-----> Reload Door of state[1] | | : | : '---' '--------------------------------- - - - """ def DoorID_provider(state_index): door_id = self.entry.get_door_id(self.index, state_index) if door_id is None: # The state implemented in the MegaState did not have a # transition to 'ReloadState'. Thus, it was a total drop-out. # => Route to the state's drop-out. door_id = TheAnalyzer.drop_out_DoorID(state_index) return door_id cmd = RouterOnStateKey(StateKeyRegister, MegaStateIndex, Iterable_StateKey_Index_Pairs, DoorID_provider) ta = TransitionAction(CommandList(cmd)) # Assign a DoorID (without categorization) knowing that no such entry # into this state existed before. ta.door_id = dial_db.new_door_id(self.index) assert not self.entry.has_transition( self.index, MegaStateIndex) # Cannot be in there twice! self.entry.enter(self.index, MegaStateIndex, ta) return ta.door_id
def do(CcFactory, AfterBeyond, LexemeEndCheckF=False, EngineType=None, ReloadStateExtern=None, LexemeMaintainedF=False, ParallelSmTerminalPairList=None): """Generates a (pseudo-one-state) state machine with the properties: Buffer Limit Code --> Reload Loop Character --> Loop Entry Else --> Exit Loop NOTE: This function does NOT code the FAILURE terminal. The caller needs to do this if required. Generate code to iterate over the input stream until -- A character occurs not in CharacterSet, or -- [optional] the 'LexemeEnd' is reached. That is, simplified: input in Set .--<--. | | LexemeEnd | +----->------> (Exit) .----. | --------->( Loop )--+----->------> Exit '----' input not in Set At the end of the iteration, the 'input_p' points to (the begin of) the first character which is not in CharacterSet (or the LexemeEnd). [i][i][i]..................[i][i][X][.... | input_p During the 'loop' possible line/column count commands may be applied. To achieve the iteration, a simplified pattern matching engine is implemented: transition map .------. | i0 |----------> Terminal0: CommandList0 +------+ | i1 |----------> Terminal1: CommandList1 +------+ | X2 |----------> Terminal Beyond: input_p--; goto TerminalExit; +------+ | i2 |----------> Terminal2: CommandList2 +------+ """ assert EngineType is not None # NOT: assert (not EngineType.subject_to_reload()) or ReloadStateExtern is None # This would mean, that the user has to make these kinds of decisions. But, # we are easily able to ignore meaningless ReloadStateExtern objects. # (*) Construct State Machine and Terminals _______________________________ # parallel_sm_list = None if ParallelSmTerminalPairList is not None: parallel_sm_list = [sm for sm, terminal in ParallelSmTerminalPairList] CsSm = CharacterSetStateMachine.from_CountCmdFactory( CcFactory, LexemeMaintainedF, ParallelSmList=parallel_sm_list) analyzer = analyzer_generator.do( CsSm.sm, EngineType, ReloadStateExtern, OnBeforeReload=CommandList.from_iterable(CsSm.on_before_reload), OnAfterReload=CommandList.from_iterable(CsSm.on_after_reload)) # -- The terminals # door_id_loop = _prepare_entry_and_reentry(analyzer, CsSm.on_begin, CsSm.on_step) def get_LexemeEndCheck_appendix(ccfactory, CC_Type): if not LexemeEndCheckF: return [GotoDoorId(door_id_loop)] # # .---------------. ,----------. no # --->| Count Command |-------< LexemeEnd? >------> DoorIdOk # '---------------' '----+-----' # | yes # .---------------. # | Lexeme End | # | Count Command |----> DoorIdOnLexemeEnd # '---------------' # elif ccfactory.requires_reference_p( ) and CC_Type == E_CharacterCountType.COLUMN: return [ GotoDoorIdIfInputPNotEqualPointer(door_id_loop, E_R.LexemeEnd), ColumnCountReferencePDeltaAdd( E_R.InputP, ccfactory.column_count_per_chunk, False), ] + AfterBeyond else: return [ GotoDoorIdIfInputPNotEqualPointer(door_id_loop, E_R.LexemeEnd), ] + AfterBeyond terminal_list = CcFactory.get_terminal_list(CsSm.on_end + AfterBeyond, CsSm.incidence_id_beyond, get_LexemeEndCheck_appendix) if ParallelSmTerminalPairList is not None: terminal_list.extend(terminal for sm, terminal in ParallelSmTerminalPairList) # (*) Generate Code _______________________________________________________ txt = _get_source_code(CcFactory, analyzer, terminal_list) return txt, DoorID.incidence(CsSm.incidence_id_beyond)
def do(CcFactory, AfterBeyond, LexemeEndCheckF=False, EngineType=None, ReloadStateExtern=None, LexemeMaintainedF=False, ParallelSmTerminalPairList=None): """Generates a (pseudo-one-state) state machine with the properties: Buffer Limit Code --> Reload Loop Character --> Loop Entry Else --> Exit Loop NOTE: This function does NOT code the FAILURE terminal. The caller needs to do this if required. Generate code to iterate over the input stream until -- A character occurs not in CharacterSet, or -- [optional] the 'LexemeEnd' is reached. That is, simplified: input in Set .--<--. | | LexemeEnd | +----->------> (Exit) .----. | --------->( Loop )--+----->------> Exit '----' input not in Set At the end of the iteration, the 'input_p' points to (the begin of) the first character which is not in CharacterSet (or the LexemeEnd). [i][i][i]..................[i][i][X][.... | input_p During the 'loop' possible line/column count commands may be applied. To achieve the iteration, a simplified pattern matching engine is implemented: transition map .------. | i0 |----------> Terminal0: CommandList0 +------+ | i1 |----------> Terminal1: CommandList1 +------+ | X2 |----------> Terminal Beyond: input_p--; goto TerminalExit; +------+ | i2 |----------> Terminal2: CommandList2 +------+ """ assert EngineType is not None # NOT: assert (not EngineType.subject_to_reload()) or ReloadStateExtern is None # This would mean, that the user has to make these kinds of decisions. But, # we are easily able to ignore meaningless ReloadStateExtern objects. # (*) Construct State Machine and Terminals _______________________________ # parallel_sm_list = None if ParallelSmTerminalPairList is not None: parallel_sm_list = [ sm for sm, terminal in ParallelSmTerminalPairList ] CsSm = CharacterSetStateMachine.from_CountCmdFactory(CcFactory, LexemeMaintainedF, ParallelSmList=parallel_sm_list) analyzer = analyzer_generator.do(CsSm.sm, EngineType, ReloadStateExtern, OnBeforeReload = CommandList.from_iterable(CsSm.on_before_reload), OnAfterReload = CommandList.from_iterable(CsSm.on_after_reload)) # -- The terminals # door_id_loop = _prepare_entry_and_reentry(analyzer, CsSm.on_begin, CsSm.on_step) def get_LexemeEndCheck_appendix(ccfactory, CC_Type): if not LexemeEndCheckF: return [ GotoDoorId(door_id_loop) ] # # .---------------. ,----------. no # --->| Count Command |-------< LexemeEnd? >------> DoorIdOk # '---------------' '----+-----' # | yes # .---------------. # | Lexeme End | # | Count Command |----> DoorIdOnLexemeEnd # '---------------' # elif ccfactory.requires_reference_p() and CC_Type == E_CharacterCountType.COLUMN: return [ GotoDoorIdIfInputPNotEqualPointer(door_id_loop, E_R.LexemeEnd), ColumnCountReferencePDeltaAdd(E_R.InputP, ccfactory.column_count_per_chunk, False), ] + AfterBeyond else: return [ GotoDoorIdIfInputPNotEqualPointer(door_id_loop, E_R.LexemeEnd), ] + AfterBeyond terminal_list = CcFactory.get_terminal_list(CsSm.on_end + AfterBeyond, CsSm.incidence_id_beyond, get_LexemeEndCheck_appendix) if ParallelSmTerminalPairList is not None: terminal_list.extend( terminal for sm, terminal in ParallelSmTerminalPairList ) # (*) Generate Code _______________________________________________________ txt = _get_source_code(CcFactory, analyzer, terminal_list) return txt, DoorID.incidence(CsSm.incidence_id_beyond)
def create_DropOut(self, SM_State): return CommandList(GotoDoorId( DoorID.global_end_of_pre_context_check()))
def prepare_for_reload(self, TheAnalyzer, BeforeReloadCmdList=None, AfterReloadCmdList=None): """Prepares state for reload. Reload procedure .- State 'X' ---. | | .-- Reloader------. | BUFFER LIMIT | .----------------. | | CODE detected ------->-------| Door from X: | | | | | Actions before | | | | | reload. | | | | '----------------' | | | | | | | | | reload buffer> | | .----------------. | | | | | Door for |---<-------(good)--* | | | RELOAD SUCCESS:| | | | | | Actions after | | (bad) | | | Reload. | '------- |--------' | '----------------' | | | .----------------. '---------------' | Door for | | RELOAD FAILURE | '----------------' (1) Create 'Door for RELOAD SUCCESS'. (2) Determine 'Door for RELOAD FAILURE'. (3) Create 'Door from X' in Reloader. (4) Adapt state X's transition map, so that: BUFFER LIMIT CODE --> reload procedure. """ assert self.transition_map is not None assert BeforeReloadCmdList is None or isinstance( BeforeReloadCmdList, CommandList) assert AfterReloadCmdList is None or isinstance( AfterReloadCmdList, CommandList) if not TheAnalyzer.engine_type.subject_to_reload(): # Engine type does not require reload => no reload. return elif self.transition_map.is_only_drop_out(): # If the state drops out anyway, then there is no need to reload. # -- The transition map is not adapted. # -- The reloader is not instrumented to reload for that state. return assert self.index in TheAnalyzer.state_db reload_state = TheAnalyzer.reload_state assert reload_state.index in (E_StateIndices.RELOAD_FORWARD, E_StateIndices.RELOAD_BACKWARD) # (1) Door for RELOAD SUCCESS # after_cl = [] if TheAnalyzer.engine_type.is_FORWARD(): after_cl.append(InputPIncrement()) else: after_cl.append(InputPDecrement()) after_cl.append(InputPDereference()) if AfterReloadCmdList is not None: after_cl.extend(AfterReloadCmdList) self.entry.enter_CommandList(self.index, reload_state.index, CommandList.from_iterable(after_cl)) self.entry.categorize(self.index) # Categorize => DoorID is available. on_success_door_id = self.entry.get_door_id(self.index, reload_state.index) # (2) Determin Door for RELOAD FAILURE # if TheAnalyzer.is_init_state_forward(self.index): on_failure_door_id = DoorID.incidence(E_IncidenceIDs.END_OF_STREAM) else: on_failure_door_id = TheAnalyzer.drop_out_DoorID(self.index) # (3) Create 'Door from X' in Reloader assert on_failure_door_id != on_success_door_id reload_door_id = reload_state.add_state(self.index, on_success_door_id, on_failure_door_id, BeforeReloadCmdList) # (4) Adapt transition map: BUFFER LIMIT CODE --> reload_door_id # self.transition_map.set_target(Setup.buffer_limit_code, reload_door_id) return
def prepare_for_reload(self, TheAnalyzer, BeforeReloadCmdList=None, AfterReloadCmdList=None): """Prepares state for reload. Reload procedure .- State 'X' ---. | | .-- Reloader------. | BUFFER LIMIT | .----------------. | | CODE detected ------->-------| Door from X: | | | | | Actions before | | | | | reload. | | | | '----------------' | | | | | | | | | reload buffer> | | .----------------. | | | | | Door for |---<-------(good)--* | | | RELOAD SUCCESS:| | | | | | Actions after | | (bad) | | | Reload. | '------- |--------' | '----------------' | | | .----------------. '---------------' | Door for | | RELOAD FAILURE | '----------------' (1) Create 'Door for RELOAD SUCCESS'. (2) Determine 'Door for RELOAD FAILURE'. (3) Create 'Door from X' in Reloader. (4) Adapt state X's transition map, so that: BUFFER LIMIT CODE --> reload procedure. """ assert self.transition_map is not None assert BeforeReloadCmdList is None or isinstance(BeforeReloadCmdList, CommandList) assert AfterReloadCmdList is None or isinstance(AfterReloadCmdList, CommandList) if not TheAnalyzer.engine_type.subject_to_reload(): # Engine type does not require reload => no reload. return elif self.transition_map.is_only_drop_out(): # If the state drops out anyway, then there is no need to reload. # -- The transition map is not adapted. # -- The reloader is not instrumented to reload for that state. return assert self.index in TheAnalyzer.state_db reload_state = TheAnalyzer.reload_state assert reload_state.index in (E_StateIndices.RELOAD_FORWARD, E_StateIndices.RELOAD_BACKWARD) # (1) Door for RELOAD SUCCESS # after_cl = [] if TheAnalyzer.engine_type.is_FORWARD(): after_cl.append(InputPIncrement()) else: after_cl.append(InputPDecrement()) after_cl.append(InputPDereference()) if AfterReloadCmdList is not None: after_cl.extend(AfterReloadCmdList) self.entry.enter_CommandList(self.index, reload_state.index, CommandList.from_iterable(after_cl)) self.entry.categorize(self.index) # Categorize => DoorID is available. on_success_door_id = self.entry.get_door_id(self.index, reload_state.index) # (2) Determin Door for RELOAD FAILURE # if TheAnalyzer.is_init_state_forward(self.index): on_failure_door_id = DoorID.incidence(E_IncidenceIDs.END_OF_STREAM) else: on_failure_door_id = TheAnalyzer.drop_out_DoorID(self.index) # (3) Create 'Door from X' in Reloader assert on_failure_door_id != on_success_door_id reload_door_id = reload_state.add_state(self.index, on_success_door_id, on_failure_door_id, BeforeReloadCmdList) # (4) Adapt transition map: BUFFER LIMIT CODE --> reload_door_id # self.transition_map.set_target(Setup.buffer_limit_code, reload_door_id) return