mirror of
https://github.com/Reuh/anselme.git
synced 2025-10-27 08:39:30 +00:00
[api] allow adding tags when running/evaluating
This commit is contained in:
parent
ed7fe34853
commit
876135401c
3 changed files with 39 additions and 26 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
local expression_to_ast = require("anselme.parser.expression.to_ast")
|
local expression_to_ast = require("anselme.parser.expression.to_ast")
|
||||||
|
|
||||||
|
local utf8 = utf8 or require("lua-utf8")
|
||||||
local ast = require("anselme.ast")
|
local ast = require("anselme.ast")
|
||||||
local PartialScope, Block, Call, Identifier = ast.PartialScope, ast.Block, ast.Call, ast.Identifier
|
local PartialScope, Block, Call, Identifier = ast.PartialScope, ast.Block, ast.Call, ast.Identifier
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,11 @@ local tag_manager = require("anselme.state.tag_manager")
|
||||||
local event_manager = require("anselme.state.event_manager")
|
local event_manager = require("anselme.state.event_manager")
|
||||||
local translation_manager = require("anselme.state.translation_manager")
|
local translation_manager = require("anselme.state.translation_manager")
|
||||||
local persistent_manager = require("anselme.state.persistent_manager")
|
local persistent_manager = require("anselme.state.persistent_manager")
|
||||||
local uuid = require("anselme.common").uuid
|
|
||||||
local parser = require("anselme.parser")
|
local parser = require("anselme.parser")
|
||||||
local binser = require("anselme.lib.binser")
|
local binser = require("anselme.lib.binser")
|
||||||
local assert0 = require("anselme.common").assert0
|
local common = require("anselme.common")
|
||||||
local operator_priority = require("anselme.common").operator_priority
|
local uuid, assert0, operator_priority = common.uuid, common.assert0, common.operator_priority
|
||||||
|
local to_anselme = require("anselme.common.to_anselme")
|
||||||
local anselme
|
local anselme
|
||||||
local Identifier, Return, Node
|
local Identifier, Return, Node
|
||||||
|
|
||||||
|
|
@ -178,12 +178,13 @@ State = class {
|
||||||
--- Load a script in this branch. It will become the active script.
|
--- Load a script in this branch. It will become the active script.
|
||||||
--
|
--
|
||||||
-- `code` is the code string or AST to run. If `code` is a string, `source` is the source name string to show in errors (optional).
|
-- `code` is the code string or AST to run. If `code` is a string, `source` is the source name string to show in errors (optional).
|
||||||
|
-- `tags` is an optional Lua table; its content will be added to the tags for the duration of the script.
|
||||||
--
|
--
|
||||||
-- Note that this will only load the script; execution will only start by using the `:step` method. Will error if a script is already active in this State.
|
-- Note that this will only load the script; execution will only start by using the `:step` method. Will error if a script is already active in this State.
|
||||||
run = function(self, code, source)
|
run = function(self, code, source, tags)
|
||||||
assert(not self:active(), "a script is already active")
|
assert(not self:active(), "a script is already active")
|
||||||
self._coroutine = coroutine.create(function()
|
self._coroutine = coroutine.create(function()
|
||||||
local r = assert0(self:eval_local(code, source))
|
local r = assert0(self:eval_local(code, source, tags))
|
||||||
event_manager:complete_flush(self)
|
event_manager:complete_flush(self)
|
||||||
if Return:is(r) then r = r.expression end
|
if Return:is(r) then r = r.expression end
|
||||||
return "return", r
|
return "return", r
|
||||||
|
|
@ -191,11 +192,11 @@ State = class {
|
||||||
end,
|
end,
|
||||||
--- Same as `:run`, but read the code from a file.
|
--- Same as `:run`, but read the code from a file.
|
||||||
-- `source` will be set as the file path.
|
-- `source` will be set as the file path.
|
||||||
run_file = function(self, path)
|
run_file = function(self, path, tags)
|
||||||
local f = assert(io.open(path, "r"))
|
local f = assert(io.open(path, "r"))
|
||||||
local block = parser(f:read("a"), path)
|
local block = parser(f:read("a"), path)
|
||||||
f:close()
|
f:close()
|
||||||
return self:run(block)
|
return self:run(block, nil, tags)
|
||||||
end,
|
end,
|
||||||
--- When a script is active, will resume running it until the next event.
|
--- When a script is active, will resume running it until the next event.
|
||||||
--
|
--
|
||||||
|
|
@ -218,16 +219,17 @@ State = class {
|
||||||
--
|
--
|
||||||
-- Will error if no script is active.
|
-- Will error if no script is active.
|
||||||
--
|
--
|
||||||
-- If `code` is given, the script will not be disabled but instead will be immediately replaced with this new script.
|
-- `code`, `source` and `tags` are all optional and have the same behaviour as in `:run`.
|
||||||
|
-- If they are given, the script will not be disabled but instead will be immediately replaced with this new script.
|
||||||
-- The new script will then be started on the next `:step` and will preserve the current scope. This can be used to trigger an exit function or similar in the active script.
|
-- The new script will then be started on the next `:step` and will preserve the current scope. This can be used to trigger an exit function or similar in the active script.
|
||||||
--
|
--
|
||||||
-- If this is called from within a running script, this will raise an `interrupt` event in order to stop the current script execution.
|
-- If this is called from within a running script, this will raise an `interrupt` event in order to stop the current script execution.
|
||||||
interrupt = function(self, code, source)
|
interrupt = function(self, code, source, tags)
|
||||||
assert(self:active(), "trying to interrupt but no script is currently active")
|
assert(self:active(), "trying to interrupt but no script is currently active")
|
||||||
local called_from_script = self:state() == "running"
|
local called_from_script = self:state() == "running"
|
||||||
if code then
|
if code then
|
||||||
self._coroutine = coroutine.create(function()
|
self._coroutine = coroutine.create(function()
|
||||||
local r = assert0(self:eval_local(code, source))
|
local r = assert0(self:eval_local(code, source, tags))
|
||||||
event_manager:complete_flush(self)
|
event_manager:complete_flush(self)
|
||||||
self.scope:reset() -- scope stack is probably messed up after the switch
|
self.scope:reset() -- scope stack is probably messed up after the switch
|
||||||
if Return:is(r) then r = r.expression end
|
if Return:is(r) then r = r.expression end
|
||||||
|
|
@ -244,19 +246,24 @@ State = class {
|
||||||
--
|
--
|
||||||
-- This can be called from outside a running script, but an error will be triggered the expression raise any event other than return.
|
-- This can be called from outside a running script, but an error will be triggered the expression raise any event other than return.
|
||||||
--
|
--
|
||||||
|
-- `code` is the code string or AST to run. If `code` is a string, `source` is the source name string to show in errors (optional).
|
||||||
|
-- `tags` is an optional Lua table; its content will be added to the tags for the duration of the expression.
|
||||||
|
--
|
||||||
-- * returns AST in case of success. Run `:to_lua(state)` on it to convert to a Lua value.
|
-- * returns AST in case of success. Run `:to_lua(state)` on it to convert to a Lua value.
|
||||||
-- * returns `nil, error message` in case of error.
|
-- * returns `nil, error message` in case of error.
|
||||||
eval = function(self, code, source)
|
eval = function(self, code, source, tags)
|
||||||
self.scope:push_global()
|
self.scope:push_global()
|
||||||
local r, e = self:eval_local(code, source)
|
local r, e = self:eval_local(code, source, tags)
|
||||||
self.scope:pop()
|
self.scope:pop()
|
||||||
return r, e
|
return r, e
|
||||||
end,
|
end,
|
||||||
--- Same as `:eval`, but evaluate the expression in the current scope.
|
--- Same as `:eval`, but evaluate the expression in the current scope.
|
||||||
eval_local = function(self, code, source)
|
eval_local = function(self, code, source, tags)
|
||||||
if type(code) == "string" then code = parser(code, source) end
|
if type(code) == "string" then code = parser(code, source) end
|
||||||
local stack_size = self.scope:size()
|
local stack_size = self.scope:size()
|
||||||
|
if tags then tag_manager:push(self, to_anselme(tags)) end
|
||||||
local s, e = pcall(code.eval, code, self)
|
local s, e = pcall(code.eval, code, self)
|
||||||
|
if tags then tag_manager:pop(self) end
|
||||||
if not s then
|
if not s then
|
||||||
self.scope:reset(stack_size)
|
self.scope:reset(stack_size)
|
||||||
return nil, e
|
return nil, e
|
||||||
|
|
|
||||||
31
doc/api.md
31
doc/api.md
|
|
@ -249,22 +249,23 @@ Returns `"inactive"` if no script is loaded.
|
||||||
|
|
||||||
_defined at line 171 of [anselme/state/State.lua](../anselme/state/State.lua):_ `state = function(self)`
|
_defined at line 171 of [anselme/state/State.lua](../anselme/state/State.lua):_ `state = function(self)`
|
||||||
|
|
||||||
### :run (code, source)
|
### :run (code, source, tags)
|
||||||
|
|
||||||
Load a script in this branch. It will become the active script.
|
Load a script in this branch. It will become the active script.
|
||||||
|
|
||||||
`code` is the code string or AST to run. If `code` is a string, `source` is the source name string to show in errors (optional).
|
`code` is the code string or AST to run. If `code` is a string, `source` is the source name string to show in errors (optional).
|
||||||
|
`tags` is an optional Lua table; its content will be added to the tags for the duration of the script.
|
||||||
|
|
||||||
Note that this will only load the script; execution will only start by using the `:step` method. Will error if a script is already active in this State.
|
Note that this will only load the script; execution will only start by using the `:step` method. Will error if a script is already active in this State.
|
||||||
|
|
||||||
_defined at line 183 of [anselme/state/State.lua](../anselme/state/State.lua):_ `run = function(self, code, source)`
|
_defined at line 184 of [anselme/state/State.lua](../anselme/state/State.lua):_ `run = function(self, code, source, tags)`
|
||||||
|
|
||||||
### :run_file (path)
|
### :run_file (path, tags)
|
||||||
|
|
||||||
Same as `:run`, but read the code from a file.
|
Same as `:run`, but read the code from a file.
|
||||||
`source` will be set as the file path.
|
`source` will be set as the file path.
|
||||||
|
|
||||||
_defined at line 194 of [anselme/state/State.lua](../anselme/state/State.lua):_ `run_file = function(self, path)`
|
_defined at line 195 of [anselme/state/State.lua](../anselme/state/State.lua):_ `run_file = function(self, path, tags)`
|
||||||
|
|
||||||
### :step ()
|
### :step ()
|
||||||
|
|
||||||
|
|
@ -274,37 +275,41 @@ Will error if no script is active.
|
||||||
|
|
||||||
Returns `event type string, event data`.
|
Returns `event type string, event data`.
|
||||||
|
|
||||||
_defined at line 205 of [anselme/state/State.lua](../anselme/state/State.lua):_ `step = function(self)`
|
_defined at line 206 of [anselme/state/State.lua](../anselme/state/State.lua):_ `step = function(self)`
|
||||||
|
|
||||||
### :interrupt (code, source)
|
### :interrupt (code, source, tags)
|
||||||
|
|
||||||
Stops the currently active script.
|
Stops the currently active script.
|
||||||
|
|
||||||
Will error if no script is active.
|
Will error if no script is active.
|
||||||
|
|
||||||
If `code` is given, the script will not be disabled but instead will be immediately replaced with this new script.
|
`code`, `source` and `tags` are all optional and have the same behaviour as in `:run`.
|
||||||
|
If they are given, the script will not be disabled but instead will be immediately replaced with this new script.
|
||||||
The new script will then be started on the next `:step` and will preserve the current scope. This can be used to trigger an exit function or similar in the active script.
|
The new script will then be started on the next `:step` and will preserve the current scope. This can be used to trigger an exit function or similar in the active script.
|
||||||
|
|
||||||
If this is called from within a running script, this will raise an `interrupt` event in order to stop the current script execution.
|
If this is called from within a running script, this will raise an `interrupt` event in order to stop the current script execution.
|
||||||
|
|
||||||
_defined at line 225 of [anselme/state/State.lua](../anselme/state/State.lua):_ `interrupt = function(self, code, source)`
|
_defined at line 227 of [anselme/state/State.lua](../anselme/state/State.lua):_ `interrupt = function(self, code, source, tags)`
|
||||||
|
|
||||||
### :eval (code, source)
|
### :eval (code, source, tags)
|
||||||
|
|
||||||
Evaluate an expression in the global scope.
|
Evaluate an expression in the global scope.
|
||||||
|
|
||||||
This can be called from outside a running script, but an error will be triggered the expression raise any event other than return.
|
This can be called from outside a running script, but an error will be triggered the expression raise any event other than return.
|
||||||
|
|
||||||
|
`code` is the code string or AST to run. If `code` is a string, `source` is the source name string to show in errors (optional).
|
||||||
|
`tags` is an optional Lua table; its content will be added to the tags for the duration of the expression.
|
||||||
|
|
||||||
* returns AST in case of success. Run `:to_lua(state)` on it to convert to a Lua value.
|
* returns AST in case of success. Run `:to_lua(state)` on it to convert to a Lua value.
|
||||||
* returns `nil, error message` in case of error.
|
* returns `nil, error message` in case of error.
|
||||||
|
|
||||||
_defined at line 249 of [anselme/state/State.lua](../anselme/state/State.lua):_ `eval = function(self, code, source)`
|
_defined at line 254 of [anselme/state/State.lua](../anselme/state/State.lua):_ `eval = function(self, code, source, tags)`
|
||||||
|
|
||||||
### :eval_local (code, source)
|
### :eval_local (code, source, tags)
|
||||||
|
|
||||||
Same as `:eval`, but evaluate the expression in the current scope.
|
Same as `:eval`, but evaluate the expression in the current scope.
|
||||||
|
|
||||||
_defined at line 256 of [anselme/state/State.lua](../anselme/state/State.lua):_ `eval_local = function(self, code, source)`
|
_defined at line 261 of [anselme/state/State.lua](../anselme/state/State.lua):_ `eval_local = function(self, code, source, tags)`
|
||||||
|
|
||||||
If you want to perform more advanced manipulation of the resulting AST nodes, look at the `ast` modules.
|
If you want to perform more advanced manipulation of the resulting AST nodes, look at the `ast` modules.
|
||||||
In particular, every Node inherits the methods from [ast.abstract.Node](../ast/abstract/Node.lua).
|
In particular, every Node inherits the methods from [ast.abstract.Node](../ast/abstract/Node.lua).
|
||||||
|
|
@ -312,4 +317,4 @@ Otherwise, each Node has its own module file defined in the [ast/](../ast) direc
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
_file generated at 2024-11-09T17:00:43Z_
|
_file generated at 2024-11-11T09:22:49Z_
|
||||||
Loading…
Add table
Add a link
Reference in a new issue