def executeInstruction( node: nodes.InstructionNode, state: programState.ProgramState, fileName: str, lines: List[str]) -> Tuple[programState.ProgramState, bool]: if isinstance(node, nodes.InstructionNode): # Execute the instruction state, err = node.function(state) # Exception handling if err is not None: if isinstance(err, programState.RunError): if err.errorType == programState.RunError.ErrorType.Error: print(generateStacktrace(state, err, fileName, lines)) return state, False elif err.errorType == programState.RunError.ErrorType.Warning: print(generateStacktrace(state, err, fileName, lines)) elif isinstance(err, programState.StopProgram): return state, False # Set a flag in the ProgramState when a subroutine returned. This way the stacktrace generator knows to not print a stacktrace element for the link register pc = state.getReg("PC") if pc == state.getReg("LR"): state.hasReturned = True # increment the program counter state.setReg("PC", pc + 4) return state, True else: if isinstance(node, programState.RunError): print(generateStacktrace(state, node, fileName, lines)) return state, False
def branchToLabel(state: programState.ProgramState, label: str) -> Tuple[programState.ProgramState, Union[programState.RunError, None]]: # Save return address in LR state.setReg("LR", state.getReg("PC")) address: Union[int, programState.RunError] = state.getLabelAddress(label) if isinstance(address, programState.RunError): return state, programState.RunError(f"Unknown startup label: {label}", programState.RunError.ErrorType.Error) else: # Subtract 4 because we will add 4 to the address later in the run loop and we need to start at address and not address+4 state.setReg("PC", address - 4) state.hasReturned = False return state, None
def branchTo( state: programState.ProgramState ) -> Tuple[programState.ProgramState, Union[programState.RunError, None]]: if link: # Save return address in LR state.setReg("LR", state.getReg("PC")[0]) address, err = state.getReg(label.contents) # Subtract 4 because we will add 4 to the address later in the run loop and we need to start at address and not address+4 state.setReg("PC", address - 4) state.hasReturned = False return state, err
def branchTo( state: programState.ProgramState ) -> Tuple[programState.ProgramState, Union[programState.RunError, None]]: # Save return address in LR pc, _ = state.getReg("PC") state.setReg("LR", pc) address: Union[int, programState.RunError] = state.getLabelAddress( label.contents) if isinstance(address, programState.RunError): return state, address else: # Subtract 4 because we will add 4 to the address later in the run loop and we need to start at address and not address+4 state.setReg("PC", address - 4) state.hasReturned = False return state, None