1
0
Fork 0
mirror of https://github.com/Reuh/anselme.git synced 2025-10-27 16:49:31 +00:00
anselme/ast/Closure.lua

58 lines
1.4 KiB
Lua

-- note: functions only appear in non-evaluated nodes! once evaluated, they always become closures
local ast = require("ast")
local Overloadable, Runtime = ast.abstract.Overloadable, ast.abstract.Runtime
local Definition
local Closure
Closure = Runtime(Overloadable) {
type = "closure",
func = nil, -- Function
scope = nil, -- Environment
exported_scope = nil, -- Environment
init = function(self, func, state)
self.func = func
self.scope = state.scope:capture()
-- layer a new export layer on top of captured/current scope
state.scope:push_export()
self.exported_scope = state.scope:capture()
-- pre-define exports
for sym, exp in pairs(self.func.exports) do
Definition:new(sym, exp):eval(state)
end
state.scope:pop()
end,
_format = function(self, ...)
return self.func:format(...)
end,
traverse = function(self, fn, ...)
fn(self.func, ...)
fn(self.scope, ...)
fn(self.exported_scope, ...)
end,
compatible_with_arguments = function(self, state, args)
return args:match_parameter_tuple(state, self.func.parameters)
end,
format_parameters = function(self, state)
return self.func.parameters:format(state)
end,
call_dispatched = function(self, state, args)
state.scope:push(self.exported_scope)
local exp = self.func:call_dispatched(state, args)
state.scope:pop()
return exp
end,
}
package.loaded[...] = Closure
Definition = ast.Definition
return Closure