1+ // MIT License
2+
3+ // Copyright (c) 2017 Vadim Grigoruk @nesbox // [email protected] 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+ #include "yue_wrapper/yue_wrapper.h"
26+
27+ static inline bool isalnum_ (char c )
28+ {
29+ return isalnum (c ) || c == '_' ;
30+ }
31+
32+ #define YUE_CODE (...) #__VA_ARGS__
33+
34+ static void evalYuescript (tic_mem * tic , const char * code )
35+ {
36+ tic_core * core = (tic_core * )tic ;
37+ lua_State * lua = (lua_State * )core -> currentVM ;
38+
39+ YueCompiler_t * compiler = yue_compiler_create (NULL , NULL , false);
40+ YueConfig_t * config = yue_config_create ();
41+ CompileInfo_t * result = yue_compile (compiler , code , config );
42+
43+ if (result -> error_msg )
44+ {
45+ core -> data -> error (core -> data -> data , result -> error_display_message );
46+ yue_compile_info_free (result );
47+ yue_config_free (config );
48+ yue_compiler_destroy (compiler );
49+ return ;
50+ }
51+
52+ const char * luaCode = result -> codes ;
53+ if (luaL_loadstring (lua , luaCode ) == LUA_OK )
54+ {
55+ if (lua_pcall (lua , 0 , 0 , 0 ) != LUA_OK )
56+ {
57+ const char * msg = lua_tostring (lua , -1 );
58+ if (msg )
59+ {
60+ core -> data -> error (core -> data -> data , msg );
61+ }
62+ }
63+ }
64+
65+ yue_compile_info_free (result );
66+ yue_config_free (config );
67+ yue_compiler_destroy (compiler );
68+ }
69+
70+ static bool initYuescript (tic_mem * tic , const char * code )
71+ {
72+ tic_core * core = (tic_core * )tic ;
73+ luaapi_close (tic );
74+
75+ core -> currentVM = luaL_newstate ();
76+ lua_State * lua = (lua_State * )core -> currentVM ;
77+ luaapi_open (lua );
78+
79+ // Create compiler with the Lua state and luaapi_open
80+ YueCompiler_t * compiler = yue_compiler_create (lua , luaapi_open , false);
81+ YueConfig_t * config = yue_config_create ();
82+ CompileInfo_t * result = yue_compile (compiler , code , config );
83+
84+ luaapi_init (core );
85+
86+ if (result -> error_msg )
87+ {
88+ core -> data -> error (core -> data -> data , result -> error_display_message );
89+ yue_compile_info_free (result );
90+ yue_config_free (config );
91+ yue_compiler_destroy (compiler );
92+ return false;
93+ }
94+
95+ bool success = true;
96+ if (luaL_loadstring (lua , result -> codes ) != LUA_OK ||
97+ lua_pcall (lua , 0 , 0 , 0 ) != LUA_OK )
98+ {
99+ const char * msg = lua_tostring (lua , -1 );
100+ if (msg ) core -> data -> error (core -> data -> data , msg );
101+ success = false;
102+ }
103+
104+ yue_compile_info_free (result );
105+ yue_config_free (config );
106+ yue_compiler_destroy (compiler );
107+ return success ;
108+ }
109+ static const char * const YueKeywords [] = {
110+ "false" ,
111+ "true" ,
112+ "nil" ,
113+ "local" ,
114+ "global" ,
115+ "return" ,
116+ "break" ,
117+ "continue" ,
118+ "for" ,
119+ "while" ,
120+ "repeat" ,
121+ "until" ,
122+ "if" ,
123+ "else" ,
124+ "elseif" ,
125+ "then" ,
126+ "switch" ,
127+ "when" ,
128+ "unless" ,
129+ "and" ,
130+ "or" ,
131+ "in" ,
132+ "not" ,
133+ "super" ,
134+ "try" ,
135+ "catch" ,
136+ "with" ,
137+ "export" ,
138+ "import" ,
139+ "from" ,
140+ "class" ,
141+ "extends" ,
142+ "using" ,
143+ "do" ,
144+ "macro" ,
145+ };
146+
147+ static const tic_outline_item * getYueOutline (const char * code , s32 * size )
148+ {
149+ enum
150+ {
151+ Size = sizeof (tic_outline_item )
152+ };
153+
154+ * size = 0 ;
155+
156+ static tic_outline_item * items = NULL ;
157+
158+ if (items )
159+ {
160+ free (items );
161+ items = NULL ;
162+ }
163+
164+ const char * ptr = code ;
165+
166+ while (1 )
167+ {
168+ static const char FuncString [] = "=->" ;
169+
170+ ptr = strstr (ptr , FuncString );
171+
172+ if (ptr )
173+ {
174+ const char * end = ptr ;
175+
176+ ptr += sizeof FuncString - 1 ;
177+
178+ while (end >= code && !isalnum_ (* end ))
179+ end -- ;
180+
181+ const char * start = end ;
182+
183+ for (const char * val = start - 1 ; val >= code && isalnum_ (* val ); val -- , start -- )
184+ ;
185+
186+ if (end > start )
187+ {
188+ tic_outline_item * new_items = (tic_outline_item * )realloc (items , (* size + 1 ) * Size );
189+ if (new_items )
190+ {
191+ items = new_items ;
192+ items [* size ].pos = start ;
193+ items [* size ].size = (s32 )(end - start + 1 );
194+ (* size )++ ;
195+ }
196+ }
197+ }
198+ else
199+ break ;
200+ }
201+
202+ return items ;
203+ }
204+
205+ static const u8 DemoRom [] = {
206+ #include "../build/assets/yuedemo.tic.dat"
207+ };
208+
209+ static const u8 MarkRom [] = {
210+ #include "../build/assets/yuemark.tic.dat"
211+ };
212+
213+ TIC_EXPORT const tic_script EXPORT_SCRIPT (Yue ) =
214+ {
215+ .id = 21 ,
216+ .name = "yue" ,
217+ .fileExtension = ".yue" ,
218+ .projectComment = "--" ,
219+ {
220+ .init = initYuescript ,
221+ .close = luaapi_close ,
222+ .tick = luaapi_tick ,
223+ .boot = luaapi_boot ,
224+
225+ .callback =
226+ {
227+ .scanline = luaapi_scn ,
228+ .border = luaapi_bdr ,
229+ .menu = luaapi_menu ,
230+ },
231+ },
232+
233+ .getOutline = getYueOutline ,
234+ .eval = evalYuescript ,
235+
236+ .blockCommentStart = "--[[" ,
237+ .blockCommentEnd = "]]" ,
238+ .blockCommentStart2 = NULL ,
239+ .blockCommentEnd2 = NULL ,
240+
241+ .blockStringStart = NULL ,
242+ .blockStringEnd = NULL ,
243+ .singleComment = "--" ,
244+ .blockEnd = NULL ,
245+
246+ .keywords = YueKeywords ,
247+ .keywordsCount = COUNT_OF (YueKeywords ),
248+
249+ .demo = {DemoRom , sizeof DemoRom },
250+ .mark = {MarkRom , sizeof MarkRom , "yuemark.tic" },
251+ };
0 commit comments