Better handling of invalid line numbers (returning nil instead of random
garbage).
This commit is contained in:
parent
dfd39f0b14
commit
0fe94570b5
@ -143,7 +143,11 @@ Files.get_line_number = (str, pos)->
|
|||||||
|
|
||||||
Files.get_line = (str, line_no)->
|
Files.get_line = (str, line_no)->
|
||||||
line_starts = Files.get_line_starts(str)
|
line_starts = Files.get_line_starts(str)
|
||||||
return str\sub(line_starts[line_no] or 1, (line_starts[line_no+1] or 1) - 2)
|
start = line_starts[line_no]
|
||||||
|
return unless start
|
||||||
|
stop = line_starts[line_no+1]
|
||||||
|
return unless stop
|
||||||
|
return str\sub(start, stop - 2)
|
||||||
|
|
||||||
get_lines = re.compile([[
|
get_lines = re.compile([[
|
||||||
lines <- {| line (%nl line)* |}
|
lines <- {| line (%nl line)* |}
|
||||||
|
15
parser.moon
15
parser.moon
@ -46,17 +46,18 @@ NOMSU_DEFS = with {}
|
|||||||
err_pos = start_pos
|
err_pos = start_pos
|
||||||
line_no = files.get_line_number(src, err_pos)
|
line_no = files.get_line_number(src, err_pos)
|
||||||
--src = files.read(userdata.source.filename)
|
--src = files.read(userdata.source.filename)
|
||||||
prev_line = line_no == 1 and "" or files.get_line(src, line_no-1)
|
prev_line = line_no == 1 and nil or files.get_line(src, line_no-1)
|
||||||
err_line = files.get_line(src, line_no)
|
err_line = files.get_line(src, line_no)
|
||||||
next_line = files.get_line(src, line_no+1)
|
next_line = files.get_line(src, line_no+1)
|
||||||
i = err_pos-files.get_line_starts(src)[line_no]
|
i = err_pos-files.get_line_starts(src)[line_no]
|
||||||
j = i + (end_pos-start_pos)
|
j = i + (end_pos-start_pos)
|
||||||
pointer = ("-")\rep(i) .. "^"
|
pointer = ("-")\rep(i) .. "^"
|
||||||
err_msg = colored.bright colored.yellow colored.onred (err_msg or "Parse error").." at #{userdata.source.filename}:#{line_no}:"
|
err_msg = colored.bright colored.yellow colored.onred (err_msg or "Parse error").." at #{userdata.source.filename}:#{line_no}:"
|
||||||
if #prev_line > 0 then err_msg ..= "\n"..colored.dim(prev_line)
|
if prev_line then err_msg ..= "\n"..colored.dim(prev_line)
|
||||||
err_line = colored.white(err_line\sub(1, i))..colored.bright(colored.red(err_line\sub(i+1,j+1)))..colored.dim(err_line\sub(j+2,-1))
|
if err_line
|
||||||
err_msg ..= "\n#{err_line}\n#{colored.red pointer}"
|
err_line = colored.white(err_line\sub(1, i))..colored.bright(colored.red(err_line\sub(i+1,j+1)))..colored.dim(err_line\sub(j+2,-1))
|
||||||
if #next_line > 0 then err_msg ..= "\n"..colored.dim(next_line)
|
err_msg ..= "\n#{err_line}\n#{colored.red pointer}"
|
||||||
|
if next_line then err_msg ..= "\n"..colored.dim(next_line)
|
||||||
seen_errors[start_pos] = err_msg
|
seen_errors[start_pos] = err_msg
|
||||||
return true
|
return true
|
||||||
|
|
||||||
@ -110,10 +111,8 @@ Parser.parse = (nomsu_code, source=nil, version=nil)->
|
|||||||
errors: {}, :source, comments: {}
|
errors: {}, :source, comments: {}
|
||||||
}
|
}
|
||||||
tree = Parser.patterns[syntax_version]\match(nomsu_code, nil, userdata)
|
tree = Parser.patterns[syntax_version]\match(nomsu_code, nil, userdata)
|
||||||
unless tree
|
if not tree or type(tree) == 'number'
|
||||||
error "In file #{colored.blue tostring(source or "<unknown>")} failed to parse:\n#{colored.onyellow colored.black nomsu_code}"
|
error "In file #{colored.blue tostring(source or "<unknown>")} failed to parse:\n#{colored.onyellow colored.black nomsu_code}"
|
||||||
if type(tree) == 'number'
|
|
||||||
return nil
|
|
||||||
|
|
||||||
if next(userdata.errors)
|
if next(userdata.errors)
|
||||||
keys = [k for k,v in pairs(userdata.errors)]
|
keys = [k for k,v in pairs(userdata.errors)]
|
||||||
|
Loading…
Reference in New Issue
Block a user