about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2021-11-04 04:08:59 -0700
committerKartik K. Agaram <vc@akkartik.com>2021-11-05 08:31:43 -0700
commit712dc16b236fdb72a666ebe60b00adc1e5c1ef6e (patch)
treee49d7c91e4975593df85176ef0df6f76ca508594 /src
parente35454c9a8e01637cc06f07586e58e470025f082 (diff)
downloadteliva-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.c74
-rw-r--r--src/notes15
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