pigpigyyy / Yuescript

A Moonscript dialect compiles to Lua.
http://yuescript.org
MIT License
424 stars 35 forks source link

[feature request] More direct source line mapping #141

Open SkyyySi opened 1 year ago

SkyyySi commented 1 year ago

Since the compiler can already append a comment to each Lua line saying what Yuescript line it came from, it would be nice if there were an option to instead just put all Lua code on the same line as the Yuescript code that produced it, as well as preserving empty lines.

For example, the code:

1| x = if this
2|     foo()
3| 
4| else
5|     bar()

would be compiled like this:

1| local x
2| if this then
3|     x = foo()
4| else
5|     x = bar()
6| end

My suggestion would be to allow for it to be compiled to something more like this:

1| local x; if this then
2|     x = foo()
3| 
4| else
5|     x = bar(); end

The goal is to make line numbers in tracebacks and debugging info map directly to their according Yuescript line, meaning that it would no longer be necessary to first look which Lua line the error occurred on and then go to the Yuescript line that produced it. Instead, we could simply go to the error line directly in the Yuescript file.

pigpigyyy commented 11 months ago

Added a new option -r to the compiler to generate Lua codes with corresponding line to the original Yuescript codes.

> yue -r test.yue

Will now compile the code

x = if this
  foo()

else
  bar()

to

local x;if this then
x = foo()else

x = bar()end

And the -r option can work with file watcher function.

> yue -r -w path_to_watch

Will generate the formatted Lua code when any script under watch folder changes.

johnd0e commented 11 months ago

@pigpigyyy it would be nice to have same option for yue lua module.

pigpigyyy commented 11 months ago

@pigpigyyy it would be nice to have same option for yue lua module.

The current line mapping function is done with a lib named luaminify, and I modified the lib source to support Lua 5.4 then added a transform function for converting Yuescript compiled codes. You can find the modified lib here: https://github.com/pigpigyyy/Yuescript/blob/main/src/3rdParty/luaminify.lua

And use it as:

local luaminify = require("luaminify")
local yue = require("yue")
local luaCode = yue.to_lua(yueCode, {reserve_line_number = true})
local output = luaminify.FormatYue(luaCode)
johnd0e commented 11 months ago

Thank you! Still I'd prefer to have possibility to use this option with loadstring/loadfile, mainly to simplify debugging tasks. Of cause I could reimplement loadstring/loadfile in my own code, but...

pigpigyyy commented 11 months ago

If you have the yue module available in Lua. You don't need 'luaminify' lib to do line mapping. You can use yue.traceback() to get debugging info with transformed line numbers.

local yue = require("yue")
local yuescriptCode = [[

if user = database.find_user "moon"
  print user.name
]]
local func, load_err = yue.loadstring(yuescriptCode, "moduleName")
if func then
  local success, result = xpcall(func, function(err)
    return yue.traceback(err)
  end)
  if success then
    return print(result)
  else
    return print("runtime error:\n" .. result)
  end
else
  return print("load error:\n" .. load_err)
end
johnd0e commented 11 months ago

You can use yue.traceback() to get debugging info with transformed line numbers.

I could use it in my code, but the issue is that the whole environment is in Lua, and I cannot change predefined error-catching functions there.