<p>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.</p>
<p>E.g. this MoonScript program:</p>
<pre><code>class C
x!
</code></pre>
<p>Compiles into:</p>
<pre class="lang-lua prettyprint-override"><code>local C
do
  local _class_0
  local _base_0 = { }
  _base_0.__index = _base_0
  _class_0 = setmetatable({
    __init = function() end,
    __base = _base_0,
    __name = &quot;C&quot;
  }, {
    __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()
</code></pre>
<p>When you run it, you get:</p>
<blockquote>
<p>input:21: attempt to call a nil value (global 'x')</p>
</blockquote>
<p>See, line 21? Should be line 2.</p>
<p>The Lua interpreter supports receiving bytecode, .luac. It supports source locations in instructions. As per <a href="https://www.lua.org/manual/5.1/luac.html" rel="nofollow noreferrer">https://www.lua.org/manual/5.1/luac.html</a>, you can even strip source locations when compiling Lua to .luac:</p>
<blockquote>
<p><strong>-s</strong> 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.</p>
</blockquote>
<p>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 <code>pcall</code> to handle exceptions and replace source locations.</p>
<p>So the question is, is there any language that compiles to Lua bytecode with source maps (or locations)?</p>
<h3>Unofficial bytecode reference</h3>
<p><a href="https://the-ravi-programming-language.readthedocs.io/en/latest/lua_bytecode_reference.html" rel="nofollow noreferrer">https://the-ravi-programming-language.readthedocs.io/en/latest/lua_bytecode_reference.html</a></p>
<p>If you search for &quot;debug&quot; in this page, you can find:</p>
<blockquote>
<p><code>GETUPVAL</code> and <code>SETUPVAL</code> instructions 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.</p>
</blockquote>
<h3>Error call stack</h3>
<p>Calling Lua's <code>error()</code> also needs source mapping, e.g.:</p>
<pre><code>error: illegal argument
  at foo/lib.lua:1:1
  at caller.lua:1:1
</code></pre>

<error-handling><debuggers>
Languages that compile to Lua bytecode (.luac) for including source locations?
CC BY-SA 4.0
2023-05-26T21:44:39.377Z
Hi Could you clarify the title of the question to match what you're asking about specifically? E.g., "Do any approaches exist for adding source locations to Lua bytecode from transpiled languages"
rydwolf
CC BY-SA 4.0
2023-05-26T21:52:39.887Z
@RydwolfPrograms Done!
Hydroper
CC BY-SA 4.0
2023-05-27T09:56:05.753Z
Many languages *do* directly compile to lua bytecode, though I don't know why moonscript specifically chose not to
mousetail 'he-him'
CC BY-SA 4.0
2023-05-31T17:34:19.967Z
I'm voting to close this question because it isn't very focused. It's well-researched and thought-out, but I can't understand what you're actually asking us. Do you want examples of languages that compile to Lua bytecode and include source maps? If so, please edit the question to make that clearer.
Ginger
CC BY-SA 4.0
2023-05-31T17:36:44.877Z
@Ginger I edited the last paragraph to clarify
Hydroper
<p>My language compiles to Lua, not bytecode, but I think the approach I use can be extended to bytecode as well. My transpiled code doesn't have many possible failure points (compile-time type checking handles most of that for me), but when there is one, I make sure to insert a &quot;failure function&quot; with the source code location.</p>
<p>For example, my language has nullable types, and with that comes the null assertion operator <code>!</code>. The &quot;intrinsics file&quot; that has the Lua code needed for the runtime to work has the following function:</p>
<pre class="lang-lua prettyprint-override"><code>function assertNonNull(value, location)
    if value == nil then
        if location ~= nil then
            error(&quot;Expression is null: &quot; .. location, 2)
        else
            error(&quot;Expression is null&quot;, 2)
        end
    else
        return value
    end
end
</code></pre>
<p>The standard library has this function:</p>
<pre><code>fun readLine(): String {
    return extern { io.read(&quot;*l&quot;) }!
}
</code></pre>
<p>The only thing you need to pay attention to here is the <code>!</code> at the end of the expression. The function gets transpiled into the following code (prettified for your sanity):</p>
<pre class="lang-lua prettyprint-override"><code>rol_readNumber_5982b = function ()
    return assertNonNull(
        io.read(&quot;*n&quot;), 
        &quot;file 'rio.rol', line 25, column 11, statement 'extern { io.read(\&quot;*n\&quot;) }!'&quot;
    )
end
</code></pre>
<p>Note how the <code>!</code> is transpiled into the function call <code>assertNonNull</code>. Also note now the source information is <em>directly compiled into the result</em>. I imagine you could do a similar thing with bytecode.</p>

CC BY-SA 4.0
2023-06-01T21:21:35.653Z
2023-06-01T21:21:35.653Z
Seggan
CC BY-SA 4.0
2023-06-01T23:25:14.567Z
Considering this kind of output is only neccessary for debugging a program, it looks useful! Though what if the language is dynamically-typed (e.g. MoonScript) and you have to compile the expression `o.x`? There can be an extra overhead if you add an error-checking step before that `o.x`.
Hydroper
CC BY-SA 4.0
2023-06-02T01:50:24.253Z
@MatheusDiasdeSouza thats why I opted for static typing, among other reasons
Seggan
# Languages that compile to Lua bytecode (.luac) for including source locations?
Posted by: username_0 on 2023-05-26
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:

GETUPVAL and SETUPVAL instructions 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
**Tags:** error-handling debuggers
> **Comments:**
> **username_1**: Hi Could you clarify the title of the question to match what you're asking about specifically? E.g., "Do any approaches exist for adding source locations to Lua bytecode from transpiled languages"  
> **username_0**: @RydwolfPrograms Done!  
> **username_2**: Many languages *do* directly compile to lua bytecode, though I don't know why moonscript specifically chose not to  
> **username_3**: I'm voting to close this question because it isn't very focused. It's well-researched and thought-out, but I can't understand what you're actually asking us. Do you want examples of languages that compile to Lua bytecode and include source maps? If so, please edit the question to make that clearer.  
> **username_0**: @Ginger I edited the last paragraph to clarify  
---
## 1 answers
### Answer by username_4 on 2023-06-01. Score: 3
My language compiles to Lua, not bytecode, but I think the approach I use can be extended to bytecode as well. My transpiled code doesn't have many possible failure points (compile-time type checking handles most of that for me), but when there is one, I make sure to insert a "failure function" with the source code location.
For example, my language has nullable types, and with that comes the null assertion operator !. The "intrinsics file" that has the Lua code needed for the runtime to work has the following function:
function assertNonNull(value, location)
    if value == nil then
        if location ~= nil then
            error("Expression is null: " .. location, 2)
        else
            error("Expression is null", 2)
        end
    else
        return value
    end
end

The standard library has this function:
fun readLine(): String {
    return extern { io.read("*l") }!
}

The only thing you need to pay attention to here is the ! at the end of the expression. The function gets transpiled into the following code (prettified for your sanity):
rol_readNumber_5982b = function ()
    return assertNonNull(
        io.read("*n"), 
        "file 'rio.rol', line 25, column 11, statement 'extern { io.read(\"*n\") }!'"
    )
end

Note how the ! is transpiled into the function call assertNonNull. Also note now the source information is directly compiled into the result. I imagine you could do a similar thing with bytecode.
> **Comments:**
> **username_0** (2023-06-01): Considering this kind of output is only neccessary for debugging a program, it looks useful! Though what if the language is dynamically-typed (e.g. MoonScript) and you have to compile the expression `o.x`? There can be an extra overhead if you add an error-checking step before that `o.x`.  
> **username_4** (2023-06-02): @MatheusDiasdeSouza thats why I opted for static typing, among other reasons  
---
