Files
llgo/c/lua/_demo/metatable/metatable.go
2024-07-28 19:32:19 +08:00

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()
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!
*/