pigpigyyy / Yuescript

A Moonscript dialect compiles to Lua.

Home Page:http://yuescript.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[feature request] close-variables for Lua versions below 5.4

SkyyySi opened this issue · comments

Lua 5.4 added support for using <close> on a variable to allow calling a destructor function as soon as it goes out of scope. I think that this feature could also be made to work with target versions below 5.4.

Let's assume we have this Yuescript code:

do
    close db_connection = { <close>: => @disconnect() }

    -- do stuff...

It could compile to something like this:

do
    local db_connection = setmetatable({}, { __close = function(self) self:disconnect() end })
    local _close_0 = assert(getmetatable(db_connection).__close)
    local _err_0 = false
    local _msg_0
    xpcall(function()

        -- do stuff...

    end, function(err)
        _err_0 = true
        _msg_0 = err
    end)
    _close_0(db_connection)
    if _err_0 then
        error(_msg_0)
    end
end

Also, I'd just like to say: Thank you for taking your time to address most of my issues and for being so responsive.

Tried to add this feature as:

f = ->
  close db_connection =
    disconnect: -> print "disconnect"
    <close>: => @disconnect!
  1, nil, 2, nil, 3

print f!

compiles to Lua target below 5.4:

local f
f = function()
  local db_connection = setmetatable({
    disconnect = function()
      return print("disconnect")
    end,
  }, {
    __close = function(self)
      return self:disconnect()
    end
  })
  local _close_0 = assert(getmetatable(db_connection).__close)
  return (function(_arg_0, ...)
    local _ok_0 = _arg_0
    _close_0(db_connection)
    if _ok_0 then
      return ...
    else
      return error(...)
    end
  end)(pcall(function()
    return 1, nil, 2, nil, 3
  end))
end
return print(f())

compiles to Lua target 5.4:

local f
f = function()
  local db_connection <close> = setmetatable({
    disconnect = function()
      return print("disconnect")
    end,
  }, {
    __close = function(self)
      return self:disconnect()
    end
  })
  return 1, nil, 2, nil, 3
end
return print(f())

Sorry for being late this time. It took me some effort trying out your good idea. And I made some modification according to the way that the variadic items can be handled, mentioned in issue #144.