diff options
-rw-r--r-- | src/Makefile | 2 | ||||
-rw-r--r-- | src/lua.c | 29 | ||||
-rw-r--r-- | src/tlv.c | 73 | ||||
-rw-r--r-- | src/x.tlv | 42 |
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 |