this repo has no description
at main 263 lines 6.5 kB view raw
1// MIT License 2 3// Copyright (c) 2017 Vadim Grigoruk @nesbox // grigoruk@gmail.com 4 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to deal 7// in the Software without restriction, including without limitation the rights 8// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9// copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11 12// The above copyright notice and this permission notice shall be included in all 13// copies or substantial portions of the Software. 14 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21// SOFTWARE. 22 23#include "core/core.h" 24#include "luaapi.h" 25 26#include <stdlib.h> 27#include <lua.h> 28#include <lauxlib.h> 29#include <lualib.h> 30#include <ctype.h> 31 32static bool initLua(tic_mem* tic, const char* code) 33{ 34 tic_core* core = (tic_core*)tic; 35 36 luaapi_close(tic); 37 38 lua_State* lua = core->currentVM = luaL_newstate(); 39 luaapi_open(lua); 40 41 luaapi_init(core); 42 43 { 44 lua_State* lua = core->currentVM; 45 46 lua_settop(lua, 0); 47 48 if(luaL_loadstring(lua, code) != LUA_OK || lua_pcall(lua, 0, LUA_MULTRET, 0) != LUA_OK) 49 { 50 core->data->error(core->data->data, lua_tostring(lua, -1)); 51 return false; 52 } 53 } 54 55 return true; 56} 57 58static const char* const LuaKeywords [] = 59{ 60 "and", "break", "do", "else", "elseif", 61 "end", "false", "for", "function", "goto", "if", 62 "in", "local", "nil", "not", "or", "repeat", 63 "return", "then", "true", "until", "while", 64 "self" 65}; 66 67static inline bool isalnum_(char c) {return isalnum(c) || c == '_';} 68 69static const tic_outline_item* getLuaOutline(const char* code, s32* size) 70{ 71 enum{Size = sizeof(tic_outline_item)}; 72 73 *size = 0; 74 75 static tic_outline_item* items = NULL; 76 77 if(items) 78 { 79 free(items); 80 items = NULL; 81 } 82 83 const char* ptr = code; 84 85 while(true) 86 { 87 static const char FuncString[] = "function "; 88 89 ptr = strstr(ptr, FuncString); 90 91 if(ptr) 92 { 93 ptr += sizeof FuncString - 1; 94 95 const char* start = ptr; 96 const char* end = start; 97 98 while(*ptr) 99 { 100 char c = *ptr; 101 102 if(isalnum_(c) || c == ':'); 103 else if(c == '(') 104 { 105 end = ptr; 106 break; 107 } 108 else break; 109 110 ptr++; 111 } 112 113 if(end > start) 114 { 115 items = realloc(items, (*size + 1) * Size); 116 117 items[*size].pos = start; 118 items[*size].size = (s32)(end - start); 119 120 (*size)++; 121 } 122 } 123 else break; 124 } 125 126 return items; 127} 128 129static void evalLua(tic_mem* tic, const char* code) 130{ 131 tic_core* core = (tic_core*)tic; 132 lua_State* lua = core->currentVM; 133 134 if (!lua) return; 135 136 lua_settop(lua, 0); 137 138 if(luaL_loadstring(lua, code) != LUA_OK || lua_pcall(lua, 0, LUA_MULTRET, 0) != LUA_OK) 139 { 140 core->data->error(core->data->data, lua_tostring(lua, -1)); 141 } 142} 143 144static const u8 DemoRom[] = 145{ 146 #include "../build/assets/luademo.tic.dat" 147}; 148 149static const u8 MarkRom[] = 150{ 151 #include "../build/assets/luamark.tic.dat" 152}; 153 154static const u8 DemoFire[] = 155{ 156 #include "../build/assets/fire.tic.dat" 157}; 158 159static const u8 DemoP3d[] = 160{ 161 #include "../build/assets/p3d.tic.dat" 162}; 163 164static const u8 DemoSfx[] = 165{ 166 #include "../build/assets/sfx.tic.dat" 167}; 168 169static const u8 DemoPalette[] = 170{ 171 #include "../build/assets/palette.tic.dat" 172}; 173 174static const u8 DemoFont[] = 175{ 176 #include "../build/assets/font.tic.dat" 177}; 178 179static const u8 DemoMusic[] = 180{ 181 #include "../build/assets/music.tic.dat" 182}; 183 184static const u8 DemoQuest[] = 185{ 186 #include "../build/assets/quest.tic.dat" 187}; 188 189static const u8 DemoTetris[] = 190{ 191 #include "../build/assets/tetris.tic.dat" 192}; 193 194static const u8 DemoBenchmark[] = 195{ 196 #include "../build/assets/benchmark.tic.dat" 197}; 198 199static const u8 DemoBpp[] = 200{ 201 #include "../build/assets/bpp.tic.dat" 202}; 203 204static const u8 DemoCar[] = 205{ 206 #include "../build/assets/car.tic.dat" 207}; 208 209TIC_EXPORT const tic_script EXPORT_SCRIPT(Lua) = 210{ 211 .id = 10, 212 .name = "lua", 213 .fileExtension = ".lua", 214 .projectComment = "--", 215 { 216 .init = initLua, 217 .close = luaapi_close, 218 .tick = luaapi_tick, 219 .boot = luaapi_boot, 220 221 .callback = 222 { 223 .scanline = luaapi_scn, 224 .border = luaapi_bdr, 225 .menu = luaapi_menu, 226 }, 227 }, 228 229 .getOutline = getLuaOutline, 230 .eval = evalLua, 231 232 .blockCommentStart = "--[[", 233 .blockCommentEnd = "]]", 234 .blockCommentStart2 = NULL, 235 .blockCommentEnd2 = NULL, 236 .singleComment = "--", 237 .blockStringStart = "[[", 238 .blockStringEnd = "]]", 239 .stdStringStartEnd = "\'\"", 240 .blockEnd = "end", 241 242 .keywords = LuaKeywords, 243 .keywordsCount = COUNT_OF(LuaKeywords), 244 245 .demo = {DemoRom, sizeof DemoRom}, 246 .mark = {MarkRom, sizeof MarkRom, "luamark.tic"}, 247 248 .demos = (struct tic_demo[]) 249 { 250 {DemoFire, sizeof DemoFire, "fire.tic"}, 251 {DemoP3d, sizeof DemoP3d, "p3d.tic"}, 252 {DemoSfx, sizeof DemoSfx, "sfx.tic"}, 253 {DemoPalette, sizeof DemoPalette, "palette.tic"}, 254 {DemoFont, sizeof DemoFont, "font.tic"}, 255 {DemoMusic, sizeof DemoMusic, "music.tic"}, 256 {DemoQuest, sizeof DemoQuest, "quest.tic"}, 257 {DemoTetris, sizeof DemoTetris, "tetris.tic"}, 258 {DemoBenchmark, sizeof DemoBenchmark, "benchmark.tic"}, 259 {DemoBpp, sizeof DemoBpp, "bpp.tic"}, 260 {DemoCar, sizeof DemoCar, "car.tic"}, 261 {0}, 262 }, 263};