from typing import * import textwrap import re from agast import * global i i = 0 class TypecheckResult: def __init__(self, pd: str = "", ex: str = ""): self.parser_data = pd self.extra = ex def typecheck(program: List[Decl]) -> TypecheckResult: res = TypecheckResult() def gen(prefix: str = "", suffix: str = "") -> str: global i presan = re.sub("[^0-9a-zA-Z]+", "_", prefix) sufsan = re.sub("[^0-9a-zA-Z]+", "_", suffix) i += 1 return f"{presan}{i}{sufsan}" def v(name: str) -> str: return f"__ag_{name}" # collect a list of name -> iface declarations ifaces: Dict[str, Decl] = dict( map(lambda c: (c.name, c), filter(lambda c: isinstance(c, Iface), program))) print(ifaces) # a high-level dictionary of productions; this has sub-productions # that should be further expanded at a later step before converting # into lark code productions_hi: Dict[str, Union[str, List[str]]] = dict() for node in filter(lambda c: isinstance(c, Node), program): node = cast(Node, node) n_class_name = gen(node.name) class_decl = textwrap.dedent(f""" class {v(n_class_name)}: pass """) res.extra += class_decl print(node.name, node.ifaces) for variant in node.variants: v_class_name = gen(f"{n_class_name}_var") class_decl = textwrap.dedent(f""" class {v(v_class_name)}({v(n_class_name)}): ''' ''' pass """) res.extra += class_decl prod_name = gen(node.name) print(prod_name) for sym in variant.prod: print("sym", sym) # for each of the equations, find out what the equation is # trying to compute, and generate a thunk corresponding to # that value. for eq in variant.equations: print("--eq", eq) print(eq.lhs) eq_name = gen(f"eq_{node.name}") thunk_name = gen(f"thunk_{node.name}") func_impl = textwrap.dedent(f""" def {eq_name}() -> None: ''' {repr(eq)} ''' pass def {thunk_name}() -> Thunk[None]: return Thunk({eq_name}) """) print(f"```py\n{func_impl}\n```") res.extra += func_impl # this is a "type alias" that connects it to one of the generated # names above res.extra += f"{node.name} = {v(n_class_name)}" return res