mirror of
https://github.com/Reuh/anselme.git
synced 2025-10-27 16:49:31 +00:00
Omit function variables from merge
This commit is contained in:
parent
40c1616cce
commit
3d32f35d67
7 changed files with 70 additions and 45 deletions
|
|
@ -2,6 +2,7 @@ local atypes, ltypes
|
|||
local eval, run_block
|
||||
local replace_with_copied_values
|
||||
local common
|
||||
local identifier_pattern
|
||||
|
||||
--- copy some text & process it to be suited to be sent to Lua in an event
|
||||
local function post_process_text(state, text)
|
||||
|
|
@ -57,7 +58,9 @@ common = {
|
|||
mt.cache = {}
|
||||
-- merge modified re-assigned variables
|
||||
for var, value in pairs(state.variables) do
|
||||
global.variables[var] = value
|
||||
if common.should_keep_variable(state, var) then
|
||||
global.variables[var] = value
|
||||
end
|
||||
state.variables[var] = nil
|
||||
end
|
||||
end,
|
||||
|
|
@ -78,6 +81,20 @@ common = {
|
|||
return var
|
||||
end
|
||||
end,
|
||||
set_variable = function(state, name, val)
|
||||
state.variables[name] = val
|
||||
end,
|
||||
--- mark a table as modified, so it will be merged on the next checkpoint if it appears somewhere in a value
|
||||
mark_as_modified = function(state, v)
|
||||
local modified = getmetatable(state.variables).modified_tables
|
||||
table.insert(modified, v)
|
||||
end,
|
||||
--- returns true if a variable should be persisted on save/merge
|
||||
-- will exclude: undefined variables, variables in functions defined with parentheses, internal anselme variables
|
||||
should_keep_variable = function(state, name)
|
||||
local v = state.variables[name]
|
||||
return v.type ~= "undefined argument" and v.type ~= "pending definition" and name:match("^"..identifier_pattern.."$") and not name:match("^anselme%.")
|
||||
end,
|
||||
--- check truthyness of an anselme value
|
||||
truthy = function(val)
|
||||
if val.type == "number" then
|
||||
|
|
@ -408,5 +425,6 @@ atypes, ltypes = types.anselme, types.lua
|
|||
eval = require((...):gsub("common$", "expression"))
|
||||
run_block = require((...):gsub("common$", "interpreter")).run_block
|
||||
replace_with_copied_values = require((...):gsub("interpreter%.common$", "common")).replace_with_copied_values
|
||||
identifier_pattern = require((...):gsub("interpreter%.common$", "parser.common")).identifier_pattern
|
||||
|
||||
return common
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
local expression
|
||||
local to_lua, from_lua, eval_text, is_of_type, truthy, format, pretty_type, get_variable, tags, eval_text_callback, events, flatten_list
|
||||
local to_lua, from_lua, eval_text, is_of_type, truthy, format, pretty_type, get_variable, tags, eval_text_callback, events, flatten_list, set_variable
|
||||
|
||||
local run
|
||||
|
||||
|
|
@ -85,7 +85,7 @@ local function eval(state, exp)
|
|||
local name = exp.left.name
|
||||
local val, vale = eval(state, exp.right)
|
||||
if not val then return val, vale end
|
||||
state.variables[name] = val
|
||||
set_variable(state, name, val)
|
||||
return val
|
||||
else
|
||||
return nil, ("don't know how to perform assignment on %s expression"):format(exp.left.type)
|
||||
|
|
@ -257,11 +257,11 @@ local function eval(state, exp)
|
|||
depths[j] = math.huge
|
||||
end
|
||||
-- set
|
||||
state.variables[param.full_name] = val
|
||||
set_variable(state, param.full_name, val)
|
||||
-- default: evaluate once function is selected
|
||||
-- there's no need to type check because the type annotation is already the default value's type, because of syntax
|
||||
elseif param.default then
|
||||
state.variables[param.full_name] = { type = "pending definition", value = { expression = param.default, source = fn.source } }
|
||||
set_variable(state, param.full_name, { type = "pending definition", value = { expression = param.default, source = fn.source } })
|
||||
else
|
||||
ok = false
|
||||
table.insert(tried_function_error_messages, ("%s: missing mandatory argument %q in function %q call"):format(fn.pretty_signature, param.name, fn.name))
|
||||
|
|
@ -300,7 +300,7 @@ local function eval(state, exp)
|
|||
depths.assignment = math.huge
|
||||
end
|
||||
-- set
|
||||
state.variables[param.full_name] = assignment
|
||||
set_variable(state, param.full_name, assignment)
|
||||
end
|
||||
if ok then
|
||||
if not selected_variant.variant then
|
||||
|
|
@ -340,7 +340,7 @@ local function eval(state, exp)
|
|||
return nil, ("unknown function type %q"):format(fn.type)
|
||||
end
|
||||
end
|
||||
-- function successfully selected
|
||||
-- function successfully selected: run
|
||||
if selected_variant.variant then
|
||||
local fn = selected_variant.variant
|
||||
if fn.type == "checkpoint" then
|
||||
|
|
@ -398,7 +398,9 @@ local function eval(state, exp)
|
|||
elseif lua_fn.mode == nil then
|
||||
local l_lua = {}
|
||||
for _, v in ipairs(final_args) do
|
||||
table.insert(l_lua, to_lua(v))
|
||||
local lv, e = to_lua(v)
|
||||
if e then return nil, e end
|
||||
table.insert(l_lua, lv)
|
||||
end
|
||||
local r, e
|
||||
if _VERSION == "Lua 5.1" and not jit then -- PUC Lua 5.1 doesn't allow yield from a pcall
|
||||
|
|
@ -429,10 +431,10 @@ local function eval(state, exp)
|
|||
if not ret then return ret, e end
|
||||
end
|
||||
-- update function vars
|
||||
state.variables[fn.namespace.."👁️"] = {
|
||||
set_variable(state, fn.namespace.."👁️", {
|
||||
type = "number",
|
||||
value = seen.value + 1
|
||||
}
|
||||
})
|
||||
-- return value
|
||||
if not ret then return nil, ("function %q didn't return a value"):format(exp.called_name) end
|
||||
return ret
|
||||
|
|
@ -464,6 +466,6 @@ run = require((...):gsub("expression$", "interpreter")).run
|
|||
expression = require((...):gsub("interpreter%.expression$", "parser.expression"))
|
||||
flatten_list = require((...):gsub("interpreter%.expression$", "parser.common")).flatten_list
|
||||
local common = require((...):gsub("expression$", "common"))
|
||||
to_lua, from_lua, eval_text, is_of_type, truthy, format, pretty_type, get_variable, tags, eval_text_callback, events = common.to_lua, common.from_lua, common.eval_text, common.is_of_type, common.truthy, common.format, common.pretty_type, common.get_variable, common.tags, common.eval_text_callback, common.events
|
||||
to_lua, from_lua, eval_text, is_of_type, truthy, format, pretty_type, get_variable, tags, eval_text_callback, events, set_variable = common.to_lua, common.from_lua, common.eval_text, common.is_of_type, common.truthy, common.format, common.pretty_type, common.get_variable, common.tags, common.eval_text_callback, common.events, common.set_variable
|
||||
|
||||
return eval
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
local eval
|
||||
local truthy, merge_state, escape, get_variable, tags, events
|
||||
local truthy, merge_state, escape, get_variable, tags, events, set_variable
|
||||
local run_line, run_block
|
||||
|
||||
-- returns var in case of success and there is a return
|
||||
|
|
@ -92,14 +92,14 @@ run_line = function(state, line)
|
|||
elseif line.type == "checkpoint" then
|
||||
local reached, reachede = get_variable(state, line.namespace.."🏁")
|
||||
if not reached then return nil, reachede end
|
||||
state.variables[line.namespace.."🏁"] = {
|
||||
set_variable(state, line.namespace.."🏁", {
|
||||
type = "number",
|
||||
value = reached.value + 1
|
||||
}
|
||||
state.variables[line.parent_function.namespace.."🔖"] = {
|
||||
})
|
||||
set_variable(state, line.parent_function.namespace.."🔖", {
|
||||
type = "string",
|
||||
value = line.name
|
||||
}
|
||||
})
|
||||
merge_state(state)
|
||||
else
|
||||
return nil, ("unknown line type %q; at %s"):format(line.type, line.source)
|
||||
|
|
@ -138,22 +138,22 @@ run_block = function(state, block, resume_from_there, i, j)
|
|||
if not seen then return nil, seene end
|
||||
local checkpoint, checkpointe = get_variable(state, parent_line.parent_function.namespace.."🔖")
|
||||
if not checkpoint then return nil, checkpointe end
|
||||
state.variables[parent_line.namespace.."👁️"] = {
|
||||
set_variable(state, parent_line.namespace.."👁️", {
|
||||
type = "number",
|
||||
value = seen.value + 1
|
||||
}
|
||||
state.variables[parent_line.namespace.."🏁"] = {
|
||||
})
|
||||
set_variable(state, parent_line.namespace.."🏁", {
|
||||
type = "number",
|
||||
value = reached.value + 1
|
||||
}
|
||||
})
|
||||
-- don't update checkpoint if an already more precise checkpoint is set
|
||||
-- (since we will go up the whole checkpoint hierarchy when resuming from a nested checkpoint)
|
||||
local current_checkpoint = checkpoint.value
|
||||
if not current_checkpoint:match("^"..escape(parent_line.name)) then
|
||||
state.variables[parent_line.parent_function.namespace.."🔖"] = {
|
||||
set_variable(state, parent_line.parent_function.namespace.."🔖", {
|
||||
type = "string",
|
||||
value = parent_line.name
|
||||
}
|
||||
})
|
||||
end
|
||||
merge_state(state)
|
||||
end
|
||||
|
|
@ -231,7 +231,7 @@ local interpreter = {
|
|||
package.loaded[...] = interpreter
|
||||
eval = require((...):gsub("interpreter$", "expression"))
|
||||
local common = require((...):gsub("interpreter$", "common"))
|
||||
truthy, merge_state, tags, get_variable, events = common.truthy, common.merge_state, common.tags, common.get_variable, common.events
|
||||
truthy, merge_state, tags, get_variable, events, set_variable = common.truthy, common.merge_state, common.tags, common.get_variable, common.events, common.set_variable
|
||||
escape = require((...):gsub("interpreter%.interpreter$", "parser.common")).escape
|
||||
|
||||
return interpreter
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue