mirror of
https://github.com/Reuh/anselme.git
synced 2025-10-27 16:49:31 +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,
|
functions = self.state.functions,
|
||||||
variables = setmetatable({}, { __index = self.state.variables }),
|
variables = setmetatable({}, { __index = self.state.variables }),
|
||||||
interpreter = {
|
interpreter = {
|
||||||
|
-- constant
|
||||||
global_state = self.state,
|
global_state = self.state,
|
||||||
coroutine = coroutine.create(function() return "return", interpreter:run(expr, namespace) end),
|
coroutine = coroutine.create(function() return "return", interpreter:run(expr, namespace) end),
|
||||||
|
-- status
|
||||||
|
running_line = nil,
|
||||||
-- events
|
-- events
|
||||||
event_type = nil,
|
event_type = nil,
|
||||||
event_buffer = nil,
|
event_buffer = nil,
|
||||||
-- skip next choices until next event change (to skip currently running choice block when resuming from a paragraph)
|
-- choice event
|
||||||
skip_choices_until_flush = nil,
|
|
||||||
-- status
|
|
||||||
running_line = nil,
|
|
||||||
-- choice
|
|
||||||
choice_selected = nil,
|
choice_selected = nil,
|
||||||
choice_available = {},
|
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
|
||||||
interrupt = nil,
|
interrupt = nil,
|
||||||
-- tags
|
-- tag stack
|
||||||
tags = tags or {},
|
tags = tags or {},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,6 @@
|
||||||
local eval
|
local eval
|
||||||
local truthy, flush_state, to_lua, eval_text
|
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 = {
|
local tags = {
|
||||||
push = function(self, state, val)
|
push = function(self, state, val)
|
||||||
local new = {}
|
local new = {}
|
||||||
|
|
@ -26,9 +15,26 @@ local tags = {
|
||||||
end,
|
end,
|
||||||
pop = function(self, state)
|
pop = function(self, state)
|
||||||
table.remove(state.interpreter.tags)
|
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
|
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
|
local run_block
|
||||||
|
|
||||||
-- returns var in case of success and there is a return
|
-- 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
|
elseif line.type == "choice" then
|
||||||
local t, er = eval_text(state, line.text)
|
local t, er = eval_text(state, line.text)
|
||||||
if not t then return t, er end
|
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)
|
write_event(state, "choice", t)
|
||||||
elseif line.type == "tag" then
|
elseif line.type == "tag" then
|
||||||
if line.expression then
|
if line.expression then
|
||||||
|
|
@ -118,7 +127,9 @@ local function run_line(state, line)
|
||||||
else
|
else
|
||||||
local choice = state.interpreter.choice_available[sel]
|
local choice = state.interpreter.choice_available[sel]
|
||||||
state.interpreter.choice_available = {}
|
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 e then return v, e end
|
||||||
if v then return v end
|
if v then return v end
|
||||||
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
|
for _, l in ipairs(t) do
|
||||||
r = r .. prefix
|
r = r .. prefix
|
||||||
local tags = ""
|
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)
|
tags = tags .. ("[%q]=%q"):format(k, v)
|
||||||
end
|
end
|
||||||
if tags ~= "" then
|
if tags ~= "" then
|
||||||
|
|
@ -39,6 +39,17 @@ local function compare(a, b)
|
||||||
end
|
end
|
||||||
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
|
-- parse args
|
||||||
local args = {}
|
local args = {}
|
||||||
local i=1
|
local i=1
|
||||||
|
|
@ -163,15 +174,8 @@ else
|
||||||
table.insert(result, { "error", err })
|
table.insert(result, { "error", err })
|
||||||
end
|
end
|
||||||
|
|
||||||
if args.write then
|
if args["write-all"] then
|
||||||
local o = assert(io.open(filebase..".lua", "w"))
|
write_result(filebase, result)
|
||||||
o:write(ser(result))
|
|
||||||
o:write("\n--[[\n")
|
|
||||||
for _, v in ipairs(result) do
|
|
||||||
o:write(inspect(v).."\n")
|
|
||||||
end
|
|
||||||
o:write("]]--")
|
|
||||||
o:close()
|
|
||||||
else
|
else
|
||||||
local o, e = loadfile(filebase..".lua")
|
local o, e = loadfile(filebase..".lua")
|
||||||
if o then
|
if o then
|
||||||
|
|
@ -188,7 +192,10 @@ else
|
||||||
success = success + 1
|
success = success + 1
|
||||||
end
|
end
|
||||||
else
|
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("> "..namespace)
|
||||||
print(e)
|
print(e)
|
||||||
print("result was:")
|
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