Much better reporting for compile-time errors (now includes source and
line number again)
This commit is contained in:
parent
83183122f1
commit
08e590ac57
64
nomsu.lua
64
nomsu.lua
@ -278,7 +278,7 @@ end
|
||||
local NomsuCompiler
|
||||
do
|
||||
local _class_0
|
||||
local stub_pattern, var_pattern, _running_files, MAX_LINE, math_expression
|
||||
local stub_pattern, var_pattern, _running_files, _report_error, MAX_LINE, math_expression
|
||||
local _base_0 = {
|
||||
define_action = function(self, signature, fn, is_compile_action)
|
||||
if is_compile_action == nil then
|
||||
@ -520,7 +520,9 @@ do
|
||||
end
|
||||
local ret = compile_action(tree, unpack(args))
|
||||
if not ret then
|
||||
error("Failed to produce any Lua")
|
||||
_report_error(tree, function(src)
|
||||
return "Compile-time action:\n" .. tostring(src) .. "\nfailed to produce any Lua"
|
||||
end)
|
||||
end
|
||||
return ret
|
||||
end
|
||||
@ -533,7 +535,9 @@ do
|
||||
else
|
||||
local tok_lua = self:tree_to_lua(tok)
|
||||
if not (tok_lua.is_value) then
|
||||
error("non-expression value inside math expression: " .. tostring(colored.yellow(repr(tok))))
|
||||
_report_error(tok, function(src)
|
||||
return "Non-expression value inside math expression:\n" .. tostring(src)
|
||||
end)
|
||||
end
|
||||
if tok.type == "Action" then
|
||||
tok_lua:parenthesize()
|
||||
@ -556,7 +560,9 @@ do
|
||||
end
|
||||
local arg_lua = self:tree_to_lua(tok)
|
||||
if not (arg_lua.is_value) then
|
||||
error("Cannot use:\n" .. tostring(colored.yellow(repr(tok))) .. "\nas an argument to " .. tostring(stub) .. ", since it's not an expression, it produces: " .. tostring(repr(arg_lua)), 0)
|
||||
_report_error(tok, function(src)
|
||||
return "Cannot use:\n" .. tostring(src) .. "\nas an argument to " .. tostring(stub) .. ", since it's not an expression, it produces: " .. tostring(repr(arg_lua)), 0
|
||||
end)
|
||||
end
|
||||
insert(args, arg_lua)
|
||||
_continue_0 = true
|
||||
@ -641,7 +647,11 @@ do
|
||||
end
|
||||
local bit_lua = self:tree_to_lua(bit)
|
||||
if not (bit_lua.is_value) then
|
||||
error("Cannot use " .. tostring(colored.yellow(repr(bit))) .. " as a string interpolation value, since it's not an expression.", 0)
|
||||
local src = ' ' .. tostring(self:tree_to_nomsu(bit)):gsub('\n', '\n ')
|
||||
local line = tostring(bit.source.filename) .. ":" .. tostring(pos_to_line(FILE_CACHE[bit.source.filename], bit.source.start))
|
||||
_report_error(bit, function(src)
|
||||
return "Cannot use:\n" .. tostring(src) .. "\nas a string interpolation value, since it's not an expression."
|
||||
end)
|
||||
end
|
||||
if #lua.bits > 0 then
|
||||
lua:append("..")
|
||||
@ -672,7 +682,9 @@ do
|
||||
for i, item in ipairs(tree) do
|
||||
local item_lua = self:tree_to_lua(item)
|
||||
if not (item_lua.is_value) then
|
||||
error("Cannot use " .. tostring(colored.yellow(repr(item))) .. " as a list item, since it's not an expression.", 0)
|
||||
_report_error(item, function(src)
|
||||
return "Cannot use:\n" .. tostring(src) .. "\nas a list item, since it's not an expression."
|
||||
end)
|
||||
end
|
||||
lua:append(item_lua)
|
||||
local item_string = tostring(item_lua)
|
||||
@ -723,11 +735,15 @@ do
|
||||
local key, value = tree[1], tree[2]
|
||||
local key_lua = self:tree_to_lua(key)
|
||||
if not (key_lua.is_value) then
|
||||
error("Cannot use " .. tostring(colored.yellow(repr(key))) .. " as a dict key, since it's not an expression.", 0)
|
||||
_report_error(tree[1], function(src)
|
||||
return "Cannot use:\n" .. tostring(src) .. "\nas a dict key, since it's not an expression."
|
||||
end)
|
||||
end
|
||||
local value_lua = value and self:tree_to_lua(value) or Lua.Value(key.source, "true")
|
||||
if not (value_lua.is_value) then
|
||||
error("Cannot use " .. tostring(colored.yellow(repr(value))) .. " as a dict value, since it's not an expression.", 0)
|
||||
_report_error(tree[2], function(src)
|
||||
return "Cannot use:\n" .. tostring(src) .. "\nas a dict value, since it's not an expression."
|
||||
end)
|
||||
end
|
||||
local key_str = tostring(key_lua):match([=[["']([a-zA-Z_][a-zA-Z0-9_]*)['"]]=])
|
||||
if key_str then
|
||||
@ -740,7 +756,9 @@ do
|
||||
elseif "IndexChain" == _exp_0 then
|
||||
local lua = self:tree_to_lua(tree[1])
|
||||
if not (lua.is_value) then
|
||||
error("Cannot index " .. tostring(colored.yellow(repr(tree[1]))) .. ", since it's not an expression.", 0)
|
||||
_report_error(tree[1], function(src)
|
||||
return "Cannot index:\n" .. tostring(src) .. "\nsince it's not an expression."
|
||||
end)
|
||||
end
|
||||
local first_char = tostring(lua):sub(1, 1)
|
||||
if first_char == "{" or first_char == '"' or first_char == "[" then
|
||||
@ -750,7 +768,9 @@ do
|
||||
local key = tree[i]
|
||||
local key_lua = self:tree_to_lua(key)
|
||||
if not (key_lua.is_value) then
|
||||
error("Cannot use " .. tostring(colored.yellow(repr(key))) .. " as an index, since it's not an expression.", 0)
|
||||
_report_error(key, function(src)
|
||||
return "Cannot use:\n" .. tostring(key) .. "\nas an index, since it's not an expression."
|
||||
end)
|
||||
end
|
||||
local key_lua_str = tostring(key_lua)
|
||||
do
|
||||
@ -884,10 +904,10 @@ do
|
||||
return nomsu
|
||||
end
|
||||
local nomsu = Nomsu(tree.source)
|
||||
for i, line in ipairs(self) do
|
||||
for i, line in ipairs(tree) do
|
||||
line = assert(self:tree_to_nomsu(line, nil, true), "Could not convert line to nomsu")
|
||||
nomsu:append(line)
|
||||
if i < #self then
|
||||
if i < #tree then
|
||||
nomsu:append("\n")
|
||||
if tostring(line):match("\n") then
|
||||
nomsu:append("\n")
|
||||
@ -1115,7 +1135,9 @@ do
|
||||
else
|
||||
local bit_lua = nomsu:tree_to_lua(bit)
|
||||
if not (bit_lua.is_value) then
|
||||
error("Cannot use " .. tostring(colored.yellow(repr(bit))) .. " as a string interpolation value, since it's not an expression.")
|
||||
_report_error(bit, function(src)
|
||||
return "Cannot use:\n" .. tostring(src) .. "\nas a string interpolation value, since it's not an expression."
|
||||
end)
|
||||
end
|
||||
lua:append(bit_lua)
|
||||
end
|
||||
@ -1142,7 +1164,9 @@ do
|
||||
else
|
||||
local bit_lua = nomsu:tree_to_lua(bit)
|
||||
if not (bit_lua.is_value) then
|
||||
error("Cannot use " .. tostring(colored.yellow(repr(bit))) .. " as a string interpolation value, since it's not an expression.", 0)
|
||||
_report_error(bit, function(src)
|
||||
return "Cannot use:\n" .. tostring(src) .. "\nas a string interpolation value, since it's not an expression."
|
||||
end)
|
||||
end
|
||||
lua:append(bit_lua)
|
||||
end
|
||||
@ -1335,6 +1359,18 @@ do
|
||||
]=], stub_defs)
|
||||
var_pattern = re.compile("{| ((('%' {%varname}) / %word) ([ ])*)+ !. |}", stub_defs)
|
||||
_running_files = { }
|
||||
_report_error = function(tok, fn)
|
||||
local file = FILE_CACHE[tok.source.filename]
|
||||
local line_no = pos_to_line(file, tok.source.start)
|
||||
local line_start = LINE_STARTS[file][line_no]
|
||||
local src = colored.dim(file:sub(line_start, tok.source.start - 1))
|
||||
src = src .. colored.underscore(colored.bright(colored.red(file:sub(tok.source.start, tok.source.stop - 1))))
|
||||
local end_of_line = (LINE_STARTS[file][pos_to_line(file, tok.source.stop) + 1] or 0) - 1
|
||||
src = src .. colored.dim(file:sub(tok.source.stop, end_of_line - 1))
|
||||
src = ' ' .. src:gsub('\n', '\n ')
|
||||
local err_msg = fn(src)
|
||||
return error(tostring(tok.source.filename) .. ":" .. tostring(line_no) .. ": " .. err_msg, 0)
|
||||
end
|
||||
MAX_LINE = 80
|
||||
math_expression = re.compile([[ ([+-] " ")* "%" (" " [*/^+-] (" " [+-])* " %")+ !. ]])
|
||||
NomsuCompiler = _class_0
|
||||
|
52
nomsu.moon
52
nomsu.moon
@ -399,6 +399,18 @@ class NomsuCompiler
|
||||
loaded[filename] = ret or true
|
||||
return ret
|
||||
|
||||
_report_error = (tok, fn)->
|
||||
file = FILE_CACHE[tok.source.filename]
|
||||
line_no = pos_to_line(file, tok.source.start)
|
||||
line_start = LINE_STARTS[file][line_no]
|
||||
src = colored.dim(file\sub(line_start, tok.source.start-1))
|
||||
src ..= colored.underscore colored.bright colored.red(file\sub(tok.source.start, tok.source.stop-1))
|
||||
end_of_line = (LINE_STARTS[file][pos_to_line(file, tok.source.stop) + 1] or 0) - 1
|
||||
src ..= colored.dim(file\sub(tok.source.stop, end_of_line-1))
|
||||
--src = ' '..tostring(@tree_to_nomsu(tok))\gsub('\n','\n ')
|
||||
src = ' '..src\gsub('\n', '\n ')
|
||||
err_msg = fn(src)
|
||||
error("#{tok.source.filename}:#{line_no}: "..err_msg, 0)
|
||||
run_lua: (lua)=>
|
||||
assert(type(lua) != 'string', "Attempt to run lua string instead of Lua (object)")
|
||||
lua_string = tostring(lua)
|
||||
@ -450,7 +462,9 @@ class NomsuCompiler
|
||||
-- Force Lua to avoid tail call optimization for debugging purposes
|
||||
-- TODO: use tail call
|
||||
ret = compile_action(tree, unpack(args))
|
||||
if not ret then error("Failed to produce any Lua")
|
||||
if not ret
|
||||
_report_error tree, (src)->
|
||||
"Compile-time action:\n#{src}\nfailed to produce any Lua"
|
||||
return ret
|
||||
action = rawget(@environment.ACTIONS, stub)
|
||||
lua = Lua.Value(tree.source)
|
||||
@ -464,7 +478,8 @@ class NomsuCompiler
|
||||
else
|
||||
tok_lua = @tree_to_lua(tok)
|
||||
unless tok_lua.is_value
|
||||
error("non-expression value inside math expression: #{colored.yellow repr(tok)}")
|
||||
_report_error tok, (src)->
|
||||
"Non-expression value inside math expression:\n#{src}"
|
||||
if tok.type == "Action"
|
||||
tok_lua\parenthesize!
|
||||
lua\append tok_lua
|
||||
@ -477,7 +492,8 @@ class NomsuCompiler
|
||||
if type(tok) == "string" then continue
|
||||
arg_lua = @tree_to_lua(tok)
|
||||
unless arg_lua.is_value
|
||||
error "Cannot use:\n#{colored.yellow repr(tok)}\nas an argument to #{stub}, since it's not an expression, it produces: #{repr arg_lua}", 0
|
||||
_report_error tok, (src)->
|
||||
"Cannot use:\n#{src}\nas an argument to #{stub}, since it's not an expression, it produces: #{repr arg_lua}", 0
|
||||
insert args, arg_lua
|
||||
|
||||
if action
|
||||
@ -525,7 +541,10 @@ class NomsuCompiler
|
||||
string_buffer = ""
|
||||
bit_lua = @tree_to_lua(bit)
|
||||
unless bit_lua.is_value
|
||||
error "Cannot use #{colored.yellow repr(bit)} as a string interpolation value, since it's not an expression.", 0
|
||||
src = ' '..tostring(@tree_to_nomsu(bit))\gsub('\n','\n ')
|
||||
line = "#{bit.source.filename}:#{pos_to_line(FILE_CACHE[bit.source.filename], bit.source.start)}"
|
||||
_report_error bit, (src)->
|
||||
"Cannot use:\n#{src}\nas a string interpolation value, since it's not an expression."
|
||||
if #lua.bits > 0 then lua\append ".."
|
||||
if bit.type != "Text"
|
||||
bit_lua = Lua.Value(bit.source, "stringify(",bit_lua,")")
|
||||
@ -545,7 +564,8 @@ class NomsuCompiler
|
||||
for i, item in ipairs tree
|
||||
item_lua = @tree_to_lua(item)
|
||||
unless item_lua.is_value
|
||||
error "Cannot use #{colored.yellow repr(item)} as a list item, since it's not an expression.", 0
|
||||
_report_error item, (src)->
|
||||
"Cannot use:\n#{src}\nas a list item, since it's not an expression."
|
||||
lua\append item_lua
|
||||
item_string = tostring(item_lua)
|
||||
last_line = item_string\match("[^\n]*$")
|
||||
@ -590,10 +610,12 @@ class NomsuCompiler
|
||||
key, value = tree[1], tree[2]
|
||||
key_lua = @tree_to_lua(key)
|
||||
unless key_lua.is_value
|
||||
error "Cannot use #{colored.yellow repr(key)} as a dict key, since it's not an expression.", 0
|
||||
_report_error tree[1], (src)->
|
||||
"Cannot use:\n#{src}\nas a dict key, since it's not an expression."
|
||||
value_lua = value and @tree_to_lua(value) or Lua.Value(key.source, "true")
|
||||
unless value_lua.is_value
|
||||
error "Cannot use #{colored.yellow repr(value)} as a dict value, since it's not an expression.", 0
|
||||
_report_error tree[2], (src)->
|
||||
"Cannot use:\n#{src}\nas a dict value, since it's not an expression."
|
||||
key_str = tostring(key_lua)\match([=[["']([a-zA-Z_][a-zA-Z0-9_]*)['"]]=])
|
||||
return if key_str
|
||||
Lua tree.source, key_str,"=",value_lua
|
||||
@ -608,7 +630,8 @@ class NomsuCompiler
|
||||
when "IndexChain"
|
||||
lua = @tree_to_lua(tree[1])
|
||||
unless lua.is_value
|
||||
error "Cannot index #{colored.yellow repr(tree[1])}, since it's not an expression.", 0
|
||||
_report_error tree[1], (src)->
|
||||
"Cannot index:\n#{src}\nsince it's not an expression."
|
||||
first_char = tostring(lua)\sub(1,1)
|
||||
if first_char == "{" or first_char == '"' or first_char == "["
|
||||
lua\parenthesize!
|
||||
@ -617,7 +640,8 @@ class NomsuCompiler
|
||||
key = tree[i]
|
||||
key_lua = @tree_to_lua(key)
|
||||
unless key_lua.is_value
|
||||
error "Cannot use #{colored.yellow repr(key)} as an index, since it's not an expression.", 0
|
||||
_report_error key, (src)->
|
||||
"Cannot use:\n#{key}\nas an index, since it's not an expression."
|
||||
key_lua_str = tostring(key_lua)
|
||||
if lua_id = key_lua_str\match("^['\"]([a-zA-Z_][a-zA-Z0-9_]*)['\"]$")
|
||||
lua\append ".#{lua_id}"
|
||||
@ -721,10 +745,10 @@ class NomsuCompiler
|
||||
nomsu\append line_nomsu
|
||||
return nomsu
|
||||
nomsu = Nomsu(tree.source)
|
||||
for i, line in ipairs @
|
||||
for i, line in ipairs tree
|
||||
line = assert(@tree_to_nomsu(line, nil, true), "Could not convert line to nomsu")
|
||||
nomsu\append line
|
||||
if i < #@
|
||||
if i < #tree
|
||||
nomsu\append "\n"
|
||||
if tostring(line)\match("\n")
|
||||
nomsu\append "\n"
|
||||
@ -892,7 +916,8 @@ class NomsuCompiler
|
||||
else
|
||||
bit_lua = nomsu\tree_to_lua(bit)
|
||||
unless bit_lua.is_value
|
||||
error "Cannot use #{colored.yellow repr(bit)} as a string interpolation value, since it's not an expression."
|
||||
_report_error bit, (src)->
|
||||
"Cannot use:\n#{src}\nas a string interpolation value, since it's not an expression."
|
||||
lua\append bit_lua
|
||||
|
||||
@define_compile_action "Lua %code", (_code)=>
|
||||
@ -914,7 +939,8 @@ class NomsuCompiler
|
||||
else
|
||||
bit_lua = nomsu\tree_to_lua(bit)
|
||||
unless bit_lua.is_value
|
||||
error "Cannot use #{colored.yellow repr(bit)} as a string interpolation value, since it's not an expression.", 0
|
||||
_report_error bit, (src)->
|
||||
"Cannot use:\n#{src}\nas a string interpolation value, since it's not an expression."
|
||||
lua\append bit_lua
|
||||
return lua
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user