mirror of
https://github.com/Reuh/anselme.git
synced 2025-10-27 16:49:31 +00:00
Prevent from restarting interpreter after return or error
This commit is contained in:
parent
c847fefd39
commit
633f7b2d61
3 changed files with 17 additions and 5 deletions
17
anselme.lua
17
anselme.lua
|
|
@ -66,12 +66,17 @@ local interpreter_methods = {
|
||||||
state = nil,
|
state = nil,
|
||||||
-- VM this interpreter belongs to
|
-- VM this interpreter belongs to
|
||||||
vm = nil,
|
vm = nil,
|
||||||
|
-- event that stopped the interpreter
|
||||||
|
end_event = nil,
|
||||||
|
|
||||||
--- run the VM until the next event
|
--- run the VM until the next event
|
||||||
-- will merge changed variables on successful script end
|
-- will merge changed variables on successful script end
|
||||||
-- returns event, data; if event is "return" or "error", the interpreter must not be stepped further
|
-- returns event, data; if event is "return" or "error", the interpreter can not be stepped further
|
||||||
step = function(self)
|
step = function(self)
|
||||||
-- check status
|
-- check status
|
||||||
|
if self.end_event then
|
||||||
|
return "error", ("interpreter can't be restarted after receiving a %s event"):format(self.end_event)
|
||||||
|
end
|
||||||
if coroutine.status(self.state.interpreter.coroutine) ~= "suspended" then
|
if coroutine.status(self.state.interpreter.coroutine) ~= "suspended" then
|
||||||
return "error", ("can't step interpreter because it has already finished or is already running (coroutine status: %s)"):format(coroutine.status(self.state.interpreter.coroutine))
|
return "error", ("can't step interpreter because it has already finished or is already running (coroutine status: %s)"):format(coroutine.status(self.state.interpreter.coroutine))
|
||||||
end
|
end
|
||||||
|
|
@ -96,8 +101,9 @@ local interpreter_methods = {
|
||||||
anselme.running = self
|
anselme.running = self
|
||||||
local success, event, data = coroutine.resume(self.state.interpreter.coroutine)
|
local success, event, data = coroutine.resume(self.state.interpreter.coroutine)
|
||||||
anselme.running = previous
|
anselme.running = previous
|
||||||
if not success then return "error", event end
|
if not success then event, data = "error", event end
|
||||||
if event == "return" then merge_state(self.state) end
|
if event == "return" then merge_state(self.state) end
|
||||||
|
if event == "return" or event == "error" then self.end_event = event end
|
||||||
return event, data
|
return event, data
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
|
@ -135,6 +141,10 @@ local interpreter_methods = {
|
||||||
--- run an expression or block: may trigger events and must be called from within the interpreter coroutine
|
--- run an expression or block: may trigger events and must be called from within the interpreter coroutine
|
||||||
-- return lua value (nil if nothing returned)
|
-- return lua value (nil if nothing returned)
|
||||||
run = function(self, expr, namespace)
|
run = function(self, expr, namespace)
|
||||||
|
-- check status
|
||||||
|
if coroutine.status(self.state.interpreter.coroutine) ~= "running" then
|
||||||
|
error("run must be called from whithin the interpreter coroutine")
|
||||||
|
end
|
||||||
-- parse
|
-- parse
|
||||||
local err
|
local err
|
||||||
if type(expr) ~= "table" then expr, err = expression(tostring(expr), self.state.interpreter.global_state, namespace or "") end
|
if type(expr) ~= "table" then expr, err = expression(tostring(expr), self.state.interpreter.global_state, namespace or "") end
|
||||||
|
|
@ -159,6 +169,9 @@ local interpreter_methods = {
|
||||||
-- return value in case of success (nil if nothing returned)
|
-- return value in case of success (nil if nothing returned)
|
||||||
-- return nil, err in case of error
|
-- return nil, err in case of error
|
||||||
eval = function(self, expr, namespace)
|
eval = function(self, expr, namespace)
|
||||||
|
if self.end_event then
|
||||||
|
return "error", ("interpreter can't be restarted after receiving a %s event"):format(self.end_event)
|
||||||
|
end
|
||||||
-- parse
|
-- parse
|
||||||
local err
|
local err
|
||||||
if type(expr) ~= "table" then expr, err = expression(tostring(expr), self.state.interpreter.global_state, namespace or "") end
|
if type(expr) ~= "table" then expr, err = expression(tostring(expr), self.state.interpreter.global_state, namespace or "") end
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ Reserved symbols that are still not used as a line type: `^+-=</[]*{}|\_!?.,;)"&
|
||||||
|
|
||||||
TODO: test reacheability of script paths
|
TODO: test reacheability of script paths
|
||||||
|
|
||||||
TODO: redisign the checkpoint system to work better when used with parallel scripts (as they will rewrite each other's variables)
|
TODO: redisign the checkpoint system to work better when used with parallel scripts (if both change the same variable, will be overwritten)
|
||||||
|
|
||||||
TODO: redisign a static type checking system
|
TODO: redisign a static type checking system
|
||||||
If we want to go full gradual typing, it would help to:
|
If we want to go full gradual typing, it would help to:
|
||||||
|
|
@ -55,5 +55,3 @@ Advantages:
|
||||||
Disadvantages:
|
Disadvantages:
|
||||||
* idk if it's worth the trouble
|
* idk if it's worth the trouble
|
||||||
* could do something like `$ ()(l::list(?), i::number)::?`, but then can't return nil on not found...
|
* could do something like `$ ()(l::list(?), i::number)::?`, but then can't return nil on not found...
|
||||||
|
|
||||||
TODO: ensure that most stuff in the state stays consistent after an error was thrown
|
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,7 @@ functions = {
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
-- alias
|
-- alias
|
||||||
|
-- TODO: directly change global state, should new aliases be kept in case of interpreter error before a merge?
|
||||||
["alias(identifier::string, alias::string)"] = {
|
["alias(identifier::string, alias::string)"] = {
|
||||||
value = function(identifier, alias)
|
value = function(identifier, alias)
|
||||||
-- check identifiers
|
-- check identifiers
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue