-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprops.lua
128 lines (112 loc) · 3.02 KB
/
props.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
function same (me, sub)
me.n_timers = sub.n_timers
me.n_tracks = sub.n_tracks
me.n_asyncs = sub.n_asyncs
me.n_emits = sub.n_emits
end
function MAX_all (me, t)
t = t or me
me.n_timers = 0
me.n_tracks = 0
me.n_asyncs = 0
me.n_emits = 0
for _, sub in ipairs(t) do
me.n_timers = MAX(me.n_timers, sub.n_timers)
me.n_tracks = MAX(me.n_tracks, sub.n_tracks)
me.n_asyncs = MAX(me.n_asyncs, sub.n_asyncs)
me.n_emits = MAX(me.n_emits, sub.n_emits)
end
end
function ADD_all (me, t)
t = t or me
me.n_timers = 0
me.n_tracks = 0
me.n_asyncs = 0
me.n_emits = 0
for _, sub in ipairs(t) do
me.n_timers = me.n_timers + sub.n_timers
me.n_tracks = me.n_tracks + sub.n_tracks
me.n_asyncs = me.n_asyncs + sub.n_asyncs
me.n_emits = me.n_emits + sub.n_emits
end
end
local STMTS = {
Block=true, Nothing=true,
Dcl_int=true, Dcl_ext=true, Dcl_pure=true, Dcl_det=true,
SetExp=true, SetBlock=true, SetStmt=true,
Return=true, Async=true, Host=true,
ParEver=true, ParOr=true, ParAnd=true, Loop=true,
Break=true, If=true, AwaitN=true, AwaitE=true, AwaitT=true, EmitE=true,
EmitT=true, CallStmt=true
}
F = {
Node_pre = function (me)
me.prio = 0
me.n_timers = 0
me.n_tracks = 1
me.n_asyncs = 0
me.n_emits = 0
if STMTS[me.id] then
me.isStmt = true
end
end,
Node = function (me)
if (not F[me.id]) and _ISNODE(me[#me]) then
same(me, me[#me])
end
end,
Block = MAX_all,
Async = function (me)
me.n_asyncs = 1
end,
If = function (me)
local c, t, f = unpack(me)
f = f or c
MAX_all(me, {t,f})
end,
ParEver = ADD_all,
ParAnd = ADD_all,
ParOr = ADD_all,
ParOr_pre = function (me)
local f = function (stmt)
local id = stmt.id
return id=='SetBlock' or id=='ParOr' or id=='Loop'
end
local top = _ITER(f)()
me.prio = top and top.prio+1 or 1
me.nd_join = true
end,
Loop_pre = function (me)
F.ParOr_pre(me)
me.brks = {}
end,
Break = function (me)
local loop = _ITER'Loop'()
local async = _ITER'Async'()
ASR(loop and (not async or loop.depth>async.depth),
me,'break without loop')
loop.brks[me] = true
end,
SetBlock_pre = function (me)
F.ParOr_pre(me)
me.rets = {}
end,
Return = function (me)
local setret = _ITER'SetBlock'()
local async = _ITER'Async'()
ASR(setret and (not async or setret.depth+1==async.depth),
me,'invalid return statement')
setret.rets[me] = true
end,
EmitE = function (me)
local acc, exp = unpack(me)
if acc.evt.dir == 'internal' then
me.n_tracks = 2 -- awake/continuation
me.n_emits = 1
end
end,
AwaitT = function (me)
me.n_timers = 1
end,
}
_VISIT(F)