The most popular language that transpiles to Lua is MoonScript. One problem with the MoonScript's compiler is that when a runtime error occurs on e.g. a table access the diagnostic source location is relative to the transpiled Lua and not to the source language.
E.g. this MoonScript program:
class C x! Compiles into:
local C do local _class_0 local _base_0 = { } _base_0.__index = _base_0 _class_0 = setmetatable({ __init = function() end, __base = _base_0, __name = "C" }, { __index = _base_0, __call = function(cls, ...) local _self_0 = setmetatable({}, _base_0) cls.__init(_self_0, ...) return _self_0 end }) _base_0.__class = _class_0 C = _class_0 end return x() When you run it, you get:
input:21: attempt to call a nil value (global 'x')
See, line 21? Should be line 2.
The Lua interpreter supports receiving bytecode, .luac. It supports source locations in instructions. As per https://www.lua.org/manual/5.1/luac.html, you can even strip source locations when compiling Lua to .luac:
-s strip debug information before writing the output file. This saves some space in very large chunks, but if errors occur when running a stripped chunk, then the error messages may not contain the full information they usually do. For instance, line numbers and names of local variables are lost.
Lua has no source maps like in PHP and JavaScript. I thought one way to adding source locations into the output code is by outputting bytecode, but I also found out someone got a hacky solution that probably involves use of pcall to handle exceptions and replace source locations.
So the question is, is there any language that compiles to Lua bytecode with source maps (or locations)?
Unofficial bytecode reference
https://the-ravi-programming-language.readthedocs.io/en/latest/lua_bytecode_reference.html
If you search for "debug" in this page, you can find:
GETUPVALandSETUPVALinstructions use internally-managed upvalue lists. The list of upvalue name strings that are found in a function prototype is for debugging purposes; it is not used by the Lua virtual machine and can be stripped by luac.
Error call stack
Calling Lua's error() also needs source mapping, e.g.:
error: illegal argument at foo/lib.lua:1:1 at caller.lua:1:1