aboutsummaryrefslogtreecommitdiffstats
path: root/src/ast_compiler.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/ast_compiler.py')
-rw-r--r--src/ast_compiler.py199
1 files changed, 10 insertions, 189 deletions
diff --git a/src/ast_compiler.py b/src/ast_compiler.py
index f0d0c79..99b4176 100644
--- a/src/ast_compiler.py
+++ b/src/ast_compiler.py
@@ -7,7 +7,7 @@ import ast
from dataclasses import dataclass
from typing import Literal, Set, cast, Any, TypeAlias, TypeVar
from collections import OrderedDict
-from tokenizer import tokenize
+
if len(sys.argv) != 3:
print("usage: ast_compiler.py <infile.py> <outfile.atk16>")
@@ -217,10 +217,6 @@ class Compiler(ast.NodeVisitor):
self.emit("hlt")
def visit_Expr(self, expr: ast.Expr):
- # if type(expr.value) != ast.Call:
- # self.emit("; NOP top-level expression")
- # return
-
self.visit(expr.value)
with self.allocated_reg() as reg:
@@ -679,185 +675,15 @@ class Compiler(ast.NodeVisitor):
raise NotImplementedError("Unhandled AnnAssign:\n" + ast.dump(node, indent=4))
-class Optimizer:
- def __init__(self):
- pass
-
- def optimize(self, asm_str: str):
- asm = asm_str.split("\n")
- asm = [row.strip() for row in asm]
- asm = [self.strip_comment(row) for row in asm]
- asm = [row for row in asm if not len(row) == 0]
- asm = [tokenize(row, retain_curlies=True) for row in asm]
- asm = self.compact_spu_spo_pattern(asm)
-
- # TODO: not safe when setting loading SP and FP
- # ldr RA SP
- # mov RA FP
- # gets optimized to
- # ldr RA FP
- #asm = self.compact_target_mov_pattern(asm)
- #asm = self.compact_target_mov_pattern(asm)
-
- # TODO: not safe at all. E.g. breaks a while True: pass loop
- #asm = self.compact_mov_source_pattern(asm)
- #asm = self.compact_mov_source_pattern(asm)
-
- asm = self.compact_spu_load_spo_pattern(asm)
- # asm = self.convert_alr_to_ali(asm)
- result = "\n".join([format_asm_row(" ".join(row)) for row in asm])
-
- return result
-
- def strip_comment(self, row: str):
- ret: str = ""
- for c in row:
- if c == ";": break
- ret += c
-
- return ret
-
- def compact_spu_spo_pattern(self, asm: list[list[str]]) -> list[list[str]]:
- i = 0
- result: list[list[str]] = []
- while i < len(asm):
- current = asm[i]
- next = asm[i + 1] if i + 1 < len(asm) else None
- i += 1
- if current[0].startswith("@") or next is None:
- result.append(current)
- continue
-
- if current[0] == "spu" and next[0] == "spo":
- print("=== compact_spu_spo_pattern")
- print(current)
- print(next)
-
- arg_current = current[1]
- arg_next = next[1]
-
- print("=== arg_current:", arg_current)
- print("=== arg_next:", arg_next)
-
- if arg_current == arg_next:
- print("=== pass")
- pass # remove both spu and spo
- else:
- print("=== mov")
- mov = ["mov", arg_current, arg_next]
- result.append(mov)
- print("=== mov:", mov)
-
- print("=== last of result:", result[len(result) - 1])
- print()
- i += 1
- continue
-
- result.append(current)
-
- return result
-
- def compact_target_mov_pattern(self, asm: list[list[str]]) -> list[list[str]]:
- ops_with_target = ["ldi", "ldr", "add", "sub", "addi", "subi", "and", "or", "xor", "sll", "slr", "sar", "slli", "slri", "sari", "inc", "dec", "mov", "ali", "alr", "lpc"]
- i = 0
- result: list[list[str]] = []
- while i < len(asm):
- current = asm[i]
- next = asm[i + 1] if i + 1 < len(asm) else None
- i += 1
- if current[0].startswith("@") or next is None:
- result.append(current)
- continue
-
- if current[0] in ops_with_target and next[0] == "mov":
-
- op_op, op_operands, op_target_reg = current[0], current[1:len(current) - 1], current[len(current) - 1]
- mov_from_reg, mov_to_reg = next[1], next[2]
-
- if op_target_reg == mov_from_reg:
- ret = [op_op, *op_operands, mov_to_reg]
- result.append(ret)
- i += 1
- continue
-
- result.append(current)
-
- return result
-
- def compact_mov_source_pattern(self, asm: list[list[str]]) -> list[list[str]]:
- ops_with_source = ["str", "ldr", "add", "sub", "addi", "subi", "and", "or", "xor", "sll", "slr", "sar", "slli", "slri", "sari", "mov", "ali", "alr"]
- i = 0
- result: list[list[str]] = []
- while i < len(asm):
- current = asm[i]
- next = asm[i + 1] if i + 1 < len(asm) else None
- i += 1
- if current[0].startswith("@") or next is None:
- result.append(current)
- continue
-
- if current[0] == "mov" and next[0] in ops_with_source:
- mov_from_reg, mov_to_reg = current[1], current[2]
- op_op, op_source_reg, op_operands = next[0], next[1], next[2:]
-
- if op_source_reg == mov_to_reg:
- ret = [op_op, op_source_reg, *op_operands]
- result.append(ret)
- i += 1
- continue
-
- result.append(current)
-
- return result
-
- def compact_spu_load_spo_pattern(self, asm: list[list[str]]) -> list[list[str]]:
- # spu RA
- # ldi int_7 RA
- # ldr RA RB
- # spo RA
- # OR
- # spu RA
- # ldi 3 RB
- # spo RA
-
- i = 0
- result: list[list[str]] = []
- while i < len(asm):
- instr0 = asm[i]
- instr1 = asm[i + 1] if i + 1 < len(asm) else None
- instr2 = asm[i + 2] if i + 2 < len(asm) else None
- instr3 = asm[i + 3] if i + 3 < len(asm) else None
- i += 1
- if instr0[0].startswith("@") or instr1 is None or instr2 is None or instr3 is None:
- result.append(instr0)
- continue
-
- if instr0[0] == "spu" and instr1[0] == "ldi" and instr2[0] == "ldr" and instr3[0] == "spo":
- spu_op, spu_reg = instr0
- ldi_op, ldi_imm, ldi_target_reg = instr1
- ldr_op, ldr_from_reg, ldr_to_reg = instr2
- spo_op, spo_reg = instr3
-
- if spu_reg == spo_reg and ldi_target_reg == ldr_from_reg and ldr_from_reg != ldr_to_reg:
- ret0 = f"ldi {ldi_imm} {ldr_to_reg}".split()
- ret1 = f"ldr {ldr_to_reg} {ldr_to_reg}".split()
- result.append(ret0)
- result.append(ret1)
- i += 3
- continue
-
- elif instr0[0] == "spu" and instr1[0] == "ldi" and instr2[0] == "spo":
- spu_op, spu_reg = instr0
- ldi_op, ldi_imm, ldi_target_reg = instr1
- spo_op, spo_reg = instr2
-
- if spu_reg == spo_reg and ldi_target_reg != spu_reg:
- ret0 = f"ldi {ldi_imm} {ldi_target_reg}".split()
- result.append(ret0)
- i += 2
- continue
-
- result.append(instr0)
+ def get_module_exports(self, node: ast.Module):
+ result: list[str] = []
+ for stmt in node.body:
+ match stmt:
+ case ast.FunctionDef(name):
+ result.append(name)
+ case _:
+ # only function exported since recognizing which assignments are constants is kinda hard
+ pass
return result
@@ -873,11 +699,6 @@ asm_out = compiler.compile(
source_py,
)
-# optimizer = Optimizer()
-# asm_out_optimized = optimizer.optimize(asm_out)
-
with open(outfile_path, "w") as f:
f.write(asm_out)
-# with open(f"{outfile_path}_optimized", "w") as f:
-# f.write(asm_out_optimized)