Improvements to indented text parsing and error reporting.

This commit is contained in:
Bruce Hill 2018-09-13 16:01:57 -07:00
parent ea310306d7
commit 4d48bf359d
5 changed files with 68 additions and 22 deletions

View File

@ -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\]+)+

View File

@ -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 "))
end
err_msg = err_msg .. ("\n\027[33;1m " .. box(err_text):gsub("\n", "\n "))
err_msg = err_msg .. "\n\027[2m" .. tostring(fmt_str:format(err_linenum)) .. tostring(err_line) .. "\027[0m"
end
for i = err_linenum + 1, err_linenum + context do
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
end
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

View File

@ -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

View File

@ -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

View File

@ -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)=>