Beispiel #1
0
def test_vm_jmpb():
    code = [*create_instr("jmpb", 0), *create_instr("nop")]

    vm = Arkhe(code)
    vm.registers[0] = 3
    vm.exc_instr()  # counter at 3
    assert vm.counter == 0
Beispiel #2
0
def test_vm_mem_dealloc():
    code = create_instr("dealloc", 0, 0)
    vm = Arkhe(code)
    vm.registers[0] = 16
    vm.memory.alloc(36)
    vm.exc_instr()
    assert len(vm.memory) == 20
Beispiel #3
0
def test_vm_jne():
    code = [*create_instr("jne", 0)]
    vm = Arkhe(code)
    vm.registers[0] = 0
    vm._eqflag = False
    vm.exc_instr()
    assert vm.counter == 0
    vm._eqflag = True
    vm.exc_instr()
    assert vm.counter == 3
Beispiel #4
0
def test_vm_comp_ne():
    code = [*create_instr("ne", 0, 1), *create_instr("ne", 1, 2)]
    vm = Arkhe(code)
    vm.registers[0] = 5
    vm.registers[1] = 5
    vm.exc_instr()
    assert not vm._eqflag
    vm.registers[2] = 10
    vm.exc_instr()
    assert vm._eqflag
Beispiel #5
0
def test_vm_mem_read():
    code = create_instr("read", 0, 1)
    vm = Arkhe(code)
    vm.registers[0] = 16
    with pytest.raises(MemoryFault):
        vm.exc_instr()
    vm.memory.alloc(100)
    vm.memory[16] = "hello"
    vm.counter = 0
    vm.exc_instr()
    assert vm.registers[1] == "hello"
Beispiel #6
0
def test_vm_math():
    code = [
        *create_instr("load", 0, 3, 232),
        *create_instr("load", 1, 1, 244),
        *create_instr("add", 0, 1, 2),
        *create_instr("sub", 2, 1, 3),
        *create_instr("mul", 1, 2, 4),
        *create_instr("truediv", 2, 3, 5),
    ]

    vm = Arkhe(code)
    vm.eval()
    assert (vm.registers[0] == 1000 and vm.registers[1] == 500
            and vm.registers[2] == 1500 and vm.registers[3] == 1000
            and vm.registers[4] == 750_000 and vm.registers[5] == 1.5)
Beispiel #7
0
def test_vm_mem_alloc():
    code = create_instr("alloc", 0)
    vm = Arkhe(code)
    vm.registers[0] = 16
    vm.exc_instr()
    assert len(vm.memory) == 16
    vm.counter = 0
    vm.exc_instr()
    assert len(vm.memory) == 32
Beispiel #8
0
def test_vm_sym_read():
    code = create_instr("symread", 0, 1)
    vm = Arkhe(code)
    vm.symtable["age"] = 15
    vm.registers[0] = "age"
    vm.exc_instr()
    assert vm.registers[1] == 15
Beispiel #9
0
def test_vm_jfn():
    code = [*create_instr("jfn", 0)]
    vm = Arkhe(code)
    vm.registers[0] = 20
    vm._eqflag = False
    vm.exc_instr()
    assert vm.counter == 23
Beispiel #10
0
def test_vm_jmp():
    code = create_instr("jmp", 0)
    vm = Arkhe(code)
    vm.registers[0] = 0
    vm.exc_instr()
    assert vm.counter == 0
Beispiel #11
0
def test_vm_load_multiple():
    code = [*create_instr("load", 0, 3, 232), *create_instr("load", 1, 1, 244)]

    vm = Arkhe(code)
    vm.eval()
    assert vm.registers[0] == 1000 and vm.registers[1] == 500
Beispiel #12
0
def test_vm_load():
    code = create_instr("load", 0, 0, 100)
    vm = Arkhe(code)
    vm.eval()
    assert vm.registers[0] == 100
Beispiel #13
0
def test_ext_libc():
    code = create_instr("ccall", 0, 1)
    vm = Arkhe(code)
    vm.registers[0] = "getpid"
    vm.exc_instr()
    assert vm.registers[1] == os.getpid()
Beispiel #14
0
def test_vm_comp_lt():
    code = [
        *create_instr("lt", 0, 1),
        *create_instr("lt", 1, 2),
        *create_instr("lt", 1, 3),
    ]
    vm = Arkhe(code)
    vm.registers[0] = 5
    vm.registers[1] = 5
    vm.exc_instr()
    assert not vm._eqflag
    vm.registers[2] = 10
    vm.exc_instr()
    assert vm._eqflag
    vm.registers[3] = 4
    vm.exc_instr()
    assert not vm._eqflag
