From 7a294e6d4e319caf16ce4f71256cd9c8dd724524 Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Thu, 27 Jun 2024 18:19:45 +0800 Subject: [PATCH 1/2] llgo/c/lua --- c/lua/_demo/error/error.go | 21 ++ c/lua/_demo/funccall-concat/funccall.go | 32 +++ c/lua/_demo/funccall-number/funccall.go | 39 +++ c/lua/_demo/funccall-string/funccall.go | 48 ++++ c/lua/_demo/hello/hello.go | 17 ++ c/lua/_demo/loadcall/loadcall.go | 22 ++ .../_demo/problem/pushinteger/pushinteger.go | 42 +++ c/lua/_demo/stack/stack.go | 80 ++++++ c/lua/lauxlib.go | 101 +++++++ c/lua/lua.go | 269 ++++++++++++++++++ c/lua/lualib.go | 8 + 11 files changed, 679 insertions(+) create mode 100644 c/lua/_demo/error/error.go create mode 100644 c/lua/_demo/funccall-concat/funccall.go create mode 100644 c/lua/_demo/funccall-number/funccall.go create mode 100644 c/lua/_demo/funccall-string/funccall.go create mode 100644 c/lua/_demo/hello/hello.go create mode 100644 c/lua/_demo/loadcall/loadcall.go create mode 100644 c/lua/_demo/problem/pushinteger/pushinteger.go create mode 100644 c/lua/_demo/stack/stack.go create mode 100644 c/lua/lauxlib.go create mode 100644 c/lua/lua.go create mode 100644 c/lua/lualib.go diff --git a/c/lua/_demo/error/error.go b/c/lua/_demo/error/error.go new file mode 100644 index 00000000..ff8a0c86 --- /dev/null +++ b/c/lua/_demo/error/error.go @@ -0,0 +1,21 @@ +package main + +import ( + _ "unsafe" + + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/c/lua" +) + +func main() { + L := lua.NewState() + defer L.Close() + L.OpenLibs() + if res := L.LoadString(c.Str("function doubleNumber(x) ! return x * 2 end")); res != lua.OK { + c.Printf(c.Str("error: %s\n"), L.ToString(-1)) + } +} + +/* Expected output: +error: [string "function doubleNumber(x) ! return x * 2 end"]:1: unexpected symbol near '!' +*/ diff --git a/c/lua/_demo/funccall-concat/funccall.go b/c/lua/_demo/funccall-concat/funccall.go new file mode 100644 index 00000000..d313314e --- /dev/null +++ b/c/lua/_demo/funccall-concat/funccall.go @@ -0,0 +1,32 @@ +package main + +import ( + _ "unsafe" + + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/c/lua" +) + +func main() { + L := lua.NewState() + defer L.Close() + + L.OpenLibs() + if res := L.Dostring(c.Str("function combineParams(num, str) return 'Result: ' .. str .. ' ' .. num end")); res != lua.OK { + c.Printf(c.Str("error: %s\n"), L.ToString(-1)) + } + L.GetGlobal(c.Str("combineParams")) + L.PushNumber(3.14159) + L.PushString(c.Str("Hello, World!")) + if res := L.PCall(2, 1, 0); res != lua.OK { + c.Printf(c.Str("error: %s\n"), L.ToString(-1)) + } + if res := L.IsString(-1); res != 0 { + result := L.ToString(-1) + c.Printf(result) + } +} + +/* Expected output: +Result: Hello, World! 3.14159 +*/ diff --git a/c/lua/_demo/funccall-number/funccall.go b/c/lua/_demo/funccall-number/funccall.go new file mode 100644 index 00000000..ddcc6e02 --- /dev/null +++ b/c/lua/_demo/funccall-number/funccall.go @@ -0,0 +1,39 @@ +package main + +import ( + _ "unsafe" + + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/c/lua" +) + +func main() { + L := lua.NewState() + defer L.Close() + + L.OpenLibs() + if res := L.LoadString(c.Str("function doubleNumber(x) return x * 2 end")); res != lua.OK { + c.Printf(c.Str("error: %s\n"), L.ToString(-1)) + } + if res := L.PCall(0, 0, 0); res != lua.OK { + c.Printf(c.Str("error: %s\n"), L.ToString(-1)) + } + + L.GetGlobal(c.Str("doubleNumber")) + L.PushNumber(10) + + if res := L.PCall(1, 1, 0); res != lua.OK { + c.Printf(c.Str("error: %s\n"), L.ToString(-1)) + } + + if res := L.IsNumber(-1); res != 0 { + result := L.ToInteger(-1) + c.Printf(c.Str("result: %lld\n"), result) + } else { + c.Printf(c.Str("error: %s\n"), L.ToString(-1)) + } +} + +/* Expected output: +result: 20 +*/ diff --git a/c/lua/_demo/funccall-string/funccall.go b/c/lua/_demo/funccall-string/funccall.go new file mode 100644 index 00000000..91d220de --- /dev/null +++ b/c/lua/_demo/funccall-string/funccall.go @@ -0,0 +1,48 @@ +package main + +import ( + _ "unsafe" + + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/c/lua" +) + +func main() { + L := lua.NewState() + defer L.Close() + + L.OpenLibs() + code := c.Str( + `function processStrings(a, b, c) + print('Received string a: ' .. a) + print('Received string b: ', b) + print('Received string c (formatted): ' .. c) + return a .. b .. c +end`) + + if res := L.Dostring(code); res != lua.OK { + c.Printf(c.Str("error: %s\n"), L.ToString(-1)) + } + + L.GetGlobal(c.Str("processStrings")) + + L.PushString(c.Str("Hello, World!")) + L.PushLString(c.Str(`Hello Lua In LLGO`), 17) + L.PushFString(c.Str(`Hello %s In %d`), c.Str("LLGO"), 2024) + + if res := L.PCall(3, 1, 0); res != lua.OK { + c.Printf(c.Str("error: %s\n"), L.ToString(-1)) + } + + if res := L.IsString(-1); res != 0 { + result := L.ToString(-1) + c.Printf(c.Str("result: %s\n"), result) + } +} + +/* Expected output: +Received string a: Hello, World! +Received string b: Hello Lua In LLGO +Received string c (formatted): Hello LLGO In 2024 +result: Hello, World!Hello Lua In LLGOHello LLGO In 2024 +*/ diff --git a/c/lua/_demo/hello/hello.go b/c/lua/_demo/hello/hello.go new file mode 100644 index 00000000..cb96ddde --- /dev/null +++ b/c/lua/_demo/hello/hello.go @@ -0,0 +1,17 @@ +package main + +import ( + _ "unsafe" + + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/c/lua" +) + +func main() { + L := lua.NewState() + defer L.Close() + L.OpenLibs() + if res := L.Dostring(c.Str("print('hello world')")); res != lua.OK { + println("error") + } +} diff --git a/c/lua/_demo/loadcall/loadcall.go b/c/lua/_demo/loadcall/loadcall.go new file mode 100644 index 00000000..9fd04671 --- /dev/null +++ b/c/lua/_demo/loadcall/loadcall.go @@ -0,0 +1,22 @@ +package main + +import ( + _ "unsafe" + + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/c/lua" +) + +func main() { + L := lua.NewState() + defer L.Close() + + L.OpenLibs() + if res := L.LoadString(c.Str("print('hello world')")); res != lua.OK { + println("error") + } + if res := L.PCall(0, 0, 0); res != lua.OK { + println("error") + } + +} diff --git a/c/lua/_demo/problem/pushinteger/pushinteger.go b/c/lua/_demo/problem/pushinteger/pushinteger.go new file mode 100644 index 00000000..815d3fe0 --- /dev/null +++ b/c/lua/_demo/problem/pushinteger/pushinteger.go @@ -0,0 +1,42 @@ +package main + +import ( + _ "unsafe" + + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/c/lua" +) + +func main() { + L := lua.NewState() + defer L.Close() + + L.OpenLibs() + // TODO(zzy): fix push interger got stuck + code := c.Str(`function combineParams(x) + return x * 2 +end`) + if res := L.Dostring(code); res != lua.OK { + c.Printf(c.Str("error: %s\n"), L.ToString(-1)) + } + L.GetGlobal(c.Str("combineParams")) + c.Printf(c.Str("stack lens:%d\n"), L.GetTop()) // stack lens:1 + + L.PushInteger(lua.Integer(42)) + pushed := L.ToInteger(-1) + + c.Printf(c.Str("pushed: %lld\n"), pushed) // pushed: 0 + c.Printf(c.Str("stack lens:%d\n"), L.GetTop()) // stack lens:1 + + // L.PushNumber(42) + // pushed := L.ToNumber(-1) + // c.Printf(c.Str("pushed: %f\n"), pushed) + + if res := L.PCall(1, 1, 0); res != lua.OK { + c.Printf(c.Str("error: %s\n"), L.ToString(-1)) + } + if res := L.IsNumber(-1); res != 0 { + result := L.ToInteger(-1) + c.Printf(c.Str("result %f"), result) + } +} diff --git a/c/lua/_demo/stack/stack.go b/c/lua/_demo/stack/stack.go new file mode 100644 index 00000000..ef1fc556 --- /dev/null +++ b/c/lua/_demo/stack/stack.go @@ -0,0 +1,80 @@ +package main + +import ( + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/c/lua" +) + +// printStack prints the current stack of the given Lua state. +func printStack(L *lua.Lua_State, stateName *c.Char) { + top := L.GetTop() + // c.Printf(c.Str("%s stack (top=%d): "), c.GoStringData("sdasd"), top) + c.Printf(c.Str("%s stack (top=%d):"), stateName, top) + for i := 1; i <= int(top); i++ { + c.Printf(c.Str("%s "), L.ToString(c.Int(i))) + } + c.Printf(c.Str("\n")) +} + +func main() { + // Create a new Lua state and open libraries + L := lua.NewState() + defer L.Close() + L.OpenLibs() + + // Push initial values onto the stack + L.PushString(c.Str("Hello")) + L.PushString(c.Str("LLGO")) + L.PushNumber(2024) + + // Print initial stack + c.Printf(c.Str("Initial stack:\n")) + printStack(L, c.Str("L1")) + + // Use absindex to ensure the index is positive + idx := -2 + absIdx := L.AbsIndex(c.Int(idx)) + c.Printf(c.Str("Absolute index of 'LLGO': %d\n"), absIdx) + + // Copy 'LLGO' to the top of the stack + L.PushValue(absIdx) + c.Printf(c.Str("\nAfter pushing 'LLGO' to the top:\n")) + printStack(L, c.Str("L1")) + + // Rotate stack elements + L.Rotate(c.Int(1), c.Int(-1)) + c.Printf(c.Str("\nAfter rotating the stack:\n")) + printStack(L, c.Str("L1")) + + // Copy the top element to index 2 + L.Copy(c.Int(-1), c.Int(2)) + c.Printf(c.Str("\nAfter copying the top element to index 2:\n")) + printStack(L, c.Str("L1")) + + // Check if we can grow the stack + if L.CheckStack(c.Int(2)) == 0 { + c.Printf(c.Str("Cannot grow stack\n")) + return + } + + // Push additional elements + L.PushNumber(3.14) + L.PushString(c.Str("Lua")) + c.Printf(c.Str("\nAfter pushing more elements:\n")) + printStack(L, c.Str("L1")) + + // Set the top of the stack, clearing extra elements + L.SetTop(c.Int(5)) + c.Printf(c.Str("\nAfter setting top to 5:\n")) + printStack(L, c.Str("L1")) + + // Create a second Lua state + L1 := lua.NewState() + defer L1.Close() + + // Move two elements to the new state + L.Xmove(L1, c.Int(2)) + c.Printf(c.Str("\nAfter moving two elements to L1:\n")) + printStack(L, c.Str("L1")) + printStack(L1, c.Str("L2")) +} diff --git a/c/lua/lauxlib.go b/c/lua/lauxlib.go new file mode 100644 index 00000000..81bcd475 --- /dev/null +++ b/c/lua/lauxlib.go @@ -0,0 +1,101 @@ +package lua + +import ( + _ "unsafe" + + "github.com/goplus/llgo/c" +) + +// /* global table */ + +// /* extra error code for 'luaL_loadfilex' */ + +// /* key, in the registry, for table of loaded modules */ + +// /* key, in the registry, for table of preloaded loaders */ + +// /* predefined references */ + +// llgo:link (*Lua_State).LoadFilex C.luaL_loadfilex +func (L *Lua_State) LoadFilex(filename *c.Char, mode *c.Char) c.Int { return 0 } + +func (L *Lua_State) LoadFile(filename *c.Char) c.Int { return L.LoadFilex(filename, nil) } + +// llgo:link (*Lua_State).LoadString C.luaL_loadstring +func (L *Lua_State) LoadString(s *c.Char) c.Int { return 0 } + +//go:linkname NewState C.luaL_newstate +func NewState() *Lua_State + +// /* +// ** =============================================================== +// ** some useful macros +// ** =============================================================== +// */ + +func (L *Lua_State) DoFile(filename *c.Char) c.Int { + if loadResult := L.LoadFile(filename); loadResult != 0 { + return loadResult + } + return L.PCall(c.Int(0), c.Int(MULTRET), c.Int(0)) +} + +func (L *Lua_State) Dostring(str *c.Char) c.Int { + if loadResult := L.LoadString(str); loadResult != 0 { + return loadResult + } + return L.PCall(c.Int(0), c.Int(MULTRET), c.Int(0)) +} + +// /* +// ** Perform arithmetic operations on lua_Integer values with wrap-around +// ** semantics, as the Lua core does. +// */ + +// /* push the value used to represent failure/error */ + +// /* +// ** {====================================================== +// ** Generic Buffer manipulation +// ** ======================================================= +// */ + +// /* }====================================================== */ + +// /* +// ** {====================================================== +// ** File handles for IO library +// ** ======================================================= +// */ + +// /* +// ** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and +// ** initial structure 'luaL_Stream' (it may contain other fields +// ** after that initial structure). +// */ + +// #define LUA_FILEHANDLE "FILE*" + +// /* }====================================================== */ + +// /* +// ** {================================================================== +// ** "Abstraction Layer" for basic report of messages and errors +// ** =================================================================== +// */ + +// /* print a string */ + +// /* print a newline and flush the output */ + +// /* print an error message */ + +// /* }================================================================== */ + +// /* +// ** {============================================================ +// ** Compatibility with deprecated conversions +// ** ============================================================= +// */ + +// /* }============================================================ */ diff --git a/c/lua/lua.go b/c/lua/lua.go new file mode 100644 index 00000000..ab1bd960 --- /dev/null +++ b/c/lua/lua.go @@ -0,0 +1,269 @@ +package lua + +import ( + _ "unsafe" + + "github.com/goplus/llgo/c" +) + +const ( + LLGoPackage = "link: $(pkg-config --libs lua); -llua -lm" +) + +// /* mark for precompiled code ('Lua') */ + +// /* option for multiple returns in 'lua_pcall' and 'lua_call' */ +const ( + MULTRET = -1 +) + +// /* +// ** Pseudo-indices +// ** (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty +// ** space after that to help overflow detection) +// */ + +// /* thread status */ +const ( + OK = 0 + YIELD = 1 + ERRRUN = 2 + ERRSYNTAX = 3 + ERRMEM = 4 + ERRERR = 5 +) + +type Lua_State struct { + Unused [8]byte +} + +// /* +// ** basic types +// */ +const ( + TNONE = -1 + TNIL = 0 + TBOOLEAN = 1 + TLIGHTUSERDATA = 2 + TNUMBER = 3 + TSTRING = 4 + TTABLE = 5 + TFUNCTION = 6 + TUSERDATA = 7 + TTHREAD = 8 + NUMTYPES = 9 +) + +// /* minimum Lua stack available to a C function */ +const ( + MINSTACK = 20 +) + +// /* predefined values in the registry */ + +// /* type of numbers in Lua */ +type Number c.Double + +// /* type for integer functions */ +// TODO(zzy):consider dynamic size +type Integer c.LongLong + +// /* unsigned integer type */ +type Unsigned c.UlongLong + +// /* type for continuation-function contexts */ +// TODO(zzy): Context may not be c.Int +type KContext c.Int + +// /* +// ** Type for C functions registered with Lua +// */ + +// /* +// ** Type for continuation functions +// */ + +// TODO(zzy): KFunction does not currently support +type KFunction func(L *Lua_State, status c.Int, ctx KContext) c.Int + +// /* +// ** Type for functions that read/write blocks when loading/dumping Lua chunks +// */ + +// /* +// ** Type for memory-allocation functions +// */ + +// /* +// ** Type for warning functions +// */ + +// /* +// ** Type used by the debug API to collect debug information +// */ + +// /* +// ** Functions to be called by the debugger in specific events +// */ + +// /* +// ** generic extra include file +// */ + +// /* +// ** RCS ident string +// */ + +// /* +// ** state manipulation +// */ +// llgo:link (*Lua_State).Close C.lua_close +func (L *Lua_State) Close() {} + +// /* +// ** basic stack manipulation +// */ + +// llgo:link (*Lua_State).AbsIndex C.lua_absindex +func (L *Lua_State) AbsIndex(idx c.Int) c.Int { return 0 } + +// llgo:link (*Lua_State).GetTop C.lua_gettop +func (L *Lua_State) GetTop() c.Int { return 0 } + +// llgo:link (*Lua_State).SetTop C.lua_settop +func (L *Lua_State) SetTop(idx c.Int) {} + +// llgo:link (*Lua_State).PushValue C.lua_pushvalue +func (L *Lua_State) PushValue(idx c.Int) {} + +// llgo:link (*Lua_State).Rotate C.lua_rotate +func (L *Lua_State) Rotate(idx c.Int, n c.Int) {} + +// llgo:link (*Lua_State).Copy C.lua_copy +func (L *Lua_State) Copy(fromidx c.Int, toidx c.Int) {} + +// llgo:link (*Lua_State).CheckStack C.lua_checkstack +func (L *Lua_State) CheckStack(n c.Int) c.Int { return 0 } + +// llgo:link (*Lua_State).Xmove C.lua_xmove +func (L *Lua_State) Xmove(to *Lua_State, n c.Int) {} + +// /* +// ** access functions (stack -> C) +// */ + +// llgo:link (*Lua_State).ToNumberx C.lua_tonumberx +func (L *Lua_State) ToNumberx(idx c.Int, isnum *c.Int) Number { return 0 } + +// llgo:link (*Lua_State).IsNumber C.lua_isnumber +func (L *Lua_State) IsNumber(idx c.Int) c.Int { return 0 } + +// llgo:link (*Lua_State).IsString C.lua_isstring +func (L *Lua_State) IsString(idx c.Int) c.Int { return 0 } + +// llgo:link (*Lua_State).ToIntegerx C.lua_tointegerx +func (L *Lua_State) ToIntegerx(idx c.Int, isnum *c.Int) Integer { return 0 } + +// llgo:link (*Lua_State).ToLString C.lua_tolstring +func (L *Lua_State) ToLString(idx c.Int, len *c.Ulong) *c.Char { return nil } + +// /* +// ** Comparison and arithmetic functions +// */ + +// /* +// ** push functions (C -> stack) +// */ +// llgo:link (*Lua_State).PushNil C.lua_pushnil +func (L *Lua_State) PushNil() {} + +// llgo:link (*Lua_State).PushNumber C.lua_pushnumber +func (L *Lua_State) PushNumber(n Number) {} + +// TODO(zzy): will get stuck +// llgo:link (*Lua_Stage).PushInteger C.lua_pushinteger +func (L *Lua_State) PushInteger(n Integer) {} + +// llgo:link (*Lua_State).PushLString C.lua_pushlstring +func (L *Lua_State) PushLString(s *c.Char, len c.Ulong) *c.Char { + return nil +} + +// llgo:link (*Lua_State).PushString C.lua_pushstring +func (L *Lua_State) PushString(s *c.Char) *c.Char { + return nil +} + +// llgo:link (*Lua_State).PushFString C.lua_pushfstring +func (L *Lua_State) PushFString(format *c.Char, __llgo_va_list ...any) *c.Char { return nil } + +// /* +// ** get functions (Lua -> stack) +// */ +// int (lua_getglobal) (lua_State *L, const char *name); +// llgo:link (*Lua_State).GetGlobal C.lua_getglobal +func (L *Lua_State) GetGlobal(name *c.Char) c.Int { return 0 } + +// /* +// ** set functions (stack -> Lua) +// */ + +// /* +// ** 'load' and 'call' functions (load and run Lua code) +// */ + +// llgo:link (*Lua_State).PCallk C.lua_pcallk +func (L *Lua_State) PCallk(nargs c.Int, nresults c.Int, errfunc c.Int, ctx KContext, k *KFunction) c.Int { + return 0 +} + +func (L *Lua_State) PCall(nargs c.Int, nresults c.Int, errfunc c.Int) c.Int { + return L.PCallk(nargs, nresults, errfunc, KContext(c.Int(0)), nil) +} + +// /* +// ** coroutine functions +// */ + +// /* +// ** Warning-related functions +// */ + +// /* +// ** garbage-collection function and options +// */ + +// /* +// ** miscellaneous functions +// */ + +// /* +// ** {============================================================== +// ** some useful macros +// ** =============================================================== +// */ +// /* }============================================================== */ + +func (L *Lua_State) ToNumber(idx c.Int) Number { return L.ToNumberx(idx, nil) } +func (L *Lua_State) ToString(idx c.Int) *c.Char { return L.ToLString(idx, nil) } +func (L *Lua_State) ToInteger(idx c.Int) Integer { return L.ToIntegerx(idx, nil) } + +// /* +// ** {============================================================== +// ** compatibility macros +// ** =============================================================== +// */ +// /* }============================================================== */ + +// /* +// ** {====================================================================== +// ** Debug API +// ** ======================================================================= +// */ +// /* +// ** Event codes +// */ +// /* +// ** Event masks +// */ +// /* }====================================================================== */ diff --git a/c/lua/lualib.go b/c/lua/lualib.go new file mode 100644 index 00000000..ef49a3bf --- /dev/null +++ b/c/lua/lualib.go @@ -0,0 +1,8 @@ +package lua + +import ( + _ "unsafe" +) + +// llgo:link (*Lua_State).OpenLibs C.luaL_openlibs +func (L *Lua_State) OpenLibs() {} From a5d7fc484a4c18e22f1cc58cdef0fc01aaf3770e Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Sun, 30 Jun 2024 19:35:45 +0800 Subject: [PATCH 2/2] llgo/c/lua:table & coroutine --- c/lua/_demo/coroutine/coroutine.go | 60 +++ c/lua/_demo/funccall-concat/funccall.go | 2 +- c/lua/_demo/funccall-string/funccall.go | 2 +- c/lua/_demo/hello/hello.go | 2 +- .../_demo/problem/pushinteger/pushinteger.go | 42 -- c/lua/_demo/stack/stack.go | 5 +- c/lua/_demo/table/table.go | 51 +++ c/lua/lauxlib.go | 16 +- c/lua/lua.go | 360 ++++++++++++++---- c/lua/lualib.go | 4 +- 10 files changed, 419 insertions(+), 125 deletions(-) create mode 100644 c/lua/_demo/coroutine/coroutine.go delete mode 100644 c/lua/_demo/problem/pushinteger/pushinteger.go create mode 100644 c/lua/_demo/table/table.go diff --git a/c/lua/_demo/coroutine/coroutine.go b/c/lua/_demo/coroutine/coroutine.go new file mode 100644 index 00000000..a215033f --- /dev/null +++ b/c/lua/_demo/coroutine/coroutine.go @@ -0,0 +1,60 @@ +package main + +import ( + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/c/lua" +) + +func coroutineFunc(L *lua.State) { + L.LoadString(c.Str(` + function coro_func() + for i = 1, 5 do + coroutine.yield(i) + end + end + `)) + L.PCall(0, 0, 0) + L.GetGlobal(c.Str("coro_func")) +} + +func main() { + L := lua.NewState() + defer L.Close() + + L.OpenLibs() + + coroutineFunc(L) // Load and get the coroutine function + + co := L.NewThread() // Create a new coroutine/thread + L.PushValue(-2) // Move the function to the top of the stack + L.XMove(co, 1) // Move the function to the new coroutine + + var nres c.Int + var status c.Int + + c.Printf(c.Str("Resuming coroutine...\n")) + // Resume coroutine and handle yields + for { + status = co.Resume(nil, 0, &nres) + c.Printf(c.Str("Resuming coroutine %d...\n"), status) + if status == lua.YIELD { + yieldValue := co.ToInteger(-1) + c.Printf(c.Str("Yield value: %d\n"), yieldValue) + co.Pop(1) // Clean up the stack + + // Check if the coroutine is yieldable + if co.IsYieldable() != 0 { + c.Printf(c.Str("Coroutine is yieldable.\n")) + } else { + c.Printf(c.Str("Coroutine is not yieldable.\n")) + } + + } else { + break + } + } + + // Check the final status of the coroutine + finalStatus := co.Status() + c.Printf(c.Str("Final status of coroutine: %d\n"), finalStatus) +} diff --git a/c/lua/_demo/funccall-concat/funccall.go b/c/lua/_demo/funccall-concat/funccall.go index d313314e..0683f458 100644 --- a/c/lua/_demo/funccall-concat/funccall.go +++ b/c/lua/_demo/funccall-concat/funccall.go @@ -12,7 +12,7 @@ func main() { defer L.Close() L.OpenLibs() - if res := L.Dostring(c.Str("function combineParams(num, str) return 'Result: ' .. str .. ' ' .. num end")); res != lua.OK { + if res := L.DoString(c.Str("function combineParams(num, str) return 'Result: ' .. str .. ' ' .. num end")); res != lua.OK { c.Printf(c.Str("error: %s\n"), L.ToString(-1)) } L.GetGlobal(c.Str("combineParams")) diff --git a/c/lua/_demo/funccall-string/funccall.go b/c/lua/_demo/funccall-string/funccall.go index 91d220de..d155f752 100644 --- a/c/lua/_demo/funccall-string/funccall.go +++ b/c/lua/_demo/funccall-string/funccall.go @@ -20,7 +20,7 @@ func main() { return a .. b .. c end`) - if res := L.Dostring(code); res != lua.OK { + if res := L.DoString(code); res != lua.OK { c.Printf(c.Str("error: %s\n"), L.ToString(-1)) } diff --git a/c/lua/_demo/hello/hello.go b/c/lua/_demo/hello/hello.go index cb96ddde..75b0c46e 100644 --- a/c/lua/_demo/hello/hello.go +++ b/c/lua/_demo/hello/hello.go @@ -11,7 +11,7 @@ func main() { L := lua.NewState() defer L.Close() L.OpenLibs() - if res := L.Dostring(c.Str("print('hello world')")); res != lua.OK { + if res := L.DoString(c.Str("print('hello world')")); res != lua.OK { println("error") } } diff --git a/c/lua/_demo/problem/pushinteger/pushinteger.go b/c/lua/_demo/problem/pushinteger/pushinteger.go deleted file mode 100644 index 815d3fe0..00000000 --- a/c/lua/_demo/problem/pushinteger/pushinteger.go +++ /dev/null @@ -1,42 +0,0 @@ -package main - -import ( - _ "unsafe" - - "github.com/goplus/llgo/c" - "github.com/goplus/llgo/c/lua" -) - -func main() { - L := lua.NewState() - defer L.Close() - - L.OpenLibs() - // TODO(zzy): fix push interger got stuck - code := c.Str(`function combineParams(x) - return x * 2 -end`) - if res := L.Dostring(code); res != lua.OK { - c.Printf(c.Str("error: %s\n"), L.ToString(-1)) - } - L.GetGlobal(c.Str("combineParams")) - c.Printf(c.Str("stack lens:%d\n"), L.GetTop()) // stack lens:1 - - L.PushInteger(lua.Integer(42)) - pushed := L.ToInteger(-1) - - c.Printf(c.Str("pushed: %lld\n"), pushed) // pushed: 0 - c.Printf(c.Str("stack lens:%d\n"), L.GetTop()) // stack lens:1 - - // L.PushNumber(42) - // pushed := L.ToNumber(-1) - // c.Printf(c.Str("pushed: %f\n"), pushed) - - if res := L.PCall(1, 1, 0); res != lua.OK { - c.Printf(c.Str("error: %s\n"), L.ToString(-1)) - } - if res := L.IsNumber(-1); res != 0 { - result := L.ToInteger(-1) - c.Printf(c.Str("result %f"), result) - } -} diff --git a/c/lua/_demo/stack/stack.go b/c/lua/_demo/stack/stack.go index ef1fc556..bf30a60d 100644 --- a/c/lua/_demo/stack/stack.go +++ b/c/lua/_demo/stack/stack.go @@ -6,9 +6,8 @@ import ( ) // printStack prints the current stack of the given Lua state. -func printStack(L *lua.Lua_State, stateName *c.Char) { +func printStack(L *lua.State, stateName *c.Char) { top := L.GetTop() - // c.Printf(c.Str("%s stack (top=%d): "), c.GoStringData("sdasd"), top) c.Printf(c.Str("%s stack (top=%d):"), stateName, top) for i := 1; i <= int(top); i++ { c.Printf(c.Str("%s "), L.ToString(c.Int(i))) @@ -73,7 +72,7 @@ func main() { defer L1.Close() // Move two elements to the new state - L.Xmove(L1, c.Int(2)) + L.XMove(L1, c.Int(2)) c.Printf(c.Str("\nAfter moving two elements to L1:\n")) printStack(L, c.Str("L1")) printStack(L1, c.Str("L2")) diff --git a/c/lua/_demo/table/table.go b/c/lua/_demo/table/table.go new file mode 100644 index 00000000..482c2d2f --- /dev/null +++ b/c/lua/_demo/table/table.go @@ -0,0 +1,51 @@ +package main + +import ( + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/c/lua" +) + +func printTable(L *lua.State) { + L.PushNil() + for L.Next(-2) != 0 { + key := L.ToString(-2) + value := L.ToString(-1) + c.Printf(c.Str("%s - %s\n"), key, value) + L.Pop(1) + } + L.Pop(1) +} + +func main() { + L := lua.NewState() + defer L.Close() + + L.OpenLibs() + + L.NewTable() + + L.PushString(c.Str("name")) + L.PushString(c.Str("John")) + L.SetTable(-3) + + L.PushString(c.Str("age")) + L.PushNumber(30) + L.SetTable(-3) + + L.PushString(c.Str("John Doe")) + L.SetField(-2, c.Str("fullname")) + + L.GetField(-1, c.Str("name")) + c.Printf(c.Str("%s\n"), L.ToString(-1)) + L.Pop(1) + + L.PushString(c.Str("age")) + L.GetTable(-2) + age := int(L.ToNumber(-1)) + c.Printf(c.Str("Age: %d\n"), age) + L.Pop(1) + + c.Printf(c.Str("All entries in the table:\n")) + printTable(L) + +} diff --git a/c/lua/lauxlib.go b/c/lua/lauxlib.go index 81bcd475..ff11d34b 100644 --- a/c/lua/lauxlib.go +++ b/c/lua/lauxlib.go @@ -16,16 +16,16 @@ import ( // /* predefined references */ -// llgo:link (*Lua_State).LoadFilex C.luaL_loadfilex -func (L *Lua_State) LoadFilex(filename *c.Char, mode *c.Char) c.Int { return 0 } +// llgo:link (*State).LoadFilex C.luaL_loadfilex +func (L *State) LoadFilex(filename *c.Char, mode *c.Char) c.Int { return 0 } -func (L *Lua_State) LoadFile(filename *c.Char) c.Int { return L.LoadFilex(filename, nil) } +func (L *State) LoadFile(filename *c.Char) c.Int { return L.LoadFilex(filename, nil) } -// llgo:link (*Lua_State).LoadString C.luaL_loadstring -func (L *Lua_State) LoadString(s *c.Char) c.Int { return 0 } +// llgo:link (*State).LoadString C.luaL_loadstring +func (L *State) LoadString(s *c.Char) c.Int { return 0 } //go:linkname NewState C.luaL_newstate -func NewState() *Lua_State +func NewState() *State // /* // ** =============================================================== @@ -33,14 +33,14 @@ func NewState() *Lua_State // ** =============================================================== // */ -func (L *Lua_State) DoFile(filename *c.Char) c.Int { +func (L *State) DoFile(filename *c.Char) c.Int { if loadResult := L.LoadFile(filename); loadResult != 0 { return loadResult } return L.PCall(c.Int(0), c.Int(MULTRET), c.Int(0)) } -func (L *Lua_State) Dostring(str *c.Char) c.Int { +func (L *State) DoString(str *c.Char) c.Int { if loadResult := L.LoadString(str); loadResult != 0 { return loadResult } diff --git a/c/lua/lua.go b/c/lua/lua.go index ab1bd960..55024d7a 100644 --- a/c/lua/lua.go +++ b/c/lua/lua.go @@ -33,7 +33,7 @@ const ( ERRERR = 5 ) -type Lua_State struct { +type State struct { Unused [8]byte } @@ -41,17 +41,17 @@ type Lua_State struct { // ** basic types // */ const ( - TNONE = -1 - TNIL = 0 - TBOOLEAN = 1 - TLIGHTUSERDATA = 2 - TNUMBER = 3 - TSTRING = 4 - TTABLE = 5 - TFUNCTION = 6 - TUSERDATA = 7 - TTHREAD = 8 - NUMTYPES = 9 + NONE = int(-1) + NIL = int(0) + BOOLEAN = int(1) + LIGHTUSERDATA = int(2) + NUMBER = int(3) + STRING = int(4) + TABLE = int(5) + FUNCTION = int(6) + USERDATA = int(7) + THREAD = int(8) + UMTYPES = int(9) ) // /* minimum Lua stack available to a C function */ @@ -60,16 +60,22 @@ const ( ) // /* predefined values in the registry */ +const ( + RIDX_MAINTHREAD = 1 + RIDX_GLOBALS = 2 + RIDX_LAST = RIDX_GLOBALS +) // /* type of numbers in Lua */ -type Number c.Double +type Number = c.Double // /* type for integer functions */ // TODO(zzy):consider dynamic size -type Integer c.LongLong + +type Integer = c.Int // /* unsigned integer type */ -type Unsigned c.UlongLong +type Unsigned = c.Uint // /* type for continuation-function contexts */ // TODO(zzy): Context may not be c.Int @@ -84,88 +90,139 @@ type KContext c.Int // */ // TODO(zzy): KFunction does not currently support -type KFunction func(L *Lua_State, status c.Int, ctx KContext) c.Int +type KFunction func(L *State, status c.Int, ctx KContext) c.Int // /* // ** Type for functions that read/write blocks when loading/dumping Lua chunks // */ +// typedef const char * (*lua_Reader) (State *L, void *ud, size_t *sz); +// typedef int (*lua_Writer) (State *L, const void *p, size_t sz, void *ud); + // /* // ** Type for memory-allocation functions // */ +// typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); + // /* // ** Type for warning functions // */ +// typedef void (*lua_WarnFunction) (void *ud, const char *msg, int tocont); + // /* // ** Type used by the debug API to collect debug information // */ +// typedef struct lua_Debug lua_Debug; + // /* // ** Functions to be called by the debugger in specific events // */ +// typedef void (*lua_Hook) (State *L, lua_Debug *ar); + // /* // ** generic extra include file // */ +// #if defined(LUA_USER_H) +// #include LUA_USER_H +// #endif + // /* // ** RCS ident string // */ +// extern const char lua_ident[]; + // /* // ** state manipulation // */ -// llgo:link (*Lua_State).Close C.lua_close -func (L *Lua_State) Close() {} +// llgo:link (*State).Close C.lua_close +func (L *State) Close() {} + +// State *(lua_newstate) (lua_Alloc f, void *ud); +// State *(lua_newthread) (State *L); + +// llgo:link (*State).NewThread C.lua_newthread +func (L *State) NewThread() *State { return nil } + +// int (lua_closethread) (State *L, State *from); +// int (lua_resetthread) (State *L); /* Deprecated! */ +// lua_CFunction (lua_atpanic) (State *L, lua_CFunction panicf); +// lua_Number (lua_version) (State *L); // /* // ** basic stack manipulation // */ -// llgo:link (*Lua_State).AbsIndex C.lua_absindex -func (L *Lua_State) AbsIndex(idx c.Int) c.Int { return 0 } +// llgo:link (*State).AbsIndex C.lua_absindex +func (L *State) AbsIndex(idx c.Int) c.Int { return 0 } -// llgo:link (*Lua_State).GetTop C.lua_gettop -func (L *Lua_State) GetTop() c.Int { return 0 } +// llgo:link (*State).GetTop C.lua_gettop +func (L *State) GetTop() c.Int { return 0 } -// llgo:link (*Lua_State).SetTop C.lua_settop -func (L *Lua_State) SetTop(idx c.Int) {} +// llgo:link (*State).SetTop C.lua_settop +func (L *State) SetTop(idx c.Int) {} -// llgo:link (*Lua_State).PushValue C.lua_pushvalue -func (L *Lua_State) PushValue(idx c.Int) {} +// llgo:link (*State).PushValue C.lua_pushvalue +func (L *State) PushValue(idx c.Int) {} -// llgo:link (*Lua_State).Rotate C.lua_rotate -func (L *Lua_State) Rotate(idx c.Int, n c.Int) {} +// llgo:link (*State).Rotate C.lua_rotate +func (L *State) Rotate(idx c.Int, n c.Int) {} -// llgo:link (*Lua_State).Copy C.lua_copy -func (L *Lua_State) Copy(fromidx c.Int, toidx c.Int) {} +// llgo:link (*State).Copy C.lua_copy +func (L *State) Copy(fromidx c.Int, toidx c.Int) {} -// llgo:link (*Lua_State).CheckStack C.lua_checkstack -func (L *Lua_State) CheckStack(n c.Int) c.Int { return 0 } +// llgo:link (*State).CheckStack C.lua_checkstack +func (L *State) CheckStack(n c.Int) c.Int { return 0 } -// llgo:link (*Lua_State).Xmove C.lua_xmove -func (L *Lua_State) Xmove(to *Lua_State, n c.Int) {} +// llgo:link (*State).XMove C.lua_xmove +func (L *State) XMove(to *State, n c.Int) {} // /* // ** access functions (stack -> C) // */ +// LUA_API int (lua_isinteger) (State *L, int idx); +// llgo:link (*State).IsInteger C.lua_isinteger +func (L *State) IsInteger(idx c.Int) c.Int { return 0 } -// llgo:link (*Lua_State).ToNumberx C.lua_tonumberx -func (L *Lua_State) ToNumberx(idx c.Int, isnum *c.Int) Number { return 0 } +// llgo:link (*State).IsNumber C.lua_isnumber +func (L *State) IsNumber(idx c.Int) c.Int { return 0 } -// llgo:link (*Lua_State).IsNumber C.lua_isnumber -func (L *Lua_State) IsNumber(idx c.Int) c.Int { return 0 } +// llgo:link (*State).IsString C.lua_isstring +func (L *State) IsString(idx c.Int) c.Int { return 0 } -// llgo:link (*Lua_State).IsString C.lua_isstring -func (L *Lua_State) IsString(idx c.Int) c.Int { return 0 } +// TODO(zzy):add to demo +// llgo:link (*State).Type C.lua_type +func (L *State) Type(idx c.Int) c.Int { return 0 } -// llgo:link (*Lua_State).ToIntegerx C.lua_tointegerx -func (L *Lua_State) ToIntegerx(idx c.Int, isnum *c.Int) Integer { return 0 } +// TODO(zzy) +// llgo:link (*State).TypeName C.lua_typename +func (L *State) TypeName(tp c.Int) *c.Char { return nil } -// llgo:link (*Lua_State).ToLString C.lua_tolstring -func (L *Lua_State) ToLString(idx c.Int, len *c.Ulong) *c.Char { return nil } +// llgo:link (*State).ToNumberx C.lua_tonumberx +func (L *State) ToNumberx(idx c.Int, isnum *c.Int) Number { return 0 } + +// llgo:link (*State).ToIntegerx C.lua_tointegerx +func (L *State) ToIntegerx(idx c.Int, isnum *c.Int) Integer { return 0 } + +// llgo:link (*State).ToBoolean C.lua_toboolean +func (L *State) ToBoolean(idx c.Int) bool { return false } + +// llgo:link (*State).ToLString C.lua_tolstring +func (L *State) ToLString(idx c.Int, len *c.Ulong) *c.Char { return nil } + +// LUA_API int (lua_iscfunction) (State *L, int idx); +// LUA_API int (lua_isuserdata) (State *L, int idx); + +// LUA_API lua_Unsigned (lua_rawlen) (State *L, int idx); +// LUA_API lua_CFunction (lua_tocfunction) (State *L, int idx); +// LUA_API void *(lua_touserdata) (State *L, int idx); +// LUA_API State *(lua_tothread) (State *L, int idx); +// LUA_API const void *(lua_topointer) (State *L, int idx); // /* // ** Comparison and arithmetic functions @@ -174,85 +231,215 @@ func (L *Lua_State) ToLString(idx c.Int, len *c.Ulong) *c.Char { return nil } // /* // ** push functions (C -> stack) // */ -// llgo:link (*Lua_State).PushNil C.lua_pushnil -func (L *Lua_State) PushNil() {} +// llgo:link (*State).PushNil C.lua_pushnil +func (L *State) PushNil() {} -// llgo:link (*Lua_State).PushNumber C.lua_pushnumber -func (L *Lua_State) PushNumber(n Number) {} +// llgo:link (*State).PushNumber C.lua_pushnumber +func (L *State) PushNumber(n Number) {} -// TODO(zzy): will get stuck -// llgo:link (*Lua_Stage).PushInteger C.lua_pushinteger -func (L *Lua_State) PushInteger(n Integer) {} +// llgo:link (*State).PushInteger C.lua_pushinteger +func (L *State) PushInteger(n Integer) {} -// llgo:link (*Lua_State).PushLString C.lua_pushlstring -func (L *Lua_State) PushLString(s *c.Char, len c.Ulong) *c.Char { +// llgo:link (*State).PushString C.lua_pushstring +func (L *State) PushString(s *c.Char) *c.Char { return nil } -// llgo:link (*Lua_State).PushString C.lua_pushstring -func (L *Lua_State) PushString(s *c.Char) *c.Char { +// llgo:link (*State).PushLString C.lua_pushlstring +func (L *State) PushLString(s *c.Char, len c.Ulong) *c.Char { return nil } -// llgo:link (*Lua_State).PushFString C.lua_pushfstring -func (L *Lua_State) PushFString(format *c.Char, __llgo_va_list ...any) *c.Char { return nil } +// llgo:link (*State).PushFString C.lua_pushfstring +func (L *State) PushFString(format *c.Char, __llgo_va_list ...any) *c.Char { return nil } + +// llgo:link (*State).PushBoolean C.lua_pushboolean +func (L *State) PushBoolean(b c.Int) {} + +//const char *(lua_pushvfstring) (State *L, const char *fmt,va_list argp); +//void (lua_pushcclosure) (State *L, lua_CFunction fn, int n); +//void (lua_pushlightuserdata) (State *L, void *p); +//int (lua_pushthread) (State *L); // /* // ** get functions (Lua -> stack) // */ -// int (lua_getglobal) (lua_State *L, const char *name); -// llgo:link (*Lua_State).GetGlobal C.lua_getglobal -func (L *Lua_State) GetGlobal(name *c.Char) c.Int { return 0 } + +// llgo:link (*State).GetGlobal C.lua_getglobal +func (L *State) GetGlobal(name *c.Char) c.Int { return 0 } + +// llgo:link (*State).GetTable C.lua_gettable +func (L *State) GetTable(idx c.Int) c.Int { return 0 } + +// llgo:link (*State).GetField C.lua_getfield +func (L *State) GetField(idx c.Int, k *c.Char) c.Int { return 0 } + +// llgo:link (*State).CreateTable C.lua_createtable +func (L *State) CreateTable(narr c.Int, nrec c.Int) {} + +// LUA_API int (lua_geti) (State *L, int idx, lua_Integer n); +// LUA_API int (lua_rawget) (State *L, int idx); +// LUA_API int (lua_rawgeti) (State *L, int idx, lua_Integer n); +// LUA_API int (lua_rawgetp) (State *L, int idx, const void *p); + +// LUA_API void *(lua_newuserdatauv) (State *L, size_t sz, int nuvalue); +// LUA_API int (lua_getmetatable) (State *L, int objindex); +// LUA_API int (lua_getiuservalue) (State *L, int idx, int n); // /* // ** set functions (stack -> Lua) // */ +// TODO(zzy):add to demo +// llgo:link (*State).SetGlobal C.lua_setglobal +func (L *State) SetGlobal(name *c.Char) {} + +// llgo:link (*State).SetTable C.lua_settable +func (L *State) SetTable(idx c.Int) {} + +// llgo:link (*State).SetField C.lua_setfield +func (L *State) SetField(idx c.Int, k *c.Char) {} + +//void (lua_seti) (State *L, int idx, lua_Integer n); +//void (lua_rawset) (State *L, int idx); +//void (lua_rawseti) (State *L, int idx, lua_Integer n); +//void (lua_rawsetp) (State *L, int idx, const void *p); +//int (lua_setmetatable) (State *L, int objindex); +//int (lua_setiuservalue) (State *L, int idx, int n); + // /* // ** 'load' and 'call' functions (load and run Lua code) // */ -// llgo:link (*Lua_State).PCallk C.lua_pcallk -func (L *Lua_State) PCallk(nargs c.Int, nresults c.Int, errfunc c.Int, ctx KContext, k *KFunction) c.Int { +// llgo:link (*State).PCallk C.lua_pcallk +func (L *State) PCallk(nargs c.Int, nresults c.Int, errfunc c.Int, ctx KContext, k *KFunction) c.Int { return 0 } -func (L *Lua_State) PCall(nargs c.Int, nresults c.Int, errfunc c.Int) c.Int { +func (L *State) PCall(nargs c.Int, nresults c.Int, errfunc c.Int) c.Int { return L.PCallk(nargs, nresults, errfunc, KContext(c.Int(0)), nil) } +// void (lua_callk) (State *L, int nargs, int nresults, lua_KContext ctx, lua_KFunction k); +// #define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL) + +// int (lua_load) (State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode); + +// int (lua_dump) (State *L, lua_Writer writer, void *data, int strip); + // /* // ** coroutine functions // */ +// llgo:link (*State).Resume C.lua_resume +func (L *State) Resume(from *State, narg c.Int, nres *c.Int) c.Int { return 0 } + +// llgo:link (*State).Status C.lua_status +func (L *State) Status() c.Int { return 0 } + +// llgo:link (*State).IsYieldable C.lua_isyieldable +func (L *State) IsYieldable() c.Int { return 0 } + +// TODO(zzy) +// int (lua_yieldk) (State *L, int nresults, lua_KContext ctx, lua_KFunction k); +// #define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL) + // /* // ** Warning-related functions // */ +//void (lua_setwarnf) (State *L, lua_WarnFunction f, void *ud); +//void (lua_warning) (State *L, const char *msg, int tocont); + // /* // ** garbage-collection function and options // */ +const ( + GCSTOP = 0 + GCRESTART = 1 + GCCOLLECT = 2 + GCCOUNT = 3 + GCCOUNTB = 4 + GCSTEP = 5 + GCSETPAUSE = 6 + GCSETSTEPMUL = 7 + GCISRUNNING = 9 + GCGEN = 10 + GCINC = 11 +) + +// LUA_API int (lua_gc) (State *L, int what, ...); + // /* // ** miscellaneous functions // */ +// llgo:link (*State).Next C.lua_next +func (L *State) Next(idx c.Int) c.Int { return 0 } + +// LUA_API int (lua_error) (State *L); + +// LUA_API void (lua_concat) (State *L, int n); +// LUA_API void (lua_len) (State *L, int idx); + +// LUA_API size_t (lua_stringtonumber) (State *L, const char *s); + +// LUA_API lua_Alloc (lua_getallocf) (State *L, void **ud); +// LUA_API void (lua_setallocf) (State *L, lua_Alloc f, void *ud); + +// LUA_API void (lua_toclose) (State *L, int idx); +// LUA_API void (lua_closeslot) (State *L, int idx); // /* // ** {============================================================== // ** some useful macros // ** =============================================================== // */ -// /* }============================================================== */ -func (L *Lua_State) ToNumber(idx c.Int) Number { return L.ToNumberx(idx, nil) } -func (L *Lua_State) ToString(idx c.Int) *c.Char { return L.ToLString(idx, nil) } -func (L *Lua_State) ToInteger(idx c.Int) Integer { return L.ToIntegerx(idx, nil) } +func (L *State) ToNumber(idx c.Int) Number { return L.ToNumberx(idx, nil) } +func (L *State) ToString(idx c.Int) *c.Char { return L.ToLString(idx, nil) } +func (L *State) ToInteger(idx c.Int) Integer { return L.ToIntegerx(idx, nil) } +func (L *State) Pop(n c.Int) { L.SetTop(-(n) - 1) } +func (L *State) NewTable() { L.CreateTable(0, 0) } +func (L *State) IsFunction(n c.Int) bool { return L.Type(n) == c.Int(FUNCTION) } +func (L *State) IsTable(n c.Int) bool { return L.Type(n) == c.Int(TABLE) } +func (L *State) IsLightUserData(n c.Int) bool { return L.Type(n) == c.Int(LIGHTUSERDATA) } +func (L *State) IsNil(n c.Int) bool { return L.Type(n) == c.Int(NIL) } +func (L *State) IsBoolean(n c.Int) bool { return L.Type(n) == c.Int(BOOLEAN) } +func (L *State) IsThread(n c.Int) bool { return L.Type(n) == c.Int(THREAD) } +func (L *State) IsNone(n c.Int) bool { return L.Type(n) == c.Int(NONE) } +func (L *State) IsNoneOrNil(n c.Int) bool { return L.Type(n) <= 0 } + +// #define lua_getextraspace(L) ((void *)((char *)(L) - LUA_EXTRASPACE)) + +// #define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) + +// #define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 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)) + +// /* }============================================================== */ // /* // ** {============================================================== // ** compatibility macros // ** =============================================================== // */ + +// #define lua_newuserdata(L,s) lua_newuserdatauv(L,s,1) +// #define lua_getuservalue(L,idx) lua_getiuservalue(L,idx,1) +// #define lua_setuservalue(L,idx) lua_setiuservalue(L,idx,1) + +// #define LUA_NUMTAGS LUA_NUMTYPES + // /* }============================================================== */ // /* @@ -263,7 +450,46 @@ func (L *Lua_State) ToInteger(idx c.Int) Integer { return L.ToIntegerx(idx, nil) // /* // ** Event codes // */ + +const ( + HOOKCALL = 0 + HOOKRET = 1 + HOOKLINE = 2 + HOOKCOUNT = 3 + HOOKTAILCALL = 4 +) + // /* // ** 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 + MASKRET = 1 << HOOKRET + MASKLINE = 1 << HOOKLINE + MASKCOUNT = 1 << HOOKCOUNT +) + +// LUA_API int (lua_getstack) (State *L, int level, lua_Debug *ar); +// LUA_API int (lua_getinfo) (State *L, const char *what, lua_Debug *ar); +// LUA_API const char *(lua_getlocal) (State *L, const lua_Debug *ar, int n); +// LUA_API const char *(lua_setlocal) (State *L, const lua_Debug *ar, int n); +// LUA_API const char *(lua_getupvalue) (State *L, int funcindex, int n); +// LUA_API const char *(lua_setupvalue) (State *L, int funcindex, int n); + +// LUA_API void *(lua_upvalueid) (State *L, int fidx, int n); +// LUA_API void (lua_upvaluejoin) (State *L, int fidx1, int n1, int fidx2, int n2); + +// LUA_API void (lua_sethook) (State *L, lua_Hook func, int mask, int count); +// LUA_API lua_Hook (lua_gethook) (State *L); +// LUA_API int (lua_gethookmask) (State *L); +// LUA_API int (lua_gethookcount) (State *L); + +// LUA_API int (lua_setcstacklimit) (State *L, unsigned int limit); + +// struct lua_Debug // /* }====================================================================== */ diff --git a/c/lua/lualib.go b/c/lua/lualib.go index ef49a3bf..e9aeb2b3 100644 --- a/c/lua/lualib.go +++ b/c/lua/lualib.go @@ -4,5 +4,5 @@ import ( _ "unsafe" ) -// llgo:link (*Lua_State).OpenLibs C.luaL_openlibs -func (L *Lua_State) OpenLibs() {} +// llgo:link (*State).OpenLibs C.luaL_openlibs +func (L *State) OpenLibs() {}