diff --git a/python/assembler.py b/python/assembler.py index 659a0bc..a0eb6ac 100644 --- a/python/assembler.py +++ b/python/assembler.py @@ -4,6 +4,45 @@ import struct import IPython +class InvalidRegisterException(Exception): + + def __init__(self, register): + super().__init__("Invalid register: {}".format(register)) + + +class InvalidOperationException(Exception): + + def __init__(self, operation): + super().__init__("Invalid operation: {}".format(operation)) + + +class ExpectedImmediateException(Exception): + + def __init__(self, value): + super().__init__("Expected immediate, got {}".format(value)) + + +class ExpectedRegisterException(Exception): + + def __init__(self, value): + super().__init__("Expected register, got {}".format(value)) + + +class IPOverwriteException(Exception): + + def __init__(self, instruction=None): + if instruction: + super().__init__("IP can't be overwritten. Instruction: {}".format(instruction)) + else: + super().__init__("IP can't be overwritten.") + + +class InvalidValueException(Exception): + + def __init__(self, instruction): + super().__init__("Invalid value while assembling: {}".format(instruction)) + + class VMAssembler: assembled_code = bytearray() @@ -27,16 +66,19 @@ class VMAssembler: imm = instruction.args[1] print(instruction) if reg.name != "ip": - if opcode.uint8() and reg.uint8() and imm.uint16(): - self.assembled_code += opcode.uint8() + reg.uint8() + imm.uint16() + if imm.isimm(): + if reg.isreg(): + if opcode.uint8() and reg.uint8() and imm.uint16(): + self.assembled_code += opcode.uint8() + reg.uint8() + imm.uint16() + else: + raise InvalidValueException(instruction) + else: + raise ExpectedRegisterException(reg) else: - sys.stderr.write( - "ERROR WHILE ASSEMBLING UNKNOWN VALUES\n") - return False + raise ExpectedImmediateException(imm) else: - sys.stderr.write("CAN'T MOVI TO IP!\n") - return False - return True + raise IPOverwriteException(instruction) + return def reg2reg(self, instruction): return @@ -50,60 +92,48 @@ class VMAssembler: reg = instruction.args[1] print(instruction) if reg.name != "ip": - if opcode.uint8() and reg.uint8() and imm.uint16(): - self.assembled_code += opcode.uint8() + imm.uint16() + reg.uint8() + if imm.isimm(): + if reg.isreg(): + if opcode.uint8() and reg.uint8() and imm.uint16(): + self.assembled_code += opcode.uint8() + imm.uint16() + reg.uint8() + else: + raise InvalidValueException(instruction) + else: + raise ExpectedRegisterException(reg) else: - sys.stderr.write( - "ERROR WHILE ASSEMBLING UNKNOWN VALUES\n") - return False + raise ExpectedImmediateException(imm) else: - sys.stderr.write("CAN'T MOVI TO IP!\n") - return False - return True + raise IPOverwriteException(instruction) + return def imm(self, instruction): return def movi(self, instruction): - if not self.imm2reg(instruction): - print("WAT") - return False - return True + self.imm2reg(instruction) def movr(self, instruction): - if not self.reg2reg(instruction): - print("WAT") - return False - return True + self.reg2reg(instruction) def getm(self, instruction): - if not self.imm2reg(instruction): - print("WAT") - return False - return True + self.imm2reg(instruction) def putm(self, instruction): - if not self.reg2imm(instruction): - print("WAT") - return False - return True + self.reg2imm(instruction) def addi(self, instruction): - if not self.imm2reg(instruction): - print("WAT") - return False - return True + self.imm2reg(instruction) class VMComponent: """ - Represents a register or a operation the VM recognizes + Represents a register, operation or an immediate the VM recognizes """ name = "" value = "" def __init__(self, name, value): - self.name = name + self.name = name.casefold() self.value = value def __repr__(self): @@ -129,6 +159,21 @@ class VMComponent: return struct.pack("