agtest/gen.py
2021-06-09 02:44:52 -05:00

53 lines
1.2 KiB
Python

import textwrap
import os
import importlib
from lark import Lark
from agast import *
from agtypeck import *
p = Lark(open("grammar.lark").read(), start="program", parser="lalr")
if __name__ == "__main__":
with open("arith.ag") as f:
data = f.read()
cst = p.parse(data)
# print("cst", cst)
trans = Parser()
ast = trans.transform(cst)
print("ast", ast)
res = typecheck(ast)
if not os.path.exists("gen"):
os.makedirs("gen")
with open("gen/arith.py", "w") as f:
fmt_str = textwrap.dedent("""
__all__ = ["parse"]
from typing import Generic, TypeVar, Optional, Callable
from lark import Lark, Transformer
T = TypeVar('T')
class Thunk(Generic[T]):
''' A thunk represents a value that may be computed lazily. '''
value: Optional[T]
def __init__(self, func: Callable[[], T]):
self.func = func
self.value = None
def get(self) -> T:
if self.value is None:
self.value = self.func()
return self.value
parser = Lark('''start:
{pd}''')
class Trans(Transformer[None]):
pass
{ex}
def parse(input: str) -> None:
print(input)
""")
f.write(fmt_str.format(pd=res.parser_data, ex=res.extra))
mod = importlib.import_module("gen.arith")
mod.parse("1 + 2 * 3") # type: ignore