Beispiel #15
0
def test_type_string():
    code = create_instr("load", 0, 104, 101, 108, 108, 111, TypeTable.STR)
    vm = Arkhe(code)
    vm.exc_instr()
    assert vm.registers[0] == "hello"
    vm.code.extend(
        create_instr("load", 1, 32, 119, 111, 114, 108, 100, 33, 32,
                     TypeTable.STR))
    vm.exc_instr()
    assert vm.registers[1] == " world! "
    vm.code.extend(create_instr("add", 0, 1, 2))
    vm.exc_instr()
    assert vm.registers[2] == "hello world! "
    vm.registers[5] = 5
    vm.code.extend(create_instr("mul", 2, 5, 3))
    vm.exc_instr()
    assert vm.registers[
        3] == "hello world! hello world! hello world! hello world! hello world! "
Beispiel #16
0
 def __init__(self, stdout=sys.stdout):
     self.vm = Arkhe()
     self.parse = Parser()
     self.stdout = stdout
Beispiel #17
0
    def run_cmd(self, command, stdout=None):
        with redirect_stdout(stdout or self.stdout):
            if command == "code":
                code = copy(self.vm.code)
                code.insert(self.vm.counter, 'SIGN')
                codesets = divide_sequence(code, INSTR_TERM)
                try:
                    current, = filter(lambda sequence: 'SIGN' in sequence,
                                      codesets)
                    evaled = codesets.index(current)
                    codesets[evaled].remove('SIGN')
                    unknown = False
                except ValueError:
                    unknown = True

                for n, codeset in enumerate(codesets, 1):
                    codeset = Instr(codeset.pop(0), codeset)
                    if unknown:
                        print(f"{n}th instr (state unknown)  -> {codeset}")
                        continue

                    if n < evaled:
                        Text["green"](
                            f"{n}th instr (executed)       -> {codeset}")
                    elif n == evaled:
                        Text["green"](
                            f"{n}th instr (last executed)  -> {codeset}")
                    else:
                        Text["blue"](
                            f"{n}th instr (pending)        -> {codeset}")

            elif command == "regs":
                allrs = set(self.vm.registers.items())
                useds = set(filter(lambda i: i[1], allrs))
                frees = allrs - useds

                print("Register states:")
                Text["blue"](f"\tTotal: {len(allrs)}")
                Text["warn"](
                    f"\tUseds: {str(len(useds)).zfill(len(f'{len(allrs)}'))}")
                Text["green"](f"\tFrees: {len(frees)}")
                for reg, val in useds:
                    print(f"r{reg} = {val}")

            elif command.startswith("r") and command[1:].isnumeric():
                reg = command[1:]
                print(f"r{reg} = {self.vm.registers[int(reg)]}")

            elif command == "mem":
                total = len(self.vm.memory)
                nonzero = len([0 for chunk in self.vm.memory if chunk])
                zero = total - nonzero
                Text["blue"](f"Allocated memory: {total}")
                Text["warn"](f"Non-zero  memory: {nonzero}")
                Text["green"](f"Free      memory: {zero}")

            elif command == "eq":
                if self.vm._eqflag:
                    Text["green"]("Equality Flag: True")
                else:
                    Text["warn"]("Equality Flag: False")

            elif command == "counter":
                Text["green"](f"Counter: {self.vm.counter}")

            elif command == "symtable":
                for key, value in self.vm.symtable.items():
                    print(f"{Text['green_p'](key)}: {Text['blue_p'](value)}")

            elif "=" in command and command.startswith("sym"):
                target, value = [
                    item.strip()
                    for item in command.replace("sym ", "").split("=")
                ]
                value = ast.literal_eval(value)
                self.vm.symtable[target] = value

            elif "=" in command and command.startswith("r"):
                target, value = [
                    item.strip()
                    for item in command.replace("r", "").split("=")
                ]
                value = ast.literal_eval(value)
                self.vm.registers[target] = value

            elif command == "reset":
                self.vm = Arkhe(
                )  # or reset counter, code, eqflag, memory, registers

            elif command.startswith("eval ") and command[5:].isnumeric():
                for _ in range(int(command[5:])):
                    self.vm.exc_instr()

            else:
                try:
                    if ";" in command:
                        self.vm.code.extend(
                            chain.from_iterable(
                                self.parse(command)
                                for command in command.split("; ")))
                    else:
                        commands = self.parse(command)
                        self.vm.code.extend(commands)
                except ParseError as exc:
                    Text["fail"]("Last instruction couldn't parsed!")
Beispiel #18
0
def test_type_bytes():
    code = create_instr("load", 0, 104, 101, 108, 108, 111, TypeTable.BYT)
    vm = Arkhe(code)
    vm.exc_instr()
    assert vm.registers[0] == b"hello"