126 lines
3.0 KiB
Go
126 lines
3.0 KiB
Go
package main
|
|
|
|
import (
|
|
"github.com/goplus/llgo/c"
|
|
"github.com/goplus/llgo/c/lua"
|
|
)
|
|
|
|
func toString(L *lua.State) c.Int {
|
|
L.Pushstring(c.Str("Hello from metatable!"))
|
|
return 1
|
|
}
|
|
|
|
func printStack(L *lua.State, message string) {
|
|
top := L.Gettop()
|
|
c.Printf(c.Str("%s - Stack size: %d\n"), c.AllocaCStr(message), c.Int(top))
|
|
for i := c.Int(1); i <= top; i++ {
|
|
t := L.Type(i)
|
|
switch t {
|
|
case c.Int(lua.STRING):
|
|
c.Printf(c.Str(" %d: string: %s\n"), c.Int(i), L.Tostring(i))
|
|
case c.Int(lua.BOOLEAN):
|
|
c.Printf(c.Str(" %d: boolean: %v\n"), c.Int(i), L.Toboolean(i))
|
|
case c.Int(lua.NUMBER):
|
|
c.Printf(c.Str(" %d: number: %f\n"), c.Int(i), L.Tonumber(i))
|
|
default:
|
|
c.Printf(c.Str(" %d: %s\n"), c.Int(i), L.Typename(t))
|
|
}
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
L := lua.Newstate__1()
|
|
defer L.Close()
|
|
|
|
L.Openlibs()
|
|
|
|
L.Newtable()
|
|
printStack(L, "After creating main table")
|
|
|
|
L.Newtable()
|
|
printStack(L, "After creating metatable")
|
|
|
|
L.Pushcfunction(toString)
|
|
printStack(L, "After Push CFunction")
|
|
|
|
L.Setfield(-2, c.Str("__tostring"))
|
|
printStack(L, "After setting __tostring")
|
|
|
|
if L.Setmetatable(-2) == 0 {
|
|
c.Printf(c.Str("Failed to set metatable\n"))
|
|
}
|
|
printStack(L, "After setting metatable")
|
|
|
|
L.Setglobal(c.Str("obj"))
|
|
printStack(L, "After setting global obj")
|
|
|
|
testcode := c.Str(`
|
|
if obj == nil then
|
|
print('obj is not defined')
|
|
else
|
|
local mt = getmetatable(obj)
|
|
if not mt then
|
|
print('Metatable not set')
|
|
elseif not mt.__tostring then
|
|
print('__tostring not set in metatable')
|
|
else
|
|
print(mt.__tostring(obj))
|
|
end
|
|
end
|
|
`)
|
|
|
|
if L.Dostring(testcode) != lua.OK {
|
|
c.Printf(c.Str("Error: %s\n"), L.Tostring(-1))
|
|
}
|
|
|
|
L.Getglobal(c.Str("obj"))
|
|
if L.Getmetatable(-1) != 0 {
|
|
c.Printf(c.Str("Metatable get success\n"))
|
|
L.Pushstring(c.Str("__tostring"))
|
|
L.Gettable(-2)
|
|
if L.Isfunction(-1) {
|
|
c.Printf(c.Str("__tostring function found in metatable\n"))
|
|
if L.Iscfunction(-1) != 0 {
|
|
c.Printf(c.Str("__tostring is a C function\n"))
|
|
cfunc := L.Tocfunction(-1)
|
|
if cfunc != nil {
|
|
c.Printf(c.Str("Successfully retrieved __tostring C function pointer\n"))
|
|
L.Pushcfunction(cfunc)
|
|
if L.Call(0, 1) == lua.OK {
|
|
result := L.Tostring(-1)
|
|
c.Printf(c.Str("Result of calling __tostring: %s\n"), result)
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
c.Printf(c.Str("__tostring function not found in metatable\n"))
|
|
}
|
|
} else {
|
|
c.Printf(c.Str("No metatable found using GetTable\n"))
|
|
}
|
|
}
|
|
|
|
/* Expected output:
|
|
After creating main table - Stack size: 1
|
|
1: table
|
|
After creating metatable - Stack size: 2
|
|
1: table
|
|
2: table
|
|
After Push CFunction - Stack size: 3
|
|
1: table
|
|
2: table
|
|
3: function
|
|
After setting __tostring - Stack size: 2
|
|
1: table
|
|
2: table
|
|
After setting metatable - Stack size: 1
|
|
1: table
|
|
After setting global obj - Stack size: 0
|
|
Hello from metatable!
|
|
Metatable get success
|
|
__tostring function found in metatable
|
|
__tostring is a C function
|
|
Successfully retrieved __tostring C function pointer
|
|
Result of calling __tostring: Hello from metatable!
|
|
*/
|