Skip to content

Instantly share code, notes, and snippets.

@anuar2k
Last active November 8, 2021 22:20
Show Gist options
  • Save anuar2k/2869784e643b536c5d46bb631d40c14d to your computer and use it in GitHub Desktop.
Save anuar2k/2869784e643b536c5d46bb631d40c14d to your computer and use it in GitHub Desktop.
SCS assembler
#!/usr/bin/env python3
import re
import sys
import pprint
REG_BIT = {
"R0": 0 << 4,
"R1": 1 << 4
}
def imm(imm):
return int(imm[1:], 0) & 0b1111
def encode_ADD(*_):
return 0b00100000
def encode_MOV(arg1, arg2):
if arg2[0] == "#":
return 0b10000000 | REG_BIT[arg1] | imm(arg2)
else:
return 0b10100000 | REG_BIT[arg1]
def encode_LDR(arg1, arg2):
return 0b11000000 | REG_BIT[arg1] | imm(arg2)
def encode_STR(arg1, arg2):
return 0b11100000 | REG_BIT[arg1] | imm(arg2)
def encode_JMP(arg1, *_):
return 0b00000000 | imm(arg1)
ENCODERS = {
"ADD": encode_ADD,
"MOV": encode_MOV,
"LDR": encode_LDR,
"STR": encode_STR,
"JMP": encode_JMP
}
def encode(statements):
return [
ENCODERS[instr](arg1, arg2)
for instr, arg1, arg2 in statements
]
STMT_PAT = re.compile(r"(\w+)(?: +([\w#]+)(?: *, *([\w#]+))?)?")
def parse_file(file):
return [
[m.group(i) for i in (1, 2, 3)]
for m in [
STMT_PAT.match(line)
for line in file.readlines()
]
if m is not None
]
JMP_ZERO = encode_JMP("#0")
def format_vector(program):
filled_program = program + [JMP_ZERO] * (16 - len(program))
return ",\n".join(format(stmt, "02X") for stmt in filled_program) + ";"
def main():
path = sys.argv[1] if len(sys.argv) > 1 else "prog.txt"
with open(path) as file:
statements = parse_file(file)
program = encode(statements)
pprint.pprint(statements)
print("-" * 20)
print(format_vector(program))
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment