c/lua:coroutine continuation
This commit is contained in:
72
c/lua/_demo/crroutine-continue/corroutine.go
Normal file
72
c/lua/_demo/crroutine-continue/corroutine.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/goplus/llgo/c"
|
||||
"github.com/goplus/llgo/c/lua"
|
||||
)
|
||||
|
||||
func countdownContinue(L *lua.State, status c.Int, ctx lua.KContext) c.Int {
|
||||
return countdown(L)
|
||||
}
|
||||
|
||||
func countdown(L *lua.State) c.Int {
|
||||
arg := L.Tointeger(lua.Upvalueindex(1))
|
||||
c.Printf(c.Str("resume called with %d\n"), arg)
|
||||
if arg > 0 {
|
||||
L.Pushinteger(arg - 1)
|
||||
L.Replace(lua.Upvalueindex(1))
|
||||
L.Pushinteger(arg)
|
||||
return L.Yieldk(1, c.Pointer(uintptr(0)), countdownContinue)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func createCountdown(L *lua.State) c.Int {
|
||||
max := L.Checkinteger(1)
|
||||
L.Pushinteger(max)
|
||||
L.Pushcclosure(countdown, 1)
|
||||
return 1
|
||||
}
|
||||
|
||||
func main() {
|
||||
L := lua.Newstate()
|
||||
L.Openlibs()
|
||||
defer L.Close()
|
||||
L.Register(c.Str("create_countdown"), createCountdown)
|
||||
|
||||
testcode := c.Str(`
|
||||
local countdown = create_countdown(5)
|
||||
local co = coroutine.create(countdown)
|
||||
while true do
|
||||
local success, value = coroutine.resume(co)
|
||||
if not success then
|
||||
print('Error:', value)
|
||||
break
|
||||
end
|
||||
if value == nil then break end
|
||||
print('Lua received:', value)
|
||||
end
|
||||
print('Countdown finished');
|
||||
`)
|
||||
|
||||
if L.Dostring(testcode) != lua.OK {
|
||||
c.Printf(c.Str("Error: %s\n"), L.Tostring(-1))
|
||||
}
|
||||
|
||||
L.Openlibs()
|
||||
}
|
||||
|
||||
/* Expected output:
|
||||
resume called with 5
|
||||
Lua received: 5
|
||||
resume called with 4
|
||||
Lua received: 4
|
||||
resume called with 3
|
||||
Lua received: 3
|
||||
resume called with 2
|
||||
Lua received: 2
|
||||
resume called with 1
|
||||
Lua received: 1
|
||||
resume called with 0
|
||||
Countdown finished
|
||||
*/
|
||||
@@ -14,6 +14,12 @@ import (
|
||||
|
||||
// /* key, in the registry, for table of preloaded loaders */
|
||||
|
||||
// llgo:link (*State).Checkinteger C.luaL_checkinteger
|
||||
func (L *State) Checkinteger(arg c.Int) Integer { return 0 }
|
||||
|
||||
// llgo:link (*State).Checknumber C.luaL_checknumber
|
||||
func (L *State) Checknumber(arg c.Int) Number { return 0 }
|
||||
|
||||
// llgo:link (*State).LError C.luaL_error
|
||||
func (L *State) LError(format *c.Char, __llgo_va_list ...any) c.Int { return 0 }
|
||||
|
||||
|
||||
28
c/lua/lua.go
28
c/lua/lua.go
@@ -23,6 +23,14 @@ const (
|
||||
// ** space after that to help overflow detection)
|
||||
// */
|
||||
|
||||
const (
|
||||
REGISTRYINDEX = -MAXSTACK - 1000
|
||||
)
|
||||
|
||||
func Upvalueindex(i c.Int) c.Int {
|
||||
return c.Int(REGISTRYINDEX) - i
|
||||
}
|
||||
|
||||
// /* thread status */
|
||||
const (
|
||||
OK = 0
|
||||
@@ -438,9 +446,19 @@ func (L *State) Isnoneornil(n c.Int) bool { return L.Type(n) <= 0 }
|
||||
// #define lua_pushliteral(L, s) lua_pushstring(L, "" s)
|
||||
// #define lua_pushglobaltable(L) ((void)lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS))
|
||||
|
||||
// #define lua_insert(L,idx) lua_rotate(L, (idx), 1)
|
||||
// #define lua_remove(L,idx) (lua_rotate(L, (idx), -1), lua_pop(L, 1))
|
||||
// #define lua_replace(L,idx) (lua_copy(L, -1, (idx)), lua_pop(L, 1))
|
||||
func (L *State) Insert(idx c.Int) {
|
||||
L.Rotate(idx, 1)
|
||||
}
|
||||
|
||||
func (L *State) Remove(idx c.Int) {
|
||||
L.Rotate(idx, -1)
|
||||
L.Pop(1)
|
||||
}
|
||||
|
||||
func (L *State) Replace(idx c.Int) {
|
||||
L.Copy(-1, idx)
|
||||
L.Pop(1)
|
||||
}
|
||||
|
||||
// /* }============================================================== */
|
||||
|
||||
@@ -478,10 +496,6 @@ const (
|
||||
// /*
|
||||
// ** Event masks
|
||||
// */
|
||||
// #define LUA_MASKCALL (1 << LUA_HOOKCALL)
|
||||
// #define LUA_MASKRET (1 << LUA_HOOKRET)
|
||||
// #define LUA_MASKLINE (1 << LUA_HOOKLINE)
|
||||
// #define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
|
||||
|
||||
const (
|
||||
MASKCALL = 1 << HOOKCOUNT
|
||||
|
||||
21
c/lua/luaconf.go
Normal file
21
c/lua/luaconf.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package lua
|
||||
|
||||
/*
|
||||
** {==================================================================
|
||||
** Macros that affect the API and must be stable (that is, must be the
|
||||
** same when you compile Lua and when you compile code that links to
|
||||
** Lua).
|
||||
** =====================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ LUAI_MAXSTACK limits the size of the Lua stack.
|
||||
** CHANGE it if you need a different limit. This limit is arbitrary;
|
||||
** its only purpose is to stop Lua from consuming unlimited stack
|
||||
** space (and to reserve some numbers for pseudo-indices).
|
||||
** (It must fit into max(size_t)/32 and max(int)/2.)
|
||||
*/
|
||||
|
||||
const (
|
||||
MAXSTACK = 1000000
|
||||
)
|
||||
Reference in New Issue
Block a user