diff options
Diffstat (limited to 'LuaSL/src/LuaSL_compile.c')
-rw-r--r-- | LuaSL/src/LuaSL_compile.c | 77 |
1 files changed, 59 insertions, 18 deletions
diff --git a/LuaSL/src/LuaSL_compile.c b/LuaSL/src/LuaSL_compile.c index 06c55ef..a410152 100644 --- a/LuaSL/src/LuaSL_compile.c +++ b/LuaSL/src/LuaSL_compile.c | |||
@@ -185,6 +185,7 @@ allowedTypes allowed[] = | |||
185 | {OT_rotation, "rotation", (ST_MULTIPLY | ST_ADD | ST_SUBTRACT | ST_EQUALITY | ST_CONCATENATION | ST_ASSIGNMENT)}, // rotation rotation * / + - == != = += -= *= /= | 185 | {OT_rotation, "rotation", (ST_MULTIPLY | ST_ADD | ST_SUBTRACT | ST_EQUALITY | ST_CONCATENATION | ST_ASSIGNMENT)}, // rotation rotation * / + - == != = += -= *= /= |
186 | 186 | ||
187 | {OT_other, "other", (ST_NONE)}, // | 187 | {OT_other, "other", (ST_NONE)}, // |
188 | {OT_undeclared, "undeclared", (ST_NONE)}, // | ||
188 | {OT_invalid, "invalid", (ST_NONE)} // | 189 | {OT_invalid, "invalid", (ST_NONE)} // |
189 | }; | 190 | }; |
190 | 191 | ||
@@ -291,22 +292,6 @@ static LSL_Leaf *findVariable(LuaSL_compiler *compiler, const char *name) | |||
291 | return var; | 292 | return var; |
292 | } | 293 | } |
293 | 294 | ||
294 | // TODO - Damn, you can reference functions declared later. | ||
295 | LSL_Leaf *checkFunction(LuaSL_compiler *compiler, LSL_Leaf *identifier) | ||
296 | { | ||
297 | gameGlobals *game = compiler->game; | ||
298 | LSL_Leaf *func = findFunction(compiler, identifier->value.stringValue); | ||
299 | |||
300 | if (NULL == func) | ||
301 | PE("NOT found %s @ line %d column %d!", identifier->value.stringValue, identifier->line, identifier->column); | ||
302 | #ifdef LUASL_DEBUG | ||
303 | else | ||
304 | PI("Found %s!", identifier->value.stringValue); | ||
305 | #endif | ||
306 | |||
307 | return func; | ||
308 | } | ||
309 | |||
310 | LSL_Leaf *checkVariable(LuaSL_compiler *compiler, LSL_Leaf *identifier) | 295 | LSL_Leaf *checkVariable(LuaSL_compiler *compiler, LSL_Leaf *identifier) |
311 | { | 296 | { |
312 | gameGlobals *game = compiler->game; | 297 | gameGlobals *game = compiler->game; |
@@ -351,6 +336,11 @@ LSL_Leaf *addOperation(LuaSL_compiler *compiler, LSL_Leaf *left, LSL_Leaf *lval, | |||
351 | } | 336 | } |
352 | else | 337 | else |
353 | lType = left->basicType; | 338 | lType = left->basicType; |
339 | if (OT_undeclared == lType) | ||
340 | { | ||
341 | lval->basicType = OT_undeclared; | ||
342 | return lval; | ||
343 | } | ||
354 | if (OT_vector < lType) | 344 | if (OT_vector < lType) |
355 | lType = allowed[lType].result; | 345 | lType = allowed[lType].result; |
356 | } | 346 | } |
@@ -367,6 +357,11 @@ LSL_Leaf *addOperation(LuaSL_compiler *compiler, LSL_Leaf *left, LSL_Leaf *lval, | |||
367 | } | 357 | } |
368 | else | 358 | else |
369 | rType = right->basicType; | 359 | rType = right->basicType; |
360 | if (OT_undeclared == rType) | ||
361 | { | ||
362 | lval->basicType = OT_undeclared; | ||
363 | return lval; | ||
364 | } | ||
370 | if (OT_vector < rType) | 365 | if (OT_vector < rType) |
371 | rType = allowed[rType].result; | 366 | rType = allowed[rType].result; |
372 | } | 367 | } |
@@ -537,16 +532,35 @@ LSL_Leaf *addFunctionBody(LuaSL_compiler *compiler, LSL_Leaf *function, LSL_Leaf | |||
537 | 532 | ||
538 | LSL_Leaf *addFunctionCall(LuaSL_compiler *compiler, LSL_Leaf *identifier, LSL_Leaf *open, LSL_Leaf *params, LSL_Leaf *close) | 533 | LSL_Leaf *addFunctionCall(LuaSL_compiler *compiler, LSL_Leaf *identifier, LSL_Leaf *open, LSL_Leaf *params, LSL_Leaf *close) |
539 | { | 534 | { |
540 | LSL_Leaf *func = checkFunction(compiler, identifier); | 535 | LSL_Leaf *func = findFunction(compiler, identifier->value.stringValue); |
536 | LSL_FunctionCall *call = calloc(1, sizeof(LSL_FunctionCall)); | ||
541 | 537 | ||
542 | identifier->token = tokens[LSL_UNKNOWN - lowestToken]; | 538 | identifier->token = tokens[LSL_UNKNOWN - lowestToken]; |
543 | 539 | ||
544 | if (func) | 540 | if (func) |
545 | { | 541 | { |
546 | // TODO - Add some structure here to hold the params. | 542 | if (call) |
543 | { | ||
544 | call->function = func->value.functionValue; | ||
545 | eina_clist_element_init(&(call->functionCall)); | ||
546 | call->call = identifier; | ||
547 | } | ||
548 | identifier->value.functionCallValue = call; | ||
549 | // TODO - Put the params in call. | ||
547 | identifier->token = tokens[LSL_FUNCTION_CALL - lowestToken]; | 550 | identifier->token = tokens[LSL_FUNCTION_CALL - lowestToken]; |
548 | identifier->basicType = func->basicType; | 551 | identifier->basicType = func->basicType; |
549 | } | 552 | } |
553 | else | ||
554 | { | ||
555 | // It may be declared later, so store it and check later. | ||
556 | if (call) | ||
557 | { | ||
558 | eina_clist_add_tail(&(compiler->danglingCalls), &(call->functionCall)); | ||
559 | call->call = identifier; | ||
560 | } | ||
561 | identifier->basicType = OT_undeclared; | ||
562 | compiler->undeclared = TRUE; | ||
563 | } | ||
550 | 564 | ||
551 | return identifier; | 565 | return identifier; |
552 | } | 566 | } |
@@ -1235,6 +1249,7 @@ Eina_Bool compileLSL(gameGlobals *game, char *script, boolean doConstants) | |||
1235 | compiler.script.functions = eina_hash_stringshared_new(burnLeaf); | 1249 | compiler.script.functions = eina_hash_stringshared_new(burnLeaf); |
1236 | compiler.script.states = eina_hash_stringshared_new(burnLeaf); | 1250 | compiler.script.states = eina_hash_stringshared_new(burnLeaf); |
1237 | compiler.script.variables = eina_hash_stringshared_new(burnLeaf); | 1251 | compiler.script.variables = eina_hash_stringshared_new(burnLeaf); |
1252 | eina_clist_init(&(compiler.danglingCalls)); | ||
1238 | #ifdef LUASL_DIFF_CHECK | 1253 | #ifdef LUASL_DIFF_CHECK |
1239 | compiler.ignorableText = eina_strbuf_new(); | 1254 | compiler.ignorableText = eina_strbuf_new(); |
1240 | #endif | 1255 | #endif |
@@ -1274,6 +1289,32 @@ Eina_Bool compileLSL(gameGlobals *game, char *script, boolean doConstants) | |||
1274 | Parse (pParser, 0, compiler.lval, &compiler); | 1289 | Parse (pParser, 0, compiler.lval, &compiler); |
1275 | ParseFree(pParser, free); | 1290 | ParseFree(pParser, free); |
1276 | 1291 | ||
1292 | if (compiler.undeclared) | ||
1293 | { | ||
1294 | PI("A second pass will be needed to check if functions where declared after they where used. To avoid this second pass, don't do that."); | ||
1295 | if (eina_clist_count(&(compiler.danglingCalls))) | ||
1296 | { | ||
1297 | LSL_FunctionCall *call = NULL; | ||
1298 | |||
1299 | EINA_CLIST_FOR_EACH_ENTRY(call, &(compiler.danglingCalls), LSL_FunctionCall, functionCall) | ||
1300 | { | ||
1301 | LSL_Leaf *func = findFunction(&(compiler), call->call->value.stringValue); | ||
1302 | |||
1303 | if (func) | ||
1304 | { | ||
1305 | call->function = func->value.functionValue; | ||
1306 | call->call->value.functionCallValue = call; | ||
1307 | call->call->token = tokens[LSL_FUNCTION_CALL - lowestToken]; | ||
1308 | call->call->basicType = func->basicType; | ||
1309 | } | ||
1310 | else | ||
1311 | PE("Undeclared function %s called @ line %d, column %d!", call->call->value.stringValue, call->call->line, call->call->column); | ||
1312 | } | ||
1313 | } | ||
1314 | // TODO - Run through the expressions, cleaning up the function calls. | ||
1315 | PI("Second pass completed."); | ||
1316 | } | ||
1317 | |||
1277 | if (doConstants) | 1318 | if (doConstants) |
1278 | { | 1319 | { |
1279 | memcpy(&constants, &(compiler.script), sizeof(LSL_Script)); | 1320 | memcpy(&constants, &(compiler.script), sizeof(LSL_Script)); |