-
Notifications
You must be signed in to change notification settings - Fork 0
/
lark_list.py
37 lines (32 loc) · 1.15 KB
/
lark_list.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
from lark_utils import Fail
from terms import builtin_func, pattern_wild, expr, wild, seq, lit
from lexer import to_rules, lex
import string
def list_pattern_func(x):
if isinstance(x,lit) and x.val == "()": # shouldn't happen..
return lex("nil")
elif isinstance(x,seq) and len(x)>=2 and \
isinstance(x[0], lit) and isinstance(x[-1], lit) and \
x[0].val == "(" and x[-1].val == ")":
if not all(isinstance(i,lit) and i.val == "," for i in x[2:-1:2]):
return Fail
items = x[1:-1:2]
items = items[::-1]
ret = lex("nil")
for i in items:
if isinstance(i, expr):
ret = seq(lex("cons(")+seq([i])+lex(",")+seq([ret])+lex(")"))
else:
return Fail
return ret
else:
return Fail
class list_pattern(pattern_wild):
def __init__(self, name):
self.pattern = list_pattern_func
self.name = name
list_cast_rule = (seq([list_pattern("x")]), seq([list_pattern("x")]))
gen_list_rules = to_rules("""nil=nil
cons($x,$y)=cons($x,$y)""")
base_list_rules = [list_cast_rule]
list_rules = base_list_rules + gen_list_rules