48 lines
1.7 KiB
Python
48 lines
1.7 KiB
Python
from ground_ast import RootNode
|
|
from typing import Any
|
|
from ground_ast import *
|
|
|
|
|
|
class Generator:
|
|
def __init__(self, ast: RootNode, code: str, output_path: str):
|
|
self.ast = ast
|
|
self.lines: list[str] = []
|
|
self.code = code
|
|
self.output_path = output_path
|
|
self.variables = {}
|
|
self.constants = {}
|
|
self.labels = []
|
|
self.constants_reverse = {}
|
|
self.constant_counter = 0
|
|
|
|
def add_constant(self, value: Any, no_string: bool = False):
|
|
existing_constant_name = self.constants_reverse.get(value, None)
|
|
if existing_constant_name != None: return f"[.{existing_constant_name}]"
|
|
self.constants["LC" + str(self.constant_counter)] = {"value": value, "no_string": no_string}
|
|
self.constants_reverse[value] = "LC" + str(self.constant_counter)
|
|
self.constant_counter += 1
|
|
return "[.LC" + str(self.constant_counter-1) + "]"
|
|
|
|
def clamp_instruction_args(self, instruction: InstructionNode, min_args: int, max_args: int):
|
|
if len(instruction.arguments) < min_args:
|
|
traceback(self.code, "TypeError", f"{instruction.instruction} expects at least {min_args} arguments.")
|
|
elif len(instruction.arguments) > max_args:
|
|
traceback(self.code, "TypeError", f"{instruction.instruction} expects at most {max_args} arguments.")
|
|
|
|
def init(self):
|
|
pass
|
|
|
|
def generate_node(self, node):
|
|
#self.lines.append(f"; {node}\n\t")
|
|
node_type = str(type(node))[19:-2]
|
|
if not hasattr(self, f"generate_{node_type}"):
|
|
raise NotImplementedError(f"Generator has no generate method for {node_type}.")
|
|
getattr(self, f"generate_{node_type}")(node)
|
|
|
|
def generate(self):
|
|
for statement in self.ast.statements:
|
|
self.generate_node(statement)
|
|
|
|
def write(self):
|
|
with open(self.output_path + ".asm", "w") as f:
|
|
f.writelines(self.lines) |