#!/usr/bin/env python3
+from __future__ import annotations
+from typing import *
import argparse
import struct
# ------------------------------------------------------------------------------
-def assemble(source: str) -> bytearray:
+def assemble(source: str) -> Tuple[bytearray, dict]:
b = bytearray()
syms = dict()
forwards = list()
'&': b'\x12', '|': b'\x13', '^': b'\x14', '~': b'\x15',
'dup': b'\x16', 'drop': b'\x17', 'swap': b'\x18',
'ien': b'\x19', 'idis': b'\x1a',
+ 'lsr': b'\x1b', 'asr': b'\x1c', 'shl': b'\x1d',
}
comment = False
# Resolve forward references
for offset, symbol in forwards:
+ if symbol not in syms:
+ print(f'Symbol "{symbol}" not defined')
assert symbol in syms
b[offset:offset+4] = struct.pack('<I', syms[symbol])
- return b
+
+ return b, syms
# ------------------------------------------------------------------------------
def main() -> int:
parser = argparse.ArgumentParser('AS - CPU0 Assembler')
parser.add_argument('--outfile', '-o', help='Output filename')
+ parser.add_argument('--mapfile', '-m', help='Symbol map filename')
parser.add_argument('filename', help='Source filename')
args = parser.parse_args()
with open(args.filename, 'r') as f:
with open(args.outfile, 'wb') as g:
s = f.read()
- b = assemble(s)
+ b, syms = assemble(s)
g.write(b)
+ if args.mapfile:
+ if args.mapfile == 'stdout':
+ for addr, sym in sorted((addr, sym) for sym, addr in syms.items()):
+ print(f'0x{addr:08x}: {sym}')
+ else:
+ with open(args.mapfile, 'w') as h:
+ for addr, sym in sorted((addr, sym) for sym, addr in syms.items()):
+ h.write(f'0x{addr:08x}: {sym}\n')
return 0