git @ Cat's Eye Technologies Strelnokoff / 36eb069
Checkpoint converting AST to be composed of variant records. Chris Pressey 1 year, 5 months ago
1 changed file(s) with 90 addition(s) and 63 deletion(s). Raw diff Collapse all Expand all
1313 fn()
1414 end
1515 end
16
1716
1817 debug = function(what, s)
1918 do_debug(what, function() print("--> (" .. s .. ")") end)
3332 return tostring(v)
3433 end
3534 end
35
36 --
37 -- Variant Records (for AST)
38 --
39
40 function make_vrecord(config)
41 return {
42 maker = function(tag)
43 local fields = config[tag]
44 if not fields then
45 error("Undefined tag: " .. tag)
46 end
47 return function(...)
48 local num_args = select("#", ...)
49 if num_args ~= #fields then
50 error(
51 "Arity error: expected " .. tostring(#fields) ..
52 " for " .. tag .. ", got " .. tostring(num_args)
53 )
54 end
55 return {
56 tag = tag,
57 field_values = {...}
58 }
59 end
60 end,
61 case = function(obj, cases)
62 local tag = obj.tag
63 local field_values = obj.field_values
64 local fields = config[tag]
65 if not fields then
66 error("Undefined tag: " .. tostring(tag))
67 end
68 if #fields ~= #field_values then
69 error("Arity error")
70 end
71
72 local sel = cases[tag] or cases.otherwise
73 if not sel then
74 error("No case for tag: " .. tag)
75 end
76
77 return sel(table.unpack(obj.field_values))
78 end
79 }
80 end
81
82 --
83 -- AST
84 --
85
86 local AST = make_vrecord({
87 assignment = {"varname", "varindex", "expr"},
88 binop = {"op", "lhs", "rhs"},
89 action = {"action", "mode", "val"},
90 literal = {"val"},
91 varaccess = {"name", "varindex"},
92 })
93
94 local Assignment = AST.maker("assignment")
95 local BinOp = AST.maker("binop")
96 local Action = AST.maker("action")
97 local Literal = AST.maker("literal")
98 local VarAccess = AST.maker("varaccess")
3699
37100 --
38101 -- Scanner
183246 end
184247 self.scanner:expect("=")
185248 local expr = self:expression0()
186 return {
187 type = "assignment",
188 varname = varname,
189 varindex = varindex,
190 expr = expr,
191 }
249 return Assignment(varname, varindex, expr)
192250 end
193251
194252 function Parser:expression0()
196254 while self.scanner.token == "=" or self.scanner.token == ">" do
197255 local t = self:consume_token()
198256 local rhs = self:expression1()
199 expr = {
200 type = t,
201 lhs = expr,
202 rhs = rhs,
203 }
257 expr = BinOp(t, expr, rhs)
204258 end
205259 return expr
206260 end
210264 while self.scanner.token == "+" or self.scanner.token == "-" do
211265 local t = self:consume_token()
212266 local rhs = self:expression2()
213 expr = {
214 type = t,
215 lhs = expr,
216 rhs = rhs,
217 }
267 expr = BinOp(t, expr, rhs)
218268 end
219269 return expr
220270 end
224274 while self.scanner.token == "*" or self.scanner.token == "/" do
225275 local t = self:consume_token()
226276 local rhs = self:primitive()
227 expr = {
228 type = t,
229 lhs = expr,
230 rhs = rhs,
231 }
277 expr = BinOp(t, expr, rhs)
232278 end
233279 return expr
234280 end
253299
254300 if self.scanner.toktype == "number" then
255301 local val = tonumber(self.scanner.token)
302 local expr = Literal(val)
256303 self.scanner:scan()
257304 if action == "PRINT" then
258 return {
259 type = "print",
260 mode = mode,
261 val = val
262 }
305 return Action("print", mode, expr)
263306 else
264307 -- FIXME what about "INPUT" ... ?
265 return {
266 type = "literal",
267 val = val
268 }
308 return expr
269309 end
270310 elseif self.scanner.toktype == "char" then
271311 local val = string.byte(self.scanner.token, 2)
312 local expr = Literal(val)
272313 -- FIXME just as above
273314 self.scanner:scan()
274315 if action == "PRINT" then
275 return {
276 type = "print",
277 mode = mode,
278 val = val
279 }
316 return Action("print", mode, expr)
280317 else
281318 -- FIXME what about "INPUT" ... ?
282 return {
283 type = "literal",
284 val = val
285 }
319 return expr
286320 end
287321 elseif self.scanner.token == "(" then
288322 self.scanner:scan()
290324 self.scanner:expect(")")
291325 -- FIXME just as above
292326 if action == "PRINT" then
293 return {
294 type = "print",
295 mode = mode,
296 val = val
297 }
327 return Action("print", mode, expr)
298328 else
299329 -- FIXME what about "INPUT" ... ?
300 return {
301 type = "literal",
302 val = val
303 }
330 return expr
304331 end
305332 else
306333 local name = self:expect_toktype("ident")
307 local ast = {
308 type = "varaccess",
309 name = name,
310 }
334 local varindex = nil
311335 if self.scanner.token == "[" then
312 ast.varindex = self:varindex()
313 end
314 return ast
315 -- ?? return ['print', 'int', $q] if $mode == 1;
316 -- ?? return ['print', 'char', $q] if $mode == 3;
317 -- ?? return $q;
336 varindex = self:varindex()
337 end
338 local expr = VarAccess(name, varindex)
339 if action == "PRINT" then
340 return Action("print", mode, expr)
341 else
342 -- FIXME what about "INPUT" ... ?
343 return expr
344 end
318345 end
319346 end
320347
326353
327354 local evaluate
328355 evaluate = function(ast)
329 local type = ast.type
330 if type == nil then -- FIXME: more explicit type on program?
356 local tag = ast.type
357 if type == nil then -- FIXME: more explicit type on program!
331358 local r = math.random(1, #ast)
332359 return evaluate(ast[r])
333360 elseif type == "assignment" then
372399 local p = Parser.new(program_text)
373400 local ast = p:program()
374401 debug("ast", render(ast))
375 local result = evaluate(ast)
376 debug("result", result)
402 --local result = evaluate(ast)
403 --debug("result", result)
377404 end
378405
379406 if arg ~= nil then