Skip to content

Instantly share code, notes, and snippets.

@mmcloughlin
Created April 23, 2019 05:40
Show Gist options
  • Save mmcloughlin/acf1c367dc6f9c36e10b9585a71ee152 to your computer and use it in GitHub Desktop.
Save mmcloughlin/acf1c367dc6f9c36e10b9585a71ee152 to your computer and use it in GitHub Desktop.
#
# Opcode values.
#
HALT = 0
LOAD = 1
STORE = 2
ADDC = 3
MVAC = 4
JEQ = 5
JLT = 6
JMP = 7
ADD = 8
SUB = 9
DEC = 10
LA = 11
LIA = 12
SIA = 13
MVAA = 14
#
# Opcode name map.
#
opcode_name = [
'HALT',
'LOAD',
'STORE',
'ADDC',
'MVAC',
'JEQ',
'JLT',
'JMP',
'ADD',
'SUB',
'DEC',
'LA',
'LIA',
'SIA',
'MVAA',
]
class Label:
def __init__(self, addr):
self.addr = addr
def resolve(self, prog):
return self.addr
def describe(self):
return str(self.addr)
class Instruction:
"""
An instruction.
"""
def __init__(self, opcode, addr=None):
self.opcode = opcode
self.addr = addr
def encode(self, prog):
code = self.opcode << 12
if self.addr:
code |= self.addr.resolve(prog)
return code
def describe(self):
s = opcode_name[self.opcode]
if self.addr:
s += '\t' + self.addr.describe()
return s
class Data:
def __init__(self, name, val, offset):
self.name = name
self.val = val
self.offset = offset
def resolve(self, prog):
return self.offset + prog.data_offset()
def describe(self):
return self.name
class Program:
def __init__(self):
self.instructions = []
self.data_section = []
def label(self):
return Label(len(self.instructions))
def add_instruction(self, instruction):
lbl = self.label()
self.instructions.append(instruction)
return lbl
def add_instructions(self, *args):
for arg in args:
self.add_instruction(Instruction(*arg))
def add_data(self, name, val):
item = Data(name, val, len(self.data_section))
self.data_section.append(item)
return item
def data_offset(self):
return len(self.instructions)
def output(self):
for instruction in self.instructions:
print('0x{encoding:04x}\t# {description}'.format(
encoding=instruction.encode(self),
description=instruction.describe(),
))
if len(self.data_section) == 0:
return
print('#')
print('# Data Section.')
print('#')
for data in self.data_section:
print('0x{val:04x}\t# {name}'.format(
val=data.val,
name=data.name,
))
def main():
p = Program()
N = p.add_data('N', 6)
p.add_instruction(Instruction(LOAD, N))
p.add_instruction(Instruction(LOAD, N))
p.add_instruction(Instruction(LOAD, N))
p.add_instruction(Instruction(LOAD, N))
p.add_instruction(Instruction(LOAD, N))
p.add_instruction(Instruction(LOAD, N))
p.add_instruction(Instruction(LOAD, N))
p.add_instruction(Instruction(LOAD, N))
p.add_instruction(Instruction(LOAD, N))
loopstart = p.label()
p.add_instruction(Instruction(LOAD, N))
p.add_instruction(Instruction(LOAD, N))
p.add_instruction(Instruction(JMP, loopstart))
p.add_instruction(Instruction(HALT))
p.output()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment