aboutsummaryrefslogtreecommitdiffstats
path: root/core/invoke.moon
diff options
context:
space:
mode:
Diffstat (limited to 'core/invoke.moon')
-rw-r--r--core/invoke.moon79
1 files changed, 79 insertions, 0 deletions
diff --git a/core/invoke.moon b/core/invoke.moon
new file mode 100644
index 0000000..78c40a2
--- /dev/null
+++ b/core/invoke.moon
@@ -0,0 +1,79 @@
+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) =>
+ args = [expr\eval scope, @registry 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: (scope, tail) =>
+ assert @head.type == 'fndef', "cant fn-invoke #{@head}"
+ { :params, :body } = @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, scope, @registry
+
+ body\eval fn_scope, @registry
+
+class do_expr extends Action
+ class DoWrapper
+ new: (@children) =>
+
+ update: (dt) =>
+ for child in *@children
+ L\push child\update, dt
+
+ get: => @children[#@children]\get!
+ getc: => @children[#@children]\getc!
+
+ __tostring: => '<dowrapper>'
+
+ eval: (scope, tail) =>
+ UpdateChildren [(expr\eval scope, @registry) or Const.empty! for expr in *tail]
+
+:op_invoke, :fn_invoke