feat: add the ability to import interpreter
This commit is contained in:
73
dopey.py
73
dopey.py
@@ -11,9 +11,9 @@ class MemoryException(Exception):
|
|||||||
""" TODO line number and column """
|
""" TODO line number and column """
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class Memory:
|
class _Memory:
|
||||||
BUFFER_SIZE = 30_000
|
BUFFER_SIZE = 30_000
|
||||||
buffer = [0 for _ in range(BUFFER_SIZE)]
|
buffer = []
|
||||||
pointer = 0
|
pointer = 0
|
||||||
input_buffer = []
|
input_buffer = []
|
||||||
|
|
||||||
@@ -21,7 +21,13 @@ class Memory:
|
|||||||
def get_pointer(cls) -> int:
|
def get_pointer(cls) -> int:
|
||||||
return cls.pointer
|
return cls.pointer
|
||||||
|
|
||||||
class Operation:
|
@classmethod
|
||||||
|
def reset(cls):
|
||||||
|
cls.buffer = [0 for _ in range(cls.BUFFER_SIZE)]
|
||||||
|
cls.pointer = 0
|
||||||
|
cls.input_buffer = []
|
||||||
|
|
||||||
|
class _Operation:
|
||||||
SHIFT_LEFT = "<"
|
SHIFT_LEFT = "<"
|
||||||
SHIFT_RIGHT = ">"
|
SHIFT_RIGHT = ">"
|
||||||
INCREMENT = "+"
|
INCREMENT = "+"
|
||||||
@@ -41,49 +47,49 @@ class Operation:
|
|||||||
return
|
return
|
||||||
|
|
||||||
# dont perform any non loop operations if inside an ignore loop
|
# dont perform any non loop operations if inside an ignore loop
|
||||||
if len(cls.loop_ignore_stack) and operation != Operation.CLOSE_LOOP and operation != Operation.OPEN_LOOP:
|
if len(cls.loop_ignore_stack) and operation != _Operation.CLOSE_LOOP and operation != _Operation.OPEN_LOOP:
|
||||||
return
|
return
|
||||||
|
|
||||||
switch[operation](program)
|
switch[operation](program)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def shift_left(cls, _) -> None:
|
def shift_left(cls, _) -> None:
|
||||||
Memory.pointer -= 1
|
_Memory.pointer -= 1
|
||||||
if Memory.pointer < 0:
|
if _Memory.pointer < 0:
|
||||||
raise MemoryException
|
raise MemoryException
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def shift_right(cls, _) -> None:
|
def shift_right(cls, _) -> None:
|
||||||
Memory.pointer += 1
|
_Memory.pointer += 1
|
||||||
if Memory.pointer >= Memory.BUFFER_SIZE:
|
if _Memory.pointer >= _Memory.BUFFER_SIZE:
|
||||||
raise MemoryException
|
raise MemoryException
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def increment(cls, _) -> None:
|
def increment(cls, _) -> None:
|
||||||
Memory.buffer[Memory.get_pointer()] += 1
|
_Memory.buffer[_Memory.get_pointer()] += 1
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def decrement(cls, _) -> None:
|
def decrement(cls, _) -> None:
|
||||||
Memory.buffer[Memory.get_pointer()] -= 1
|
_Memory.buffer[_Memory.get_pointer()] -= 1
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def output(cls, _) -> None:
|
def output(cls, _) -> None:
|
||||||
sys.stdout.write(chr(Memory.buffer[Memory.get_pointer()])) # TODO rollover if too big in ASCII
|
sys.stdout.write(chr(_Memory.buffer[_Memory.get_pointer()])) # TODO rollover if too big in ASCII
|
||||||
sys.stdout.flush() # TODO possible performance issue
|
sys.stdout.flush() # TODO possible performance issue
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def input(cls, _) -> None:
|
def input(cls, _) -> None:
|
||||||
if not len(Memory.input_buffer):
|
if not len(_Memory.input_buffer):
|
||||||
input_ = sys.stdin.readline()
|
input_ = sys.stdin.readline()
|
||||||
Memory.input_buffer += list(input_)
|
_Memory.input_buffer += list(input_)
|
||||||
if len(Memory.input_buffer):
|
if len(_Memory.input_buffer):
|
||||||
Memory.buffer[Memory.get_pointer()] = ord(Memory.input_buffer.pop(0))
|
_Memory.buffer[_Memory.get_pointer()] = ord(_Memory.input_buffer.pop(0))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def open_loop(cls, program: List) -> None:
|
def open_loop(cls, program: List) -> None:
|
||||||
if not Memory.buffer[Memory.get_pointer()]:
|
if not _Memory.buffer[_Memory.get_pointer()]:
|
||||||
# enter ignore loop if byte at pointer is zero
|
# enter ignore loop if byte at pointer is zero
|
||||||
cls.loop_ignore_stack.append(Operation.OPEN_LOOP)
|
cls.loop_ignore_stack.append(_Operation.OPEN_LOOP)
|
||||||
else:
|
else:
|
||||||
# save start loop position should we need to return
|
# save start loop position should we need to return
|
||||||
cls.loop_stack.append(program[1]-1)
|
cls.loop_stack.append(program[1]-1)
|
||||||
@@ -101,7 +107,7 @@ class Operation:
|
|||||||
|
|
||||||
# check if we need to repeat
|
# check if we need to repeat
|
||||||
last_open_loop_pos = cls.loop_stack.pop()
|
last_open_loop_pos = cls.loop_stack.pop()
|
||||||
if Memory.buffer[Memory.get_pointer()]:
|
if _Memory.buffer[_Memory.get_pointer()]:
|
||||||
program[1] = last_open_loop_pos
|
program[1] = last_open_loop_pos
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -117,6 +123,24 @@ class Operation:
|
|||||||
cls.CLOSE_LOOP: cls.close_loop
|
cls.CLOSE_LOOP: cls.close_loop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Interpreter:
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def execute(self, str_program: str) -> None:
|
||||||
|
_Memory.reset()
|
||||||
|
|
||||||
|
program = [str_program, 0] # TODO create program class
|
||||||
|
switch = _Operation.get_operations_in_switch()
|
||||||
|
|
||||||
|
while program[1] < len(program[0]):
|
||||||
|
operation = program[0][program[1]]
|
||||||
|
program[1] += 1
|
||||||
|
_Operation.perform(operation, program, switch)
|
||||||
|
|
||||||
|
if len(_Operation.loop_stack):
|
||||||
|
raise MismatchBracketException
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
file_location = None
|
file_location = None
|
||||||
if len(sys.argv) != 2:
|
if len(sys.argv) != 2:
|
||||||
@@ -126,18 +150,11 @@ def main() -> None:
|
|||||||
file_location = sys.argv[1]
|
file_location = sys.argv[1]
|
||||||
|
|
||||||
file = open(file_location, "r")
|
file = open(file_location, "r")
|
||||||
program = [file.read(), 0] # TODO create program class
|
str_program = file.read()
|
||||||
file.close()
|
file.close()
|
||||||
|
|
||||||
switch = Operation.get_operations_in_switch()
|
interpreter = Interpreter()
|
||||||
while program[1] < len(program[0]):
|
interpreter.execute(str_program)
|
||||||
operation = program[0][program[1]]
|
|
||||||
program[1] += 1
|
|
||||||
Operation.perform(operation, program, switch)
|
|
||||||
|
|
||||||
if len(Operation.loop_stack):
|
|
||||||
raise MismatchBracketException
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user