initial
This commit is contained in:
commit
323c7a6282
7 changed files with 120 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
.mypy_cache
|
||||||
|
gen/
|
2
Justfile
Normal file
2
Justfile
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
watch:
|
||||||
|
watchexec -ce py -i gen 'mypy *.py && python gen.py && mypy gen/*.py'
|
13
arith.ag
Normal file
13
arith.ag
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
iface Node {
|
||||||
|
val: int,
|
||||||
|
}
|
||||||
|
|
||||||
|
node Expr : Node {
|
||||||
|
<l:Expr> "+" <r:Expr> => {
|
||||||
|
self.val = l.val + r.val;
|
||||||
|
}
|
||||||
|
<l:Expr> "*" <r:Expr> => {
|
||||||
|
self.val = l.val * r.val;
|
||||||
|
}
|
||||||
|
<n:r"[0-9]+"> => { self.val = parseInt(n); }
|
||||||
|
}
|
22
gen.py
Normal file
22
gen.py
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import textwrap
|
||||||
|
import os
|
||||||
|
from lark import Lark
|
||||||
|
|
||||||
|
p = Lark(open("grammar.lark").read())
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
with open("arith.ag") as f:
|
||||||
|
data = f.read()
|
||||||
|
|
||||||
|
t = p.parse(data)
|
||||||
|
print(t)
|
||||||
|
|
||||||
|
if not os.path.exists("gen"):
|
||||||
|
os.makedirs("gen")
|
||||||
|
with open("gen/arith.py", "w") as f:
|
||||||
|
f.write(textwrap.dedent("""
|
||||||
|
from typing import Generic, TypeVar
|
||||||
|
T = TypeVar('T')
|
||||||
|
class Thunk(Generic[T]):
|
||||||
|
pass
|
||||||
|
"""))
|
44
grammar.lark
Normal file
44
grammar.lark
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
start: decl*
|
||||||
|
|
||||||
|
decl: iface
|
||||||
|
| node
|
||||||
|
|
||||||
|
iface: IFACE IDENT "{" iface_field (COMMA iface_field)? COMMA? "}"
|
||||||
|
iface_field: IDENT COLON IDENT
|
||||||
|
|
||||||
|
node: NODE IDENT COLON IDENT "{" node_prod* "}"
|
||||||
|
node_prod: prod THICCARROW "{" (equation SEMI)* "}"
|
||||||
|
prod: sym*
|
||||||
|
sym: IDENT
|
||||||
|
| LANG IDENT COLON node_ref RANG
|
||||||
|
| STRING
|
||||||
|
node_ref: IDENT
|
||||||
|
| STRING
|
||||||
|
equation: expr EQ expr
|
||||||
|
|
||||||
|
expr: expr DOT expr
|
||||||
|
| expr ADD expr
|
||||||
|
| expr MUL expr
|
||||||
|
| expr LPAR args RPAR
|
||||||
|
| IDENT
|
||||||
|
args: expr (COMMA expr)? COMMA?
|
||||||
|
|
||||||
|
IDENT: /([a-zA-Z][a-zA-Z0-9_]*)|(_[a-zA-Z0-9_]+)/
|
||||||
|
IFACE: "iface"
|
||||||
|
NODE: "node"
|
||||||
|
LANG: "<"
|
||||||
|
RANG: ">"
|
||||||
|
ADD: "+"
|
||||||
|
MUL: "*"
|
||||||
|
COMMA: ","
|
||||||
|
COLON: ":"
|
||||||
|
LPAR: "("
|
||||||
|
RPAR: ")"
|
||||||
|
EQ: "="
|
||||||
|
DOT: "."
|
||||||
|
SEMI: ";"
|
||||||
|
THICCARROW: "=>"
|
||||||
|
|
||||||
|
%import python.STRING
|
||||||
|
%import common.WS
|
||||||
|
%ignore WS
|
35
main.py
Normal file
35
main.py
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
from typing import Generic, TypeVar, Optional, Callable
|
||||||
|
|
||||||
|
T = TypeVar("T")
|
||||||
|
|
||||||
|
class Thunk(Generic[T]):
|
||||||
|
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
|
||||||
|
|
||||||
|
class Node:
|
||||||
|
value: Thunk[int]
|
||||||
|
|
||||||
|
class Add(Node):
|
||||||
|
def __init__(self, left: Node, right: Node):
|
||||||
|
self.value = Thunk(lambda: left.value.get() + right.value.get())
|
||||||
|
|
||||||
|
class Mul(Node):
|
||||||
|
def __init__(self, left: Node, right: Node):
|
||||||
|
self.value = Thunk(lambda: left.value.get() * right.value.get())
|
||||||
|
|
||||||
|
class Lit(Node):
|
||||||
|
def __init__(self, num: int):
|
||||||
|
self.num = num
|
||||||
|
self.value = Thunk(lambda: num)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
tree = Add(Mul(Lit(3), Lit(4)), Lit(5))
|
||||||
|
print(tree.value.get())
|
2
mypy.ini
Normal file
2
mypy.ini
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[mypy]
|
||||||
|
strict = True
|
Loading…
Reference in a new issue