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

Merge state on vm:eval, new aliases need to be merged

This commit is contained in:
Étienne Fildadut 2021-12-02 19:24:48 +01:00
parent 721464218c
commit 607313d5ce
3 changed files with 18 additions and 9 deletions

View file

@ -139,6 +139,7 @@ local interpreter_methods = {
end,
--- run an expression or block: may trigger events and must be called from within the interpreter coroutine
-- no automatic merge if this change the interpreter state, merge is done once we reach end of script in a call to :step as usual
-- return lua value (nil if nothing returned)
run = function(self, expr, namespace)
-- check status
@ -165,7 +166,9 @@ local interpreter_methods = {
return to_lua(r)
end,
--- evaluate an expression or block
-- can be called from outside the coroutine
-- can be called from outside the coroutine. Will create a new coroutine that operate on this interpreter state.
-- no automatic merge if this change the interpreter state, merge is done once we reach end of script in a call to :step as usual
-- the expression can't yield events
-- return value in case of success (nil if nothing returned)
-- return nil, err in case of error
eval = function(self, expr, namespace)
@ -469,8 +472,8 @@ local vm_mt = {
state = {
feature_flags = self.state.feature_flags,
builtin_aliases = self.state.builtin_aliases,
aliases = self.state.aliases,
functions = self.state.functions,
aliases = setmetatable({}, { __index = self.state.aliases }),
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({}, { __index = self.state.variables }),
interpreter = {
-- constant
@ -497,8 +500,8 @@ local vm_mt = {
return setmetatable(interpreter, interpreter_methods)
end,
--- eval code
-- unlike :run, this does not support events and will return the result of the expression directly.
-- does not merge state after execution automatically
-- behave like :run, except the expression can not emit events and will return the result of the expression directly.
-- merge state after sucessful execution automatically like :run
-- expr: expression to evaluate (string or parsed expression), or a block to evaluate
-- namespace(default=""): namespace to evaluate the expression in
-- tags(default={}): defaults tag when evaluating the expression
@ -507,7 +510,10 @@ local vm_mt = {
eval = function(self, expr, namespace, tags)
local interpreter, err = self:run("()", namespace, tags)
if not interpreter then return interpreter, err end
return interpreter:eval(expr, namespace)
local r, e = interpreter:eval(expr, namespace)
if e then return r, e end
assert(interpreter:step() == "return") -- trigger merge / end-of-script things
return r
end
}
vm_mt.__index = vm_mt

View file

@ -32,9 +32,13 @@ local common
common = {
--- merge interpreter state with global state
merge_state = function(state)
local global_vars = state.interpreter.global_state.variables
local global = state.interpreter.global_state
for alias, fqm in pairs(state.aliases) do
global.aliases[alias] = fqm
state.aliases[alias] = nil
end
for var, value in pairs(state.variables) do
global_vars[var] = value
global.variables[var] = value
state.variables[var] = nil
end
end,

View file

@ -125,7 +125,6 @@ functions = {
end
},
-- alias
-- TODO: currently directly change global state, should new aliases be kept in case of interpreter error before a merge?
["alias(identifier::string, alias::string)"] = {
value = function(identifier, alias)
-- check identifiers