blob: 9b7c000f36279d62b6427e906ffb231ab4cd8ac4 (
plain)
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
(;module:
lux
(lux [function]
(data (coll [list "L/" Fold<List>]))))
(type: #export #rec Pattern
(#BoolP Bool)
(#NatP Nat)
(#IntP Int)
(#DegP Deg)
(#RealP Real)
(#TextP Text)
(#TupleP (List Pattern))
(#VariantP Nat Nat Pattern)
(#BindP Nat))
(type: #export #rec Analysis
#Unit
(#Bool Bool)
(#Nat Nat)
(#Int Int)
(#Deg Deg)
(#Real Real)
(#Text Text)
(#Sum (Either Analysis Analysis))
(#Product Analysis Analysis)
(#Case Analysis (List [Pattern Analysis]))
(#Function Scope Analysis)
(#Apply Analysis Analysis)
(#Procedure Text (List Analysis))
(#Variable Ref)
(#Definition Ident))
## Variants get analysed as binary sum types for the sake of semantic
## simplicity.
## This is because you can encode a variant of any size using just
## binary sums by nesting them.
(do-template [<name> <side>]
[(def: (<name> inner)
(-> Analysis Analysis)
(#Sum (<side> inner)))]
[sum-left #;Left]
[sum-right #;Right])
(def: #export (sum tag size temp value)
(-> Nat Nat Nat Analysis Analysis)
(if (n.= (n.dec size) tag)
(if (n.= +1 tag)
(sum-right value)
(L/fold (function;const sum-left)
(sum-right value)
(list;n.range +0 (n.- +2 tag))))
(L/fold (function;const sum-left)
(case value
(#Sum _)
(#Case value (list [(#BindP temp)
(#Variable (#;Local temp))]))
_
value)
(list;n.range +0 tag))))
## Tuples get analysed into binary products for the sake of semantic
## simplicity, since products/pairs can encode tuples of any length
## through nesting.
(def: #export (product members)
(-> (List Analysis) Analysis)
(case members
#;Nil
#Unit
(#;Cons singleton #;Nil)
singleton
(#;Cons left right)
(#Product left (product right))))
## Function application gets analysed into single-argument
## applications, since every other kind of application can be encoded
## into a finite series of single-argument applications.
(def: #export (apply args func)
(-> (List Analysis) Analysis Analysis)
(L/fold (function [arg func] (#Apply arg func))
func
args))
|