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
|
class Registry
new: () =>
@map = {}
-- methods for Tag
last: (index) => @last_map[index]
replace: (index, expr, ignore_dup=false) =>
L\trace "reg: setting #{index} to #{expr}"
assert not @map[index] or ignore_dup, "duplicate tags with index #{index}!"
@map[index] = expr
init: (tag, expr) =>
L\trace "reg: init pending to #{expr}"
table.insert @pending, { :tag, :expr }
active: ->
assert Registry.active_registry, "no active Registry!"
-- public methods
wrap: (fn) =>
(...) ->
@prepare!
with fn ...
@finalize!
prepare: =>
assert not @prev, "already have a previous registry? #{@prev}"
@prev, @@active_registry = @@active_registry, @
@last_map, @map, @pending = @map, {}, {}
finalize: =>
for tag, val in pairs @last_map
if not @map[tag]
val\destroy!
for { :tag, :expr } in *@pending
-- tag was solved by another pending registration
-- (e.g. first [A] is solved, then [5.A] is solved)
continue if tag\index!
L\trace "assigning new tag #{value} to #{tag} #{expr}"
tag\set @next_tag!
@map[tag\index!] = expr
assert @ == @@active_registry, "not the active registry!"
@@active_registry, @prev = @prev, nil
next_tag: => #@map + 1
class SimpleRegistry extends Registry
new: =>
@cnt = 1
init: (tag, expr) =>
tag\set @cnt
@cnt += 1
last: (index) =>
replace: (index, expr) =>
finalize: =>
assert @ == @@active_registry, "not the active registry!"
@@active_registry, @prev = @prev, nil
{
:Registry
:SimpleRegistry
}
|