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
10
anselme.lua
10
anselme.lua
|
|
@ -25,11 +25,11 @@ local eval = require(anselme_root.."interpreter.expression")
|
||||||
local run_line = require(anselme_root.."interpreter.interpreter").run_line
|
local run_line = require(anselme_root.."interpreter.interpreter").run_line
|
||||||
local run = require(anselme_root.."interpreter.interpreter").run
|
local run = require(anselme_root.."interpreter.interpreter").run
|
||||||
local to_lua = require(anselme_root.."interpreter.common").to_lua
|
local to_lua = require(anselme_root.."interpreter.common").to_lua
|
||||||
local identifier_pattern = require(anselme_root.."parser.common").identifier_pattern
|
|
||||||
local merge_state = require(anselme_root.."interpreter.common").merge_state
|
local merge_state = require(anselme_root.."interpreter.common").merge_state
|
||||||
local stdfuncs = require(anselme_root.."stdlib.functions")
|
local stdfuncs = require(anselme_root.."stdlib.functions")
|
||||||
local bootscript = require(anselme_root.."stdlib.bootscript")
|
local bootscript = require(anselme_root.."stdlib.bootscript")
|
||||||
local copy = require(anselme_root.."common").copy
|
local copy = require(anselme_root.."common").copy
|
||||||
|
local should_keep_variable = require(anselme_root.."interpreter.common").should_keep_variable
|
||||||
|
|
||||||
-- wrappers for love.filesystem / luafilesystem
|
-- wrappers for love.filesystem / luafilesystem
|
||||||
local function list_directory(path)
|
local function list_directory(path)
|
||||||
|
|
@ -410,7 +410,7 @@ local vm_mt = {
|
||||||
save = function(self)
|
save = function(self)
|
||||||
local vars = {}
|
local vars = {}
|
||||||
for k, v in pairs(self.state.variables) do
|
for k, v in pairs(self.state.variables) do
|
||||||
if v.type ~= "undefined argument" and v.type ~= "pending definition" and k:match("^"..identifier_pattern.."$") then
|
if should_keep_variable(self.state, k) then
|
||||||
vars[k] = v
|
vars[k] = v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -479,15 +479,17 @@ local vm_mt = {
|
||||||
functions = self.state.functions, -- no need for a cache as we can't define or modify any function from the interpreter for now
|
functions = self.state.functions, -- no need for a cache as we can't define or modify any function from the interpreter for now
|
||||||
variables = setmetatable({}, {
|
variables = setmetatable({}, {
|
||||||
__index = function(variables, k)
|
__index = function(variables, k)
|
||||||
local cache = getmetatable(variables).cache
|
local mt = getmetatable(variables)
|
||||||
|
local cache = mt.cache
|
||||||
if cache[k] == nil then
|
if cache[k] == nil then
|
||||||
cache[k] = copy(self.state.variables[k], getmetatable(variables).copy_cache)
|
cache[k] = copy(self.state.variables[k], getmetatable(variables).copy_cache)
|
||||||
end
|
end
|
||||||
return cache[k]
|
return cache[k]
|
||||||
end,
|
end,
|
||||||
|
-- variables that keep current state and should be cleared at each checkpoint
|
||||||
copy_cache = {}, -- table of [original table] = copied table
|
copy_cache = {}, -- table of [original table] = copied table
|
||||||
modified_tables = {}, -- list of modified tables (copies) that should be merged with global state on next checkpoint
|
modified_tables = {}, -- list of modified tables (copies) that should be merged with global state on next checkpoint
|
||||||
cache = {} -- cache of previously read values (copies), to get repeatable reads & handle mutable types without changing global state
|
cache = {}, -- cache of previously read values (copies), to get repeatable reads & handle mutable types without changing global state
|
||||||
}),
|
}),
|
||||||
interpreter = {
|
interpreter = {
|
||||||
-- constant
|
-- constant
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
|
local identifier_pattern
|
||||||
|
|
||||||
--- replace values recursively in table t according to to_replace ([old table] = new table)
|
--- replace values recursively in table t according to to_replace ([old table] = new table)
|
||||||
|
-- already_replaced is a temporary table to avoid infinite loop & duplicate processing, no need to give it
|
||||||
local function replace_in_table(t, to_replace, already_replaced)
|
local function replace_in_table(t, to_replace, already_replaced)
|
||||||
already_replaced = already_replaced or {}
|
already_replaced = already_replaced or {}
|
||||||
already_replaced[t] = true
|
already_replaced[t] = true
|
||||||
|
|
@ -56,8 +59,12 @@ common = {
|
||||||
for _, m in ipairs(copied_to_replace) do
|
for _, m in ipairs(copied_to_replace) do
|
||||||
replace_in_table(m, not_modified)
|
replace_in_table(m, not_modified)
|
||||||
end
|
end
|
||||||
-- replace
|
-- replace in t
|
||||||
replace_in_table(t, to_replace)
|
replace_in_table(t, to_replace)
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
package.loaded[...] = common
|
||||||
|
identifier_pattern = require((...):gsub("common$", "parser.common")).identifier_pattern
|
||||||
|
|
||||||
return common
|
return common
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ local atypes, ltypes
|
||||||
local eval, run_block
|
local eval, run_block
|
||||||
local replace_with_copied_values
|
local replace_with_copied_values
|
||||||
local common
|
local common
|
||||||
|
local identifier_pattern
|
||||||
|
|
||||||
--- copy some text & process it to be suited to be sent to Lua in an event
|
--- copy some text & process it to be suited to be sent to Lua in an event
|
||||||
local function post_process_text(state, text)
|
local function post_process_text(state, text)
|
||||||
|
|
@ -57,7 +58,9 @@ common = {
|
||||||
mt.cache = {}
|
mt.cache = {}
|
||||||
-- merge modified re-assigned variables
|
-- merge modified re-assigned variables
|
||||||
for var, value in pairs(state.variables) do
|
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
|
state.variables[var] = nil
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
@ -78,6 +81,20 @@ common = {
|
||||||
return var
|
return var
|
||||||
end
|
end
|
||||||
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
|
--- check truthyness of an anselme value
|
||||||
truthy = function(val)
|
truthy = function(val)
|
||||||
if val.type == "number" then
|
if val.type == "number" then
|
||||||
|
|
@ -408,5 +425,6 @@ atypes, ltypes = types.anselme, types.lua
|
||||||
eval = require((...):gsub("common$", "expression"))
|
eval = require((...):gsub("common$", "expression"))
|
||||||
run_block = require((...):gsub("common$", "interpreter")).run_block
|
run_block = require((...):gsub("common$", "interpreter")).run_block
|
||||||
replace_with_copied_values = require((...):gsub("interpreter%.common$", "common")).replace_with_copied_values
|
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
|
return common
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
local expression
|
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
|
local run
|
||||||
|
|
||||||
|
|
@ -85,7 +85,7 @@ local function eval(state, exp)
|
||||||
local name = exp.left.name
|
local name = exp.left.name
|
||||||
local val, vale = eval(state, exp.right)
|
local val, vale = eval(state, exp.right)
|
||||||
if not val then return val, vale end
|
if not val then return val, vale end
|
||||||
state.variables[name] = val
|
set_variable(state, name, val)
|
||||||
return val
|
return val
|
||||||
else
|
else
|
||||||
return nil, ("don't know how to perform assignment on %s expression"):format(exp.left.type)
|
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
|
depths[j] = math.huge
|
||||||
end
|
end
|
||||||
-- set
|
-- set
|
||||||
state.variables[param.full_name] = val
|
set_variable(state, param.full_name, val)
|
||||||
-- default: evaluate once function is selected
|
-- 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
|
-- 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
|
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
|
else
|
||||||
ok = false
|
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))
|
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
|
depths.assignment = math.huge
|
||||||
end
|
end
|
||||||
-- set
|
-- set
|
||||||
state.variables[param.full_name] = assignment
|
set_variable(state, param.full_name, assignment)
|
||||||
end
|
end
|
||||||
if ok then
|
if ok then
|
||||||
if not selected_variant.variant 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)
|
return nil, ("unknown function type %q"):format(fn.type)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- function successfully selected
|
-- function successfully selected: run
|
||||||
if selected_variant.variant then
|
if selected_variant.variant then
|
||||||
local fn = selected_variant.variant
|
local fn = selected_variant.variant
|
||||||
if fn.type == "checkpoint" then
|
if fn.type == "checkpoint" then
|
||||||
|
|
@ -398,7 +398,9 @@ local function eval(state, exp)
|
||||||
elseif lua_fn.mode == nil then
|
elseif lua_fn.mode == nil then
|
||||||
local l_lua = {}
|
local l_lua = {}
|
||||||
for _, v in ipairs(final_args) do
|
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
|
end
|
||||||
local r, e
|
local r, e
|
||||||
if _VERSION == "Lua 5.1" and not jit then -- PUC Lua 5.1 doesn't allow yield from a pcall
|
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
|
if not ret then return ret, e end
|
||||||
end
|
end
|
||||||
-- update function vars
|
-- update function vars
|
||||||
state.variables[fn.namespace.."👁️"] = {
|
set_variable(state, fn.namespace.."👁️", {
|
||||||
type = "number",
|
type = "number",
|
||||||
value = seen.value + 1
|
value = seen.value + 1
|
||||||
}
|
})
|
||||||
-- return value
|
-- return value
|
||||||
if not ret then return nil, ("function %q didn't return a value"):format(exp.called_name) end
|
if not ret then return nil, ("function %q didn't return a value"):format(exp.called_name) end
|
||||||
return ret
|
return ret
|
||||||
|
|
@ -464,6 +466,6 @@ run = require((...):gsub("expression$", "interpreter")).run
|
||||||
expression = require((...):gsub("interpreter%.expression$", "parser.expression"))
|
expression = require((...):gsub("interpreter%.expression$", "parser.expression"))
|
||||||
flatten_list = require((...):gsub("interpreter%.expression$", "parser.common")).flatten_list
|
flatten_list = require((...):gsub("interpreter%.expression$", "parser.common")).flatten_list
|
||||||
local common = require((...):gsub("expression$", "common"))
|
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
|
return eval
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
local eval
|
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
|
local run_line, run_block
|
||||||
|
|
||||||
-- returns var in case of success and there is a return
|
-- 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
|
elseif line.type == "checkpoint" then
|
||||||
local reached, reachede = get_variable(state, line.namespace.."🏁")
|
local reached, reachede = get_variable(state, line.namespace.."🏁")
|
||||||
if not reached then return nil, reachede end
|
if not reached then return nil, reachede end
|
||||||
state.variables[line.namespace.."🏁"] = {
|
set_variable(state, line.namespace.."🏁", {
|
||||||
type = "number",
|
type = "number",
|
||||||
value = reached.value + 1
|
value = reached.value + 1
|
||||||
}
|
})
|
||||||
state.variables[line.parent_function.namespace.."🔖"] = {
|
set_variable(state, line.parent_function.namespace.."🔖", {
|
||||||
type = "string",
|
type = "string",
|
||||||
value = line.name
|
value = line.name
|
||||||
}
|
})
|
||||||
merge_state(state)
|
merge_state(state)
|
||||||
else
|
else
|
||||||
return nil, ("unknown line type %q; at %s"):format(line.type, line.source)
|
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
|
if not seen then return nil, seene end
|
||||||
local checkpoint, checkpointe = get_variable(state, parent_line.parent_function.namespace.."🔖")
|
local checkpoint, checkpointe = get_variable(state, parent_line.parent_function.namespace.."🔖")
|
||||||
if not checkpoint then return nil, checkpointe end
|
if not checkpoint then return nil, checkpointe end
|
||||||
state.variables[parent_line.namespace.."👁️"] = {
|
set_variable(state, parent_line.namespace.."👁️", {
|
||||||
type = "number",
|
type = "number",
|
||||||
value = seen.value + 1
|
value = seen.value + 1
|
||||||
}
|
})
|
||||||
state.variables[parent_line.namespace.."🏁"] = {
|
set_variable(state, parent_line.namespace.."🏁", {
|
||||||
type = "number",
|
type = "number",
|
||||||
value = reached.value + 1
|
value = reached.value + 1
|
||||||
}
|
})
|
||||||
-- don't update checkpoint if an already more precise checkpoint is set
|
-- 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)
|
-- (since we will go up the whole checkpoint hierarchy when resuming from a nested checkpoint)
|
||||||
local current_checkpoint = checkpoint.value
|
local current_checkpoint = checkpoint.value
|
||||||
if not current_checkpoint:match("^"..escape(parent_line.name)) then
|
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",
|
type = "string",
|
||||||
value = parent_line.name
|
value = parent_line.name
|
||||||
}
|
})
|
||||||
end
|
end
|
||||||
merge_state(state)
|
merge_state(state)
|
||||||
end
|
end
|
||||||
|
|
@ -231,7 +231,7 @@ local interpreter = {
|
||||||
package.loaded[...] = interpreter
|
package.loaded[...] = interpreter
|
||||||
eval = require((...):gsub("interpreter$", "expression"))
|
eval = require((...):gsub("interpreter$", "expression"))
|
||||||
local common = require((...):gsub("interpreter$", "common"))
|
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
|
escape = require((...):gsub("interpreter%.interpreter$", "parser.common")).escape
|
||||||
|
|
||||||
return interpreter
|
return interpreter
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,9 @@ TODO: the function decorator feels a bit glued-on to the current syntax
|
||||||
|
|
||||||
TODO: simplify language, it is much too complicated. Less line types? (var def, func, checkpoint, tag). Rewrite some ad hoc syntax using the expression system?
|
TODO: simplify language, it is much too complicated. Less line types? (var def, func, checkpoint, tag). Rewrite some ad hoc syntax using the expression system?
|
||||||
|
|
||||||
TODO: functions/checkpoint: separate from scoping and/or actual functions? with proper scoping & stuff
|
TODO: functions: might be nice to have actual scoping for functions that are called with arguments; to allow proper recursion & stuff (as right now if you call the same function from itself both instances will share variables...). Would require a fair amount of changes to the code though.
|
||||||
|
|
||||||
|
TODO: a way to make loops
|
||||||
|
|
||||||
TODO: fn/checkpoint/tag: maybe consider them a regular func call that takes children as arg; can keep compatibility using $/§ as shortcut for the actual call.
|
TODO: fn/checkpoint/tag: maybe consider them a regular func call that takes children as arg; can keep compatibility using $/§ as shortcut for the actual call.
|
||||||
would allow more flexibility esp. for tags...
|
would allow more flexibility esp. for tags...
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,4 @@
|
||||||
local truthy, anselme, compare, is_of_type, identifier_pattern, format_identifier, find, get_variable
|
local truthy, anselme, compare, is_of_type, identifier_pattern, format_identifier, find, get_variable, mark_as_modified
|
||||||
|
|
||||||
--- mark a table as modified, so it will be merged on the next checkpoint if it appears somewhere in a value
|
|
||||||
local function mark_as_modified(v)
|
|
||||||
local modified = getmetatable(anselme.running.state.variables).modified_tables
|
|
||||||
table.insert(modified, v)
|
|
||||||
end
|
|
||||||
|
|
||||||
local lua_functions
|
local lua_functions
|
||||||
lua_functions = {
|
lua_functions = {
|
||||||
|
|
@ -116,7 +110,7 @@ lua_functions = {
|
||||||
local lv = l.type == "type" and l.value[1] or l
|
local lv = l.type == "type" and l.value[1] or l
|
||||||
local iv = i.type == "type" and i.value[1] or i
|
local iv = i.type == "type" and i.value[1] or i
|
||||||
lv.value[iv.value] = v
|
lv.value[iv.value] = v
|
||||||
mark_as_modified(lv.value)
|
mark_as_modified(anselme.running.state, lv.value)
|
||||||
return v
|
return v
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
|
|
@ -129,7 +123,7 @@ lua_functions = {
|
||||||
for _, x in ipairs(lv.value) do
|
for _, x in ipairs(lv.value) do
|
||||||
if x.type == "pair" and compare(x.value[1], kv) then
|
if x.type == "pair" and compare(x.value[1], kv) then
|
||||||
x.value[2] = v
|
x.value[2] = v
|
||||||
mark_as_modified(x.value)
|
mark_as_modified(anselme.running.state, x.value)
|
||||||
return v
|
return v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -138,7 +132,7 @@ lua_functions = {
|
||||||
type = "pair",
|
type = "pair",
|
||||||
value = { kv, v }
|
value = { kv, v }
|
||||||
})
|
})
|
||||||
mark_as_modified(lv.value)
|
mark_as_modified(anselme.running.state, lv.value)
|
||||||
return v
|
return v
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
|
|
@ -151,7 +145,7 @@ lua_functions = {
|
||||||
["_!(fn::variable reference)"] = {
|
["_!(fn::variable reference)"] = {
|
||||||
mode = "untyped raw",
|
mode = "untyped raw",
|
||||||
value = function(v)
|
value = function(v)
|
||||||
return anselme.running.state.variables[v.value]
|
return get_variable(anselme.running.state, v.value)
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
-- format
|
-- format
|
||||||
|
|
@ -226,7 +220,7 @@ lua_functions = {
|
||||||
value = function(l, v)
|
value = function(l, v)
|
||||||
local lv = l.type == "type" and l.value[1] or l
|
local lv = l.type == "type" and l.value[1] or l
|
||||||
table.insert(lv.value, v)
|
table.insert(lv.value, v)
|
||||||
mark_as_modified(lv.value)
|
mark_as_modified(anselme.running.state, lv.value)
|
||||||
return l
|
return l
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
|
|
@ -236,21 +230,21 @@ lua_functions = {
|
||||||
local lv = l.type == "type" and l.value[1] or l
|
local lv = l.type == "type" and l.value[1] or l
|
||||||
local iv = i.type == "type" and i.value[1] or i
|
local iv = i.type == "type" and i.value[1] or i
|
||||||
table.insert(lv.value, iv.value, v)
|
table.insert(lv.value, iv.value, v)
|
||||||
mark_as_modified(lv.value)
|
mark_as_modified(anselme.running.state, lv.value)
|
||||||
return l
|
return l
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
["remove(l::list)"] = {
|
["remove(l::list)"] = {
|
||||||
mode = "untyped raw",
|
mode = "untyped raw",
|
||||||
value = function(l)
|
value = function(l)
|
||||||
mark_as_modified(l.value)
|
mark_as_modified(anselme.running.state, l.value)
|
||||||
return table.remove(l.value)
|
return table.remove(l.value)
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
["remove(l::list, i::number)"] = {
|
["remove(l::list, i::number)"] = {
|
||||||
mode = "untyped raw",
|
mode = "untyped raw",
|
||||||
value = function(l, i)
|
value = function(l, i)
|
||||||
mark_as_modified(l.value)
|
mark_as_modified(anselme.running.state, l.value)
|
||||||
return table.remove(l.value, i.value)
|
return table.remove(l.value, i.value)
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
|
|
@ -337,7 +331,7 @@ local functions = {
|
||||||
|
|
||||||
package.loaded[...] = functions
|
package.loaded[...] = functions
|
||||||
local icommon = require((...):gsub("stdlib%.functions$", "interpreter.common"))
|
local icommon = require((...):gsub("stdlib%.functions$", "interpreter.common"))
|
||||||
truthy, compare, is_of_type, get_variable = icommon.truthy, icommon.compare, icommon.is_of_type, icommon.get_variable
|
truthy, compare, is_of_type, get_variable, mark_as_modified = icommon.truthy, icommon.compare, icommon.is_of_type, icommon.get_variable, icommon.mark_as_modified
|
||||||
local pcommon = require((...):gsub("stdlib%.functions$", "parser.common"))
|
local pcommon = require((...):gsub("stdlib%.functions$", "parser.common"))
|
||||||
identifier_pattern, format_identifier, find = pcommon.identifier_pattern, pcommon.format_identifier, pcommon.find
|
identifier_pattern, format_identifier, find = pcommon.identifier_pattern, pcommon.format_identifier, pcommon.find
|
||||||
anselme = require((...):gsub("stdlib%.functions$", "anselme"))
|
anselme = require((...):gsub("stdlib%.functions$", "anselme"))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue