assembler: add support for binary output

This commit is contained in:
Zack Buhman 2025-11-03 22:04:20 -06:00
parent 2c62869ccd
commit fbe23d3506
5 changed files with 66 additions and 16 deletions

View File

@ -1,4 +1,5 @@
import sys import sys
import struct
from assembler.lexer import Lexer, LexerError from assembler.lexer import Lexer, LexerError
from assembler.parser import ParserError from assembler.parser import ParserError
@ -17,12 +18,11 @@ def frontend_inner(buf):
ins = validate_instruction(ins_ast) ins = validate_instruction(ins_ast)
code = [0] * 6 code = [0] * 6
emit_instruction(code, ins) emit_instruction(code, ins)
print("\n".join(f"0x{code[i]:08x}," for i in range(6))) yield code
print()
def frontend(filename, buf): def frontend(filename, buf):
try: try:
frontend_inner(buf) yield from frontend_inner(buf)
except LexerError as e: except LexerError as e:
print_error(filename, buf, e) print_error(filename, buf, e)
raise raise
@ -34,7 +34,23 @@ def frontend(filename, buf):
raise raise
if __name__ == "__main__": if __name__ == "__main__":
assert len(sys.argv) in {2, 3}
input_filename = sys.argv[1] input_filename = sys.argv[1]
binary = len(sys.argv) == 3
if binary:
output_filename = sys.argv[2]
with open(input_filename, 'rb') as f: with open(input_filename, 'rb') as f:
buf = f.read() buf = f.read()
frontend(input_filename, buf)
code_gen = list(frontend(input_filename, buf))
if not binary:
for cw in code_gen:
print("\n".join(f"0x{cw[i]:08x}," for i in range(6)))
print()
else:
with open(output_filename, 'wb') as f:
for cw in code_gen:
data = struct.pack("<IIIIII", *cw)
f.write(data)

View File

@ -1,4 +1,5 @@
import sys import sys
import struct
from assembler.lexer import Lexer, LexerError from assembler.lexer import Lexer, LexerError
from assembler.validator import ValidatorError from assembler.validator import ValidatorError
@ -48,9 +49,22 @@ def frontend(filename, buf):
raise raise
if __name__ == "__main__": if __name__ == "__main__":
assert len(sys.argv) in {2, 3}
input_filename = sys.argv[1] input_filename = sys.argv[1]
#output_filename = sys.argv[2] binary = len(sys.argv) == 3
if binary:
output_filename = sys.argv[2]
with open(input_filename, 'rb') as f: with open(input_filename, 'rb') as f:
buf = f.read() buf = f.read()
for cw in frontend(input_filename, buf):
code_gen = list(frontend(input_filename, buf))
if not binary:
for cw in code_gen:
print(f"0x{cw[0]:08x}, 0x{cw[1]:08x}, 0x{cw[2]:08x}, 0x{cw[3]:08x},") print(f"0x{cw[0]:08x}, 0x{cw[1]:08x}, 0x{cw[2]:08x}, 0x{cw[3]:08x},")
else:
with open(output_filename, 'wb') as f:
for cw in code_gen:
data = struct.pack("<IIII", *cw)
f.write(data)

View File

@ -6,6 +6,7 @@ import pvs_dual_math
import itertools import itertools
from functools import partial from functools import partial
import sys import sys
import struct
def out(level, *args): def out(level, *args):
sys.stdout.write(" " * level + " ".join(args)) sys.stdout.write(" " * level + " ".join(args))
@ -248,8 +249,14 @@ def parse_hex(s):
if __name__ == "__main__": if __name__ == "__main__":
filename = sys.argv[1] filename = sys.argv[1]
if filename.endswith(".bin"):
with open(filename, 'rb') as f:
buf = f.read()
code = [struct.unpack("<I", buf[i*4:i*4+4])[0] for i in range(len(buf) // 4)]
else:
with open(filename) as f: with open(filename) as f:
buf = f.read() buf = f.read()
code = [parse_hex(c.strip()) for c in buf.split(',') if c.strip()] code = [parse_hex(c.strip()) for c in buf.split(',') if c.strip()]
for i in range(len(code) // 4): for i in range(len(code) // 4):
parse_instruction(code[i*4:i*4+4]) parse_instruction(code[i*4:i*4+4])

View File

@ -1,3 +1,4 @@
import struct
import sys import sys
import parse_bits import parse_bits
from collections import OrderedDict from collections import OrderedDict
@ -149,6 +150,11 @@ def parse_hex(s):
if __name__ == "__main__": if __name__ == "__main__":
filename = sys.argv[1] filename = sys.argv[1]
if filename.endswith(".bin"):
with open(filename, 'rb') as f:
buf = f.read()
code = [struct.unpack("<I", buf[i*4:i*4+4])[0] for i in range(len(buf) // 4)]
else:
with open(filename) as f: with open(filename) as f:
buf = f.read() buf = f.read()
code = [parse_hex(c.strip()) for c in buf.split(',') if c.strip()] code = [parse_hex(c.strip()) for c in buf.split(',') if c.strip()]

View File

@ -4,6 +4,7 @@ import parse_bits
from collections import OrderedDict from collections import OrderedDict
from functools import partial from functools import partial
from pprint import pprint from pprint import pprint
import struct
VERBOSE = environ.get("VERBOSE", "false").lower() == "true" VERBOSE = environ.get("VERBOSE", "false").lower() == "true"
@ -479,9 +480,15 @@ def parse_hex(s):
if __name__ == "__main__": if __name__ == "__main__":
filename = sys.argv[1] filename = sys.argv[1]
if filename.endswith(".bin"):
with open(filename, 'rb') as f:
buf = f.read()
code = [struct.unpack("<I", buf[i*4:i*4+4])[0] for i in range(len(buf) // 4)]
else:
with open(filename) as f: with open(filename) as f:
buf = f.read() buf = f.read()
code = [parse_hex(c.strip()) for c in buf.split(',') if c.strip()] code = [parse_hex(c.strip()) for c in buf.split(',') if c.strip()]
for i in range(len(code) // 6): for i in range(len(code) // 6):
start = (i + 0) * 6 start = (i + 0) * 6
end = (i + 1) * 6 end = (i + 1) * 6