1-
21#include <stdio.h>
32#include <stdlib.h>
3+ #include <stdint.h>
44#include <string.h>
55
66/**
@@ -112,6 +112,7 @@ char *RunFunction(AST tree)
112112 if (soare_fn .name )
113113 return soare_fn .exec (tree -> child );
114114
115+ // Function is not defined
115116 return LeaveException (UndefinedReference , tree -> value , tree -> file );
116117 }
117118
@@ -166,10 +167,10 @@ char *RunFunction(AST tree)
166167 return NULL ;
167168}
168169
169- static char broken = 0 ;
170+ static uint8_t broken = 0 ;
170171
171172/**
172- * @brief Executes code from a tree
173+ * @brief Interprets an AST node tree
173174 *
174175 * @param tree
175176 * @return char*
@@ -179,158 +180,155 @@ static char *Runtime(AST tree)
179180 if (!tree )
180181 return NULL ;
181182
182- AST root = tree ;
183- AST tmp = NULL ;
184- MEM get = NULL ;
185-
186- char * returned = NULL ;
187- unsigned char error = 0 ;
188-
189- broken = 0 ;
190-
191183 MEM statement = MemLast (MEMORY );
184+
192185 MemJoin (statement , FUNCTION );
193186 FUNCTION = NULL ;
194187
195- for (AST curr = root -> child ; curr && !ErrorLevel (); curr = curr -> sibling )
188+ broken = 0 ;
189+
190+ for (AST curr = tree -> child ; curr && !ErrorLevel (); curr = curr -> sibling )
196191 {
197192 switch (curr -> type )
198193 {
199- // Store function into MEMORY
200194 case NODE_FUNCTION :
201-
195+ // Store function definition in current scope
202196 MemPushf (statement , curr -> value , curr );
203197 break ;
204198
205- // Import SOARE code from an other file
206- case NODE_IMPORT :
207-
208- if ((tmp = loadimport (curr -> value )))
209- BranchJuxtapose (curr , tmp -> child );
210- break ;
211-
212- // Call a function
213199 case NODE_CALL :
214-
200+ // Execute function call and free result
215201 free (RunFunction (curr ));
216202 break ;
217203
218- // Push a new variable into MEMORY
219- case NODE_MEMNEW :
204+ case NODE_BREAK :
205+ // Break out of loop
206+ broken = 1 ;
207+ return ExitStatement (statement , NULL );
220208
209+ case NODE_RETURN :
210+ // Return from function
211+ return ExitStatement (statement , Eval (curr -> child ));
212+
213+ case NODE_RAISE :
214+ // Raise an exception
215+ return ExitStatementError (statement , RaiseException , curr -> value , curr -> file );
216+
217+ case NODE_IMPORT :
218+ {
219+ // Import external file and merge its AST
220+ AST tmp = loadimport (curr -> value );
221+ if (tmp )
222+ BranchJuxtapose (curr , tmp -> child );
223+ }
224+ break ;
225+
226+ case NODE_MEMNEW :
227+ // Create new variable in current scope
221228 MemPush (statement , curr -> value , Eval (curr -> child ));
222229 break ;
223230
224- // Set a value to a variable
225231 case NODE_MEMSET :
232+ {
233+ // Set variable value in current scope
234+ MEM get = MemGet (MEMORY , curr -> value );
226235
227- if (!( get = MemGet ( MEMORY , curr -> value )) )
236+ if (!get )
228237 return ExitStatementError (statement , UndefinedReference , curr -> value , curr -> file );
229238
230239 if (get -> body )
231240 return ExitStatementError (statement , VariableDefinedAsFunction , curr -> value , curr -> file );
232241
233242 MemSet (get , Eval (curr -> child ));
234- break ;
243+ }
244+ break ;
235245
236- // Condition statement (if)
237- case NODE_CONDITION :
246+ case NODE_CUSTOM_KEYWORD :
247+ {
248+ // Execute custom keyword handler
249+ soare_keyword keyword = soare_getkeyword (curr -> value );
250+ if (keyword .name )
251+ keyword .exec ();
252+ }
253+ break ;
238254
239- returned = Eval (curr -> child );
240- tmp = curr -> child ;
255+ case NODE_CONDITION :
256+ {
257+ // Evaluate condition chain (if/or/else)
258+ AST tmp = curr -> child ;
259+ char * condition = Eval (tmp );
241260
242- while (returned )
261+ while (condition )
243262 {
244- if (strcmp (returned , "0" ))
263+ if (strcmp (condition , "0" ))
245264 {
246- free (returned );
265+ free (condition );
247266
248- if ((returned = Runtime (tmp -> sibling )) || broken )
249- return ExitStatement (statement , returned );
267+ char * value = Runtime (tmp -> sibling );
250268
269+ if (value || broken )
270+ return ExitStatement (statement , value );
251271 break ;
252272 }
253273
254- free (returned );
274+ free (condition );
255275
256- if (!( tmp = tmp -> sibling -> sibling ) )
276+ if (!tmp -> sibling )
257277 break ;
258278
259- returned = Eval (tmp );
279+ tmp = tmp -> sibling -> sibling ;
280+ condition = Eval (tmp );
260281 }
261- break ;
282+ }
283+ break ;
262284
263- // Repetition statement (while)
264285 case NODE_REPETITION :
286+ {
287+ // Loop while condition is true (!= "0")
288+ char * condition = Eval (curr -> child );
265289
266- while (( returned = Eval ( curr -> child )) )
290+ while (condition && strcmp ( condition , "0" ) && ! ErrorLevel () && ! broken )
267291 {
268- if (!strcmp (returned , "0" ) || ErrorLevel () || broken )
269- break ;
292+ free (condition );
293+
294+ char * value = Runtime (curr -> child -> sibling );
270295
271- free (returned );
296+ if (value )
297+ return ExitStatement (statement , value );
272298
273- if ((returned = Runtime (curr -> child -> sibling )))
274- return ExitStatement (statement , returned );
299+ condition = Eval (curr -> child );
275300 }
276301
277- free (returned );
278- break ;
302+ free (condition );
303+ }
304+ break ;
279305
280- // try/iferror statement
281306 case NODE_TRY :
282-
283- error = AsIgnoredException ();
307+ {
308+ // try/iferror block
309+ unsigned char previous = AsIgnoredException ();
284310 IgnoreException (1 );
285- returned = Runtime (curr -> child );
286- IgnoreException (error );
311+ char * value = Runtime (curr -> child );
312+ IgnoreException (previous );
287313
288314 if (ErrorLevel () && !broken )
289315 {
290- free (returned );
316+ free (value );
291317 ClearException ();
292- returned = Runtime (curr -> child -> sibling );
318+ value = Runtime (curr -> child -> sibling );
293319 }
294320
295- if (!returned && !broken )
296- break ;
297-
298- return ExitStatement (statement , returned );
299-
300- // Break loop
301- case NODE_BREAK :
302-
303- broken = 1 ;
304- return ExitStatement (statement , NULL );
305-
306- // Return
307- case NODE_RETURN :
308-
309- return ExitStatement (statement , Eval (curr -> child ));
310-
311- // Leave new exception
312- case NODE_RAISE :
313-
314- return ExitStatementError (statement , RaiseException , curr -> value , curr -> file );
315-
316- // Custom keyword
317- case NODE_CUSTOM_KEYWORD :
318-
319- printf ("d" );
320- soare_keyword keyword = soare_getkeyword (curr -> value );
321-
322- if (keyword .name )
323- keyword .exec ();
324-
325- break ;
321+ if (value || broken )
322+ return ExitStatement (statement , value );
323+ }
324+ break ;
326325
327326 default :
328-
329327 break ;
330328 }
331329 }
332330
333- // Quit
331+ // Free scope and return
334332 return ExitStatement (statement , NULL );
335333}
336334
0 commit comments