c/lua:metatable
This commit is contained in:
125
c/lua/_demo/metatable/metatable.go
Normal file
125
c/lua/_demo/metatable/metatable.go
Normal file
@@ -0,0 +1,125 @@
|
||||
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!
|
||||
*/
|
||||
Reference in New Issue
Block a user