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

Add nil expression and fix return behavior with nil expression

This commit is contained in:
Étienne Fildadut 2021-04-12 01:10:42 +02:00
parent 6488bef75c
commit b9c6d1d704
10 changed files with 84 additions and 21 deletions

View file

@ -255,7 +255,7 @@ Paragraphs always have the following variable defined in its namespace by defaul
:42 foo :42 foo
``` ```
* `@`: return line. Can be followed by an [expression](#expressions). Exit the current function and returns the expression's value. * `@`: return line. Can be followed by an [expression](#expressions); otherwise nil expression is assumed. Exit the current function and returns the expression's value.
``` ```
$ hey $ hey
@ -417,7 +417,7 @@ Note that these are *not* Lua expressions.
Default types are: Default types are:
* `nil`: nil. * `nil`: nil. Can be defined using empty parantheses `()`.
* `number`: a number. Can be defined similarly to Lua number literals. * `number`: a number. Can be defined similarly to Lua number literals.

View file

@ -9,8 +9,14 @@ local unpack = table.unpack or unpack
-- returns evaluated value if success -- returns evaluated value if success
-- returns nil, error if error -- returns nil, error if error
local function eval(state, exp) local function eval(state, exp)
-- nil
if exp.type == "nil" then
return {
type = "nil",
value = nil
}
-- number -- number
if exp.type == "number" then elseif exp.type == "number" then
return { return {
type = "number", type = "number",
value = exp.value value = exp.value

View file

@ -95,11 +95,8 @@ local function run_line(state, line)
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
elseif line.type == "return" then elseif line.type == "return" then
local v, e local v, e = eval(state, line.expression)
if line.expression then if not v then return v, ("%s; at %s"):format(e, line.source) end
v, e = eval(state, line.expression)
if not v then return v, ("%s; at %s"):format(e, line.source) end
end
return v return v
elseif line.type == "text" then elseif line.type == "text" then
local t, er = eval_text(state, line.text) local t, er = eval_text(state, line.text)

View file

@ -63,9 +63,15 @@ local function expression(s, state, namespace, currentPriority, operatingOn)
elseif s:match("^%b()") then elseif s:match("^%b()") then
local content, r = s:match("^(%b())(.*)$") local content, r = s:match("^(%b())(.*)$")
content = content:gsub("^%(", ""):gsub("%)$", "") content = content:gsub("^%(", ""):gsub("%)$", "")
local exp, r_paren = expression(content, state, namespace) local exp
if not exp then return nil, "invalid expression inside parentheses: "..r_paren end if content:match("[^%s]") then
if r_paren:match("[^%s]") then return nil, ("unexpected %q at end of parenthesis expression"):format(r_paren) end local r_paren
exp, r_paren = expression(content, state, namespace)
if not exp then return nil, "invalid expression inside parentheses: "..r_paren end
if r_paren:match("[^%s]") then return nil, ("unexpected %q at end of parenthesis expression"):format(r_paren) end
else
exp = { type = "nil", return_type = "nil", value = nil }
end
return expression(r, state, namespace, currentPriority, { return expression(r, state, namespace, currentPriority, {
type = "parentheses", type = "parentheses",
return_type = exp.return_type, return_type = exp.return_type,

View file

@ -29,14 +29,10 @@ local function parse(state)
end end
-- expressions -- expressions
if line.expression then if line.expression then
if line.expression:match("[^%s]") then local exp, rem = expression(line.expression, state, namespace)
local exp, rem = expression(line.expression, state, namespace) if not exp then return nil, ("%s; at %s"):format(rem, line.source) end
if not exp then return nil, ("%s; at %s"):format(rem, line.source) end if rem:match("[^%s]") then return nil, ("expected end of expression before %q; at %s"):format(rem, line.source) end
if rem:match("[^%s]") then return nil, ("expected end of expression before %q; at %s"):format(rem, line.source) end line.expression = exp
line.expression = exp
else
line.expression = nil
end
-- function return type information -- function return type information
if line.type == "return" then if line.type == "return" then
local variant = line.parent_function.variant local variant = line.parent_function.variant

View file

@ -303,12 +303,22 @@ local function parse_line(line, state, namespace)
elseif l:match("^%#") then elseif l:match("^%#") then
r.type = "tag" r.type = "tag"
r.child = true r.child = true
r.expression = l:match("^%#(.*)$") local expr = l:match("^%#(.*)$")
if expr:match("[^%s]") then
r.expression = expr
else
r.expression = nil
end
-- return -- return
elseif l:match("^%@") then elseif l:match("^%@") then
r.type = "return" r.type = "return"
r.parent_function = true r.parent_function = true
r.expression = l:match("^%@(.*)$") local expr = l:match("^%@(.*)$")
if expr:match("[^%s]") then
r.expression = expr
else
r.expression = "()"
end
-- text -- text
elseif l:match("[^%s]") then elseif l:match("[^%s]") then
r.type = "text" r.type = "text"

View file

@ -0,0 +1,9 @@
$ hey
§ foo
@2
@3
@5
u
{hey}
{hey.foo}

View file

@ -0,0 +1,19 @@
local _={}
_[7]={}
_[6]={}
_[5]={data="2",tags=_[7]}
_[4]={data="5",tags=_[6]}
_[3]={_[4],_[5]}
_[2]={"return"}
_[1]={"text",_[3]}
return {_[1],_[2]}
--[[
{ "text", { {
data = "5",
tags = {}
}, {
data = "2",
tags = {}
} } }
{ "return" }
]]--

View file

@ -0,0 +1,6 @@
$ hey
@5
a
@2
{hey}

View file

@ -0,0 +1,14 @@
local _={}
_[5]={}
_[4]={data="5",tags=_[5]}
_[3]={_[4]}
_[2]={"return"}
_[1]={"text",_[3]}
return {_[1],_[2]}
--[[
{ "text", { {
data = "5",
tags = {}
} } }
{ "return" }
]]--