about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile2
-rw-r--r--src/lua.c29
-rw-r--r--src/tlv.c73
-rw-r--r--src/x.tlv42
4 files changed, 119 insertions, 27 deletions
diff --git a/src/Makefile b/src/Makefile
index 65580bb..d9ef9b1 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -26,7 +26,7 @@ LUA_A=	liblua.a
 CORE_O=	lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \
 	lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o  \
 	lundump.o lvm.o lzio.o \
-	kilo.o
+	kilo.o tlv.o
 LIB_O=	lauxlib.o lbaselib.o menu.o ldblib.o liolib.o lmathlib.o \
 	loslib.o ltablib.o lstrlib.o loadlib.o linit.o
 
diff --git a/src/lua.c b/src/lua.c
index c245d24..eb16b51 100644
--- a/src/lua.c
+++ b/src/lua.c
@@ -168,25 +168,6 @@ static int docall (lua_State *L, int narg, int clear) {
 }
 
 
-/* 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;
-  int argc = 0;
-  while (argv[argc]) argc++;  /* count total number of arguments */
-  narg = argc - (n + 1);  /* number of arguments to the script */
-  luaL_checkstack(L, narg + 3, "too many arguments to script");
-  for (i=n+1; i < argc; i++)
-    lua_pushstring(L, argv[i]);
-  lua_createtable(L, narg, n + 1);
-  for (i=0; i < argc; i++) {
-    lua_pushstring(L, argv[i]);
-    lua_rawseti(L, -2, i - n);
-  }
-  return narg;
-}
-
-
 static int dofile (lua_State *L, const char *name) {
   int status = luaL_loadfile(L, name) || docall(L, 0, 1);
   return report_in_developer_mode(L, status);
@@ -326,17 +307,13 @@ int load_definitions(lua_State *L) {
 
 
 char *Image_name = NULL;
+void load_tlv (lua_State *L, char *filename);
 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");
+  /* TODO: pass args in */
   /* parse and load file contents (teliva_program array) */
   Image_name = argv[n];
-  status = luaL_loadfile(L, Image_name);
-  lua_insert(L, -(narg+1));
-  if (status != 0) return report(L, status);  /* can't recover within teliva */
-  status = docall(L, narg, 0);
-  if (status != 0) return report(L, status);  /* can't recover within teliva */
+  load_tlv(L, Image_name);
   status = load_definitions(L);
   if (status != 0) return 0;
   /* call main() */
diff --git a/src/tlv.c b/src/tlv.c
new file mode 100644
index 0000000..bf23da8
--- /dev/null
+++ b/src/tlv.c
@@ -0,0 +1,73 @@
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+
+#include "lua.h"
+#include "lauxlib.h"
+
+void teliva_load_multiline_string(lua_State* L, FILE* in) {
+  luaL_Buffer b;
+  luaL_buffinit(L, &b);
+  char line[1024] = {'\0'};
+  int indent = -1;
+  while (!feof(in)) {
+    char c = fgetc(in);
+    ungetc(c, in);
+    if (c != ' ') break;
+    assert(fgets(line, 1024, in));
+    assert(line[strlen(line)-1] == '\n');
+    char* start = strchr(line, '>');
+    if (indent == -1)
+      indent = start - line;
+    else
+      assert(indent == start - line);
+    ++start;  /* skip '>' */
+    luaL_addstring(&b, start);
+  }
+  luaL_pushresult(&b);
+}
+
+/* leave a single table on stack containing the next top-level definition from the file */
+void teliva_load_definition(lua_State* L, FILE* in) {
+  lua_newtable(L);
+  int def_idx = lua_gettop(L);
+  char line[1024] = {'\0'};
+  char key[512] = {'\0'};
+  char value[1024] = {'\0'};
+  while (!feof(in)) {
+    assert(fgets(line, 1024, in));
+    assert(line[strlen(line)-1] == '\n');
+    if (line[0] == '#') continue;  /* comment */
+    assert(line[0] == '-' || line[0] == ' ');
+    assert(line[1] == ' ');
+    memset(key, 0, 512);
+    memset(value, 0, 1024);
+    sscanf(line+2, "%s%s", key, value);
+    assert(key[strlen(key)-1] == ':');
+    key[strlen(key)-1] = '\0';
+    lua_pushstring(L, key);
+    if (value[0] != '\0')
+      lua_pushstring(L, value);  /* value string on same line */
+    else
+      teliva_load_multiline_string(L, in);  /* load from later lines */
+    lua_settable(L, def_idx);
+    /* done with this definition? */
+    char c = fgetc(in);
+    ungetc(c, in);
+    if (c != ' ') break;
+  }
+}
+
+void load_tlv(lua_State* L, char* filename) {
+  lua_newtable(L);
+  int history_array = lua_gettop(L);
+  FILE* in = fopen(filename, "r");
+  for (int i = 1; !feof(in); ++i) {
+    teliva_load_definition(L, in);
+    if (lua_isnil(L, -1)) break;
+    lua_rawseti(L, history_array, i);
+  }
+  fclose(in);
+  lua_setglobal(L, "teliva_program");
+}
diff --git a/src/x.tlv b/src/x.tlv
new file mode 100644
index 0000000..4204c72
--- /dev/null
+++ b/src/x.tlv
@@ -0,0 +1,42 @@
+- __teliva_timestamp: original
+  window:
+    >window = curses.stdscr()
+- __teliva_timestamp: original
+  n:
+    >n = 0
+- __teliva_timestamp: original
+  render:
+    >function render(window)
+    >  window:clear()
+    >  window:attron(curses.A_BOLD)
+    >  window:attron(curses.color_pair(6))
+    >  window:mvaddstr(10, 10, "     ")
+    >  window:mvaddstr(10, 11, n)
+    >  window:attroff(curses.color_pair(6))
+    >  window:attroff(curses.A_BOLD)
+    >  curses.refresh()
+    >end
+- __teliva_timestamp: original
+  menu:
+    >menu = {Enter="increment"}
+- __teliva_timestamp: original
+  update:
+    >function update(window)
+    >  local key = curses.getch()
+    >  if key == 10 then
+    >    n = n+1
+    >  end
+    >end
+- __teliva_timestamp: original
+  main:
+    >function main()
+    >  for i=1,7 do
+    >    curses.init_pair(i, 0, i)
+    >  end
+    >  curses.init_pair(255, 15, 1)  -- reserved for Teliva error messages
+    >
+    >  while true do
+    >    render(window)
+    >    update(window)
+    >  end
+    >end