-
Notifications
You must be signed in to change notification settings - Fork 0
/
type_syntax.shen
70 lines (55 loc) · 1.4 KB
/
type_syntax.shen
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
(datatype lazy-seq-type
X : (lazy (list A));
___________________
X : (lazy-seq A);
_________________
[] : (lazy-seq A);
X : A; Y : (lazy-seq A);
_______________________
(freeze (cons X Y)) : (lazy-seq A);
X : (lazy-seq A);
________________
(thaw X) : (thawed-seq A);
X : (thawed-seq A);
__________________
(head X) : A;
X : (thawed-seq A);
__________________
(tail X) : (lazy-seq A);
X : (lazy-seq A);
________________
(= (thaw X) []) : boolean;)
(deftype lazy-seq
(if
(or
(= X [])
(: X (lazy (list A))))
(: X (lazy-seq A)))
(if
(and
(: X A)
(: Y (lazy-seq A)))
(: (freeze (cons X Y)) (lazy-seq A)))
(if
(: X (lazy-seq A))
(and
(: (thaw X) (thawed-seq A))
(: (= (thaw X) []) boolean)))
(if
(: X (thawed-seq A))
(and
(: (head X) A)
(: (tail X) (lazy-seq A)))))
(defmacro deftype-macro
[deftype Name | Rules] ->
[datatype (intern (@s (str Name) "-type")) | (mapcan #'sequent Rules)])
(define sequent
[if [and | Ps] Q] -> (append (mapcan #'label Ps) [__] (label Q))
[if [or | Ps] Q] -> (mapcan (/. P (sequent [if P Q])) Ps)
[if P [and | Qs]] -> (mapcan (/. Q (sequent [if P Q])) Qs)
[if P [or | Qs]] -> (append (label P) [__] (mapcan #'label Qs))
[if P Q] -> (append (label P) [__] (label Q))
Q -> (append [__] (label Q)))
(define label
[: X T] -> [X : T ;]
X -> [X ;])