1
0
Fork 0
mirror of https://github.com/Reuh/anselme.git synced 2025-10-28 00:59:31 +00:00

Custom format for Typed and dispatch refactor

This commit is contained in:
Étienne Fildadut 2023-12-28 14:28:14 +01:00
parent e222f0fb28
commit 91e1311560
8 changed files with 75 additions and 26 deletions

View file

@ -64,7 +64,7 @@ Node = class {
-- to be preferably used during construction only
set_source = function(self, source)
local str_source = tostring(source)
if self.source == "?" then
if self.source == "?" and str_source ~= "?" then
self.source = str_source
self:traverse(traverse.set_source, str_source)
end
@ -156,16 +156,39 @@ Node = class {
return t
end,
-- call the node with the given arguments
-- return result AST
-- arg is a ArgumentTuple node (already evaluated)
-- redefine if relevant
-- do not redefine; instead redefine :dispatch and :call_dispatched
call = function(self, state, arg)
local dispatched, dispatched_arg = self:dispatch(state, arg)
if dispatched then
return dispatched:call_dispatched(state, dispatched_arg)
else
error(("can't call %s %s: %s"):format(self.type, self:format(state), dispatched_arg), 0)
end
end,
-- find a function that can be called with the given arguments
-- return function, arg if a function is found that can be called with arg. The returned arg may be different than the input arg.
-- return nil, message if no matching function found
dispatch = function(self, state, arg)
-- by default, look for custom call operator
if state.scope:defined(custom_call_identifier) then
local custom_call = custom_call_identifier:eval(state)
return custom_call:call(state, arg:with_first_argument(self))
else
error("trying to call a "..self.type..": "..self:format(state))
local dispatched, dispatched_arg = custom_call:dispatch(state, arg:with_first_argument(self))
if dispatched then
return dispatched, dispatched_arg
else
return nil, dispatched_arg
end
end
return nil, "not callable"
end,
-- call the node with the given arguments
-- this assumes that this node was correctly dispatched to (was returned by a previous call to :dispatch)
-- you can therefore assume that the arguments are valid and compatible with this node
call_dispatched = function(self, state, arg)
error(("%s is not callable"):format(self.type))
end,
-- merge any changes back into the main branch

View file

@ -1,3 +1,5 @@
-- for nodes that can be put in an Overload
local ast = require("ast")
return ast.abstract.Node {
@ -9,19 +11,21 @@ return ast.abstract.Node {
compatible_with_arguments = function(self, state, args)
error("not implemented for "..self.type)
end,
-- same as :call, but assumes :compatible_with_arguments was checked before the call
call_compatible = function(self, state, args)
error("not implemented for "..self.type)
end,
-- return string
format_parameters = function(self, state)
return self:format(state)
end,
-- default for :call
call = function(self, state, args)
assert(self:compatible_with_arguments(state, args))
return self:call_compatible(state, args)
end
-- can be called either after a successful :dispatch or :compatible_with_arguments
call_dispatched = function(self, state, args)
error("not implemented for "..self.type)
end,
-- default for :dispatch
dispatch = function(self, state, args)
local s, err = self:compatible_with_arguments(state, args)
if s then return self, args
else return nil, err end
end,
}