mirror of
https://github.com/Reuh/anselme.git
synced 2025-10-27 08:39:30 +00:00
Preserve tags in choices children
This commit is contained in:
parent
b9c6d1d704
commit
5c3e9d2c5d
5 changed files with 134 additions and 30 deletions
13
anselme.lua
13
anselme.lua
|
|
@ -337,21 +337,22 @@ local vm_mt = {
|
|||
functions = self.state.functions,
|
||||
variables = setmetatable({}, { __index = self.state.variables }),
|
||||
interpreter = {
|
||||
-- constant
|
||||
global_state = self.state,
|
||||
coroutine = coroutine.create(function() return "return", interpreter:run(expr, namespace) end),
|
||||
-- status
|
||||
running_line = nil,
|
||||
-- events
|
||||
event_type = nil,
|
||||
event_buffer = nil,
|
||||
-- skip next choices until next event change (to skip currently running choice block when resuming from a paragraph)
|
||||
skip_choices_until_flush = nil,
|
||||
-- status
|
||||
running_line = nil,
|
||||
-- choice
|
||||
-- choice event
|
||||
choice_selected = nil,
|
||||
choice_available = {},
|
||||
-- skip next choices until next event change (to skip currently running choice block when resuming from a paragraph)
|
||||
skip_choices_until_flush = nil,
|
||||
-- interrupt
|
||||
interrupt = nil,
|
||||
-- tags
|
||||
-- tag stack
|
||||
tags = tags or {},
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,17 +1,6 @@
|
|||
local eval
|
||||
local truthy, flush_state, to_lua, eval_text
|
||||
|
||||
local function write_event(state, type, data)
|
||||
if state.interpreter.event_buffer and state.interpreter.event_type ~= type then
|
||||
error(("previous event of type %q has not been flushed, can't write new %q event"):format(state.interpreter.event_type, type))
|
||||
end
|
||||
if not state.interpreter.event_buffer then
|
||||
state.interpreter.event_type = type
|
||||
state.interpreter.event_buffer = {}
|
||||
end
|
||||
table.insert(state.interpreter.event_buffer, { data = data, tags = state.interpreter.tags[#state.interpreter.tags] or {} })
|
||||
end
|
||||
|
||||
local tags = {
|
||||
push = function(self, state, val)
|
||||
local new = {}
|
||||
|
|
@ -26,9 +15,26 @@ local tags = {
|
|||
end,
|
||||
pop = function(self, state)
|
||||
table.remove(state.interpreter.tags)
|
||||
end,
|
||||
current = function(self, state)
|
||||
return state.interpreter.tags[#state.interpreter.tags] or {}
|
||||
end,
|
||||
push_ignore_past = function(self, state, tags)
|
||||
table.insert(state.interpreter.tags, tags)
|
||||
end
|
||||
}
|
||||
|
||||
local function write_event(state, type, data)
|
||||
if state.interpreter.event_buffer and state.interpreter.event_type ~= type then
|
||||
error(("previous event of type %q has not been flushed, can't write new %q event"):format(state.interpreter.event_type, type))
|
||||
end
|
||||
if not state.interpreter.event_buffer then
|
||||
state.interpreter.event_type = type
|
||||
state.interpreter.event_buffer = {}
|
||||
end
|
||||
table.insert(state.interpreter.event_buffer, { data = data, tags = tags:current(state) })
|
||||
end
|
||||
|
||||
local run_block
|
||||
|
||||
-- returns var in case of success and there is a return
|
||||
|
|
@ -82,7 +88,10 @@ local function run_line(state, line)
|
|||
elseif line.type == "choice" then
|
||||
local t, er = eval_text(state, line.text)
|
||||
if not t then return t, er end
|
||||
table.insert(state.interpreter.choice_available, line.child)
|
||||
table.insert(state.interpreter.choice_available, {
|
||||
tags = tags:current(state),
|
||||
block = line.child
|
||||
})
|
||||
write_event(state, "choice", t)
|
||||
elseif line.type == "tag" then
|
||||
if line.expression then
|
||||
|
|
@ -118,7 +127,9 @@ local function run_line(state, line)
|
|||
else
|
||||
local choice = state.interpreter.choice_available[sel]
|
||||
state.interpreter.choice_available = {}
|
||||
local v, e = run_block(state, choice)
|
||||
tags:push_ignore_past(state, choice.tags)
|
||||
local v, e = run_block(state, choice.block)
|
||||
tags:pop(state)
|
||||
if e then return v, e end
|
||||
if v then return v end
|
||||
end
|
||||
|
|
|
|||
29
test/run.lua
29
test/run.lua
|
|
@ -9,7 +9,7 @@ local function format_text(t, prefix)
|
|||
for _, l in ipairs(t) do
|
||||
r = r .. prefix
|
||||
local tags = ""
|
||||
for k, v in ipairs(l.tags) do
|
||||
for k, v in pairs(l.tags) do
|
||||
tags = tags .. ("[%q]=%q"):format(k, v)
|
||||
end
|
||||
if tags ~= "" then
|
||||
|
|
@ -39,6 +39,17 @@ local function compare(a, b)
|
|||
end
|
||||
end
|
||||
|
||||
local function write_result(filebase, result)
|
||||
local o = assert(io.open(filebase..".lua", "w"))
|
||||
o:write(ser(result))
|
||||
o:write("\n--[[\n")
|
||||
for _, v in ipairs(result) do
|
||||
o:write(inspect(v).."\n")
|
||||
end
|
||||
o:write("]]--")
|
||||
o:close()
|
||||
end
|
||||
|
||||
-- parse args
|
||||
local args = {}
|
||||
local i=1
|
||||
|
|
@ -163,15 +174,8 @@ else
|
|||
table.insert(result, { "error", err })
|
||||
end
|
||||
|
||||
if args.write then
|
||||
local o = assert(io.open(filebase..".lua", "w"))
|
||||
o:write(ser(result))
|
||||
o:write("\n--[[\n")
|
||||
for _, v in ipairs(result) do
|
||||
o:write(inspect(v).."\n")
|
||||
end
|
||||
o:write("]]--")
|
||||
o:close()
|
||||
if args["write-all"] then
|
||||
write_result(filebase, result)
|
||||
else
|
||||
local o, e = loadfile(filebase..".lua")
|
||||
if o then
|
||||
|
|
@ -188,7 +192,10 @@ else
|
|||
success = success + 1
|
||||
end
|
||||
else
|
||||
if not args.silent then
|
||||
if args["write-new"] and e:match("No such file") then
|
||||
write_result(filebase, result)
|
||||
print("Written result file for "..filebase)
|
||||
elseif not args.silent then
|
||||
print("> "..namespace)
|
||||
print(e)
|
||||
print("result was:")
|
||||
|
|
|
|||
16
test/tests/choice preserve tags.ans
Normal file
16
test/tests/choice preserve tags.ans
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
$ f
|
||||
# 42
|
||||
> a
|
||||
b
|
||||
|
||||
~ f
|
||||
> c
|
||||
~ choose(1)
|
||||
|
||||
# "k":"v"
|
||||
~ f
|
||||
> d
|
||||
~ choose(1)
|
||||
e
|
||||
|
||||
f
|
||||
69
test/tests/choice preserve tags.lua
Normal file
69
test/tests/choice preserve tags.lua
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
local _={}
|
||||
_[26]={}
|
||||
_[25]={k="v"}
|
||||
_[24]={42,k="v"}
|
||||
_[23]={}
|
||||
_[22]={42}
|
||||
_[21]={tags=_[26],data="f"}
|
||||
_[20]={tags=_[25],data="e"}
|
||||
_[19]={tags=_[24],data="b"}
|
||||
_[18]={tags=_[25],data="d"}
|
||||
_[17]={tags=_[24],data="a"}
|
||||
_[16]={tags=_[22],data="b"}
|
||||
_[15]={tags=_[23],data="c"}
|
||||
_[14]={tags=_[22],data="a"}
|
||||
_[13]={_[21]}
|
||||
_[12]={_[20]}
|
||||
_[11]={_[19]}
|
||||
_[10]={_[17],_[18]}
|
||||
_[9]={_[16]}
|
||||
_[8]={_[14],_[15]}
|
||||
_[7]={"return"}
|
||||
_[6]={"text",_[13]}
|
||||
_[5]={"text",_[12]}
|
||||
_[4]={"text",_[11]}
|
||||
_[3]={"choice",_[10]}
|
||||
_[2]={"text",_[9]}
|
||||
_[1]={"choice",_[8]}
|
||||
return {_[1],_[2],_[3],_[4],_[5],_[6],_[7]}
|
||||
--[[
|
||||
{ "choice", { {
|
||||
data = "a",
|
||||
tags = { 42 }
|
||||
}, {
|
||||
data = "c",
|
||||
tags = {}
|
||||
} } }
|
||||
{ "text", { {
|
||||
data = "b",
|
||||
tags = { 42 }
|
||||
} } }
|
||||
{ "choice", { {
|
||||
data = "a",
|
||||
tags = { 42,
|
||||
k = "v"
|
||||
}
|
||||
}, {
|
||||
data = "d",
|
||||
tags = {
|
||||
k = "v"
|
||||
}
|
||||
} } }
|
||||
{ "text", { {
|
||||
data = "b",
|
||||
tags = { 42,
|
||||
k = "v"
|
||||
}
|
||||
} } }
|
||||
{ "text", { {
|
||||
data = "e",
|
||||
tags = {
|
||||
k = "v"
|
||||
}
|
||||
} } }
|
||||
{ "text", { {
|
||||
data = "f",
|
||||
tags = {}
|
||||
} } }
|
||||
{ "return" }
|
||||
]]--
|
||||
Loading…
Add table
Add a link
Reference in a new issue