aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bitbucket@bruce-hill.com>2018-09-13 16:01:57 -0700
committerBruce Hill <bitbucket@bruce-hill.com>2018-09-13 16:02:40 -0700
commit4d48bf359df98512a2a741d48ea222d055b733c0 (patch)
treef05f33baf4dd776f3f68230a611beafedbb2da4b
parentea310306d73e0bc6542f7133825549ae4471b06a (diff)
Improvements to indented text parsing and error reporting.
-rw-r--r--nomsu.4.peg25
-rw-r--r--pretty_errors.lua32
-rw-r--r--pretty_errors.moon27
-rw-r--r--string2.lua2
-rw-r--r--string2.moon2
5 files changed, 67 insertions, 21 deletions
diff --git a/nomsu.4.peg b/nomsu.4.peg
index ed119c5..eb0c878 100644
--- a/nomsu.4.peg
+++ b/nomsu.4.peg
@@ -59,6 +59,10 @@ missing_bracket_error (Error):
missing_brace_error (Error):
{:error: {~ eol -> "Line ended before finding a closing }-brace" ~} :}
{:hint: {~ '' -> 'Put a "}" here' ~} :}
+disallowed_interpolation (Error):
+ {:error: {~ ("\" ('\:' / '(..)' / '[..]' / '{..}') (%nl (&(%nl) / =curr_indent ' ' [^%nl]*))*) ->
+ "Sorry, indented text interpolations are not currently supported on the first line of multi-line text." ~} :}
+ {:hint: {~ '' -> 'Move the code for the first line of text to the next line by ending this line with "\" and starting the next line indented with "..", followed by the code for the first line.' ~} :}
section_division: ("~")^+3 eol
@@ -124,7 +128,7 @@ inline_text (Text):
!(cool_indented_text / indented_text)
('"' _inline_text* ('"' / missing_quote_err / unexpected_code))
_inline_text:
- {~ (('\"' -> '"') / ('\\' -> '\') / escaped_char / [^%nl\"])+ ~}
+ {~ (('\"' -> '"') / ('\\' -> '\') / escaped_char / [^%nl\"]+)+ ~}
/ inline_text_interpolation
inline_text_interpolation:
"\" (
@@ -140,13 +144,24 @@ indented_text (Text):
(indented_plain_text / text_interpolation / {~ %nl+ (=curr_indent -> "") ~})*
unexpected_code?
{:curr_indent: %nil :}
+
+
+cool_quote:
+ '"' !(%nl+ !(=curr_indent))
cool_indented_text (Text):
({|
- '"' _inline_text* '\' %nl {:curr_indent: indent :} '..'
- (indented_plain_text / text_interpolation / {~ %nl+ (=curr_indent -> "") ~})*
- unexpected_code?
+ '"'
+ _inline_text*
+ (('\' %nl+ {:curr_indent: indent :} '..')
+ / disallowed_interpolation? {%nl+} {:curr_indent: indent :})
+ (indented_cool_plain_text / text_interpolation / {~ %nl+ (=curr_indent -> "") ~})*
+ ('"' eol / missing_quote_err)
|} -> unpack)
- ({(%nl &%nl)+}? %nl =curr_indent '..' _inline_text* '"')?
+indented_cool_plain_text (Text):
+ {~ ((("\" blank_lines =curr_indent "..") -> "") / (!text_interpolation ((!("\n") escaped_char) / ('\\' -> '\') / '\')) / (cool_quote / [^%nl"\])+)+
+ (%nl+ (=curr_indent -> ""))* ~}
+
+
-- Tracking text-lines-within-indented-text as separate objects allows for better debugging line info
indented_plain_text (Text):
{~ (("\\" -> "\") / (("\" blank_lines =curr_indent "..") -> "") / (!text_interpolation "\") / [^%nl\]+)+
diff --git a/pretty_errors.lua b/pretty_errors.lua
index f2a608e..7402703 100644
--- a/pretty_errors.lua
+++ b/pretty_errors.lua
@@ -35,19 +35,37 @@ format_error = function(err)
end
end
if err_line then
- local box_width = 60
local before = err_line:sub(1, err_linepos - 1)
local during = err_line:sub(err_linepos, err_linepos + err_size - 1)
local after = err_line:sub(err_linepos + err_size, -1)
err_line = "\027[0m" .. tostring(before) .. "\027[41;30m" .. tostring(during) .. tostring(nl_indicator) .. "\027[0m" .. tostring(after)
- err_msg = err_msg .. "\n\027[2m" .. tostring(fmt_str:format(err_linenum)) .. tostring(err_line) .. "\027[0m\n" .. tostring(pointer)
- local err_text = "\027[47;31;1m" .. tostring((" " .. err.error):wrap_to_1(box_width):gsub("\n", "\n\027[47;31;1m "))
- if err.hint then
- err_text = err_text .. "\n\027[47;30m" .. tostring((" Suggestion: " .. tostring(err.hint)):wrap_to_1(box_width):gsub("\n", "\n\027[47;30m "))
+ err_msg = err_msg .. "\n\027[2m" .. tostring(fmt_str:format(err_linenum)) .. tostring(err_line) .. "\027[0m"
+ end
+ local _, err_linenum_end, err_linepos_end = string2.line_at(err.source, err.stop)
+ if err_linenum_end == err_linenum then
+ err_msg = err_msg .. "\n" .. tostring(pointer)
+ else
+ for i = err_linenum + 1, err_linenum_end do
+ do
+ local line = string2.line(err.source, i)
+ if line then
+ if i == err_linenum_end then
+ local during, after = line:sub(1, err_linepos_end - 1), line:sub(err_linepos_end, -1)
+ err_msg = err_msg .. "\n\027[2m" .. tostring(fmt_str:format(i)) .. "\027[0;41;30m" .. tostring(during) .. "\027[0m" .. tostring(after)
+ else
+ err_msg = err_msg .. "\n\027[2m" .. tostring(fmt_str:format(i)) .. "\027[0m" .. tostring(line) .. "\027[0m"
+ end
+ end
+ end
end
- err_msg = err_msg .. ("\n\027[33;1m " .. box(err_text):gsub("\n", "\n "))
end
- for i = err_linenum + 1, err_linenum + context do
+ local box_width = 70
+ local err_text = "\027[47;31;1m" .. tostring((" " .. err.error):wrap_to_1(box_width):gsub("\n", "\n\027[47;31;1m "))
+ if err.hint then
+ err_text = err_text .. "\n\027[47;30m" .. tostring((" Suggestion: " .. tostring(err.hint)):wrap_to_1(box_width):gsub("\n", "\n\027[47;30m "))
+ end
+ err_msg = err_msg .. ("\n\027[33;1m " .. box(err_text):gsub("\n", "\n "))
+ for i = err_linenum_end + 1, err_linenum_end + context do
do
local line = string2.line(err.source, i)
if line then
diff --git a/pretty_errors.moon b/pretty_errors.moon
index 3adada5..3b583b7 100644
--- a/pretty_errors.moon
+++ b/pretty_errors.moon
@@ -28,17 +28,30 @@ format_error = (err)->
if line = string2.line(err.source, i)
err_msg ..= "\n\027[2m#{fmt_str\format(i)}\027[0m#{line}\027[0m"
if err_line
- box_width = 60
before = err_line\sub(1, err_linepos-1)
during = err_line\sub(err_linepos,err_linepos+err_size-1)
after = err_line\sub(err_linepos+err_size, -1)
err_line = "\027[0m#{before}\027[41;30m#{during}#{nl_indicator}\027[0m#{after}"
- err_msg ..= "\n\027[2m#{fmt_str\format(err_linenum)}#{err_line}\027[0m\n#{pointer}"
- err_text = "\027[47;31;1m#{(" "..err.error)\wrap_to_1(box_width)\gsub("\n", "\n\027[47;31;1m ")}"
- if err.hint
- err_text ..= "\n\027[47;30m#{(" Suggestion: #{err.hint}")\wrap_to_1(box_width)\gsub("\n", "\n\027[47;30m ")}"
- err_msg ..= "\n\027[33;1m "..box(err_text)\gsub("\n", "\n ")
- for i=err_linenum+1,err_linenum+context
+ err_msg ..= "\n\027[2m#{fmt_str\format(err_linenum)}#{err_line}\027[0m"
+ _, err_linenum_end, err_linepos_end = string2.line_at(err.source, err.stop)
+ if err_linenum_end == err_linenum
+ err_msg ..= "\n#{pointer}"
+ else
+ for i=err_linenum+1,err_linenum_end
+ if line = string2.line(err.source, i)
+ if i == err_linenum_end
+ during, after = line\sub(1,err_linepos_end-1), line\sub(err_linepos_end,-1)
+ err_msg ..= "\n\027[2m#{fmt_str\format(i)}\027[0;41;30m#{during}\027[0m#{after}"
+ else
+ err_msg ..= "\n\027[2m#{fmt_str\format(i)}\027[0m#{line}\027[0m"
+
+ box_width = 70
+ err_text = "\027[47;31;1m#{(" "..err.error)\wrap_to_1(box_width)\gsub("\n", "\n\027[47;31;1m ")}"
+ if err.hint
+ err_text ..= "\n\027[47;30m#{(" Suggestion: #{err.hint}")\wrap_to_1(box_width)\gsub("\n", "\n\027[47;30m ")}"
+ err_msg ..= "\n\027[33;1m "..box(err_text)\gsub("\n", "\n ")
+
+ for i=err_linenum_end+1,err_linenum_end+context
if line = string2.line(err.source, i)
err_msg ..= "\n\027[2m#{fmt_str\format(i)}\027[0m#{line}\027[0m"
return err_msg
diff --git a/string2.lua b/string2.lua
index 387fd65..80883d9 100644
--- a/string2.lua
+++ b/string2.lua
@@ -71,7 +71,7 @@ local string2 = {
return
end
for i, line, start, stop in isplit(self, '\n') do
- if stop >= pos then
+ if stop + 1 >= pos then
return line, i, (pos - start + 1)
end
end
diff --git a/string2.moon b/string2.moon
index 735a2cb..2273cff 100644
--- a/string2.moon
+++ b/string2.moon
@@ -26,7 +26,7 @@ string2 = {
assert(type(pos) == 'number', "Invalid string position")
return if pos < 1 or pos > #@
for i, line, start, stop in isplit(@, '\n')
- if stop >= pos
+ if stop+1 >= pos
return line, i, (pos-start+1)
wrap: (maxlen=80, buffer=8)=>