diff options
| author | Jan Tuomi <jans.tuomi@gmail.com> | 2023-04-10 21:10:16 +0300 |
|---|---|---|
| committer | Jan Tuomi <jans.tuomi@gmail.com> | 2023-04-10 23:55:17 +0300 |
| commit | 9a6001ad380e83a545188b58145387593b117b48 (patch) | |
| tree | a991cea5e5163b18c0666de89a7eccd55308b227 /src/asm_pass4.py | |
| parent | 56fd37c60eb0d58ed4762340ddc85b74347bcd71 (diff) | |
Refactor into multipass compiler
Diffstat (limited to 'src/asm_pass4.py')
| -rw-r--r-- | src/asm_pass4.py | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/asm_pass4.py b/src/asm_pass4.py new file mode 100644 index 0000000..96d9e65 --- /dev/null +++ b/src/asm_pass4.py @@ -0,0 +1,64 @@ +from dataclasses import dataclass +from assembler_ops import * +from assembler_eval import * +from asm_pass3 import * + +@dataclass +class Result4Line: + line_num: int + address: int + word: int + text: str + +@dataclass +class Result4: + lines: list[Result4Line] + options: Options + operations: OpExpansionDict + labels: dict[str, int] + +def translate_opt(arg: str, options: Options) -> str: + match arg: + case "__STACK_POINTER": return options.stack_pointer + case "__CSR_SCRATCH": return options.csr_scratch + case _: return arg + +def pass_4(result3: Result3) -> Result4: + result_lines: list[Result4Line] = [] + address = 0 + + for line in result3.lines: + keyword, *args = line.parts + meta = Meta( + address=address, + ) + + args = list(map(lambda a: translate_opt(a, result3.options), args)) + text = " ".join([keyword, *args]) + + if keyword in operations: + fn = operations[keyword] + word = fn(meta, result3.labels, *args) + result_lines.append(Result4Line( + line_num=line.line_num, + address=line.address, + word=word, + text=text, + )) + else: + try: + result_lines.append(Result4Line( + line_num=line.line_num, + address=line.address, + word=eval_expr(result3.labels, keyword), + text=text, + )) + except: + raise Exception(f"Invalid assembly at {line.line_num + 1}\n\n{line}") + + return Result4( + operations=result3.operations, + labels=result3.labels, + options=result3.options, + lines=result_lines, + ) |
