util-sta.lua /size: 9412 b    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
util-sta
'
]
=
{
2
version
=
1
.
001
,
3
comment
=
"
companion to util-ini.mkiv
"
,
4
author
=
"
Hans Hagen, PRAGMA-ADE, Hasselt NL
"
,
5
copyright
=
"
PRAGMA ADE / ConTeXt Development Team
"
,
6
license
=
"
see context related readme files
"
7
}
8 9
local
insert
,
remove
,
fastcopy
,
concat
=
table
.
insert
,
table
.
remove
,
table
.
fastcopy
,
table
.
concat
10
local
format
=
string
.
format
11
local
select
,
tostring
=
select
,
tostring
12 13
local
trace_stacker
=
false
trackers
.
register
(
"
stacker.resolve
"
,
function
(
v
)
trace_stacker
=
v
end
)
14 15
local
stacker
=
stacker
or
{
}
16 17
utilities
.
stacker
=
stacker
18 19
local
function
start
(
s
,
t
,
first
,
last
)
20
if
s
.
mode
=
=
"
switch
"
then
21
local
n
=
tostring
(
t
[
last
]
)
22
if
trace_stacker
then
23
s
.
report
(
"
start: %s
"
,
n
)
24
end
25
return
n
26
else
27
local
r
=
{
}
28
for
i
=
first
,
last
do
29
r
[
#
r
+
1
]
=
tostring
(
t
[
i
]
)
30
end
31
local
n
=
concat
(
r
,
"
"
)
32
if
trace_stacker
then
33
s
.
report
(
"
start: %s
"
,
n
)
34
end
35
return
n
36
end
37
end
38 39
local
function
stop
(
s
,
t
,
first
,
last
)
40
if
s
.
mode
=
=
"
switch
"
then
41
local
n
=
tostring
(
false
)
42
if
trace_stacker
then
43
s
.
report
(
"
stop: %s
"
,
n
)
44
end
45
return
n
46
else
47
local
r
=
{
}
48
for
i
=
last
,
first
,
-1
do
49
r
[
#
r
+
1
]
=
tostring
(
false
)
50
end
51
local
n
=
concat
(
r
,
"
"
)
52
if
trace_stacker
then
53
s
.
report
(
"
stop: %s
"
,
n
)
54
end
55
return
n
56
end
57
end
58 59
local
function
change
(
s
,
t1
,
first1
,
last1
,
t2
,
first2
,
last2
)
60
if
s
.
mode
=
=
"
switch
"
then
61
local
n
=
tostring
(
t2
[
last2
]
)
62
if
trace_stacker
then
63
s
.
report
(
"
change: %s
"
,
n
)
64
end
65
return
n
66
else
67
local
r
=
{
}
68
for
i
=
last1
,
first1
,
-1
do
69
r
[
#
r
+
1
]
=
tostring
(
false
)
70
end
71
local
n
=
concat
(
r
,
"
"
)
72
for
i
=
first2
,
last2
do
73
r
[
#
r
+
1
]
=
tostring
(
t2
[
i
]
)
74
end
75
if
trace_stacker
then
76
s
.
report
(
"
change: %s
"
,
n
)
77
end
78
return
n
79
end
80
end
81 82
function
stacker
.
new
(
name
)
83 84
-- to be sped up, mmaybe foo:bar syntax here but then quite some access
85 86
local
report
=
logs
.
reporter
(
"
stacker
"
,
name
or
nil
)
87 88
local
s
89 90
local
stack
=
{
}
91
local
list
=
{
}
92
local
ids
=
{
}
93
local
hash
=
{
}
94 95
local
hashing
=
true
96 97
local
function
push
(
...
)
98
-- todo check if more than 1 argument
99
for
i
=
1
,
select
(
"
#
"
,
...
)
do
100
insert
(
stack
,
(
select
(
i
,
...
)
)
)
-- watch the ()
101
end
102
if
hashing
then
103
local
c
=
concat
(
stack
,
"
|
"
)
104
local
n
=
hash
[
c
]
105
if
not
n
then
106
n
=
#
list
+
1
107
hash
[
c
]
=
n
108
list
[
n
]
=
fastcopy
(
stack
)
109
end
110
insert
(
ids
,
n
)
111
return
n
112
else
113
local
n
=
#
list
+
1
114
list
[
n
]
=
fastcopy
(
stack
)
115
insert
(
ids
,
n
)
116
return
n
117
end
118
end
119 120
local
function
pop
(
)
121
remove
(
stack
)
122
remove
(
ids
)
123
return
ids
[
#
ids
]
or
s
.
unset
or
-1
124
end
125 126
local
function
clean
(
)
127
if
#
stack
=
=
0
then
128
if
trace_stacker
then
129
s
.
report
(
"
%s list entries, %s stack entries
"
,
#
list
,
#
stack
)
130
end
131
end
132
end
133 134
local
tops
=
{
}
135
local
top
=
nil
136
local
switch
=
nil
137 138
local
function
resolve_reset
(
mode
)
139
if
#
tops
>
0
then
140
report
(
"
resetting %s left-over states of %a
"
,
#
tops
,
name
)
141
end
142
tops
=
{
}
143
top
=
nil
144
switch
=
nil
145
end
146 147
local
function
resolve_begin
(
mode
)
148
if
mode
then
149
switch
=
mode
=
=
"
switch
"
150
else
151
switch
=
s
.
mode
=
=
"
switch
"
152
end
153
top
=
{
switch
=
switch
}
154
insert
(
tops
,
top
)
155
end
156 157
local
function
resolve_step
(
ti
)
-- keep track of changes outside function !
158
-- todo: optimize for n=1 etc
159
if
not
top
then
160
-- report("messed op stacker %a",name)
161
return
162
end
163
local
result
=
nil
164
local
noftop
=
#
top
165
if
ti
>
0
then
166
local
current
=
list
[
ti
]
167
if
current
then
168
local
noflist
=
#
current
169
local
nofsame
=
0
170
if
noflist
>
noftop
then
171
for
i
=
1
,
noflist
do
172
if
current
[
i
]
=
=
top
[
i
]
then
173
nofsame
=
i
174
else
175
break
176
end
177
end
178
else
179
for
i
=
1
,
noflist
do
180
if
current
[
i
]
=
=
top
[
i
]
then
181
nofsame
=
i
182
else
183
break
184
end
185
end
186
end
187
local
plus
=
nofsame
+
1
188
if
plus
<
=
noftop
then
189
if
plus
<
=
noflist
then
190
if
switch
then
191
result
=
s
.
change
(
s
,
top
,
plus
,
noftop
,
current
,
nofsame
,
noflist
)
192
else
193
result
=
s
.
change
(
s
,
top
,
plus
,
noftop
,
current
,
plus
,
noflist
)
194
end
195
else
196
if
switch
then
197
result
=
s
.
change
(
s
,
top
,
plus
,
noftop
,
current
,
nofsame
,
noflist
)
198
else
199
result
=
s
.
stop
(
s
,
top
,
plus
,
noftop
)
200
end
201
end
202
elseif
plus
<
=
noflist
then
203
if
switch
then
204
result
=
s
.
start
(
s
,
current
,
nofsame
,
noflist
)
205
else
206
result
=
s
.
start
(
s
,
current
,
plus
,
noflist
)
207
end
208
end
209
top
=
current
210
else
211
if
1
<
=
noftop
then
212
result
=
s
.
stop
(
s
,
top
,
1
,
noftop
)
213
end
214
top
=
{
}
215
end
216
return
result
217
else
218
if
1
<
=
noftop
then
219
result
=
s
.
stop
(
s
,
top
,
1
,
noftop
)
220
end
221
top
=
{
}
222
return
result
223
end
224
end
225 226
local
function
resolve_end
(
)
227
-- resolve_step(s.unset)
228
if
#
tops
>
0
then
-- was #top brrr
229
local
result
=
s
.
stop
(
s
,
top
,
1
,
#
top
)
230
remove
(
tops
)
231
top
=
tops
[
#
tops
]
232
switch
=
top
and
top
.
switch
233
return
result
234
end
235
end
236 237
local
function
resolve
(
t
)
238
resolve_begin
(
)
239
for
i
=
1
,
#
t
do
240
resolve_step
(
t
[
i
]
)
241
end
242
resolve_end
(
)
243
end
244 245
s
=
{
246
name
=
name
or
"
unknown
"
,
247
unset
=
-1
,
248
report
=
report
,
249
start
=
start
,
250
stop
=
stop
,
251
change
=
change
,
252
push
=
push
,
253
pop
=
pop
,
254
clean
=
clean
,
255
resolve
=
resolve
,
256
resolve_begin
=
resolve_begin
,
257
resolve_step
=
resolve_step
,
258
resolve_end
=
resolve_end
,
259
resolve_reset
=
resolve_reset
,
260
}
261 262
return
s
-- we can overload functions
263 264
end
265 266
-- local s = utilities.stacker.new("demo")
267
--
268
-- local unset = s.unset
269
-- local push = s.push
270
-- local pop = s.pop
271
--
272
-- local t = {
273
-- unset,
274
-- unset,
275
-- push("a"), -- a
276
-- push("b","c"), -- a b c
277
-- pop(), -- a b
278
-- push("d"), -- a b d
279
-- pop(), -- a b
280
-- unset,
281
-- pop(), -- a
282
-- pop(), -- b
283
-- unset,
284
-- unset,
285
-- }
286
--
287
-- s.resolve(t)
288 289
-- demostacker = utilities.stacker.new("demos")
290
--
291
-- local whatever = {
292
-- one = "1 0 0 RG 1 0 0 rg",
293
-- two = "1 1 0 RG 1 1 0 rg",
294
-- [false] = "0 G 0 g",
295
-- }
296
--
297
-- local concat = table.concat
298
--
299
-- local pageliteral = nodes.pool.pageliteral
300
--
301
-- function demostacker.start(s,t,first,last)
302
-- local n = whatever[t[last]]
303
-- -- s.report("start: %s",n)
304
-- return pageliteral(n)
305
-- end
306
--
307
-- function demostacker.stop(s,t,first,last)
308
-- local n = whatever[false]
309
-- -- s.report("stop: %s",n)
310
-- return pageliteral(n)
311
-- end
312
--
313
-- function demostacker.change(s,t1,first1,last1,t2,first2,last2)
314
-- local n = whatever[t2[last2]]
315
-- -- s.report("change: %s",n)
316
-- return pageliteral(n)
317
-- end
318
--
319
-- demostacker.mode = "switch"
320
--
321
-- local whatever = {
322
-- one = "/OC /test1 BDC",
323
-- two = "/OC /test2 BDC",
324
-- [false] = "EMC",
325
-- }
326
--
327
-- demostacker = utilities.stacker.new("demos")
328
--
329
-- function demostacker.start(s,t,first,last)
330
-- local r = { }
331
-- for i=first,last do
332
-- r[#r+1] = whatever[t[i]]
333
-- end
334
-- -- s.report("start: %s",concat(r," "))
335
-- return pageliteral(concat(r," "))
336
-- end
337
--
338
-- function demostacker.stop(s,t,first,last)
339
-- local r = { }
340
-- for i=last,first,-1 do
341
-- r[#r+1] = whatever[false]
342
-- end
343
-- -- s.report("stop: %s",concat(r," "))
344
-- return pageliteral(concat(r," "))
345
-- end
346
--
347
-- function demostacker.change(s,t1,first1,last1,t2,first2,last2)
348
-- local r = { }
349
-- for i=last1,first1,-1 do
350
-- r[#r+1] = whatever[false]
351
-- end
352
-- for i=first2,last2 do
353
-- r[#r+1] = whatever[t2[i]]
354
-- end
355
-- -- s.report("change: %s",concat(r," "))
356
-- return pageliteral(concat(r," "))
357
-- end
358
--
359
-- demostacker.mode = "stack"
360