diff options
Diffstat (limited to 'core/invoke.moon')
| -rw-r--r-- | core/invoke.moon | 79 |
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 |
