Started assembler
This commit is contained in:
parent
388422ea40
commit
3fe2fcde42
|
@ -0,0 +1,136 @@
|
|||
# Kyler Olsen
|
||||
# Feb 2024
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
class AssemblerError(Exception): pass
|
||||
|
||||
class Instruction(namedtuple('Instruction', ['bb', 'bl', 'lb', 'll'])):
|
||||
|
||||
def __int__(self) -> int:
|
||||
return (
|
||||
(self.bb << 9) +
|
||||
(self.bl << 6) +
|
||||
(self.lb << 3) +
|
||||
(self.ll)
|
||||
)
|
||||
|
||||
def oct_str(self) -> str:
|
||||
return (
|
||||
str(self.bb) +
|
||||
str(self.bl) +
|
||||
str(self.lb) +
|
||||
str(self.ll)
|
||||
)
|
||||
|
||||
def reg(reg: str) -> int:
|
||||
register_names = [
|
||||
"ZR",
|
||||
"PC",
|
||||
"SP",
|
||||
"MP",
|
||||
"D0",
|
||||
"D1",
|
||||
"D2",
|
||||
"D3",
|
||||
]
|
||||
register_numbers = [
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
]
|
||||
if reg.upper() in register_names:
|
||||
return register_names.index(reg.upper())
|
||||
elif reg in register_numbers:
|
||||
return register_numbers.index(reg)
|
||||
else:
|
||||
raise AssemblerError(f"Invalid Register: {reg}")
|
||||
|
||||
def reg1(l: str) -> int:
|
||||
args = l.split(' ')
|
||||
if len(args) == 2:
|
||||
return reg(args[1])
|
||||
else:
|
||||
raise AssemblerError(f"Invalid number of arguments: {args[0]}")
|
||||
|
||||
def reg2(l: str) -> tuple[int, int]:
|
||||
args = l.split(' ')
|
||||
if len(args) == 3:
|
||||
return reg(args[2]), reg(args[1])
|
||||
else:
|
||||
raise AssemblerError(f"Invalid number of arguments: {args[0]}")
|
||||
|
||||
def reg3(l: str) -> tuple[int, int, int]:
|
||||
args = l.split(' ')
|
||||
if len(args) == 4:
|
||||
return reg(args[2]), reg(args[3]), reg(args[1])
|
||||
else:
|
||||
raise AssemblerError(f"Invalid number of arguments: {args[0]}")
|
||||
|
||||
def immediate(l: str) -> Instruction:
|
||||
args = l.split(' ')
|
||||
if len(args) == 2:
|
||||
if 'b' in args[1]:
|
||||
value = int(args[1].split('b')[1], base=2)
|
||||
elif 'o' in args[1]:
|
||||
value = int(args[1].split('o')[1], base=8)
|
||||
elif 'x' in args[1]:
|
||||
value = int(args[1].split('x')[1], base=16)
|
||||
else:
|
||||
value = int(args[1])
|
||||
|
||||
return Instruction(
|
||||
0,
|
||||
2 + ((value & 0x040) >> 6),
|
||||
(value & 0x038) >> 3,
|
||||
value & 0x007,
|
||||
)
|
||||
else:
|
||||
raise AssemblerError(f"Invalid number of arguments: {args[0]}")
|
||||
|
||||
def parse(s: str) -> list[Instruction]:
|
||||
instruction_set = {
|
||||
"NOP": lambda _: Instruction(0,0,0,0),
|
||||
"HLT": lambda _: Instruction(0,0,0,1),
|
||||
"INT": lambda _: Instruction(0,0,0,2),
|
||||
"BNZ": lambda _: Instruction(0,0,0,3),
|
||||
"BLK": lambda _: Instruction(0,0,0,4),
|
||||
"ENB": lambda _: Instruction(0,0,0,5),
|
||||
|
||||
"GLA": lambda l: Instruction(0,0,2,reg1(l)),
|
||||
"GET": lambda l: Instruction(0,0,3,reg1(l)),
|
||||
"LOD": lambda l: Instruction(0,0,4,reg1(l)),
|
||||
"STR": lambda l: Instruction(0,0,5,reg1(l)),
|
||||
"PSH": lambda l: Instruction(0,0,6,reg1(l)),
|
||||
"POP": lambda l: Instruction(0,0,7,reg1(l)),
|
||||
|
||||
"LDI": lambda l: immediate(l),
|
||||
|
||||
"LSH": lambda l: Instruction(0,4,*reg2(l)),
|
||||
"RSH": lambda l: Instruction(0,5,*reg2(l)),
|
||||
"INC": lambda l: Instruction(0,6,*reg2(l)),
|
||||
"DEC": lambda l: Instruction(0,7,*reg2(l)),
|
||||
|
||||
"AND": lambda l: Instruction(1,*reg3(l)),
|
||||
"OR": lambda l: Instruction(2,*reg3(l)),
|
||||
"NAD": lambda l: Instruction(3,*reg3(l)),
|
||||
"SUB": lambda l: Instruction(4,*reg3(l)),
|
||||
"XOR": lambda l: Instruction(5,*reg3(l)),
|
||||
"NOR": lambda l: Instruction(6,*reg3(l)),
|
||||
"ADD": lambda l: Instruction(7,*reg3(l)),
|
||||
}
|
||||
instructions = []
|
||||
|
||||
for rl in s.splitlines(False):
|
||||
l = rl.strip()
|
||||
if l[:3] in instruction_set:
|
||||
instructions.append(instruction_set[l[:3]](l))
|
||||
elif l[:2] in instruction_set:
|
||||
instructions.append(instruction_set[l[:2]](l))
|
||||
|
||||
return instructions
|
|
@ -0,0 +1,4 @@
|
|||
# Kyler Olsen
|
||||
# Feb 2024
|
||||
|
||||
|
Loading…
Reference in New Issue