From b9c6d1d7043758978b0af11bdb45a26dcf68f0ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Reuh=20Fildadut?= Date: Mon, 12 Apr 2021 01:10:42 +0200 Subject: [PATCH] Add nil expression and fix return behavior with nil expression --- README.md | 4 ++-- interpreter/expression.lua | 8 +++++++- interpreter/interpreter.lua | 7 ++----- parser/expression.lua | 12 +++++++++--- parser/postparser.lua | 12 ++++-------- parser/preparser.lua | 14 ++++++++++++-- .../function return exit function nested.ans | 9 +++++++++ .../function return exit function nested.lua | 19 +++++++++++++++++++ test/tests/function return exit function.ans | 6 ++++++ test/tests/function return exit function.lua | 14 ++++++++++++++ 10 files changed, 84 insertions(+), 21 deletions(-) create mode 100644 test/tests/function return exit function nested.ans create mode 100644 test/tests/function return exit function nested.lua create mode 100644 test/tests/function return exit function.ans create mode 100644 test/tests/function return exit function.lua diff --git a/README.md b/README.md index 6db4c4c..8502ca2 100644 --- a/README.md +++ b/README.md @@ -255,7 +255,7 @@ Paragraphs always have the following variable defined in its namespace by defaul :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 @@ -417,7 +417,7 @@ Note that these are *not* Lua expressions. Default types are: -* `nil`: nil. +* `nil`: nil. Can be defined using empty parantheses `()`. * `number`: a number. Can be defined similarly to Lua number literals. diff --git a/interpreter/expression.lua b/interpreter/expression.lua index 17069ff..fb2d4c7 100644 --- a/interpreter/expression.lua +++ b/interpreter/expression.lua @@ -9,8 +9,14 @@ local unpack = table.unpack or unpack -- returns evaluated value if success -- returns nil, error if error local function eval(state, exp) + -- nil + if exp.type == "nil" then + return { + type = "nil", + value = nil + } -- number - if exp.type == "number" then + elseif exp.type == "number" then return { type = "number", value = exp.value diff --git a/interpreter/interpreter.lua b/interpreter/interpreter.lua index c521f46..5634c13 100644 --- a/interpreter/interpreter.lua +++ b/interpreter/interpreter.lua @@ -95,11 +95,8 @@ local function run_line(state, line) if e then return v, e end if v then return v end elseif line.type == "return" then - local v, e - if line.expression then - v, e = eval(state, line.expression) - if not v then return v, ("%s; at %s"):format(e, line.source) end - end + local v, e = eval(state, line.expression) + if not v then return v, ("%s; at %s"):format(e, line.source) end return v elseif line.type == "text" then local t, er = eval_text(state, line.text) diff --git a/parser/expression.lua b/parser/expression.lua index 5d41680..777d5b3 100644 --- a/parser/expression.lua +++ b/parser/expression.lua @@ -63,9 +63,15 @@ local function expression(s, state, namespace, currentPriority, operatingOn) elseif s:match("^%b()") then local content, r = s:match("^(%b())(.*)$") content = content:gsub("^%(", ""):gsub("%)$", "") - local 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 + local exp + if content:match("[^%s]") then + 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, { type = "parentheses", return_type = exp.return_type, diff --git a/parser/postparser.lua b/parser/postparser.lua index 10dd62a..bdfe058 100644 --- a/parser/postparser.lua +++ b/parser/postparser.lua @@ -29,14 +29,10 @@ local function parse(state) end -- expressions if line.expression then - if line.expression:match("[^%s]") then - local exp, rem = expression(line.expression, state, namespace) - 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 - line.expression = exp - else - line.expression = nil - end + local exp, rem = expression(line.expression, state, namespace) + 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 + line.expression = exp -- function return type information if line.type == "return" then local variant = line.parent_function.variant diff --git a/parser/preparser.lua b/parser/preparser.lua index 6659d60..887677d 100644 --- a/parser/preparser.lua +++ b/parser/preparser.lua @@ -303,12 +303,22 @@ local function parse_line(line, state, namespace) elseif l:match("^%#") then r.type = "tag" 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 elseif l:match("^%@") then r.type = "return" 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 elseif l:match("[^%s]") then r.type = "text" diff --git a/test/tests/function return exit function nested.ans b/test/tests/function return exit function nested.ans new file mode 100644 index 0000000..7c7d87a --- /dev/null +++ b/test/tests/function return exit function nested.ans @@ -0,0 +1,9 @@ +$ hey + ยง foo + @2 + @3 + @5 + u + +{hey} +{hey.foo} \ No newline at end of file diff --git a/test/tests/function return exit function nested.lua b/test/tests/function return exit function nested.lua new file mode 100644 index 0000000..baedcdc --- /dev/null +++ b/test/tests/function return exit function nested.lua @@ -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" } +]]-- \ No newline at end of file diff --git a/test/tests/function return exit function.ans b/test/tests/function return exit function.ans new file mode 100644 index 0000000..c1799f0 --- /dev/null +++ b/test/tests/function return exit function.ans @@ -0,0 +1,6 @@ +$ hey + @5 + a + @2 + +{hey} \ No newline at end of file diff --git a/test/tests/function return exit function.lua b/test/tests/function return exit function.lua new file mode 100644 index 0000000..9d39b3d --- /dev/null +++ b/test/tests/function return exit function.lua @@ -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" } +]]-- \ No newline at end of file