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

[language] add inline comments and allow multiline comments

This commit is contained in:
Étienne Fildadut 2024-01-16 17:40:26 +01:00
parent a702f250f9
commit 6d9c3dd403
7 changed files with 50 additions and 20 deletions

View file

@ -3,21 +3,36 @@ local primary = require("anselme.parser.expression.primary.primary")
local comment local comment
comment = primary { comment = primary {
match = function(self, str) match = function(self, str)
return str:match("^%/%*") return str:match("^%/%*") or str:match("^%-%-")
end, end,
parse = function(self, source, options, str) parse = function(self, source, options, str)
local limit_pattern = options.limit_pattern local limit_pattern = options.limit_pattern
local rem = source:consume(str:match("^(%/%*)(.*)$"))
local allow_implicit_stop, stop_str, stop_pattern, rem
if str:match("^%/%*") then
allow_implicit_stop = false
stop_str = "*/"
stop_pattern = "%*%/"
rem = source:consume(str:match("^(%/%*)(.*)$"))
else
allow_implicit_stop = true
stop_str = "--"
stop_pattern = "%-%-"
rem = source:consume(str:match("^(%-%-)(.*)$"))
end
local comment_pattern = "^([^%/%*%-"..(allow_implicit_stop and "\n" or "").."]*)(.-)$"
local at_stop_pattern = "^"..stop_pattern
local content_list = {} local content_list = {}
while not rem:match("^%*%/") do while not rem:match(at_stop_pattern) do
local content local content
content, rem = rem:match("^([^\n%/%*]*)(.-)$") content, rem = rem:match(comment_pattern)
-- cut the text prematurely at limit_pattern if relevant -- cut the text prematurely at limit_pattern if relevant
if limit_pattern and content:match(limit_pattern) then if allow_implicit_stop and limit_pattern and content:match(limit_pattern) then
local pos = content:match("()"..limit_pattern) -- limit_pattern can contain $, so can't directly extract with captures local pos = content:match("()"..limit_pattern) -- limit_pattern can contain $, so can't directly extract with captures
content, rem = source:count(content:sub(1, pos-1)), ("*/%s%s"):format(content:sub(pos), rem) content, rem = source:count(content:sub(1, pos-1)), ("%s%s%s"):format(stop_str, content:sub(pos), rem)
source:increment(-2) source:increment(-2)
else else
source:count(content) source:count(content)
@ -34,15 +49,15 @@ comment = primary {
table.insert(content_list, subcomment) table.insert(content_list, subcomment)
table.insert(content_list, "*/") table.insert(content_list, "*/")
-- consumed everything until end-of-string, close your eyes and imagine the text has been closed -- consumed everything until end-of-string, close your eyes and imagine the text has been closed
elseif rem:match("^\n") or not rem:match("[^%s]") then elseif allow_implicit_stop and rem:match("^\n") or not rem:match("[^%s]") then
rem = "*/" .. rem rem = stop_str .. rem
source:increment(-2) source:increment(-2)
-- no end token after the comment -- no end token after the comment
elseif not rem:match("^%*%/") then elseif not rem:match(at_stop_pattern) then
-- single * or /, keep on commentin' -- non-end *, /, or -, keep on commentin'
if rem:match("^[%*%/]") then if rem:match("^[%*%/%-]") then
local s local s
s, rem = source:count(rem:match("^([%*%/])(.-)$")) s, rem = source:count(rem:match("^([%*%/%-])(.-)$"))
table.insert(content_list, s) table.insert(content_list, s)
-- anything else -- anything else
else else
@ -50,7 +65,7 @@ comment = primary {
end end
end end
end end
rem = source:consume(rem:match("^(%*%/)(.*)$")) rem = source:consume(rem:match("^("..stop_pattern..")(.*)$"))
return table.concat(content_list, ""), rem return table.concat(content_list, ""), rem
end end

View file

@ -36,7 +36,8 @@ return primary {
local rem = source:consume(str:match("^("..self.start_pattern..")(.-)$")) local rem = source:consume(str:match("^("..self.start_pattern..")(.-)$"))
local string_pattern = "^([^%{%\\"..stop_pattern..(self.allow_implicit_stop and "\n" or "").."]*)(.-)$" local string_pattern = "^([^%{%\\"..stop_pattern..(self.allow_implicit_stop and "\n" or "").."]*)(.-)$"
while not rem:match("^"..stop_pattern) do local at_stop_pattern = "^"..stop_pattern
while not rem:match(at_stop_pattern) do
local text_source = source:clone() local text_source = source:clone()
local text local text
text, rem = rem:match(string_pattern) -- get all text until something potentially happens text, rem = rem:match(string_pattern) -- get all text until something potentially happens
@ -71,7 +72,7 @@ return primary {
rem = self.stop_char .. rem rem = self.stop_char .. rem
source:increment(-1) source:increment(-1)
-- no end token after the comment -- no end token after the comment
elseif not rem:match("^"..stop_pattern) then elseif not rem:match(at_stop_pattern) then
error(("unexpected %q at end of "..self.type):format(rem:match("^[^\n]*")), 0) error(("unexpected %q at end of "..self.type):format(rem:match("^[^\n]*")), 0)
end end
end end

View file

@ -23,7 +23,7 @@ Issue: dispatch is decided before evaluating default values.
--- ---
Multiline comments? Comment syntax, not sure about using -- for inline and /* for multiline.
# Can be done later # Can be done later

View file

@ -11,5 +11,5 @@
|{{1,2,4, |{{1,2,4,
/* hey */3, /* hey */3,
9 9
/* hoy -- hoy
,6}} ,6}}

View file

@ -11,5 +11,5 @@
|{[1,2,4, |{[1,2,4,
/* hey */3, /* hey */3,
9 9
/* hoy -- hoy
,6]} ,6]}

View file

@ -1,9 +1,23 @@
/*hey couic + 5*/ --hey couic + 5
/*nested /*comments*/ d*/ /*nested /*comments*/ d*/
--nested /*comments*/ d--
/* mul
ti
line
error("d")
*/
2 /*end of line*/ 2 /*end of line*/
2 --end of line--
/*start of line*/ 3 /*start of line*/ 3
--start of line-- 3
5 + /*middle*/ 3 5 + /*middle*/ 3
5 + --middle-- 3

View file

@ -11,5 +11,5 @@
|{(1,2,4, |{(1,2,4,
/* hey */3, /* hey */3,
9 9
/* hoy -- hoy
,6)} ,6)}