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
|
import Const from require 'core.const'
import Action from require 'core.base'
import Scope from require 'core.scope'
class UpdateChildren
new: (@children) =>
update: (dt) =>
for child in *@children
-- L\trace "updating #{child}"
L\push child\update, dt
get: => @children[#@children]\get!
getc: => @children[#@children]\getc!
__tostring: => '<forwarder>'
class op_invoke extends Action
patch: (head) =>
return true if head == @head
@op\destroy! if @op
@head = head
assert @head.type == 'opdef', "cant op-invoke #{@head}"
@op = @head\getc!!
true
eval: (scope, tail) =>
L\trace "evaling #{@}"
args = L\push -> [L\push expr\eval, scope for expr in *tail]
-- Const 'op', with @op
with @op
\setup unpack args
class fn_invoke extends Action
-- @TODO:
-- need to :patch() the case where the new head is a new fndef
-- but corresponds to the last head over time
patch: (head) =>
return true if head == @head
@head = head
true
eval: (outer_scope, tail) =>
assert @head.type == 'fndef', "cant fn-invoke #{@head}"
{ :params, :body, :scope } = @head\getc!
assert #params == #tail, "argument count mismatch in #{@head}"
fn_scope = Scope @, scope
for i=1,#params
name = params[i]\getc!
argm = tail[i]
fn_scope\set name, L\push argm\eval, outer_scope
body = body\clone @tag
body\eval fn_scope
class do_expr extends Action
eval: (scope, tail) =>
UpdateChildren [(expr\eval scope) or Const.empty! for expr in *tail]
{
:op_invoke, :fn_invoke
:UpdateChildren
}
|