1
0
Fork 0
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:
Étienne Fildadut 2021-04-12 01:58:10 +02:00
parent b9c6d1d704
commit 5c3e9d2c5d
5 changed files with 134 additions and 30 deletions

View file

@ -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 {},
}
},

View file

@ -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

View file

@ -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:")

View file

@ -0,0 +1,16 @@
$ f
# 42
> a
b
~ f
> c
~ choose(1)
# "k":"v"
~ f
> d
~ choose(1)
e
f

View 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" }
]]--