about summary refs log tree commit diff stats
path: root/src/lua.c
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2021-11-10 22:04:36 -0800
committerKartik K. Agaram <vc@akkartik.com>2021-11-10 22:09:12 -0800
commitefbb57d33976db19167c0d69ff87daabf61785af (patch)
tree6713d80f1533f9e5b40088a10088914e514686ab /src/lua.c
parent8dcf08565d8e757b791387049f7ff852910a50c9 (diff)
downloadteliva-efbb57d33976db19167c0d69ff87daabf61785af.tar.gz
new .tlv image format
Plan is for this to be the default representation for Teliva programs.
Text-friendly but not meant to be edited directly as text. Will
eventually include both code and data definitions, both current snapshot
and past revision history.

Right now .tlv files seem to run. Error checking is non-existent,
because I don't understand Lua's idioms around 'status' yet. Opening the
editor expectedly segfaults.

This commit is the most mind-bending bit of code I've written in a long
time.
Diffstat (limited to 'src/lua.c')
-rw-r--r--src/lua.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/lua.c b/src/lua.c
index f41b1fa..94a9509 100644
--- a/src/lua.c
+++ b/src/lua.c
@@ -138,6 +138,7 @@ static void print_version (void) {
 }
 
 
+/* pushes commandline args to the stack, then an array of all commandline args */
 static int getargs (lua_State *L, char **argv, int n) {
   int narg;
   int i;
@@ -259,7 +260,78 @@ static void dotty (lua_State *L) {
 }
 
 
+static int has_extension (const char *filename, const char *extension) {
+  const char *filename_final_dot = strrchr(filename, '.');
+  if (filename_final_dot == NULL) return 0;
+  return strcmp(filename_final_dot+1, extension) == 0;
+}
+
+
+static void stackDump (lua_State *L) {
+  int i;
+  int top = lua_gettop(L);
+  for (i = 1; i <= top; i++) {  /* repeat for each level */
+    int t = lua_type(L, i);
+    switch (t) {
+
+      case LUA_TSTRING:  /* strings */
+        printf("`%s'", lua_tostring(L, i));
+        break;
+
+      case LUA_TBOOLEAN:  /* booleans */
+        printf(lua_toboolean(L, i) ? "true" : "false");
+        break;
+
+      case LUA_TNUMBER:  /* numbers */
+        printf("%g", lua_tonumber(L, i));
+        break;
+
+      default:  /* other values */
+        printf("%s", lua_typename(L, t));
+        break;
+
+    }
+    printf("  ");  /* put a separator */
+  }
+  printf("\n");  /* end the listing */
+}
+
+
+static int handle_image (lua_State *L, char **argv, int n) {
+  int status;
+  int narg = getargs(L, argv, n);  /* collect arguments */
+  lua_setglobal(L, "arg");
+  /* parse and load file contents (teliva_program table) */
+  status = luaL_loadfile(L, argv[n]);
+  lua_insert(L, -(narg+1));
+  if (status != 0) {
+    return status;
+  }
+  status = docall(L, narg, 0);
+  lua_getglobal(L, "teliva_program");
+  int table = lua_gettop(L);
+//?   endwin();
+  /* parse and load each binding in teliva_program */
+  for (lua_pushnil(L); lua_next(L, table) != 0; lua_pop(L, 1)) {
+    const char* key = lua_tostring(L, -2);
+    const char* value = lua_tostring(L, -1);
+//?     printf("===\nkey: %s\n", key);
+//?     printf("value: %s\n", value);
+    dostring(L, value, key);
+//?     stackDump(L);
+  }
+  /* call main() */
+  lua_getglobal(L, "main");
+  docall(L, 0, 1);
+//?   stackDump(L);
+//?   exit(1);
+  return 0;
+}
+
+
 static int handle_script (lua_State *L, char **argv, int n) {
+  if (has_extension(argv[n], "tlv"))
+    return handle_image(L, argv, n);
   int status;
   int narg = getargs(L, argv, n);  /* collect arguments */
   lua_setglobal(L, "arg");