aboutsummaryrefslogtreecommitdiffstats
path: root/core/base.moon
blob: dcf600a4e0a9cf9e14e496e278953b69260d9046 (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
71
72
73
74
75
76
77
78
79
80
class Op
-- common
  new: =>
  -- (...) => @setup ...

  get: => @value
  getc: =>
    L\warn "stream #{@} cast to constant"
    @value

-- Value interface
  update: =>

  destroy: =>

-- static
  __tostring: => "<op: #{@@__name}>"
  __inherited: (cls) => cls.__base.__tostring = @__tostring

  spawn: (Opdef, ...) ->
    Opdef ...

class Action
-- common
  new: (head, @tag) =>
    @patch head

-- AST interface
  -- * eval args
  -- * perform scope effects
  -- * patch nested exprs
  -- * return runtime-tree value
  eval: (scope, tail) => error "not implemented"

  -- free resources
  destroy: =>

  -- update this instance for :eavl() with new head
  -- if :patch() returns false, this instance is :destroy'ed and recreated instead
  -- must *not* return false when called after :new()
  -- only considered if Action types match
  patch: (head) =>
    if head == @head
      true

    @head = head

-- static
  @get_or_create: (ActionType, head, tag) ->
    last = tag\last!
    compatible = last and
                 (last.__class == ActionType) and
                 (last\patch head) and
                 last

    L\trace if compatible
      "reusing #{last} for #{tag} <#{ActionType.__name} #{head}>"
    else if last
      "replacing #{last} with new #{tag} <#{ActionType.__name} #{head}>"
    else
      "initializing #{tag} <#{ActionType.__name} #{head}>"

    if compatible
      tag\keep compatible
      compatible
    else
      last\destroy! if last
      with next = ActionType head, tag
        tag\replace next

  __tostring: => "<#{@@__name} #{@head}>"
  __inherited: (cls) => cls.__base.__tostring = @__tostring

class FnDef
  new: (@params, @body, @scope) =>

  __tostring: =>
    table.concat [p\stringify! for p in *@params], ' '

:Op, :Action, :FnDef