diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2021-11-04 04:08:59 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2021-11-05 08:31:43 -0700 |
commit | 712dc16b236fdb72a666ebe60b00adc1e5c1ef6e (patch) | |
tree | e49d7c91e4975593df85176ef0df6f76ca508594 /src | |
parent | e35454c9a8e01637cc06f07586e58e470025f082 (diff) | |
download | teliva-712dc16b236fdb72a666ebe60b00adc1e5c1ef6e.tar.gz |
going through chapter 28 of https://www.lua.org/pil
User-defined C data. I think I have some understanding of the Lua stack now. It's a different kind of verbose, error-prone syntax than Mu that requires me to play computer in my head. But I don't fully grok metatables yet. At least not well enough to grok everything that's going on in lcurses/ext.
Diffstat (limited to 'src')
-rw-r--r-- | src/lua.c | 74 | ||||
-rw-r--r-- | src/notes | 15 |
2 files changed, 86 insertions, 3 deletions
diff --git a/src/lua.c b/src/lua.c index e40b61c..aa73699 100644 --- a/src/lua.c +++ b/src/lua.c @@ -368,6 +368,75 @@ static int pmain (lua_State *L) { } +//? static const char *WINDOWMETA = "curses:window"; // metatable for all ncurses WINDOW objects +//? // prototype for all ncurses WINDOW metatables +//? static const luaL_Reg curses_window_fns[] = { +//? {"addstr", Waddstr}, +//? {NULL, NULL} +//? }; + + +typedef struct NumArray { + int size; + double values[1]; /* variable part */ +} NumArray; + + +static int newarray (lua_State *L) { + int n = luaL_checkint(L, 1); + size_t nbytes = sizeof(NumArray) + (n - 1)*sizeof(double); + NumArray *a = (NumArray *)lua_newuserdata(L, nbytes); + a->size = n; + return 1; /* new userdatum is already on the stack */ +} + + +static int setarray (lua_State *L) { + NumArray *a = (NumArray *)lua_touserdata(L, 1); + int index = luaL_checkint(L, 2); + double value = luaL_checknumber(L, 3); + + luaL_argcheck(L, a != NULL, 1, "`array' expected"); + + luaL_argcheck(L, 1 <= index && index <= a->size, 2, + "index out of range"); + + a->values[index-1] = value; + return 0; +} + + +static int getarray (lua_State *L) { + NumArray *a = (NumArray *)lua_touserdata(L, 1); + int index = luaL_checkint(L, 2); + + luaL_argcheck(L, a != NULL, 1, "`array' expected"); + + luaL_argcheck(L, 1 <= index && index <= a->size, 2, + "index out of range"); + + lua_pushnumber(L, a->values[index-1]); + return 1; +} + + +static int getsize (lua_State *L) { + NumArray *a = (NumArray *)lua_touserdata(L, 1); + luaL_argcheck(L, a != NULL, 1, "`array' expected"); + lua_pushnumber(L, a->size); + return 1; +} + + +static const struct luaL_Reg arraylib[] = { + {"new", newarray}, + {"set", setarray}, + {"get", getarray}, + {"size", getsize}, + {NULL, NULL} +}; + + int main (int argc, char **argv) { int status; struct Smain s; @@ -376,11 +445,10 @@ int main (int argc, char **argv) { l_message(argv[0], "cannot create state: not enough memory"); return EXIT_FAILURE; } + luaL_register(L, "array", arraylib); +//? luaL_register(L, "curses.window", curses_window_fns); initscr(); echo(); - lua_pushinteger(L, 42); - lua_setfield(L, -1, "answer"); -//? lua_setglobal(L, "answer"); s.argc = argc; s.argv = argv; status = lua_cpcall(L, &pmain, &s); diff --git a/src/notes b/src/notes index 3a87b2a..ade61bf 100644 --- a/src/notes +++ b/src/notes @@ -11,3 +11,18 @@ lua_State: Lua's stack vs globals: https://lucasklassmann.com/blog/2019-02-02-how-to-embeddeding-lua-in-c/#exposing-a-simple-variable More info on the stack: https://www.lua.org/pil/24.2.html + + + +# T[k] = v + +## Approach 1: + -- initial { ... T ... } + push k + push v + settable index(T) + -- final { ... T ... } + +## Approach 2 (if k is a string): + push v + setfield index(T), k |