mirror of
https://github.com/Reuh/anselme.git
synced 2025-10-27 08:39:30 +00:00
[language] allow multiline strings
This commit is contained in:
parent
eaadb4ace6
commit
a702f250f9
13 changed files with 38 additions and 39 deletions
|
|
@ -16,7 +16,7 @@ local String = ast.abstract.Node {
|
|||
end,
|
||||
|
||||
_format = function(self)
|
||||
return ("%q"):format(self.string)
|
||||
return ("\"%s\""):format(self.string:gsub("[\n\t\"]", { ["\n"] = "\\n", ["\t"] = "\\t", ["\""] = "\\\"" }))
|
||||
end,
|
||||
|
||||
to_lua = function(self, state)
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ Struct = ast.abstract.Runtime {
|
|||
if v ~= nil then
|
||||
return v
|
||||
else
|
||||
error(("key %q is undefined in %s"):format(key:format(), self.type), 0)
|
||||
error(("key %s is undefined in %s"):format(key:format(), self.type), 0)
|
||||
end
|
||||
end,
|
||||
get_strict = function(self, key)
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ comment = primary {
|
|||
table.insert(content_list, "/*")
|
||||
table.insert(content_list, subcomment)
|
||||
table.insert(content_list, "*/")
|
||||
-- consumed everything until end-of-line/file, 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
|
||||
rem = "*/" .. rem
|
||||
source:increment(-2)
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ local escape_code = {
|
|||
return primary {
|
||||
type = "string", -- interpolation type - used for errors
|
||||
start_pattern = "\"", -- pattern that start the string interpolation
|
||||
stop_char = "\"", -- character that stops the string interpolation - must be a single character!
|
||||
stop_char = "\"", -- character that stops the string interpolation - must be a single one byte character!
|
||||
|
||||
allow_implicit_stop = false, -- set to true to allow the string to be closed implicitely when reaching the end of the expression or limit_pattern
|
||||
allow_implicit_stop = false, -- set to true to allow the string to be closed implicitely when reaching the end of the expression, line, or limit_pattern
|
||||
|
||||
interpolation = StringInterpolation,
|
||||
|
||||
|
|
@ -35,10 +35,11 @@ return primary {
|
|||
local start_source = source:clone()
|
||||
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 text_source = source:clone()
|
||||
local text
|
||||
text, rem = rem:match("^([^\n%{%\\"..stop_pattern.."]*)(.-)$") -- get all text until something potentially happens
|
||||
text, rem = rem:match(string_pattern) -- get all text until something potentially happens
|
||||
|
||||
-- cut the text prematurely at limit_pattern if relevant
|
||||
if self.allow_implicit_stop and limit_pattern and text:match(limit_pattern) then
|
||||
|
|
@ -53,7 +54,7 @@ return primary {
|
|||
|
||||
-- interpolated expression
|
||||
if rem:match("^%{") then
|
||||
local opts = options:with { limit_pattern = "%}", allow_newlines = false }
|
||||
local opts = options:with { limit_pattern = "%}", allow_newlines = not self.allow_implicit_stop }
|
||||
local ok, exp
|
||||
ok, exp, rem = pcall(expression_to_ast, source, opts, source:consume(rem:match("^(%{)(.*)$")))
|
||||
if not ok then error("invalid expression inside interpolation: "..exp, 0) end
|
||||
|
|
@ -65,7 +66,7 @@ return primary {
|
|||
elseif rem:match("^\\") then
|
||||
text, rem = source:consume(rem:match("^(\\(.))(.*)$"))
|
||||
interpolation:insert(String:new(escape_code[text] or text))
|
||||
-- consumed everything until end-of-line/file, implicit stop allowed, close your eyes and imagine the text has been closed
|
||||
-- consumed everything until end-of-string, implicit stop allowed, close your eyes and imagine the text has been closed
|
||||
elseif self.allow_implicit_stop and (rem:match("^\n") or not rem:match("[^%s]")) then
|
||||
rem = self.stop_char .. rem
|
||||
source:increment(-1)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
local string = require("anselme.parser.expression.primary.string")
|
||||
|
||||
local ast = require("anselme.ast")
|
||||
local TextInterpolation, Translatable = ast.TextInterpolation, ast.Translatable
|
||||
local TextInterpolation, Translatable, String = ast.TextInterpolation, ast.Translatable, ast.String
|
||||
|
||||
return string {
|
||||
type = "text",
|
||||
|
|
@ -16,7 +16,7 @@ return string {
|
|||
|
||||
-- remove terminal space
|
||||
local last = interpolation.list[#interpolation.list]
|
||||
if ast.String:is(last) then last.string = last.string:gsub("[ \t]$", "") end
|
||||
if String:is(last) then last.string = last.string:gsub("[ \t]$", "") end
|
||||
|
||||
return Translatable:new(interpolation):set_source(start_source), rem
|
||||
end
|
||||
|
|
|
|||
2
ideas.md
2
ideas.md
|
|
@ -23,7 +23,7 @@ Issue: dispatch is decided before evaluating default values.
|
|||
|
||||
---
|
||||
|
||||
Multiline string and comments?
|
||||
Multiline comments?
|
||||
|
||||
# Can be done later
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
--# run #--
|
||||
--- text ---
|
||||
| {}"" {}"\"Name: Darmanin\\\
|
||||
Age: 38\"" {}"" |
|
||||
| {}"" {}"\"Name: Darmanin\nAge: 38\"" {}"" |
|
||||
--- return ---
|
||||
()
|
||||
--# saved #--
|
||||
|
|
|
|||
|
|
@ -1,25 +1,15 @@
|
|||
--# run #--
|
||||
--- text ---
|
||||
| {}"" {}"1" {}"" {}"\
|
||||
" {}"" |
|
||||
| {}"" {}"2" {}"" {}"\
|
||||
" {}"" |
|
||||
| {}"" {}"3" {}"" {}"\
|
||||
" {}"" |
|
||||
| {}"" {}"4" {}"" {}"\
|
||||
" {}"" |
|
||||
| {}"" {}"5" {}"" {}"\
|
||||
" {}"" |
|
||||
| {}"" {}"6" {}"" {}"\
|
||||
" {}"" |
|
||||
| {}"" {}"7" {}"" {}"\
|
||||
" {}"" |
|
||||
| {}"" {}"8" {}"" {}"\
|
||||
" {}"" |
|
||||
| {}"" {}"9" {}"" {}"\
|
||||
" {}"" |
|
||||
| {}"" {}"10" {}"" {}"\
|
||||
" {}"" |
|
||||
| {}"" {}"1" {}"" |
|
||||
| {}"" {}"2" {}"" |
|
||||
| {}"" {}"3" {}"" |
|
||||
| {}"" {}"4" {}"" |
|
||||
| {}"" {}"5" {}"" |
|
||||
| {}"" {}"6" {}"" |
|
||||
| {}"" {}"7" {}"" |
|
||||
| {}"" {}"8" {}"" |
|
||||
| {}"" {}"9" {}"" |
|
||||
| {}"" {}"10" {}"" |
|
||||
--- text ---
|
||||
| {}"" {}"11" {}"" |
|
||||
--- return ---
|
||||
|
|
|
|||
5
test/results/multiline string.ans
Normal file
5
test/results/multiline string.ans
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
--# run #--
|
||||
--- return ---
|
||||
"foo\nbar\n\ta\n\tb\n\t c\n d"
|
||||
--# saved #--
|
||||
{}
|
||||
|
|
@ -4,10 +4,9 @@
|
|||
--- text ---
|
||||
| {}"quote " {}"\"" {}"" |
|
||||
--- text ---
|
||||
| {}"other codes " {}"\
|
||||
" {}" " {}"\\" {}" " {}"\9" {}" " {}"{" {}"braces}" |
|
||||
| {}"other codes " {}"\n" {}" " {}"\" {}" " {}"\t" {}" " {}"{" {}"braces}" |
|
||||
--- text ---
|
||||
| {}"" {}"escaping expressions abc and {stuff} \\ and quotes \"" {}"" |
|
||||
| {}"" {}"escaping expressions abc and {stuff} \ and quotes \"" {}"" |
|
||||
--- return ---
|
||||
()
|
||||
--# saved #--
|
||||
|
|
|
|||
|
|
@ -4,8 +4,7 @@
|
|||
--- text ---
|
||||
| {}"quote " {}"\"" {}"" |
|
||||
--- text ---
|
||||
| {}"other codes " {}"\
|
||||
" {}" " {}"\\" {}" " {}"\9" {}"" |
|
||||
| {}"other codes " {}"\n" {}" " {}"\" {}" " {}"\t" {}"" |
|
||||
--- text ---
|
||||
| {}"decorators " {}"#" {}" tag " {}"~" {}" condition " {}"$" {}" fn" |
|
||||
--- text ---
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
:i = 0
|
||||
|
||||
while($()(i += 1; i <= 10), $| {i}\n |!)
|
||||
while($()(i += 1; i <= 10), $| {i} |!)
|
||||
|
||||
|{i}
|
||||
|
|
|
|||
6
test/tests/multiline string.ans
Normal file
6
test/tests/multiline string.ans
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
"foo
|
||||
bar
|
||||
a
|
||||
b
|
||||
c
|
||||
d"
|
||||
Loading…
Add table
Add a link
Reference in a new issue