code / nomsu

Lines6.6K Lua5.1K PEG1.3K make117
2 others 83
Markdown60 Bourne Again Shell23
(363 lines)
1 local insert, remove, concat
2 do
3 local _obj_0 = table
4 insert, remove, concat = _obj_0.insert, _obj_0.remove, _obj_0.concat
5 end
6 local Source
7 Source = require("code_obj").Source
8 local List, Dict
9 do
10 local _obj_0 = require('containers')
11 List, Dict = _obj_0.List, _obj_0.Dict
12 end
13 local Files = require('files')
14 local unpack = unpack or table.unpack
15 local as_lua
16 as_lua = function(self)
17 if type(self) == 'number' then
18 return tostring(self)
19 end
20 do
21 local mt = getmetatable(self)
22 if mt then
23 do
24 local _as_lua = mt.as_lua
25 if _as_lua then
26 return _as_lua(self)
27 end
28 end
29 end
30 end
31 if self.as_lua then
32 return self:as_lua()
33 end
34 return error("Not supported: " .. tostring(self))
35 end
36 local SyntaxTree
37 do
38 local _class_0
39 local _base_0 = {
40 __tostring = function(self)
41 local bits
42 do
43 local _accum_0 = { }
44 local _len_0 = 1
45 for _index_0 = 1, #self do
46 local b = self[_index_0]
47 _accum_0[_len_0] = type(b) == 'string' and b:as_lua() or tostring(b)
48 _len_0 = _len_0 + 1
49 end
50 bits = _accum_0
51 end
52 for k, v in pairs(self) do
53 if not (bits[k] or k == 'type' or k == 'source') then
54 table.insert(bits, tostring(k) .. "=" .. tostring(type(v) == 'string' and v:as_lua() or v))
55 end
56 end
57 return tostring(self.type) .. "{" .. tostring(table.concat(bits, ", ")) .. "}"
58 end,
59 __eq = function(self, other)
60 if type(self) ~= type(other) or #self ~= #other or getmetatable(self) ~= getmetatable(other) then
61 return false
62 end
63 if self.type ~= other.type then
64 return false
65 end
66 for i = 1, #self do
67 if self[i] ~= other[i] then
68 return false
69 end
70 end
71 return true
72 end,
73 as_lua = function(self)
74 local bits
75 do
76 local _accum_0 = { }
77 local _len_0 = 1
78 for _index_0 = 1, #self do
79 local b = self[_index_0]
80 _accum_0[_len_0] = as_lua(b)
81 _len_0 = _len_0 + 1
82 end
83 bits = _accum_0
84 end
85 for k, v in pairs(self) do
86 if not (bits[k]) then
87 table.insert(bits, "[ " .. tostring(as_lua(k)) .. "]=" .. tostring(as_lua(v)))
88 end
89 end
90 return "SyntaxTree{" .. tostring(table.concat(bits, ", ")) .. "}"
91 end,
92 get_source_file = function(self)
93 return self.__class.source_code_for_tree[self]
94 end,
95 get_source_code = function(self)
96 return self.__class.source_code_for_tree[self]:sub(self.source.start, self.source.stop - 1)
97 end,
98 add = function(self, ...)
99 local n = #self
100 for i = 1, select('#', ...) do
101 self[n + i] = select(i, ...)
102 end
103 self.stub = nil
104 end,
105 with = function(self, fn)
106 if type(fn) == 'table' then
107 local replacements = fn
108 fn = function(t)
109 if t.type == "Var" then
111 local r = replacements[t:as_var()]
112 if r then
113 return r
114 end
115 end
116 end
117 end
118 end
119 local replacement = fn(self)
120 if replacement == false then
121 return nil
122 end
123 if replacement then
124 if SyntaxTree:is_instance(replacement) then
126 local _tbl_0 = { }
127 for k, v in pairs(replacement) do
128 _tbl_0[k] = v
129 end
130 replacement = _tbl_0
131 end
132 replacement.source = self.source
133 if self.comments then
134 replacement.comments = {
135 unpack(self.comments)
137 end
138 replacement = SyntaxTree(replacement)
139 end
140 else
141 replacement = {
142 source = self.source,
143 comments = self.comments and {
144 unpack(self.comments)
147 local changes = false
148 for k, v in pairs(self) do
149 local _continue_0 = false
150 repeat
151 replacement[k] = v
152 if SyntaxTree:is_instance(v) then
153 local r = v:with(fn)
154 if r == v or r == nil then
155 _continue_0 = true
156 break
157 end
158 changes = true
159 replacement[k] = r
160 end
161 _continue_0 = true
162 until true
163 if not _continue_0 then
164 break
165 end
166 end
167 if not (changes) then
168 return self
169 end
170 replacement = SyntaxTree(replacement)
171 end
172 return replacement
173 end,
174 contains = function(self, subtree)
175 if subtree == self then
176 return true
177 end
178 for k, v in pairs(self) do
179 if SyntaxTree:is_instance(v) then
180 if v:contains(subtree) then
181 return true
182 end
183 end
184 end
185 return false
186 end,
187 get_args = function(self)
188 assert(self.type == "Action" or self.type == "MethodCall", "Only actions and method calls have arguments")
189 local args = { }
190 if self.type == "MethodCall" then
191 args[1] = self[1]
192 for i = 2, #self do
193 local _list_0 = self[i]
194 for _index_0 = 1, #_list_0 do
195 local tok = _list_0[_index_0]
196 if type(tok) ~= 'string' then
197 args[#args + 1] = tok
198 end
199 end
200 end
201 else
202 for _index_0 = 1, #self do
203 local tok = self[_index_0]
204 if type(tok) ~= 'string' then
205 args[#args + 1] = tok
206 end
207 end
208 end
209 return args
210 end,
211 get_stub = function(self)
212 local _exp_0 = self.type
213 if "Action" == _exp_0 then
214 local stub_bits = { }
215 local arg_i = 1
216 for _index_0 = 1, #self do
217 local a = self[_index_0]
218 if type(a) == 'string' then
219 stub_bits[#stub_bits + 1] = a
220 else
221 stub_bits[#stub_bits + 1] = arg_i
222 arg_i = arg_i + 1
223 end
224 end
225 while type(stub_bits[#stub_bits]) == 'number' do
226 stub_bits[#stub_bits] = nil
227 end
228 return concat(stub_bits, " ")
229 elseif "MethodCall" == _exp_0 then
230 return "0, " .. table.concat((function()
231 local _accum_0 = { }
232 local _len_0 = 1
233 for i = 2, #self do
234 _accum_0[_len_0] = self[i]:get_stub()
235 _len_0 = _len_0 + 1
236 end
237 return _accum_0
238 end)(), "; ")
239 else
240 return error(tostring(self.type) .. "s do not have stubs")
241 end
242 end,
243 as_var = function(self)
244 assert(self.type == "Var")
245 if type(self[1]) == 'string' then
246 return self[1]
247 else
248 return self[1]:get_stub()
249 end
250 end,
251 matching = function(self, patt)
252 if patt.type == "Var" then
253 return {
254 [patt:as_var()] = self
256 end
257 if patt.type ~= self.type then
258 return nil
259 end
260 if patt.type == "Action" and patt:get_stub() ~= self:get_stub() then
261 return nil
262 end
263 if #self ~= #patt then
264 return nil
265 end
266 local match = { }
267 for i = 1, #self do
268 local v = self[i]
269 local pv = patt[i]
270 if type(v) ~= type(pv) then
271 return nil
272 end
273 if type(v) ~= 'table' then
274 if not (v == pv) then
275 return nil
276 end
277 else
278 local m = v:matching(pv)
279 if not (m) then
280 return nil
281 end
282 for mk, mv in pairs(m) do
283 if match[mk] and match[mk] ~= mv then
284 return nil
285 end
286 match[mk] = mv
287 end
288 end
289 end
290 return Dict(match)
291 end,
292 _breadth_first = function(self)
293 coroutine.yield(self)
294 for _index_0 = 1, #self do
295 local child = self[_index_0]
296 if getmetatable(child) == SyntaxTree.__base then
297 child:_breadth_first()
298 end
299 end
300 end,
301 breadth_first = function(self)
302 return coroutine.create(function()
303 return self:_breadth_first()
304 end)
305 end,
306 _depth_first = function(self)
307 coroutine.yield(self)
308 for _index_0 = 1, #self do
309 local child = self[_index_0]
310 if getmetatable(child) == SyntaxTree.__base then
311 child:_depth_first()
312 end
313 end
314 end,
315 depth_first = function(self)
316 return coroutine.create(function()
317 return self:_depth_first()
318 end)
319 end
321 _base_0.__index = _base_0
322 _class_0 = setmetatable({
323 __init = function() end,
324 __base = _base_0,
325 __name = "SyntaxTree"
326 }, {
327 __index = _base_0,
328 __call = function(cls, ...)
329 local _self_0 = setmetatable({}, _base_0)
330 cls.__init(_self_0, ...)
331 return _self_0
332 end
334 _base_0.__class = _class_0
335 local self = _class_0
336 self.source_code_for_tree = setmetatable({ }, {
337 __index = function(self, t)
338 local s = t.source
339 local f = Files.read(s.filename)
340 return f
341 end,
342 __mode = "k"
344 self.is_instance = function(self, t)
345 return type(t) == 'table' and getmetatable(t) == self.__base
346 end
347 SyntaxTree = _class_0
348 end
349 SyntaxTree.__base.__type = "a Syntax Tree"
350 getmetatable(SyntaxTree).__call = function(self, t, ...)
351 if type(t.source) == 'string' then
352 t.source = Source:from_string(t.source)
353 end
354 setmetatable(t, self.__base)
355 for i = 1, select("#", ...) do
356 t[i] = select(i, ...)
357 end
358 if t.type == 'Action' then
359 t.stub = t:get_stub()
360 end
361 return t
362 end
363 return SyntaxTree