diff --git a/common/init.lua b/common/init.lua index a0e6ee1..1634a74 100644 --- a/common/init.lua +++ b/common/init.lua @@ -52,7 +52,7 @@ local common = { operator_priority = { [";_"] = 1, ["$_"] = 1, - ["@_"] = 2, + ["@_"] = 1, ["_,_"] = 2, ["_=_"] = 3, ["_!_"] = 12, diff --git a/parser/expression/primary/function_definition.lua b/parser/expression/primary/function_definition.lua index 2ef37fd..cd3105b 100644 --- a/parser/expression/primary/function_definition.lua +++ b/parser/expression/primary/function_definition.lua @@ -42,7 +42,6 @@ local function_parameter_maybe_parenthesis = function_parameter_no_default { end } - -- signature type 1: unary prefix -- :$-parameter exp -- returns symbol, parameter_tuple, rem if success @@ -195,7 +194,7 @@ return primary { -- parse expression local right s, right, rem = pcall(expression_to_ast, source, rem, limit_pattern, operator_priority["$_"]) - if not s then error(("invalid expression after unop %q: %s"):format(self.operator, right), 0) end + if not s then error(("invalid expression in function definition: %s"):format(right), 0) end -- return function local fn = Function:new(parameters, right):set_source(source_start) diff --git a/parser/expression/primary/init.lua b/parser/expression/primary/init.lua index eae9843..7c40663 100644 --- a/parser/expression/primary/init.lua +++ b/parser/expression/primary/init.lua @@ -21,7 +21,6 @@ local primaries = { -- 1 r("prefix.semicolon"), r("prefix.function"), - -- 2 r("prefix.return"), -- 3.5 r("prefix.else"), diff --git a/parser/expression/primary/prefix/prefix_maybe_nil_right.lua b/parser/expression/primary/prefix/prefix_maybe_nil_right.lua new file mode 100644 index 0000000..df95b33 --- /dev/null +++ b/parser/expression/primary/prefix/prefix_maybe_nil_right.lua @@ -0,0 +1,21 @@ +local prefix = require("parser.expression.primary.prefix.prefix") +local escape = require("common").escape +local expression_to_ast = require("parser.expression.to_ast") + +local ast = require("ast") +local Nil = ast.Nil + +return prefix { + parse = function(self, source, str, limit_pattern) + local source_start = source:clone() + local escaped = escape(self.operator) + + local sright = source:consume(str:match("^("..escaped..")(.*)$")) + local s, right, rem = pcall(expression_to_ast, source, sright, limit_pattern, self.priority) + if not s then + return self:build_ast(Nil:new()):set_source(source_start), sright + else + return self:build_ast(right):set_source(source_start), rem + end + end, +} diff --git a/parser/expression/primary/prefix/return.lua b/parser/expression/primary/prefix/return.lua index 0c34e8c..cbb98fe 100644 --- a/parser/expression/primary/prefix/return.lua +++ b/parser/expression/primary/prefix/return.lua @@ -1,11 +1,11 @@ -local prefix = require("parser.expression.primary.prefix.prefix") +local prefix_maybe_nil_right = require("parser.expression.primary.prefix.prefix_maybe_nil_right") local ast = require("ast") local Return = ast.Return local operator_priority = require("common").operator_priority -return prefix { +return prefix_maybe_nil_right { operator = "@", priority = operator_priority["@_"],