aboutsummaryrefslogtreecommitdiff
path: root/examples/math.lua
diff options
context:
space:
mode:
authorChloe Kudryavtsev <toast@toast.cafe>2021-12-23 17:41:22 -0500
committerChloe Kudryavtsev <toast@toast.cafe>2021-12-23 17:41:22 -0500
commitf342c5e84ede465bc2393f0034cb09e9a9149c70 (patch)
treef88b42f8d294e2a459f97c8bb7bf141db47cd27a /examples/math.lua
parentinitial import (diff)
add math.lua example
Diffstat (limited to 'examples/math.lua')
-rw-r--r--examples/math.lua63
1 files changed, 63 insertions, 0 deletions
diff --git a/examples/math.lua b/examples/math.lua
new file mode 100644
index 0000000..eed979b
--- /dev/null
+++ b/examples/math.lua
@@ -0,0 +1,63 @@
+local patok = require 'patok'
+local inspect = require 'inspect'
+local pm = require 'piecemeal'
+
+local lexer = patok {
+ op = '[+*]',
+ digit = '%d+',
+ space = '%s+',
+}()
+
+local lex = {
+ -- plus = pm.lexeme 'plus',
+ plus = pm.value '+',
+ times = pm.value '*',
+ digit = pm.postp(pm.lexeme 'digit', function(d) return tonumber(d.value) end),
+ space = pm.opt(pm.lexeme 'space')
+}
+
+local function findnums(d, acc)
+ local out = acc or {}
+ for _, v in ipairs(d) do -- only ipairs to avoid triggering on tokens
+ if type(v) == 'number' then
+ table.insert(out, v)
+ elseif type(v) == 'table' then
+ findnums(v, out)
+ end
+ end
+ return out
+end
+
+local mult = pm.postp(
+ pm.all(lex.digit, pm.star(pm.all(lex.space, lex.times, lex.space, lex.digit))),
+ function (d)
+ local acc = 1
+ for _, v in ipairs(findnums(d)) do
+ acc = acc * v
+ end
+ return acc
+ end)
+
+local add = pm.postp(
+ pm.all(mult, pm.star(pm.all(lex.space, lex.plus, lex.space, mult))),
+ function (d)
+ local acc = 0
+ for _, v in ipairs(findnums(d)) do
+ acc = acc + v
+ end
+ return acc
+ end)
+
+local expr = add
+
+local test
+if arg[1] then
+ local f = io.open(arg[1], 'r')
+ test = f:read '*a'
+ f:close()
+else
+ test = [[10 + 5 * 2 + 10]]
+end
+
+local eind, out = pm.parse(test, lexer, expr)
+print(eind, out)