Commits

jas43 committed 36970e8

Bindings for lightuserdata.

lightdata can be used to pass a C pointer (e.g. to a Fortran object) from
Fortran to the lua stack and vice versa.

Comments (0)

Files changed (4)

LuaFortran/flu_binding.f90

   public :: flu_insert
   public :: flu_isFunction, flu_isNumber, flu_isTable
   public :: flu_isNone, flu_isNoneOrNil, flu_isNil
-  public :: flu_isBoolean
+  public :: flu_isBoolean, flu_islightuserdata
   public :: flu_pcall
   public :: flu_next
   public :: flu_setTop
   public :: flu_setTable, flu_setField
   public :: flu_todouble
-  public :: flu_tolstring, flu_tonumber, flu_toboolean
+  public :: flu_tolstring, flu_tonumber, flu_toboolean, flu_touserdata
   public :: flu_pop
   public :: flu_pushinteger, flu_pushnil, flu_pushnumber, flu_pushboolean
-  public :: flu_pushstring, flu_pushvalue
+  public :: flu_pushstring, flu_pushvalue, flu_pushlightuserdata
 
   public :: flu_copyptr
   public :: flu_register
   end function flu_isNone
 
 
+  function flu_islightuserdata(L, index) result(is_lightuserdata)
+    type(flu_State) :: L
+    integer         :: index
+    logical         :: is_lightuserdata
+
+    integer(kind=c_int) :: c_index
+
+    c_index = int(index, kind = c_int)
+    is_lightuserdata = (lua_Type(L%state, c_index) .eq. LUA_TLIGHTUSERDATA)
+  end function flu_islightuserdata
+
+
   function flu_next(L, index) result(exists)
     type(flu_State) :: L
     integer, intent(in) :: index
     call lua_pushvalue(L%state, c_index)
   end subroutine flu_pushvalue
 
+  subroutine flu_pushlightuserdata(L, ptr)
+    type(flu_State) :: L
+    type(c_ptr) :: ptr
+
+    call lua_pushlightuserdata(L%state, ptr)
+
+  end subroutine flu_pushlightuserdata
+
 
   subroutine flu_settable(L, n)
     type(flu_State) :: L
     bool = (lua_toBoolean(L%state, c_index) == 1)
   end function flu_toBoolean
 
+
+  function flu_touserdata(L, index) result(ptr)
+    type(flu_State) :: L
+    integer :: index
+    type(c_ptr) :: ptr
+
+    integer(kind=c_int) :: c_index
+
+    c_index = index
+    ptr = lua_touserdata(L%state, c_index)
+  end function flu_touserdata
+
   subroutine flu_pushcclosure(L, fn, n)
     type(flu_State), value :: L 
     procedure(lua_Function) :: fn

LuaFortran/lua_fif.f90

       integer(kind=c_int) :: lua_toboolean
     end function lua_toboolean
 
+    function lua_touserdata(L, index) bind(c, name="lua_touserdata")
+      use, intrinsic :: iso_c_binding
+      type(c_ptr), value :: L
+      integer(kind=c_int), value :: index
+      type(c_ptr) :: lua_touserdata
+    end function lua_touserdata
+
     function lua_type(L, index) bind(c, name="lua_type")
       use, intrinsic :: iso_c_binding
       type(c_ptr), value :: L
       integer(c_int), value :: n
     end subroutine lua_pushcclosure
 
+    subroutine lua_pushlightuserdata(L, ptr) bind(c, name="lua_pushlightuserdata")
+      use, intrinsic :: iso_c_binding
+      type(c_ptr), value :: L
+      type(c_ptr), value :: ptr
+    end subroutine lua_pushlightuserdata
+
   end interface
   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

LuaFortran/lua_parameters.f90

   integer(kind=c_int), parameter :: LUA_TNONE = -1
   integer(kind=c_int), parameter :: LUA_TNIL = 0
   integer(kind=c_int), parameter :: LUA_TBOOLEAN = 1
+  integer(kind=c_int), parameter :: LUA_TLIGHTUSERDATA = 2
   integer(kind=c_int), parameter :: LUA_TTABLE = 5
   integer(kind=c_int), parameter :: LUA_TFUNCTION = 6
 

source/aot_top_module.f90

     module procedure aot_top_get_long
     module procedure aot_top_get_string
     module procedure aot_top_get_logical
+    module procedure aot_top_get_userdata
   end interface
 
 contains
   end subroutine aot_top_get_string
 
 
+  !> Interpret topmost entry on Lua stack as userdata.
+  subroutine aot_top_get_userdata(val, ErrCode, L, default)
+    use, intrinsic :: iso_c_binding
+    type(flu_State) :: L !< Handle to the Lua script
+
+    !> Value of the Variable in the script
+    type(c_ptr), intent(out) :: val
+
+    !> Error code to indicate what kind of problem might have occured.
+    integer, intent(out) :: ErrCode
+
+    !> Some default value, that should be used, if the variable is not set in
+    !! the Lua script.
+    type(c_ptr), optional, intent(in) :: default
+
+    logical :: not_retrievable
+
+    ErrCode = 0
+    not_retrievable = .false.
+
+    if (flu_isNoneOrNil(L, -1)) then
+      ErrCode = ibSet(ErrCode, aoterr_NonExistent)
+      not_retrievable = .true.
+    else
+      if (flu_islightuserdata(L, -1)) then
+        val = flu_touserdata(L, -1)
+      else
+        ErrCode = ibSet(ErrCode, aoterr_WrongType)
+        ErrCode = ibSet(ErrCode, aoterr_Fatal)
+        not_retrievable = .true.
+      end if
+    end if
+
+    if (not_retrievable) then
+      if (present(default)) then
+        val = default
+      else
+        ErrCode = ibSet(ErrCode, aoterr_Fatal)
+      end if
+    end if
+    call flu_pop(L)
+
+  end subroutine aot_top_get_userdata
+
+
 end module aot_top_module