def delete(self, base: Q) -> None: base %= 1 index = fraction_to_index(base) if self.stacks[index] is not None: self.stacks[index] = None self.pool.append(base)
def new(self, size: int = 0) -> Q: if self.pool: base = self.pool.pop() else: base = self.next_base self.next_base = next_fraction(self.next_base) index = fraction_to_index(base) while len(self.stacks) <= index: self.stacks.append(None) self.stacks[index] = size * [Q(0)] return base
def step(self) -> None: instruction = self.memory[self.registers[IR]] self.registers[IR] += 1 operand, opcode = divmod(instruction, 1) index = fraction_to_index(opcode) if index == GET_INDEX: address = self.registers[DR] - 1 handle = floor(self.memory[address]) if not self.streams[handle]: self.registers[IR] -= 1 return False elif index == HCF_INDEX: self.registers[IR] -= 1 return False operation = INDEX_TO_OPERATION[index] operation(self, operand) return True
from quest.memory import Memory from quest.opcode import Opcode from quest.operations import OPERATIONS from quest.register import Register from quest.stdio import StandardStream from quest.utils import fraction_to_index IR = Register.IR.value DR = Register.DR.value CR = Register.CR.value STDIN = StandardStream.STDIN.value STDOUT = StandardStream.STDOUT.value STDERR = StandardStream.STDERR.value GET_INDEX = fraction_to_index(Opcode.GET.value) HCF_INDEX = fraction_to_index(Opcode.HCF.value) INDEX_TO_OPERATION = 256 * [None] for opcode, operation in OPERATIONS.items(): index = fraction_to_index(opcode.value) INDEX_TO_OPERATION[index] = operation class Process: def __init__(self, machine_code: list = [], argv: list = []) -> None: self.registers = len(Register) * [Q(0)] self.memory = Memory() self.registers[IR] = self.memory.new()
def size(self, base: Q) -> int: index = fraction_to_index(base % 1) return len(self.stacks[index])
def pop(self, base: Q) -> Q: index = fraction_to_index(base % 1) return self.stacks[index].pop()
def push(self, base: Q, value: Q) -> None: index = fraction_to_index(base % 1) self.stacks[index].append(value)
def __setitem__(self, address: Q, value: Q) -> None: offset, base = divmod(address, 1) index = fraction_to_index(base) stack = self.stacks[index] stack[offset % len(stack)] = value
def __getitem__(self, address: Q) -> Q: offset, base = divmod(address, 1) index = fraction_to_index(base) stack = self.stacks[index] return stack[offset % len(stack)]