1
0
Fork 0
mirror of https://github.com/Reuh/anselme.git synced 2025-10-28 00:59:31 +00:00

Add eventbuffer type

This commit is contained in:
Étienne Fildadut 2021-12-02 18:39:43 +01:00
parent 02d50fb79f
commit 721464218c
10 changed files with 211 additions and 121 deletions

View file

@ -135,18 +135,17 @@ common = {
return t
end,
-- parse interpolated expressions in a text
-- type sets the type of the returned expression (text is in text field)
-- allow_subtext (bool) to enable or not [subtext] support
-- if allow_binops is given, if one of the caracters of allow_binops appear unescaped in the text, it will interpreter a binary operator expression
-- * returns a text expression, remaining (if the right expression stop before the end of the text)
-- if allow_binops is not given:
-- * returns a list of strings and expressions (text elements)
-- * returns an expression with given type (string by default) and as a value a list of strings and expressions (text elements)
-- * if allow_binops is given, also returns remaining string (if the right expression stop before the end of the text)
-- * nil, err: in case of error
parse_text = function(text, state, namespace, allow_binops, allow_subtext, in_subtext)
parse_text = function(text, state, namespace, type, allow_binops, allow_subtext, in_subtext)
local l = {}
local text_exp
local text_exp = { type = type, text = l }
local delimiters = ""
if allow_binops then
text_exp = { type = "text", text = l }
delimiters = allow_binops
end
if allow_subtext then
@ -182,7 +181,7 @@ common = {
text = rem:match("^%s*}(.*)$")
-- start subtext
elseif allow_subtext and r:match("^%[") then
local exp, rem = common.parse_text(r:gsub("^%[", ""), state, namespace, allow_binops, allow_subtext, true)
local exp, rem = common.parse_text(r:gsub("^%[", ""), state, namespace, "text", allow_binops, allow_subtext, true)
if not exp then return nil, rem end
if not rem:match("^%]") then return nil, ("expected closing ] at end of subtext before %q"):format(rem) end
-- add to text
@ -193,7 +192,7 @@ common = {
if allow_binops then
return text_exp, r
else
return l
return text_exp
end
-- binop expression at the end of the text
elseif allow_binops and r:match(("^[%s]"):format(allow_binops)) then
@ -209,7 +208,7 @@ common = {
if allow_binops then
return text_exp, ""
else
return l
return text_exp
end
end,
-- find compatible function variants from a fully qualified name

View file

@ -29,6 +29,30 @@ local unops_prio = {
[11] = {},
}
local function get_text_in_litteral(s, start_pos)
local d, r
-- find end of string
start_pos = start_pos or 2
local i = start_pos
while true do
local skip
skip = s:match("^[^%\\\"]-%b{}()", i) -- skip interpolated expressions
if skip then i = skip end
skip = s:match("^[^%\\\"]-\\.()", i) -- skip escape codes (need to skip every escape code in order to correctly parse \\": the " is not escaped)
if skip then i = skip end
if not skip then -- nothing skipped
local end_pos = s:match("^[^%\"]-\"()", i) -- search final double quote
if end_pos then
d, r = s:sub(start_pos, end_pos-2), s:sub(end_pos)
break
else
return nil, ("expected \" to finish string near %q"):format(s:sub(i))
end
end
end
return d, r
end
--- parse an expression
-- return expr, remaining if success
-- returns nil, err if error
@ -48,32 +72,16 @@ local function expression(s, state, namespace, current_priority, operating_on)
})
-- string
elseif s:match("^%\"") then
local d, r
-- find end of string
local i = 2
while true do
local skip
skip = s:match("^[^%\\\"]-%b{}()", i) -- skip interpolated expressions
if skip then i = skip end
skip = s:match("^[^%\\\"]-\\.()", i) -- skip escape codes (need to skip every escape code in order to correctly parse \\": the " is not escaped)
if skip then i = skip end
if not skip then -- nothing skipped
local end_pos = s:match("^[^%\"]-\"()", i) -- search final double quote
if end_pos then
d, r = s:sub(2, end_pos-2), s:sub(end_pos)
break
else
return nil, ("expected \" to finish string near %q"):format(s:sub(i))
end
end
end
-- parse interpolated expressions
local l, e = parse_text(d, state, namespace)
local d, r = get_text_in_litteral(s)
local l, e = parse_text(d, state, namespace, "string") -- parse interpolated expressions
if not l then return l, e end
return expression(r, state, namespace, current_priority, {
type = "string",
value = l
})
return expression(r, state, namespace, current_priority, l)
-- text
elseif s:match("^t%\"") then
local d, r = get_text_in_litteral(s, 3)
local l, e = parse_text(d, state, namespace, "text", nil, true) -- parse interpolated expressions and subtext
if not l then return l, e end
return expression(r, state, namespace, current_priority, l)
-- paranthesis
elseif s:match("^%b()") then
local content, r = s:match("^(%b())(.*)$")
@ -119,7 +127,7 @@ local function expression(s, state, namespace, current_priority, operating_on)
type = "list",
left = {
type = "string",
value = { name }
text = { name }
},
right = val
}

View file

@ -57,7 +57,7 @@ local function parse(state)
end
-- text (text & choice lines)
if line.text then
local txt, err = parse_text(line.text, state, namespace, "#~", true)
local txt, err = parse_text(line.text, state, namespace, "text", "#~", true)
if not txt then return nil, ("%s; at %s"):format(err, line.source) end
if err:match("[^%s]") then return nil, ("expected end of expression in end-of-text expression before %q"):format(err) end
line.text = txt