-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtypes.lua
321 lines (321 loc) · 5.43 KB
/
types.lua
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
local util = require("__zk-lib__/lualib/moonscript/util")
local Set
Set = require("__zk-lib__/lualib/moonscript/data").Set
local insert
insert = table.insert
local unpack
unpack = util.unpack
local manual_return = Set({
"foreach",
"for",
"while",
"return"
})
local cascading = Set({
"if",
"unless",
"with",
"switch",
"class",
"do"
})
local terminating = Set({
"return",
"break"
})
local ntype
ntype = function(node)
local _exp_0 = type(node)
if "nil" == _exp_0 then
return "nil"
elseif "table" == _exp_0 then
return node[1]
else
return "value"
end
end
local mtype
do
local moon_type = util.moon.type
mtype = function(val)
local mt = getmetatable(val)
if mt and mt.smart_node then
return "table"
end
return moon_type(val)
end
end
local value_can_be_statement
value_can_be_statement = function(node)
if not (ntype(node) == "chain") then
return false
end
return ntype(node[#node]) == "call"
end
local is_value
is_value = function(stm)
return package.loaded["__zk-lib__/lualib/moonscript/compile"].Block:is_value(stm) or package.loaded["__zk-lib__/lualib/moonscript/transform/value"]:can_transform(stm)
end
local value_is_singular
value_is_singular = function(node)
return type(node) ~= "table" or node[1] ~= "exp" or #node == 2
end
local is_slice
is_slice = function(node)
return ntype(node) == "chain" and ntype(node[#node]) == "slice"
end
local t = { }
local node_types = {
class = {
{
"name",
"Tmp"
},
{
"body",
t
}
},
fndef = {
{
"args",
t
},
{
"whitelist",
t
},
{
"arrow",
"slim"
},
{
"body",
t
}
},
foreach = {
{
"names",
t
},
{
"iter"
},
{
"body",
t
}
},
["for"] = {
{
"name"
},
{
"bounds",
t
},
{
"body",
t
}
},
["while"] = {
{
"cond",
t
},
{
"body",
t
}
},
assign = {
{
"names",
t
},
{
"values",
t
}
},
declare = {
{
"names",
t
}
},
["if"] = {
{
"cond",
t
},
{
"then",
t
}
}
}
local build_table
build_table = function()
local key_table = { }
for node_name, args in pairs(node_types) do
local index = { }
for i, tuple in ipairs(args) do
local prop_name = tuple[1]
index[prop_name] = i + 1
end
key_table[node_name] = index
end
return key_table
end
local key_table = build_table()
local make_builder
make_builder = function(name)
local spec = node_types[name]
if not spec then
error("don't know how to build node: " .. name)
end
return function(props)
if props == nil then
props = { }
end
local node = {
name
}
for i, arg in ipairs(spec) do
local key, default_value = unpack(arg)
local val
if props[key] then
val = props[key]
else
val = default_value
end
if val == t then
val = { }
end
node[i + 1] = val
end
return node
end
end
local build = nil
build = setmetatable({
group = function(body)
if body == nil then
body = { }
end
return {
"group",
body
}
end,
["do"] = function(body)
return {
"do",
body
}
end,
assign_one = function(name, value)
return build.assign({
names = {
name
},
values = {
value
}
})
end,
table = function(tbl)
if tbl == nil then
tbl = { }
end
for _index_0 = 1, #tbl do
local tuple = tbl[_index_0]
if type(tuple[1]) == "string" then
tuple[1] = {
"key_literal",
tuple[1]
}
end
end
return {
"table",
tbl
}
end,
block_exp = function(body)
return {
"block_exp",
body
}
end,
chain = function(parts)
local base = parts.base or error("expecting base property for chain")
if type(base) == "string" then
base = {
"ref",
base
}
end
local node = {
"chain",
base
}
for _index_0 = 1, #parts do
local part = parts[_index_0]
insert(node, part)
end
return node
end
}, {
__index = function(self, name)
self[name] = make_builder(name)
return rawget(self, name)
end
})
local smart_node_mt = setmetatable({ }, {
__index = function(self, node_type)
local index = key_table[node_type]
local mt = {
smart_node = true,
__index = function(node, key)
if index[key] then
return rawget(node, index[key])
elseif type(key) == "string" then
return error("unknown key: `" .. key .. "` on node type: `" .. ntype(node) .. "`")
end
end,
__newindex = function(node, key, value)
if index[key] then
key = index[key]
end
return rawset(node, key, value)
end
}
self[node_type] = mt
return mt
end
})
local smart_node
smart_node = function(node)
return setmetatable(node, smart_node_mt[ntype(node)])
end
local NOOP = {
"noop"
}
return {
ntype = ntype,
smart_node = smart_node,
build = build,
is_value = is_value,
is_slice = is_slice,
manual_return = manual_return,
cascading = cascading,
value_is_singular = value_is_singular,
value_can_be_statement = value_can_be_statement,
mtype = mtype,
terminating = terminating,
NOOP = NOOP
}