mirror of
https://github.com/Reuh/anselme.git
synced 2025-10-27 16:49:31 +00:00
The previous system needed to store of the scope and full AST to build a Resumable object, which means that if persisted, updating the resumable script will have no effect. The new system instead uses an anchor token and does not require any information besides the anchor name.
66 lines
1.6 KiB
Lua
66 lines
1.6 KiB
Lua
local ast = require("ast")
|
|
local ArgumentTuple, Nil, Boolean, Identifier = ast.ArgumentTuple, ast.Nil, ast.Boolean, ast.Identifier
|
|
|
|
local if_identifier = Identifier:new("_if_status")
|
|
local if_symbol = if_identifier:to_symbol()
|
|
|
|
local function ensure_if_variable(state)
|
|
if not state.scope:defined_in_current(if_symbol) then
|
|
state.scope:define(if_symbol, Boolean:new(false))
|
|
end
|
|
end
|
|
local function set_if_variable(state, bool)
|
|
state.scope:set(if_identifier, Boolean:new(bool))
|
|
end
|
|
local function last_if_success(state)
|
|
return state.scope:get(if_identifier):truthy()
|
|
end
|
|
|
|
return {
|
|
{
|
|
"_~_", "(condition, expression)", function(state, condition, expression)
|
|
ensure_if_variable(state)
|
|
if condition:truthy() then
|
|
local r = expression:call(state, ArgumentTuple:new())
|
|
set_if_variable(state, true)
|
|
return r
|
|
else
|
|
set_if_variable(state, false)
|
|
return Nil:new()
|
|
end
|
|
end
|
|
},
|
|
{
|
|
"~_", "(expression)",
|
|
function(state, expression)
|
|
ensure_if_variable(state)
|
|
if last_if_success(state) then
|
|
return Nil:new()
|
|
else
|
|
local r = expression:call(state, ArgumentTuple:new())
|
|
set_if_variable(state, true)
|
|
return r
|
|
end
|
|
end
|
|
},
|
|
|
|
{
|
|
"_~?_", "(condition, expression)",
|
|
function(state, condition, expression)
|
|
ensure_if_variable(state)
|
|
local cond = condition:call(state, ArgumentTuple:new())
|
|
local r
|
|
if cond:truthy() then
|
|
set_if_variable(state, true)
|
|
else
|
|
set_if_variable(state, false)
|
|
return Nil:new()
|
|
end
|
|
while cond:truthy() do
|
|
r = expression:call(state, ArgumentTuple:new())
|
|
cond = condition:call(state, ArgumentTuple:new())
|
|
end
|
|
return r
|
|
end
|
|
},
|
|
}
|