47 lines
2.2 KiB
Plaintext
47 lines
2.2 KiB
Plaintext
![]() |
-- This file has code for converting errors to user-friendly format, with colors,
|
||
|
-- line numbers, code excerpts, and so on.
|
||
|
require "containers"
|
||
|
string2 = require 'string2'
|
||
|
|
||
|
box = (text)->
|
||
|
max_line = 0
|
||
|
for line in text\gmatch("[^\n]+")
|
||
|
max_line = math.max(max_line, #(line\gsub("\027%[[0-9;]*m","")))
|
||
|
ret = ("\n"..text)\gsub "\n([^\n]*)", (line)->
|
||
|
line_len = #(line\gsub("\027%[[0-9;]*m",""))
|
||
|
return "\n#{line}#{(" ")\rep(max_line-line_len)} \027[0m"
|
||
|
return ret\sub(2,-1), max_line
|
||
|
|
||
|
format_error = (err)->
|
||
|
context = err.context or 2
|
||
|
err_line, err_linenum, err_linepos = string2.line_at(err.source, err.start)
|
||
|
-- TODO: better handle multi-line errors
|
||
|
err_size = math.min((err.stop - err.start), (#err_line-err_linepos) + 1)
|
||
|
nl_indicator = (err_linepos > #err_line) and " " or ""
|
||
|
fmt_str = " %#{#tostring(err_linenum+context)}d|"
|
||
|
pointer = if err_size >= 2
|
||
|
(" ")\rep(err_linepos+#fmt_str\format(0)-1).."╚#{("═")\rep(err_size-2)}╝"
|
||
|
else
|
||
|
(" ")\rep(err_linepos+#fmt_str\format(0)-1).."⬆"
|
||
|
err_msg = "\027[33;41;1mParse error at #{err.filename}:#{err_linenum}\027[0m"
|
||
|
for i=err_linenum-context,err_linenum-1
|
||
|
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
|
||
|
if line = string2.line(err.source, i)
|
||
|
err_msg ..= "\n\027[2m#{fmt_str\format(i)}\027[0m#{line}\027[0m"
|
||
|
return err_msg
|
||
|
|
||
|
return format_error
|