Beispiel #1
0
Datei: vm.py Projekt: iBug/HRM
 def __init__(self, istream=[], dynamicMem=False, initMem=None, memSize=16):
     self.core = Core()
     if initMem is not None:
         self.mem = initMem
     if len(self.mem) < memSize:
         self.mem += [Value(None)] * (memSize - len(self.mem))
     self.dynamicMem = dynamicMem
     self.istream = [Value(i) for i in istream]  # For safety
     self.ostream = []
     self.cmd = None  # Instruction list
Beispiel #2
0
def parseArg(s):
    if s.lower() in set(('none', '-')):
        return Value(None)
    if s.startswith('[') and s.endswith(']'):
        return Reference(int(s[1:-1]))
    try:
        return Value(int(s))
    except ValueError:
        if len(s) != 1:
            raise ValueError('"{}" is not an argument'.format(s))
        return Value(s)
Beispiel #3
0
def jz(vm, line):
    if vm.core.ax == Value(None):
        raise ValueError("You have nothing to test")
    if vm.core.ax.zero():
        vm.core.pc = line
    else:
        vm.core.pc += 1
    return True
Beispiel #4
0
def inbox(vm):
    try:
        vm.core.ax = vm.istream[0]
        vm.istream = vm.istream[1:]
        return True
    except IndexError:
        vm.core.ax = Value(None)
        raise CommandError("reached end of input")
Beispiel #5
0
def readProgram(stream):
    prog = Program()
    lines = [i.strip() for i in stream]
    while True:
        isMeta = False  # Processed as a meta line
        meta = lines[0].split()
        if len(meta) == 0:
            isMeta = True
            lines = lines[1:]
            continue

        meta[0] = meta[0].lower()
        if meta[0] == 'mem':
            isMeta = True
            prog.initMem = [parseArg(i.strip()) for i in meta[1:]]
        if meta[0] == 'memsize':
            isMeta = True
            memlen = int(meta[1])
            assert 0 < memlen <= MAX_INT
            prog.dynamicMem = False
            prog.initMem += [Value(None)] * (
                (memlen -
                 len(prog.initMem)) if len(prog.initMem) <= memlen else 0)
        if isMeta:
            lines = lines[1:]
        else:
            break

    jumps = []  # Later we're going to parse the tags

    for line in lines:
        cmd = [i.strip() for i in line.split()]
        if len(cmd) == 0:  # Blank line, ignore it
            continue
        if cmd[0].startswith(
                '#') or cmd[0].lower() == 'comment':  # This is a comment
            continue
        if cmd[0].endswith(':'):  # This is a jump tag
            prog.tags[cmd[0][:-1]] = len(prog.cmds)
            continue

        cmd[0] = cmd[0].lower()
        if isJump(cmd[0]):
            jumps.append(len(prog.cmds))  # Record jumps
            prog.cmds.append(Command(cmd[0], *cmd[1]))
            continue
        prog.cmds.append(Command(cmd[0], *[parseArg(i) for i in cmd[1:]]))

    for i in jumps:
        # Lookup and replace
        try:
            prog.cmds[i].ops[0] = prog.tags[prog.cmds[i].ops[0]]
        except KeyError:
            raise ValueError('No such tag "{}"'.format(prog.cmds[i].ops[0]))

    return prog
Beispiel #6
0
def outbox(vm):
    if vm.core.ax == Value(None):
        raise CommandError('You have nothing to outbox')
    vm.ostream.append(vm.core.ax.copy())
    vm.core.ax = Value(None)
    return True
Beispiel #7
0
def bumpdown(vm, target):
    vm.core.ax = vm.getMem(getMemIndex(vm, target))
    vm.core.ax -= Value(1)
    vm.setMem(getMemIndex(vm, target), vm.core.ax)
    return True
Beispiel #8
0
def bumpup(vm, target):
    # Don't call COPYFROM and COPYTO directly, they will increment the program counter
    vm.core.ax = vm.getMem(getMemIndex(vm, target))
    vm.core.ax += Value(1)
    vm.setMem(getMemIndex(vm, target), vm.core.ax)
    return True
Beispiel #9
0
Datei: vm.py Projekt: iBug/HRM
 def __init__(self, initAx=Value(None)):
     self.ax = initAx  # Accumulator
     self.pc = 0  # Program Counter