diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/LuaSL/LuaSL_LSL_tree.h | 17 | ||||
-rw-r--r-- | src/LuaSL/LuaSL_compile.c | 61 |
2 files changed, 60 insertions, 18 deletions
diff --git a/src/LuaSL/LuaSL_LSL_tree.h b/src/LuaSL/LuaSL_LSL_tree.h index 26d63b1..e7c5e36 100644 --- a/src/LuaSL/LuaSL_LSL_tree.h +++ b/src/LuaSL/LuaSL_LSL_tree.h | |||
@@ -235,6 +235,14 @@ struct _LSL_Identifier // For variables and function parameters. | |||
235 | miscFlags flags; | 235 | miscFlags flags; |
236 | }; | 236 | }; |
237 | 237 | ||
238 | struct _LSL_DanglingVar | ||
239 | { | ||
240 | Eina_Clist dangler; // Entry for variables used before they are defined. | ||
241 | LSL_Leaf *identifier; | ||
242 | LSL_Leaf *dot; | ||
243 | LSL_Leaf *sub; | ||
244 | }; | ||
245 | |||
238 | struct _LSL_Statement | 246 | struct _LSL_Statement |
239 | { | 247 | { |
240 | Eina_Clist statement; // For block statement lists, this is the entry. | 248 | Eina_Clist statement; // For block statement lists, this is the entry. |
@@ -272,7 +280,7 @@ struct _LSL_Function | |||
272 | // LSL_Leaf *params; // So we store the parenthesis, and their ignorables. | 280 | // LSL_Leaf *params; // So we store the parenthesis, and their ignorables. |
273 | // This points to the params leaf, which is a function, pointing to this structure. The actual params are in vars. | 281 | // This points to the params leaf, which is a function, pointing to this structure. The actual params are in vars. |
274 | #endif | 282 | #endif |
275 | Eina_Inarray vars; // Eina Inarray has not been released yet (Eina 1.2). | 283 | Eina_Inarray vars; |
276 | LSL_Block *block; | 284 | LSL_Block *block; |
277 | miscFlags flags; | 285 | miscFlags flags; |
278 | }; | 286 | }; |
@@ -280,7 +288,7 @@ struct _LSL_Function | |||
280 | struct _LSL_FunctionCall | 288 | struct _LSL_FunctionCall |
281 | { | 289 | { |
282 | LSL_Function *function; | 290 | LSL_Function *function; |
283 | Eina_Inarray params; // Eina Inarray has not been released yet (Eina 1.2). | 291 | Eina_Inarray params; |
284 | Eina_Clist dangler; // Entry for function calls used before the function is defined. | 292 | Eina_Clist dangler; // Entry for function calls used before the function is defined. |
285 | LSL_Leaf *call; // This is to stash the details for dangling ones, to search later. | 293 | LSL_Leaf *call; // This is to stash the details for dangling ones, to search later. |
286 | // The line and column details are needed for bitching, so we need the leaf. | 294 | // The line and column details are needed for bitching, so we need the leaf. |
@@ -386,8 +394,9 @@ typedef struct | |||
386 | LSL_Block *currentBlock; | 394 | LSL_Block *currentBlock; |
387 | LSL_Function *currentFunction; | 395 | LSL_Function *currentFunction; |
388 | Eina_Clist danglingCalls; // HEAD for function calls used before the function is defined. | 396 | Eina_Clist danglingCalls; // HEAD for function calls used before the function is defined. |
389 | int column, line; | 397 | Eina_Clist danglingVars; // HEAD for variable refs used before the variable is defined. |
390 | int undeclared; | 398 | int column, line, pass; |
399 | boolean undeclared; | ||
391 | boolean inState; | 400 | boolean inState; |
392 | boolean isLSL; | 401 | boolean isLSL; |
393 | boolean isLua; | 402 | boolean isLua; |
diff --git a/src/LuaSL/LuaSL_compile.c b/src/LuaSL/LuaSL_compile.c index dab974c..f1e7db1 100644 --- a/src/LuaSL/LuaSL_compile.c +++ b/src/LuaSL/LuaSL_compile.c | |||
@@ -346,6 +346,7 @@ LSL_Leaf *checkVariable(LuaSL_compiler *compiler, LSL_Leaf *identifier, LSL_Leaf | |||
346 | if (LUASL_DEBUG) | 346 | if (LUASL_DEBUG) |
347 | PI("Found %s!", identifier->value.stringValue); | 347 | PI("Found %s!", identifier->value.stringValue); |
348 | identifier->value.identifierValue = var->value.identifierValue; | 348 | identifier->value.identifierValue = var->value.identifierValue; |
349 | identifier->toKen = tokens[LSL_IDENTIFIER - lowestToken]; | ||
349 | identifier->basicType = var->basicType; | 350 | identifier->basicType = var->basicType; |
350 | if ((dot) && (sub)) | 351 | if ((dot) && (sub)) |
351 | { | 352 | { |
@@ -370,11 +371,28 @@ LSL_Leaf *checkVariable(LuaSL_compiler *compiler, LSL_Leaf *identifier, LSL_Leaf | |||
370 | } | 371 | } |
371 | else | 372 | else |
372 | { | 373 | { |
373 | // compiler->compiler->bugCount++; | 374 | struct _LSL_DanglingVar *dangler = calloc(1, sizeof(struct _LSL_DanglingVar)); |
374 | // sendBack(compiler->compiler->client, compiler->compiler->SID, "compilerError(%d,%d,NOT FOUND variable %s)", identifier->line, identifier->column, identifier->value.stringValue); | 375 | |
375 | finishMessage(compiler->compiler, addMessage(&(compiler->compiler->messages), sizeof(compileMessage), | 376 | if (LUASL_DEBUG) |
376 | "NOT FOUND variable %s", identifier->value.stringValue), | 377 | PW("NOT Found variable %s!", identifier->value.stringValue); |
377 | 1, identifier->column, identifier->line); | 378 | if (0 < compiler->pass) |
379 | { | ||
380 | finishMessage(compiler->compiler, addMessage(&(compiler->compiler->messages), sizeof(compileMessage), | ||
381 | "NOT FOUND variable %s", identifier->value.stringValue), | ||
382 | 1, identifier->column, identifier->line); | ||
383 | } | ||
384 | else | ||
385 | { | ||
386 | // It may be declared later, so store it and check later. | ||
387 | dangler->identifier = identifier; | ||
388 | dangler->dot = dot; | ||
389 | dangler->sub = sub; | ||
390 | eina_clist_add_tail(&(compiler->danglingVars), &(dangler->dangler)); | ||
391 | // Here the identifier stringValue needs to be kept for later searching. | ||
392 | identifier->toKen = tokens[LSL_UNKNOWN - lowestToken]; | ||
393 | identifier->basicType = OT_undeclared; | ||
394 | compiler->undeclared = TRUE; | ||
395 | } | ||
378 | } | 396 | } |
379 | } | 397 | } |
380 | 398 | ||
@@ -415,7 +433,7 @@ LSL_Leaf *addOperation(LuaSL_compiler *compiler, LSL_Leaf *left, LSL_Leaf *lval, | |||
415 | lType = left->basicType; | 433 | lType = left->basicType; |
416 | if (OT_undeclared == lType) | 434 | if (OT_undeclared == lType) |
417 | { | 435 | { |
418 | compiler->script.warningCount++; | 436 | // compiler->script.warningCount++; |
419 | // sendBack(compiler->compiler->client, compiler->compiler->SID, "compilerWarning(%d,%d,Undeclared identifier issue, deferring this until the second pass)", lval->line, lval->column); | 437 | // sendBack(compiler->compiler->client, compiler->compiler->SID, "compilerWarning(%d,%d,Undeclared identifier issue, deferring this until the second pass)", lval->line, lval->column); |
420 | lval->basicType = OT_undeclared; | 438 | lval->basicType = OT_undeclared; |
421 | return lval; | 439 | return lval; |
@@ -443,7 +461,7 @@ LSL_Leaf *addOperation(LuaSL_compiler *compiler, LSL_Leaf *left, LSL_Leaf *lval, | |||
443 | rType = right->basicType; | 461 | rType = right->basicType; |
444 | if (OT_undeclared == rType) | 462 | if (OT_undeclared == rType) |
445 | { | 463 | { |
446 | compiler->script.warningCount++; | 464 | // compiler->script.warningCount++; |
447 | // sendBack(compiler->compiler->client, compiler->compiler->SID, "compilerWarning(%d,%d,Undeclared identifier issue, deferring this until the second pass)", lval->line, lval->column); | 465 | // sendBack(compiler->compiler->client, compiler->compiler->SID, "compilerWarning(%d,%d,Undeclared identifier issue, deferring this until the second pass)", lval->line, lval->column); |
448 | lval->basicType = OT_undeclared; | 466 | lval->basicType = OT_undeclared; |
449 | return lval; | 467 | return lval; |
@@ -833,7 +851,7 @@ LSL_Leaf *collectArguments(LuaSL_compiler *compiler, LSL_Leaf *list, LSL_Leaf *c | |||
833 | if (call) | 851 | if (call) |
834 | { | 852 | { |
835 | list->value.functionCallValue = call; | 853 | list->value.functionCallValue = call; |
836 | eina_inarray_step_set(&(call->params), sizeof(Eina_Inarray), sizeof(LSL_Leaf), 3); | 854 | eina_inarray_step_set(&(call->params), sizeof(Eina_Inarray), sizeof(LSL_Leaf *), 3); |
837 | } | 855 | } |
838 | } | 856 | } |
839 | 857 | ||
@@ -847,7 +865,7 @@ LSL_Leaf *collectArguments(LuaSL_compiler *compiler, LSL_Leaf *list, LSL_Leaf *c | |||
847 | if (comma) | 865 | if (comma) |
848 | eina_inarray_push(&(call->params), comma); | 866 | eina_inarray_push(&(call->params), comma); |
849 | } | 867 | } |
850 | eina_inarray_push(&(call->params), arg); | 868 | eina_inarray_push(&(call->params), &arg); |
851 | // At this point, pointers to arg are not pointing to the one in call->params, AND arg is no longer needed. | 869 | // At this point, pointers to arg are not pointing to the one in call->params, AND arg is no longer needed. |
852 | } | 870 | } |
853 | } | 871 | } |
@@ -2010,7 +2028,7 @@ static void outputFunctionCallToken(FILE *file, outputMode mode, LSL_Leaf *conte | |||
2010 | if (content) | 2028 | if (content) |
2011 | { | 2029 | { |
2012 | LSL_FunctionCall *call = content->value.functionCallValue; | 2030 | LSL_FunctionCall *call = content->value.functionCallValue; |
2013 | LSL_Leaf *param = NULL; | 2031 | LSL_Leaf **param = NULL; |
2014 | boolean first = TRUE; | 2032 | boolean first = TRUE; |
2015 | 2033 | ||
2016 | // TODO - should output it's own ignorable here. | 2034 | // TODO - should output it's own ignorable here. |
@@ -2022,7 +2040,7 @@ static void outputFunctionCallToken(FILE *file, outputMode mode, LSL_Leaf *conte | |||
2022 | { | 2040 | { |
2023 | if ((OM_LUA == mode) && (!first)) | 2041 | if ((OM_LUA == mode) && (!first)) |
2024 | fprintf(file, ", "); | 2042 | fprintf(file, ", "); |
2025 | outputLeaf(file, mode, param); | 2043 | outputLeaf(file, mode, *param); |
2026 | first = FALSE; | 2044 | first = FALSE; |
2027 | } | 2045 | } |
2028 | fprintf(file, ")"); | 2046 | fprintf(file, ")"); |
@@ -2081,7 +2099,7 @@ static void outputListToken(FILE *file, outputMode mode, LSL_Leaf *content) | |||
2081 | if (parens->contents) | 2099 | if (parens->contents) |
2082 | { | 2100 | { |
2083 | LSL_FunctionCall *call = parens->contents->value.functionCallValue; | 2101 | LSL_FunctionCall *call = parens->contents->value.functionCallValue; |
2084 | LSL_Leaf *param = NULL; | 2102 | LSL_Leaf **param = NULL; |
2085 | const char *ig = ""; | 2103 | const char *ig = ""; |
2086 | 2104 | ||
2087 | // TODO - should output it's own ignorable here. | 2105 | // TODO - should output it's own ignorable here. |
@@ -2107,7 +2125,7 @@ static void outputListToken(FILE *file, outputMode mode, LSL_Leaf *content) | |||
2107 | } | 2125 | } |
2108 | EINA_INARRAY_FOREACH((&(call->params)), param) | 2126 | EINA_INARRAY_FOREACH((&(call->params)), param) |
2109 | { | 2127 | { |
2110 | outputLeaf(file, mode, param); | 2128 | outputLeaf(file, mode, *param); |
2111 | if (OM_LUA == mode) | 2129 | if (OM_LUA == mode) |
2112 | fprintf(file, ", "); | 2130 | fprintf(file, ", "); |
2113 | } | 2131 | } |
@@ -2258,6 +2276,7 @@ void compileLSL(LuaCompiler *compiler) | |||
2258 | lcompiler->script.states = eina_hash_stringshared_new(burnLeaf); | 2276 | lcompiler->script.states = eina_hash_stringshared_new(burnLeaf); |
2259 | lcompiler->script.variables = eina_hash_stringshared_new(burnLeaf); | 2277 | lcompiler->script.variables = eina_hash_stringshared_new(burnLeaf); |
2260 | eina_clist_init(&(lcompiler->danglingCalls)); | 2278 | eina_clist_init(&(lcompiler->danglingCalls)); |
2279 | eina_clist_init(&(lcompiler->danglingVars)); | ||
2261 | #if LUASL_DIFF_CHECK | 2280 | #if LUASL_DIFF_CHECK |
2262 | lcompiler->ignorable = eina_strbuf_new(); | 2281 | lcompiler->ignorable = eina_strbuf_new(); |
2263 | #endif | 2282 | #endif |
@@ -2370,7 +2389,18 @@ void compileLSL(LuaCompiler *compiler) | |||
2370 | 2389 | ||
2371 | if (lcompiler->undeclared) | 2390 | if (lcompiler->undeclared) |
2372 | { | 2391 | { |
2373 | // PW("A second pass is needed to check if functions where used before they where declared. To avoid this second pass, don't do that."); | 2392 | lcompiler->pass++; |
2393 | // PW("A second pass is needed to check functions or variables that where used before they where declared. To avoid this second pass, don't do that."); | ||
2394 | if (eina_clist_count(&(lcompiler->danglingVars))) | ||
2395 | { | ||
2396 | struct _LSL_DanglingVar *dangleVar = NULL; | ||
2397 | |||
2398 | EINA_CLIST_FOR_EACH_ENTRY(dangleVar, &(lcompiler->danglingVars), struct _LSL_DanglingVar, dangler) | ||
2399 | { | ||
2400 | checkVariable(lcompiler, dangleVar->identifier, dangleVar->dot, dangleVar->sub); | ||
2401 | } | ||
2402 | } | ||
2403 | |||
2374 | if (eina_clist_count(&(lcompiler->danglingCalls))) | 2404 | if (eina_clist_count(&(lcompiler->danglingCalls))) |
2375 | { | 2405 | { |
2376 | LSL_FunctionCall *call = NULL; | 2406 | LSL_FunctionCall *call = NULL; |
@@ -2395,6 +2425,9 @@ void compileLSL(LuaCompiler *compiler) | |||
2395 | } | 2425 | } |
2396 | } | 2426 | } |
2397 | } | 2427 | } |
2428 | |||
2429 | // TODO - Should clean up these clists. | ||
2430 | |||
2398 | secondPass(lcompiler, lcompiler->ast); | 2431 | secondPass(lcompiler, lcompiler->ast); |
2399 | // PD("Second pass completed."); | 2432 | // PD("Second pass completed."); |
2400 | } | 2433 | } |