diff --git a/src/code.c b/src/code.c index 382f82f..12892f3 100644 --- a/src/code.c +++ b/src/code.c @@ -194,79 +194,7 @@ static inline bool islineend(char c) {return c == '\n' || c == '\0';} static inline bool isalpha_(char c) {return isalpha(c) || c == '_';} static inline bool isalnum_(char c) {return isalnum(c) || c == '_';} -typedef struct -{ - const char* blockCommentStart; - const char* blockCommentEnd; - const char* blockStringStart; - const char* blockStringEnd; - const char* singleCommentStart; - - const char* const * keywords; - s32 keywordsCount; -} SyntaxConfig; - -static const char* const LuaKeywords [] = -{ - "and", "break", "do", "else", "elseif", - "end", "false", "for", "function", "goto", "if", - "in", "local", "nil", "not", "or", "repeat", - "return", "then", "true", "until", "while" -}; - -static const SyntaxConfig LuaSyntaxConfig = -{ - .blockCommentStart = "--[[", - .blockCommentEnd = "]]", - .singleCommentStart = "--", - .blockStringStart = "[[", - .blockStringEnd = "]]", - .keywords = LuaKeywords, - .keywordsCount = COUNT_OF(LuaKeywords), -}; - -static const char* const MoonKeywords [] = -{ - "false", "true", "nil", "return", - "break", "continue", "for", "while", - "if", "else", "elseif", "unless", "switch", - "when", "and", "or", "in", "do", - "not", "super", "try", "catch", - "with", "export", "import", "then", - "from", "class", "extends", "new" -}; - -static const SyntaxConfig MoonSyntaxConfig = -{ - .blockCommentStart = NULL, - .blockCommentEnd = NULL, - .blockStringStart = NULL, - .blockStringEnd = NULL, - .singleCommentStart = "--", - .keywords = MoonKeywords, - .keywordsCount = COUNT_OF(MoonKeywords), -}; - -static const char* const JsKeywords [] = -{ - "break", "do", "instanceof", "typeof", "case", "else", "new", - "var", "catch", "finally", "return", "void", "continue", "for", - "switch", "while", "debugger", "function", "this", "with", - "default", "if", "throw", "delete", "in", "try", "const" -}; - -static const SyntaxConfig JsSyntaxConfig = -{ - .blockCommentStart = "/*", - .blockCommentEnd = "*/", - .blockStringStart = NULL, - .blockStringEnd = NULL, - .singleCommentStart = "//", - .keywords = JsKeywords, - .keywordsCount = COUNT_OF(JsKeywords), -}; - -static void parse(const char* start, u8* color, const SyntaxConfig* config) +static void parse(const char* start, u8* color, const tic_script_config* config) { const char* ptr = start; @@ -412,10 +340,10 @@ static void parse(const char* start, u8* color, const SyntaxConfig* config) ptr++; continue; } - else if(config->singleCommentStart && memcmp(ptr, config->singleCommentStart, strlen(config->singleCommentStart)) == 0) + else if(config->singleComment && memcmp(ptr, config->singleComment, strlen(config->singleComment)) == 0) { singleCommentStart = ptr; - ptr += strlen(config->singleCommentStart); + ptr += strlen(config->singleComment); continue; } else if(isalpha_(c)) @@ -444,12 +372,9 @@ static void parseSyntaxColor(Code* code) { memset(code->colorBuffer, getConfig()->theme.code.var, sizeof(code->colorBuffer)); - switch(code->tic->api.get_script(code->tic)) - { - case tic_script_moon: parse(code->src, code->colorBuffer, &MoonSyntaxConfig); break; - case tic_script_lua: parse(code->src, code->colorBuffer, &LuaSyntaxConfig); break; - case tic_script_js: parse(code->src, code->colorBuffer, &JsSyntaxConfig); break; - } + tic_mem* tic = code->tic; + + parse(code->src, code->colorBuffer, tic->api.get_script_config(tic)); } static char* getLineByPos(Code* code, char* pos) @@ -1124,7 +1049,7 @@ static void setOutlineMode(Code* code) code->outline.index = 0; memset(code->outline.items, 0, OUTLINE_ITEMS_SIZE); - code->tic->api.get_script(code->tic) == tic_script_moon + code->tic->api.get_script_config(code->tic)->lang == tic_script_moon ? setMoonscriptOutlineMode(code) : setLuaOutlineMode(code); @@ -1158,7 +1083,10 @@ static void commentLine(Code* code) static char Comment[] = "-- "; enum {Size = sizeof Comment-1}; - strcpy(Comment, code->tic->api.get_script(code->tic) == tic_script_js ? "// " : "-- "); + tic_mem* tic = code->tic; + + memcpy(Comment, tic->api.get_script_config(tic)->singleComment, + strlen(tic->api.get_script_config(tic)->singleComment)); char* line = getLine(code); diff --git a/src/jsapi.c b/src/jsapi.c index 4a752cd..08bddf3 100644 --- a/src/jsapi.c +++ b/src/jsapi.c @@ -27,8 +27,10 @@ static const char TicMachine[] = "_TIC80"; -void closeJavascript(tic_machine* machine) +static void closeJavascript(tic_mem* tic) { + tic_machine* machine = (tic_machine*)tic; + if(machine->js) { duk_destroy_heap(machine->js); @@ -775,7 +777,7 @@ s32 duk_timeout_check(void* udata) static void initDuktape(tic_machine* machine) { - closeJavascript(machine); + closeJavascript((tic_mem*)machine); duk_context* duk = machine->js = duk_create_heap(NULL, NULL, NULL, machine, NULL); @@ -794,8 +796,10 @@ static void initDuktape(tic_machine* machine) } } -bool initJavascript(tic_machine* machine, const char* code) +static bool initJavascript(tic_mem* tic, const char* code) { + tic_machine* machine = (tic_machine*)tic; + initDuktape(machine); duk_context* duktape = machine->js; @@ -809,8 +813,10 @@ bool initJavascript(tic_machine* machine, const char* code) return true; } -void callJavascriptTick(tic_machine* machine) +static void callJavascriptTick(tic_mem* tic) { + tic_machine* machine = (tic_machine*)tic; + const char* TicFunc = ApiKeywords[0]; duk_context* duk = machine->js; @@ -832,7 +838,7 @@ void callJavascriptTick(tic_machine* machine) } } -void callJavascriptScanline(tic_mem* memory, s32 row, void* data) +static void callJavascriptScanline(tic_mem* memory, s32 row, void* data) { tic_machine* machine = (tic_machine*)memory; duk_context* duk = machine->js; @@ -853,7 +859,7 @@ void callJavascriptScanline(tic_mem* memory, s32 row, void* data) else duk_pop(duk); } -void callJavascriptOverlap(tic_mem* memory, void* data) +static void callJavascriptOverlap(tic_mem* memory, void* data) { tic_machine* machine = (tic_machine*)memory; duk_context* duk = machine->js; @@ -870,4 +876,36 @@ void callJavascriptOverlap(tic_mem* memory, void* data) else duk_pop(duk); } else duk_pop(duk); -} \ No newline at end of file +} + +static const char* const JsKeywords [] = +{ + "break", "do", "instanceof", "typeof", "case", "else", "new", + "var", "catch", "finally", "return", "void", "continue", "for", + "switch", "while", "debugger", "function", "this", "with", + "default", "if", "throw", "delete", "in", "try", "const" +}; + +static const tic_script_config JsSyntaxConfig = +{ + .lang = tic_script_js, + + .init = initJavascript, + .close = closeJavascript, + .tick = callJavascriptTick, + .scanline = callJavascriptScanline, + .overlap = callJavascriptOverlap, + + .blockCommentStart = "/*", + .blockCommentEnd = "*/", + .blockStringStart = NULL, + .blockStringEnd = NULL, + .singleComment = "//", + .keywords = JsKeywords, + .keywordsCount = COUNT_OF(JsKeywords), +}; + +const tic_script_config* getJsScriptConfig() +{ + return &JsSyntaxConfig; +} diff --git a/src/luaapi.c b/src/luaapi.c index 1731175..6742d8f 100644 --- a/src/luaapi.c +++ b/src/luaapi.c @@ -1114,8 +1114,10 @@ static void initAPI(tic_machine* machine) lua_sethook(machine->lua, &checkForceExit, LUA_MASKCOUNT, LUA_LOC_STACK); } -void closeLua(tic_machine* machine) +static void closeLua(tic_mem* tic) { + tic_machine* machine = (tic_machine*)tic; + if(machine->lua) { lua_close(machine->lua); @@ -1123,27 +1125,21 @@ void closeLua(tic_machine* machine) } } -bool initLua(tic_machine* machine, const char* code) +static bool initLua(tic_mem* tic, const char* code) { - closeLua(machine); + tic_machine* machine = (tic_machine*)tic; + + closeLua(tic); lua_State* lua = machine->lua = luaL_newstate(); static const luaL_Reg loadedlibs[] = { { "_G", luaopen_base }, - //{ LUA_LOADLIBNAME, luaopen_package }, { LUA_COLIBNAME, luaopen_coroutine }, { LUA_TABLIBNAME, luaopen_table }, - // {LUA_IOLIBNAME, luaopen_io}, - // {LUA_OSLIBNAME, luaopen_os}, { LUA_STRLIBNAME, luaopen_string }, { LUA_MATHLIBNAME, luaopen_math }, - // {LUA_UTF8LIBNAME, luaopen_utf8}, - //{ LUA_DBLIBNAME, luaopen_debug }, - // #if defined(LUA_COMPAT_BITLIB) - // {LUA_BITLIBNAME, luaopen_bit32}, - // #endif { NULL, NULL } }; @@ -1181,9 +1177,10 @@ static const char* execute_moonscript_src = MOON_CODE( return fn() ); -bool initMoonscript(tic_machine* machine, const char* code) +static bool initMoonscript(tic_mem* tic, const char* code) { - closeLua(machine); + tic_machine* machine = (tic_machine*)tic; + closeLua(tic); lua_State* lua = machine->lua = luaL_newstate(); @@ -1245,8 +1242,10 @@ bool initMoonscript(tic_machine* machine, const char* code) return true; } -void callLuaTick(tic_machine* machine) +static void callLuaTick(tic_mem* tic) { + tic_machine* machine = (tic_machine*)tic; + const char* TicFunc = ApiKeywords[0]; lua_State* lua = machine->lua; @@ -1267,7 +1266,7 @@ void callLuaTick(tic_machine* machine) } } -void callLuaScanline(tic_mem* memory, s32 row, void* data) +static void callLuaScanline(tic_mem* memory, s32 row, void* data) { tic_machine* machine = (tic_machine*)memory; lua_State* lua = machine->lua; @@ -1287,7 +1286,7 @@ void callLuaScanline(tic_mem* memory, s32 row, void* data) } } -void callLuaOverlap(tic_mem* memory, void* data) +static void callLuaOverlap(tic_mem* memory, void* data) { tic_machine* machine = (tic_machine*)memory; lua_State* lua = machine->lua; @@ -1306,3 +1305,70 @@ void callLuaOverlap(tic_mem* memory, void* data) } } + +static const char* const LuaKeywords [] = +{ + "and", "break", "do", "else", "elseif", + "end", "false", "for", "function", "goto", "if", + "in", "local", "nil", "not", "or", "repeat", + "return", "then", "true", "until", "while" +}; + +static const tic_script_config LuaSyntaxConfig = +{ + .lang = tic_script_lua, + + .init = initLua, + .close = closeLua, + .tick = callLuaTick, + .scanline = callLuaScanline, + .overlap = callLuaOverlap, + + .blockCommentStart = "--[[", + .blockCommentEnd = "]]", + .singleComment = "--", + .blockStringStart = "[[", + .blockStringEnd = "]]", + .keywords = LuaKeywords, + .keywordsCount = COUNT_OF(LuaKeywords), +}; + +const tic_script_config* getLuaScriptConfig() +{ + return &LuaSyntaxConfig; +} + +static const char* const MoonKeywords [] = +{ + "false", "true", "nil", "return", + "break", "continue", "for", "while", + "if", "else", "elseif", "unless", "switch", + "when", "and", "or", "in", "do", + "not", "super", "try", "catch", + "with", "export", "import", "then", + "from", "class", "extends", "new" +}; + +static const tic_script_config MoonSyntaxConfig = +{ + .lang = tic_script_moon, + + .init = initMoonscript, + .close = closeLua, + .tick = callLuaTick, + .scanline = callLuaScanline, + .overlap = callLuaOverlap, + + .blockCommentStart = NULL, + .blockCommentEnd = NULL, + .blockStringStart = NULL, + .blockStringEnd = NULL, + .singleComment = "--", + .keywords = MoonKeywords, + .keywordsCount = COUNT_OF(MoonKeywords), +}; + +const tic_script_config* getMoonScriptConfig() +{ + return &MoonSyntaxConfig; +} \ No newline at end of file diff --git a/src/machine.h b/src/machine.h index e3d6909..6047ccc 100644 --- a/src/machine.h +++ b/src/machine.h @@ -82,6 +82,7 @@ typedef struct Channel channels[TIC_SOUND_CHANNELS]; } music; + tic_tick tick; tic_scanline scanline; struct @@ -142,18 +143,6 @@ s32 drawText(tic_mem* memory, const char* text, s32 x, s32 y, s32 width, s32 hei s32 drawSpriteFont(tic_mem* memory, u8 symbol, s32 x, s32 y, s32 width, s32 height, u8 chromakey, s32 scale); s32 drawFixedSpriteFont(tic_mem* memory, u8 index, s32 x, s32 y, s32 width, s32 height, u8 chromakey, s32 scale); -void closeLua(tic_machine* machine); -void closeJavascript(tic_machine* machine); - -bool initMoonscript(tic_machine* machine, const char* code); -bool initLua(tic_machine* machine, const char* code); -bool initJavascript(tic_machine* machine, const char* code); - -void callLuaTick(tic_machine* machine); -void callJavascriptTick(tic_machine* machine); - -void callLuaScanline(tic_mem* memory, s32 row, void* data); -void callJavascriptScanline(tic_mem* memory, s32 row, void* data); - -void callLuaOverlap(tic_mem* memory, void* data); -void callJavascriptOverlap(tic_mem* memory, void* data); +const tic_script_config* getLuaScriptConfig(); +const tic_script_config* getMoonScriptConfig(); +const tic_script_config* getJsScriptConfig(); diff --git a/src/tic.c b/src/tic.c index ecc71ef..fb8c30d 100644 --- a/src/tic.c +++ b/src/tic.c @@ -559,8 +559,10 @@ void tic_close(tic_mem* memory) machine->state.initialized = false; - closeJavascript(machine); - closeLua(machine); + getLuaScriptConfig()->close(memory); + getMoonScriptConfig()->close(memory); + getJsScriptConfig()->close(memory); + blip_delete(machine->blip); free(memory->samples.buffer); @@ -1500,13 +1502,19 @@ static bool isJavascript(const char* code) return compareMetatag(code, "script", "js") || compareMetatag(code, "script", "javascript"); } -static tic_script_lang api_get_script(tic_mem* memory) +static const tic_script_config* getScriptConfig(const char* code) { - if(isMoonscript(memory->cart.bank0.code.data)) return tic_script_moon; - if(isJavascript(memory->cart.bank0.code.data)) return tic_script_js; - return tic_script_lua; + if(isMoonscript(code)) return getMoonScriptConfig(); + if(isJavascript(code)) return getJsScriptConfig(); + return getLuaScriptConfig(); } +static const tic_script_config* api_get_script_config(tic_mem* memory) +{ + return getScriptConfig(memory->cart.bank0.code.data); +} + + static void updateSaveid(tic_mem* memory) { memset(memory->saveid, 0, sizeof memory->saveid); @@ -1527,9 +1535,9 @@ static void updateSaveid(tic_mem* memory) } } -static void api_tick(tic_mem* memory, tic_tick_data* data) +static void api_tick(tic_mem* tic, tic_tick_data* data) { - tic_machine* machine = (tic_machine*)memory; + tic_machine* machine = (tic_machine*)tic; machine->data = data; @@ -1544,7 +1552,7 @@ static void api_tick(tic_mem* memory, tic_tick_data* data) for(s32 i = TIC_BANKS - 1; i >= 0; i--) { - const char* bankCode = memory->cart.banks[i].code.data; + const char* bankCode = tic->cart.banks[i].code.data; if(strlen(bankCode)) strcat(code, bankCode); @@ -1554,35 +1562,18 @@ static void api_tick(tic_mem* memory, tic_tick_data* data) data->preprocessor(data->data, code); bool done = false; + const tic_script_config* config = NULL; if(strlen(code)) { - cart2ram(memory); - memory->input = compareMetatag(code, "input", "mouse") ? tic_mouse_input : tic_gamepad_input; + cart2ram(tic); + tic->input = compareMetatag(code, "input", "mouse") ? tic_mouse_input : tic_gamepad_input; - if(memory->input == tic_mouse_input) - memory->ram.vram.vars.mask.data = 0; + if(tic->input == tic_mouse_input) + tic->ram.vram.vars.mask.data = 0; - memory->script = tic_script_lua; - - if (isMoonscript(code)) - { - if(initMoonscript(machine, code)) - { - memory->script = tic_script_moon; - done = true; - } - } - else if(isJavascript(code)) - { - if(initJavascript(machine, code)) - { - memory->script = tic_script_js; - done = true; - } - } - else if(initLua(machine, code)) - done = true; + config = getScriptConfig(code); + done = config->init(tic, code); } else { @@ -1595,17 +1586,17 @@ static void api_tick(tic_mem* memory, tic_tick_data* data) { data->start = data->counter(); - machine->state.scanline = memory->script == tic_script_js ? callJavascriptScanline : callLuaScanline; - machine->state.ovr.callback = memory->script == tic_script_js ? callJavascriptOverlap : callLuaOverlap; + machine->state.tick = config->tick; + machine->state.scanline = config->scanline; + machine->state.ovr.callback = config->overlap; + machine->state.initialized = true; } else return; } } - memory->script == tic_script_js - ? callJavascriptTick(machine) - : callLuaTick(machine); + machine->state.tick(tic); } static void api_scanline(tic_mem* memory, s32 row, void* data) @@ -1877,7 +1868,6 @@ static void initApi(tic_api* api) INIT_API(reset); INIT_API(pause); INIT_API(resume); - INIT_API(get_script); INIT_API(sync); INIT_API(btnp); INIT_API(load); @@ -1886,6 +1876,8 @@ static void initApi(tic_api* api) INIT_API(tick_end); INIT_API(blit); + INIT_API(get_script_config); + #undef INIT_API } diff --git a/src/ticapi.h b/src/ticapi.h index 0802684..caa2b4f 100644 --- a/src/ticapi.h +++ b/src/ticapi.h @@ -64,9 +64,34 @@ typedef struct } tic_tick_data; typedef struct tic_mem tic_mem; +typedef void(*tic_tick)(tic_mem* memory); typedef void(*tic_scanline)(tic_mem* memory, s32 row, void* data); typedef void(*tic_overlap)(tic_mem* memory, void* data); +typedef struct +{ + tic_script_lang lang; + + struct + { + bool(*init)(tic_mem* memory, const char* code); + void(*close)(tic_mem* memory); + + tic_tick tick; + tic_scanline scanline; + tic_overlap overlap; + }; + + const char* blockCommentStart; + const char* blockCommentEnd; + const char* blockStringStart; + const char* blockStringEnd; + const char* singleComment; + + const char* const * keywords; + s32 keywordsCount; +} tic_script_config; + typedef struct { s32 (*draw_char) (tic_mem* memory, u8 symbol, s32 x, s32 y, u8 color); @@ -113,7 +138,7 @@ typedef struct void (*tick_end) (tic_mem* memory); void (*blit) (tic_mem* tic, tic_scanline scanline, tic_overlap overlap, void* data); - tic_script_lang (*get_script)(tic_mem* memory); + const tic_script_config* (*get_script_config)(tic_mem* memory); } tic_api; struct tic_mem @@ -122,7 +147,6 @@ struct tic_mem tic_cartridge cart; tic_cartridge config; tic_input_method input; - tic_script_lang script; tic_font font; tic_api api;