mirror of
https://github.com/Reuh/anselme.git
synced 2025-10-27 16:49:31 +00:00
Add text buffer syntax
This commit is contained in:
parent
ccaa40a99d
commit
e9606cdee0
13 changed files with 345 additions and 145 deletions
|
|
@ -5,49 +5,6 @@ local common
|
|||
local identifier_pattern
|
||||
local copy
|
||||
|
||||
--- copy some text & process it to be suited to be sent to Lua in an event
|
||||
local function post_process_text(state, text)
|
||||
local r = {}
|
||||
-- copy into r & convert tags to lua
|
||||
for _, t in ipairs(text) do
|
||||
local tags = common.to_lua(t.tags)
|
||||
if state.interpreter.base_lua_tags then
|
||||
for k, v in pairs(state.interpreter.base_lua_tags) do
|
||||
if tags[k] == nil then tags[k] = v end
|
||||
end
|
||||
end
|
||||
table.insert(r, {
|
||||
text = t.text,
|
||||
tags = tags
|
||||
})
|
||||
end
|
||||
-- remove trailing spaces
|
||||
if state.feature_flags["strip trailing spaces"] then
|
||||
local final = r[#r]
|
||||
if final then
|
||||
final.text = final.text:match("^(.-) *$")
|
||||
if final.text == "" then
|
||||
table.remove(r)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- remove duplicate spaces
|
||||
if state.feature_flags["strip duplicate spaces"] then
|
||||
for i=1, #r-1 do
|
||||
local a, b = r[i], r[i+1]
|
||||
local na = #a.text:match(" *$")
|
||||
local nb = #b.text:match("^ *")
|
||||
if na > 0 and nb > 0 then -- remove duplicated spaces from second element first
|
||||
b.text = b.text:match("^ *(.-)$")
|
||||
end
|
||||
if na > 1 then
|
||||
a.text = a.text:match("^(.- ) *$")
|
||||
end
|
||||
end
|
||||
end
|
||||
return r
|
||||
end
|
||||
|
||||
local function random_identifier()
|
||||
local r = ""
|
||||
for _=1, 16 do -- that's live 10^31 possibilities, ought to be enough for anyone
|
||||
|
|
@ -383,9 +340,9 @@ common = {
|
|||
--- convert anselme value to lua
|
||||
-- lua value: if success (may be nil!)
|
||||
-- nil, err: if error
|
||||
to_lua = function(val)
|
||||
to_lua = function(val, state)
|
||||
if atypes[val.type] and atypes[val.type].to_lua then
|
||||
return atypes[val.type].to_lua(val.value)
|
||||
return atypes[val.type].to_lua(val.value, state)
|
||||
else
|
||||
return nil, ("no Lua exporter for type %q"):format(val.type)
|
||||
end
|
||||
|
|
@ -598,14 +555,14 @@ common = {
|
|||
local choices
|
||||
-- copy & process text buffer
|
||||
if type == "text" then
|
||||
buffer = post_process_text(state, event.value)
|
||||
buffer = common.post_process_text(state, event.value)
|
||||
-- copy & process choice buffer
|
||||
elseif type == "choice" then
|
||||
-- copy & process choice text content into buffer, and needed private state into choices for each choice
|
||||
buffer = {}
|
||||
choices = {}
|
||||
for _, c in ipairs(event.value) do
|
||||
table.insert(buffer, post_process_text(state, c))
|
||||
table.insert(buffer, common.post_process_text(state, c))
|
||||
table.insert(choices, c._state)
|
||||
end
|
||||
-- discard empty choices
|
||||
|
|
@ -647,7 +604,49 @@ common = {
|
|||
end
|
||||
return true
|
||||
end
|
||||
}
|
||||
},
|
||||
--- copy some text & process it to be suited to be sent to Lua in an event
|
||||
post_process_text = function(state, text)
|
||||
local r = {}
|
||||
-- copy into r & convert tags to lua
|
||||
for _, t in ipairs(text) do
|
||||
local tags = common.to_lua(t.tags, state)
|
||||
if state.interpreter.base_lua_tags then
|
||||
for k, v in pairs(state.interpreter.base_lua_tags) do
|
||||
if tags[k] == nil then tags[k] = v end
|
||||
end
|
||||
end
|
||||
table.insert(r, {
|
||||
text = t.text,
|
||||
tags = tags
|
||||
})
|
||||
end
|
||||
-- remove trailing spaces
|
||||
if state.feature_flags["strip trailing spaces"] then
|
||||
local final = r[#r]
|
||||
if final then
|
||||
final.text = final.text:match("^(.-) *$")
|
||||
if final.text == "" then
|
||||
table.remove(r)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- remove duplicate spaces
|
||||
if state.feature_flags["strip duplicate spaces"] then
|
||||
for i=1, #r-1 do
|
||||
local a, b = r[i], r[i+1]
|
||||
local na = #a.text:match(" *$")
|
||||
local nb = #b.text:match("^ *")
|
||||
if na > 0 and nb > 0 then -- remove duplicated spaces from second element first
|
||||
b.text = b.text:match("^ *(.-)$")
|
||||
end
|
||||
if na > 1 then
|
||||
a.text = a.text:match("^(.- ) *$")
|
||||
end
|
||||
end
|
||||
end
|
||||
return r
|
||||
end
|
||||
}
|
||||
|
||||
package.loaded[...] = common
|
||||
|
|
|
|||
|
|
@ -29,11 +29,33 @@ local function eval(state, exp)
|
|||
type = "string",
|
||||
value = t
|
||||
}
|
||||
-- text buffer
|
||||
elseif exp.type == "text buffer" then
|
||||
-- eval text expression
|
||||
local v, e = eval(state, exp.text)
|
||||
if not v then return v, e end
|
||||
local l = v.type == "list" and v.value or { v }
|
||||
-- write resulting buffers (plural if loop in text expression) into a single result buffer
|
||||
local buffer = {}
|
||||
for _, item in ipairs(l) do
|
||||
if item.type == "event buffer" then
|
||||
for _, event in ipairs(item.value) do
|
||||
if event.type ~= "text" and event.type ~= "flush" then
|
||||
return nil, ("event %q can't be captured in a text buffer"):format(event.type)
|
||||
end
|
||||
table.insert(buffer, event)
|
||||
end
|
||||
end
|
||||
end
|
||||
return {
|
||||
type = "event buffer",
|
||||
value = buffer
|
||||
}
|
||||
-- parentheses
|
||||
elseif exp.type == "parentheses" then
|
||||
return eval(state, exp.expression)
|
||||
-- list defined in brackets
|
||||
elseif exp.type == "list_brackets" then
|
||||
elseif exp.type == "list brackets" then
|
||||
if exp.expression then
|
||||
local v, e = eval(state, exp.expression)
|
||||
if not v then return nil, e end
|
||||
|
|
@ -53,9 +75,9 @@ local function eval(state, exp)
|
|||
}
|
||||
end
|
||||
-- map defined in brackets
|
||||
elseif exp.type == "map_brackets" then
|
||||
elseif exp.type == "map brackets" then
|
||||
-- get constructing list
|
||||
local list, e = eval(state, { type = "list_brackets", expression = exp.expression })
|
||||
local list, e = eval(state, { type = "list brackets", expression = exp.expression })
|
||||
if not list then return nil, e end
|
||||
-- make map
|
||||
local map = {}
|
||||
|
|
@ -166,7 +188,7 @@ local function eval(state, exp)
|
|||
}
|
||||
-- tag
|
||||
elseif exp.type == "#" then
|
||||
local right, righte = eval(state, { type = "map_brackets", expression = exp.right })
|
||||
local right, righte = eval(state, { type = "map brackets", expression = exp.right })
|
||||
if not right then return nil, righte end
|
||||
tags:push(state, right)
|
||||
local left, lefte = eval(state, exp.left)
|
||||
|
|
@ -202,7 +224,7 @@ local function eval(state, exp)
|
|||
end
|
||||
-- function
|
||||
elseif exp.type == "function call" then
|
||||
-- eval args: map_brackets
|
||||
-- eval args: map brackets
|
||||
local args = {}
|
||||
local last_contiguous_positional = 0
|
||||
if exp.argument then
|
||||
|
|
@ -444,7 +466,7 @@ local function eval(state, exp)
|
|||
elseif lua_fn.mode == nil then
|
||||
local l_lua = {}
|
||||
for _, v in ipairs(final_args) do
|
||||
local lv, e = to_lua(v)
|
||||
local lv, e = to_lua(v, state)
|
||||
if e then return nil, e end
|
||||
table.insert(l_lua, lv)
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue