aboutsummaryrefslogtreecommitdiffstats
path: root/core/registry.moon
blob: 3fc6d55b3caef5f88a330a3f4b4512346f04a33e (plain)
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
}