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.
This commit is contained in:
Kartik K. Agaram 2021-11-10 22:04:36 -08:00
parent 8dcf08565d
commit efbb57d339
2 changed files with 109 additions and 0 deletions

37
counter.tlv Normal file
View File

@ -0,0 +1,37 @@
teliva_program = {
window = [[window = curses.stdscr()]],
n = [[n = 0]],
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
]],
menu = [[menu = {Enter="increment"}]],
update = [[
function update(window)
local key = curses.getch()
if key == 10 then
n = n+1
end
end
]],
main = [[
function main()
for i=1,7 do
curses.init_pair(i, 0, i)
end
while true do
render(window)
update(window)
end
end
]],
}

View File

@ -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");