-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathflow.lua
84 lines (77 loc) · 2.45 KB
/
flow.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
-- if you don't feel like writing IIFEs, this writes them for you
-- (let ((a 42) (b "foo")) (print (.. b a)))
parens8[[
(rawset builtin "let" (fn (lookup exp2 exp3) (
(fn (names values) (select 2
(foreach exp2 (fn (binding) (id
(add names (rawget binding 1))
(add values (rawget binding 2))
)))
(compile (pack (pack "fn" names exp3) (unpack values)) lookup)
))
(pack) (pack)
)))
(rawset builtin "loop" (fn (lookup exp2 exp3) (compile
(pack (pack "fn" (pack "__ps8_loop") (pack "id"
(pack "set" "__ps8_loop" (pack "fn" (pack)
(pack "when" exp2 (pack "__ps8_loop" exp3))
))
(pack "__ps8_loop")
)))
lookup
)))
]]
-- the "loop" builtin is a "poor man's while", implemented as a tail recursion.
-- thanks to lua, such an implementation will not blow up the stack.
-- if you're really strapped for tokens, it will at least save you the headache
-- of implementing a tail recursion loop correctly yourself.
-- this is what the generated code looks like:
-- (fn (__ps8_loop) (id
-- (set __ps8_loop (fn ()
-- (when exp2 (__ps8_loop exp3))
-- ))
-- (__ps8_loop)
-- ))
-- if you *really* need proper loops and can justify the token cost however...
-- (while (< x 3) (set x (+ 1 x))
parens8[[
(fn (closure) (rawset builtin "while" (fn (lookup cond body)
(closure (compile_n lookup cond body))
)))
]](function(a1, a2) return function(frame)
while (a1(frame)) a2(frame)
end end)
-- `foreach` should take care of your collection traversal needs, but if for
-- some reason you think doing numeric loops in parens-8 is a good idea (it
-- usually isn't), there's a builtin for it:
-- (for (i 1 10 2) (body))
-- (for ((k v) (pairs foo)) (body))
-- 79 tokens for the lot, each syntax can be disabled individually
parens8[[
(fn (closures) (rawset builtin "for" (fn (lookup args body)
(when (rawget args 3)
(select 1 (closures
(compile (pack "fn" (pack (rawget args 1)) body) lookup)
(compile_n lookup (unpack args 2))))
(select 2 (closures
(compile (pack "fn" (rawget args 1) body) lookup)
(compile (rawget args 2) lookup)))
)
)))
]](function(cbody, a, b, c) return
function(frame) -- numeric for loop (28 tokens)
local body = cbody(frame)
for i = a(frame), b(frame), c and c(frame) or 1 do
body(i)
end
end,
function(frame) -- generic for loop (41 tokens)
local body, next, state = cbody(frame), a(frame)
local function loop(var, ...)
if (var == nil) return
body(var, ...)
return loop(next(state, var))
end
return loop(next(state))
end
end)