1
0
Fork 0
mirror of https://github.com/Reuh/anselme.git synced 2025-10-27 16:49:31 +00:00
anselme/stdlib/conditionals.lua
Étienne Reuh Fildadut 56ed6c912b Replace checkpoint system
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.
2023-12-27 17:06:35 +01:00

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
},
}