int su_compile(su_state *s, const char *code, const char *name, char **inline_c, char **result, size_t *size) { const char *tmp; size_t buffer_size; lua_State *L = lua_open(); su_state *sc = su_init(su_allocator(s)); su_libinit(sc); ___saurus(sc); luaL_openlibs(L); luaopen_writebin(L); if (luaL_loadstring(L, compiler_code)) { *result = dup(s, lua_tostring(L, -1)); if (size) *size = strlen(*result); lua_close(L); su_close(sc); return -1; } if (lua_pcall(L, 0, 0, 0)) { lua_getglobal(L, "saurus_error"); if (lua_isnil(L, -1)) lua_pop(L, 1); *result = dup(s, lua_tostring(L, -1)); if (size) *size = strlen(*result); lua_close(L); su_close(sc); return -2; } lua_getglobal(L, "repl"); lua_pushstring(L, code); lua_pushstring(L, name ? name : "?"); if (lua_pcall(L, 2, 1, 0)) { lua_getglobal(L, "saurus_error"); if (lua_isnil(L, -1)) { lua_pop(L, 1); *result = dup(s, lua_tostring(L, -1)); } else { *result = dup(s, lua_tostring(L, -1)); } if (size) *size = strlen(*result); lua_close(L); su_close(sc); return -3; } tmp = lua_tolstring(L, -1, &buffer_size); *result = (char*)su_allocate(s, NULL, buffer_size); memcpy(*result, tmp, buffer_size); if (size) *size = buffer_size; if (inline_c) { lua_getglobal(L, "c_code"); if (lua_isnil(L, -1)) tmp = lua_tostring(L, -1); *inline_c = (char*)su_allocate(s, NULL, strlen(tmp) + 1); strcpy(*inline_c, tmp); } lua_close(L); su_close(sc); return 0; }
static int luasofia_su_init(lua_State *L) { lua_pushinteger(L, su_init()); return 1; }
int main(int argc, char *argv[]) { int ret, i; int compile; FILE *fp; jmp_buf err; su_state *s; lua_State *L; char *tmp; const char *tmp2; const char *input, *output; int print_help = argc > 1 && strstr("-h -v --help --version", argv[1]) != NULL; int pipe = argc > 1 && !strcmp("--", argv[1]); compiler = su_init(NULL); su_libinit(compiler); ___saurus(compiler); atexit(shutdown); if (!pipe && (argc <= 1 || print_help)) { printf("S A U R U S\nCopyright (c) 2009-2015 Andreas T Jonsson <*****@*****.**>\nVersion: %s\n\n", su_version(NULL, NULL, NULL)); if (print_help) { puts("Usage: saurus <options> <input.su> <output.suc>\n\tOptions:\n\t\t'-c' Compile source file to binary file.\n\t\t'--' read from STDIN."); return 0; } } s = su_init(NULL); su_libinit(s); L = lua_open(); luaL_openlibs(L); luaopen_writebin(L); if (luaL_loadstring(L, compiler_code)) { fprintf(stderr, "%s\n", lua_tostring(L, -1)); lua_close(L); su_close(s); return -1; } if (lua_pcall(L, 0, 0, 0)) { lua_getglobal(L, "saurus_error"); if (lua_isnil(L, -1)) lua_pop(L, 1); fprintf(stderr, "%s\n", lua_tostring(L, -1)); lua_close(L); su_close(s); return -1; } ret = 0; if (argc < 2 || pipe) { if (!pipe) puts("Type '_h' for help or '_q' to exit.\n"); su_pushstring(s, repl_help_text); su_setglobal(s, "_h"); su_pushstring(s, "_q"); su_setglobal(s, "_q"); ret = setjmp(err); if (!pipe) su_seterror(s, err, ret); jump: for (;;) { if (!pipe) printf("> "); fgets(buffer, BUFFER_SIZE, stdin); lua_getglobal(L, "repl"); lua_pushstring(L, buffer); lua_pushstring(L, argv[0]); if (lua_pcall(L, 2, 1, 0)) { lua_getglobal(L, "saurus_error"); if (lua_isnil(L, -1)) { lua_pop(L, 1); puts(lua_tostring(L, -1)); } else { puts(lua_tostring(L, -1)); lua_pop(L, 1); } lua_pop(L, 1); goto jump; } lua_getglobal(L, "c_code"); su_assert(s, lua_isnil(L, -1), "Inline C is not supported in interpreter!"); lua_pop(L, 1); tmp2 = lua_tolstring(L, -1, NULL); su_assert(s, su_getglobal(s, "io"), "Could not retrieve 'io' namespace."); su_pushstring(s, "print"); su_assert(s, su_map_get(s, -2), "Could not retrieve 'print' function."); if (su_load(s, NULL, (void*)tmp2)) { su_close(s); lua_close(L); fprintf(stderr, "Could not load: %s\n", argv[1]); return -1; } lua_pop(L, 1); su_call(s, 0, 1); if (su_type(s, -1) == SU_STRING && !strcmp(su_tostring(s, -1, NULL), "_q")) { ret = 0; break; } su_call(s, 1, 0); su_pop(s, 1); } } else { compile = !strcmp(argv[1], "-c"); input = compile ? argv[2] : argv[1]; if (compile) { if (argc < 4) { fputs("Expected input and output file!", stderr); lua_close(L); su_close(s); return -1; } } else { fp = fopen(input, "rb"); if (!fp) { fprintf(stderr, "Could not open: %s\n", input); lua_close(L); su_close(s); return -1; } if (fread(buffer, 1, 1, fp) == 1) { if (*buffer == '\x1b') { rewind(fp); if (su_load(s, &reader_fp, fp)) { su_close(s); lua_close(L); fclose(fp); fprintf(stderr, "Could not load: %s\n", input); return -1; } su_pushstring(s, input); for (i = 2; i < argc; i++) su_pushstring(s, argv[i]); su_call(s, argc - 1, 1); if (su_type(s, -1) == SU_NUMBER) ret = (int)su_tonumber(s, -1); su_close(s); lua_close(L); fclose(fp); return ret; } } fclose(fp); } tmp = tmpnam(buffer); output = compile ? argv[3] : tmp; lua_getglobal(L, "compile"); lua_pushstring(L, input); lua_pushstring(L, output); lua_pushboolean(L, compile); if (lua_pcall(L, 3, 0, 0)) { lua_getglobal(L, "saurus_error"); if (lua_isnil(L, -1)) lua_pop(L, 1); fprintf(stderr, "%s\n", lua_tostring(L, -1)); lua_close(L); su_close(s); return -1; } if (!compile) { fp = fopen(output, "rb"); if (!fp) { fprintf(stderr, "Could not open: %s\n", output); lua_close(L); su_close(s); return -1; } if (su_load(s, &reader_fp, fp)) { su_close(s); lua_close(L); fclose(fp); remove(tmp); fprintf(stderr, "Could not load: %s\n", output); return -1; } fclose(fp); remove(tmp); su_pushstring(s, argv[1]); for (i = 2; i < argc; i++) su_pushstring(s, argv[i]); su_call(s, argc - 1, 1); if (su_type(s, -1) == SU_NUMBER) ret = (int)su_tonumber(s, -1); } } lua_close(L); su_close(s); return ret; }