mirror of
https://github.com/Reuh/anselme.git
synced 2025-10-27 16:49:31 +00:00
[language] allow newlines between ! and identifier in _!_ call operator
This commit is contained in:
parent
69da1ff223
commit
03922ebde4
8 changed files with 26 additions and 30 deletions
|
|
@ -78,6 +78,9 @@ Call = ast.abstract.Node {
|
||||||
is_simple_assignment = function(self)
|
is_simple_assignment = function(self)
|
||||||
return self:is_infix("_=_") and Quote:is(self.arguments.positional[1]) and Identifier:is(self.arguments.positional[1].expression)
|
return self:is_infix("_=_") and Quote:is(self.arguments.positional[1]) and Identifier:is(self.arguments.positional[1].expression)
|
||||||
end,
|
end,
|
||||||
|
is_implicit_block_identifier = function(self)
|
||||||
|
return Identifier:is(self.func) and self.func.name == "_" and self.explicit == false
|
||||||
|
end,
|
||||||
|
|
||||||
traverse = function(self, fn, ...)
|
traverse = function(self, fn, ...)
|
||||||
fn(self.func, ...)
|
fn(self.func, ...)
|
||||||
|
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
local prefix = require("anselme.parser.expression.primary.prefix.prefix")
|
|
||||||
local escape = require("anselme.common").escape
|
|
||||||
local expression_to_ast = require("anselme.parser.expression.to_ast")
|
|
||||||
|
|
||||||
local ast = require("anselme.ast")
|
|
||||||
local Nil = ast.Nil
|
|
||||||
|
|
||||||
return prefix {
|
|
||||||
parse = function(self, source, options, str)
|
|
||||||
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, options, sright, 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,
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
local infix = require("anselme.parser.expression.secondary.infix.infix")
|
local infix_or_suffix = require("anselme.parser.expression.secondary.infix.infix_or_suffix")
|
||||||
local escape = require("anselme.common").escape
|
local escape = require("anselme.common").escape
|
||||||
local identifier = require("anselme.parser.expression.primary.identifier")
|
local identifier = require("anselme.parser.expression.primary.identifier")
|
||||||
|
|
||||||
|
|
@ -7,15 +7,14 @@ local operator_priority = require("anselme.common").operator_priority
|
||||||
local ast = require("anselme.ast")
|
local ast = require("anselme.ast")
|
||||||
local Call, ArgumentTuple = ast.Call, ast.ArgumentTuple
|
local Call, ArgumentTuple = ast.Call, ast.ArgumentTuple
|
||||||
|
|
||||||
return infix {
|
return infix_or_suffix {
|
||||||
operator = "!",
|
operator = "!",
|
||||||
identifier = "_!_",
|
identifier = "_!_",
|
||||||
priority = operator_priority["_!_"],
|
priority = operator_priority["_!_"],
|
||||||
|
|
||||||
match = function(self, str, current_priority, primary)
|
match = function(self, str, current_priority, primary)
|
||||||
local escaped = escape(self.operator)
|
local escaped = escape(self.operator)
|
||||||
-- TODO: doesn't support newline between ! and identifier, even in multiline expression
|
return self.priority > current_priority and str:match("^"..escaped) and identifier:match(str:match("^"..escaped.."[ \t\n]*(.-)$"))
|
||||||
return self.priority > current_priority and str:match("^"..escaped) and identifier:match(str:match("^"..escaped.."[ \t]*(.-)$"))
|
|
||||||
end,
|
end,
|
||||||
|
|
||||||
build_ast = function(self, left, right)
|
build_ast = function(self, left, right)
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
-- same as infix, but skip if no valid expression after the operator instead of erroring
|
-- same as infix, but skip if no valid expression or end-of-line after the operator instead of erroring
|
||||||
-- useful for operators that are both valid as infix and as suffix
|
-- useful for operators that are both valid as infix and as suffix
|
||||||
|
|
||||||
local infix = require("anselme.parser.expression.secondary.infix.infix")
|
local infix = require("anselme.parser.expression.secondary.infix.infix")
|
||||||
local escape = require("anselme.common").escape
|
local escape = require("anselme.common").escape
|
||||||
local expression_to_ast = require("anselme.parser.expression.to_ast")
|
local expression_to_ast = require("anselme.parser.expression.to_ast")
|
||||||
|
|
||||||
|
local ast = require("anselme.ast")
|
||||||
|
local Call = ast.Call
|
||||||
|
|
||||||
return infix {
|
return infix {
|
||||||
-- returns exp, rem if expression found
|
-- returns exp, rem if expression found
|
||||||
-- returns nil if no expression found
|
-- returns nil if no expression found
|
||||||
|
|
@ -27,6 +30,8 @@ return infix {
|
||||||
local s, right, rem = pcall(expression_to_ast, source, options, sright, self.priority)
|
local s, right, rem = pcall(expression_to_ast, source, options, sright, self.priority)
|
||||||
if not s then return nil end
|
if not s then return nil end
|
||||||
|
|
||||||
|
if Call:is(right) and right:is_implicit_block_identifier() then return nil end -- skip if end-of-line, ignoring implicit _
|
||||||
|
|
||||||
return self:build_ast(primary, right):set_source(start_source), rem
|
return self:build_ast(primary, right):set_source(start_source), rem
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,9 @@
|
||||||
↳ from [4mtest/tests/merge nested mutable error bis.ans:14:7[0m in call: [2merror("abort")[0m[0m
|
↳ from [4mtest/tests/merge nested mutable error bis.ans:14:7[0m in call: [2merror("abort")[0m[0m
|
||||||
↳ from [4mtest/tests/merge nested mutable error bis.ans:4:1[0m in block: [2minsert(a, b)…[0m[0m
|
↳ from [4mtest/tests/merge nested mutable error bis.ans:4:1[0m in block: [2minsert(a, b)…[0m[0m
|
||||||
↳ from [4mtest/tests/merge nested mutable error bis.ans:3:18[0m in call: [2m_[0m[0m
|
↳ from [4mtest/tests/merge nested mutable error bis.ans:3:18[0m in call: [2m_[0m[0m
|
||||||
↳ from [4mstdlib/script.ans:31:6[0m in call: [2mfn![0m[0m
|
↳ from [4mstdlib/script.ans:31:7[0m in call: [2mfn![0m[0m
|
||||||
↳ from [4mstdlib/script.ans:30:1[0m in block: [2mresume target = ()…[0m[0m
|
↳ from [4mstdlib/script.ans:30:1[0m in block: [2mresume target = ()…[0m[0m
|
||||||
↳ from [4mstdlib/script.ans:29:7[0m in call: [2melse![0m[0m
|
↳ from [4mstdlib/script.ans:29:8[0m in call: [2melse![0m[0m
|
||||||
↳ from [4mstdlib/script.ans:26:1[0m in block: [2mif(fn . "current checkpoint")…[0m[0m
|
↳ from [4mstdlib/script.ans:26:1[0m in block: [2mif(fn . "current checkpoint")…[0m[0m
|
||||||
↳ from [4mstdlib/script.ans:25:8[0m in call: [2m_[0m[0m
|
↳ from [4mstdlib/script.ans:25:8[0m in call: [2m_[0m[0m
|
||||||
↳ from [4mstdlib/script.ans:39:9[0m in call: [2mvalue(s)![0m[0m
|
↳ from [4mstdlib/script.ans:39:9[0m in call: [2mvalue(s)![0m[0m
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,9 @@
|
||||||
↳ from [4mtest/tests/merge nested mutable error.ans:14:7[0m in call: [2merror("abort")[0m[0m
|
↳ from [4mtest/tests/merge nested mutable error.ans:14:7[0m in call: [2merror("abort")[0m[0m
|
||||||
↳ from [4mtest/tests/merge nested mutable error.ans:4:1[0m in block: [2minsert(a, b)…[0m[0m
|
↳ from [4mtest/tests/merge nested mutable error.ans:4:1[0m in block: [2minsert(a, b)…[0m[0m
|
||||||
↳ from [4mtest/tests/merge nested mutable error.ans:3:18[0m in call: [2m_[0m[0m
|
↳ from [4mtest/tests/merge nested mutable error.ans:3:18[0m in call: [2m_[0m[0m
|
||||||
↳ from [4mstdlib/script.ans:31:6[0m in call: [2mfn![0m[0m
|
↳ from [4mstdlib/script.ans:31:7[0m in call: [2mfn![0m[0m
|
||||||
↳ from [4mstdlib/script.ans:30:1[0m in block: [2mresume target = ()…[0m[0m
|
↳ from [4mstdlib/script.ans:30:1[0m in block: [2mresume target = ()…[0m[0m
|
||||||
↳ from [4mstdlib/script.ans:29:7[0m in call: [2melse![0m[0m
|
↳ from [4mstdlib/script.ans:29:8[0m in call: [2melse![0m[0m
|
||||||
↳ from [4mstdlib/script.ans:26:1[0m in block: [2mif(fn . "current checkpoint")…[0m[0m
|
↳ from [4mstdlib/script.ans:26:1[0m in block: [2mif(fn . "current checkpoint")…[0m[0m
|
||||||
↳ from [4mstdlib/script.ans:25:8[0m in call: [2m_[0m[0m
|
↳ from [4mstdlib/script.ans:25:8[0m in call: [2m_[0m[0m
|
||||||
↳ from [4mstdlib/script.ans:39:9[0m in call: [2mvalue(s)![0m[0m
|
↳ from [4mstdlib/script.ans:39:9[0m in call: [2mvalue(s)![0m[0m
|
||||||
|
|
|
||||||
5
test/results/method call newline.ans
Normal file
5
test/results/method call newline.ans
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
--# run #--
|
||||||
|
--- return ---
|
||||||
|
5
|
||||||
|
--# saved #--
|
||||||
|
{}
|
||||||
5
test/tests/method call newline.ans
Normal file
5
test/tests/method call newline.ans
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
(
|
||||||
|
"hello"
|
||||||
|
!
|
||||||
|
len
|
||||||
|
)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue