From 6d9c3dd4034a6e533a55bf3bb2302e8cae4d0bca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Reuh=20Fildadut?= Date: Tue, 16 Jan 2024 17:40:26 +0100 Subject: [PATCH] [language] add inline comments and allow multiline comments --- anselme/parser/expression/comment.lua | 41 +++++++++++++------- anselme/parser/expression/primary/string.lua | 5 ++- ideas.md | 2 +- test/tests/brace multiline.ans | 2 +- test/tests/bracket multiline.ans | 2 +- test/tests/comment.ans | 16 +++++++- test/tests/parentheses multiline.ans | 2 +- 7 files changed, 50 insertions(+), 20 deletions(-) diff --git a/anselme/parser/expression/comment.lua b/anselme/parser/expression/comment.lua index ca693cf..4f4159a 100644 --- a/anselme/parser/expression/comment.lua +++ b/anselme/parser/expression/comment.lua @@ -3,21 +3,36 @@ local primary = require("anselme.parser.expression.primary.primary") local comment comment = primary { match = function(self, str) - return str:match("^%/%*") + return str:match("^%/%*") or str:match("^%-%-") end, parse = function(self, source, options, str) 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 = {} - while not rem:match("^%*%/") do + while not rem:match(at_stop_pattern) do local content - content, rem = rem:match("^([^\n%/%*]*)(.-)$") + content, rem = rem:match(comment_pattern) -- 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 - 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) else source:count(content) @@ -34,15 +49,15 @@ comment = primary { table.insert(content_list, subcomment) table.insert(content_list, "*/") -- 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 - rem = "*/" .. rem + elseif allow_implicit_stop and rem:match("^\n") or not rem:match("[^%s]") then + rem = stop_str .. rem source:increment(-2) -- no end token after the comment - elseif not rem:match("^%*%/") then - -- single * or /, keep on commentin' - if rem:match("^[%*%/]") then + elseif not rem:match(at_stop_pattern) then + -- non-end *, /, or -, keep on commentin' + if rem:match("^[%*%/%-]") then local s - s, rem = source:count(rem:match("^([%*%/])(.-)$")) + s, rem = source:count(rem:match("^([%*%/%-])(.-)$")) table.insert(content_list, s) -- anything else else @@ -50,7 +65,7 @@ comment = primary { end end end - rem = source:consume(rem:match("^(%*%/)(.*)$")) + rem = source:consume(rem:match("^("..stop_pattern..")(.*)$")) return table.concat(content_list, ""), rem end diff --git a/anselme/parser/expression/primary/string.lua b/anselme/parser/expression/primary/string.lua index 4fd5dc0..07d11d3 100644 --- a/anselme/parser/expression/primary/string.lua +++ b/anselme/parser/expression/primary/string.lua @@ -36,7 +36,8 @@ return primary { local rem = source:consume(str:match("^("..self.start_pattern..")(.-)$")) 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 text, rem = rem:match(string_pattern) -- get all text until something potentially happens @@ -71,7 +72,7 @@ return primary { rem = self.stop_char .. rem source:increment(-1) -- 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) end end diff --git a/ideas.md b/ideas.md index 09a7937..f9ceec2 100644 --- a/ideas.md +++ b/ideas.md @@ -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 diff --git a/test/tests/brace multiline.ans b/test/tests/brace multiline.ans index 21ac2af..6366218 100644 --- a/test/tests/brace multiline.ans +++ b/test/tests/brace multiline.ans @@ -11,5 +11,5 @@ |{{1,2,4, /* hey */3, 9 - /* hoy + -- hoy ,6}} diff --git a/test/tests/bracket multiline.ans b/test/tests/bracket multiline.ans index f9c957c..b735f9f 100644 --- a/test/tests/bracket multiline.ans +++ b/test/tests/bracket multiline.ans @@ -11,5 +11,5 @@ |{[1,2,4, /* hey */3, 9 - /* hoy + -- hoy ,6]} diff --git a/test/tests/comment.ans b/test/tests/comment.ans index a33f92e..8912301 100644 --- a/test/tests/comment.ans +++ b/test/tests/comment.ans @@ -1,9 +1,23 @@ -/*hey couic + 5*/ +--hey couic + 5 /*nested /*comments*/ d*/ +--nested /*comments*/ d-- + +/* mul +ti +line +error("d") +*/ + 2 /*end of line*/ +2 --end of line-- + /*start of line*/ 3 +--start of line-- 3 + 5 + /*middle*/ 3 + +5 + --middle-- 3 diff --git a/test/tests/parentheses multiline.ans b/test/tests/parentheses multiline.ans index d046b9e..5cb7bf3 100644 --- a/test/tests/parentheses multiline.ans +++ b/test/tests/parentheses multiline.ans @@ -11,5 +11,5 @@ |{(1,2,4, /* hey */3, 9 - /* hoy + -- hoy ,6)}