diff options
-rw-r--r-- | LuaSL/src/LuaSL_LSL_tree.h | 5 | ||||
-rw-r--r-- | LuaSL/src/LuaSL_compile.c | 25 | ||||
-rw-r--r-- | LuaSL/src/LuaSL_lemon_yaccer.y | 6 | ||||
-rw-r--r-- | LuaSL/src/LuaSL_lexer.l | 4 |
4 files changed, 26 insertions, 14 deletions
diff --git a/LuaSL/src/LuaSL_LSL_tree.h b/LuaSL/src/LuaSL_LSL_tree.h index 24f838a..e5a415a 100644 --- a/LuaSL/src/LuaSL_LSL_tree.h +++ b/LuaSL/src/LuaSL_LSL_tree.h | |||
@@ -360,6 +360,7 @@ typedef struct | |||
360 | #endif | 360 | #endif |
361 | LSL_Leaf *lval; | 361 | LSL_Leaf *lval; |
362 | LSL_Block *currentBlock; | 362 | LSL_Block *currentBlock; |
363 | LSL_Function *currentFunction; | ||
363 | Eina_Clist danglingCalls; // HEAD for function calls used before the function is defined. | 364 | Eina_Clist danglingCalls; // HEAD for function calls used before the function is defined. |
364 | int column, line; | 365 | int column, line; |
365 | int undeclared; | 366 | int undeclared; |
@@ -372,6 +373,7 @@ typedef struct | |||
372 | 373 | ||
373 | 374 | ||
374 | void burnLeaf(void *data); | 375 | void burnLeaf(void *data); |
376 | LSL_Leaf *addBlock(LuaSL_compiler *compiler, LSL_Leaf *left, LSL_Leaf *lval, LSL_Leaf *right); | ||
375 | LSL_Leaf *addCrement(LuaSL_compiler *compiler, LSL_Leaf *variable, LSL_Leaf *crement); | 377 | LSL_Leaf *addCrement(LuaSL_compiler *compiler, LSL_Leaf *variable, LSL_Leaf *crement); |
376 | LSL_Leaf *addFunction(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *identifier, LSL_Leaf *open, LSL_Leaf *params, LSL_Leaf *close); | 378 | LSL_Leaf *addFunction(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *identifier, LSL_Leaf *open, LSL_Leaf *params, LSL_Leaf *close); |
377 | LSL_Leaf *addFunctionBody(LuaSL_compiler *compiler, LSL_Leaf *function, LSL_Leaf *block); | 379 | LSL_Leaf *addFunctionBody(LuaSL_compiler *compiler, LSL_Leaf *function, LSL_Leaf *block); |
@@ -384,11 +386,10 @@ LSL_Leaf *addStatement(LuaSL_compiler *compiler, LSL_Leaf *lval, LSL_Type type, | |||
384 | LSL_Leaf *addTypecast(LSL_Leaf *lval, LSL_Leaf *type, LSL_Leaf *rval, LSL_Leaf *expr); | 386 | LSL_Leaf *addTypecast(LSL_Leaf *lval, LSL_Leaf *type, LSL_Leaf *rval, LSL_Leaf *expr); |
385 | LSL_Leaf *addVariable(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *identifier, LSL_Leaf *assignment, LSL_Leaf *expr); | 387 | LSL_Leaf *addVariable(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *identifier, LSL_Leaf *assignment, LSL_Leaf *expr); |
386 | 388 | ||
387 | void beginBlock(LuaSL_compiler *compiler, LSL_Leaf *block); | 389 | LSL_Leaf *beginBlock(LuaSL_compiler *compiler, LSL_Leaf *block); |
388 | LSL_Leaf *checkVariable(LuaSL_compiler *compiler, LSL_Leaf *identifier); | 390 | LSL_Leaf *checkVariable(LuaSL_compiler *compiler, LSL_Leaf *identifier); |
389 | LSL_Leaf *collectParameters(LuaSL_compiler *compiler, LSL_Leaf *list, LSL_Leaf *comma, LSL_Leaf *newParam); | 391 | LSL_Leaf *collectParameters(LuaSL_compiler *compiler, LSL_Leaf *list, LSL_Leaf *comma, LSL_Leaf *newParam); |
390 | LSL_Leaf *collectStatements(LuaSL_compiler *compiler, LSL_Leaf *list, LSL_Leaf *newStatement); | 392 | LSL_Leaf *collectStatements(LuaSL_compiler *compiler, LSL_Leaf *list, LSL_Leaf *newStatement); |
391 | void endBlock(LuaSL_compiler *compiler, LSL_Leaf *block); | ||
392 | 393 | ||
393 | void *ParseAlloc(void *(*mallocProc)(size_t)); | 394 | void *ParseAlloc(void *(*mallocProc)(size_t)); |
394 | void ParseTrace(FILE *TraceFILE, char *zTracePrompt); | 395 | void ParseTrace(FILE *TraceFILE, char *zTracePrompt); |
diff --git a/LuaSL/src/LuaSL_compile.c b/LuaSL/src/LuaSL_compile.c index 48f2910..e4a526a 100644 --- a/LuaSL/src/LuaSL_compile.c +++ b/LuaSL/src/LuaSL_compile.c | |||
@@ -446,6 +446,13 @@ LSL_Leaf *addOperation(LuaSL_compiler *compiler, LSL_Leaf *left, LSL_Leaf *lval, | |||
446 | return lval; | 446 | return lval; |
447 | } | 447 | } |
448 | 448 | ||
449 | LSL_Leaf *addBlock(LuaSL_compiler *compiler, LSL_Leaf *left, LSL_Leaf *lval, LSL_Leaf *right) | ||
450 | { | ||
451 | // Damn, look ahead. The } symbol is getting read (and thus endBlock called) before the last statement in the block is reduced (which actually calls the add*() functions). | ||
452 | compiler->currentBlock = compiler->currentBlock->outerBlock; | ||
453 | return lval; | ||
454 | } | ||
455 | |||
449 | LSL_Leaf *addCrement(LuaSL_compiler *compiler, LSL_Leaf *variable, LSL_Leaf *crement) | 456 | LSL_Leaf *addCrement(LuaSL_compiler *compiler, LSL_Leaf *variable, LSL_Leaf *crement) |
450 | { | 457 | { |
451 | if ((variable) && (crement)) | 458 | if ((variable) && (crement)) |
@@ -541,8 +548,7 @@ LSL_Leaf *addFunction(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *identi | |||
541 | func->params = addParenthesis(open, params, LSL_PARAMETER_LIST, close); | 548 | func->params = addParenthesis(open, params, LSL_PARAMETER_LIST, close); |
542 | #endif | 549 | #endif |
543 | } | 550 | } |
544 | if (compiler->currentBlock) | 551 | compiler->currentFunction = func; |
545 | compiler->currentBlock->function = func; | ||
546 | } | 552 | } |
547 | } | 553 | } |
548 | 554 | ||
@@ -725,12 +731,13 @@ LSL_Leaf *addStatement(LuaSL_compiler *compiler, LSL_Leaf *lval, LSL_Type type, | |||
725 | 731 | ||
726 | LSL_Leaf *collectStatements(LuaSL_compiler *compiler, LSL_Leaf *list, LSL_Leaf *statement) | 732 | LSL_Leaf *collectStatements(LuaSL_compiler *compiler, LSL_Leaf *list, LSL_Leaf *statement) |
727 | { | 733 | { |
734 | boolean wasNull = FALSE; | ||
728 | if (NULL == list) | 735 | if (NULL == list) |
729 | { | 736 | { |
730 | list = newLeaf(LSL_BLOCK_OPEN, NULL, NULL); | 737 | list = newLeaf(LSL_BLOCK_OPEN, NULL, NULL); |
731 | if (list) | 738 | if (list) |
732 | { | 739 | { |
733 | list->value.blockValue = compiler->currentBlock; // Maybe NULL. | 740 | wasNull = TRUE; |
734 | } | 741 | } |
735 | } | 742 | } |
736 | 743 | ||
@@ -738,6 +745,8 @@ LSL_Leaf *collectStatements(LuaSL_compiler *compiler, LSL_Leaf *list, LSL_Leaf * | |||
738 | { | 745 | { |
739 | if (statement) | 746 | if (statement) |
740 | { | 747 | { |
748 | if (!wasNull) | ||
749 | list->value.blockValue = compiler->currentBlock; // Maybe NULL. | ||
741 | if (list->value.blockValue) | 750 | if (list->value.blockValue) |
742 | { | 751 | { |
743 | eina_clist_add_tail(&(list->value.blockValue->statements), &(statement->value.statementValue->statement)); | 752 | eina_clist_add_tail(&(list->value.blockValue->statements), &(statement->value.statementValue->statement)); |
@@ -792,7 +801,7 @@ LSL_Leaf *addVariable(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *identi | |||
792 | return identifier; | 801 | return identifier; |
793 | } | 802 | } |
794 | 803 | ||
795 | void beginBlock(LuaSL_compiler *compiler, LSL_Leaf *block) | 804 | LSL_Leaf *beginBlock(LuaSL_compiler *compiler, LSL_Leaf *block) |
796 | { | 805 | { |
797 | LSL_Block *blok = calloc(1, sizeof(LSL_Block)); | 806 | LSL_Block *blok = calloc(1, sizeof(LSL_Block)); |
798 | 807 | ||
@@ -803,12 +812,10 @@ void beginBlock(LuaSL_compiler *compiler, LSL_Leaf *block) | |||
803 | block->value.blockValue = blok; | 812 | block->value.blockValue = blok; |
804 | blok->outerBlock = compiler->currentBlock; | 813 | blok->outerBlock = compiler->currentBlock; |
805 | compiler->currentBlock = blok; | 814 | compiler->currentBlock = blok; |
815 | blok->function = compiler->currentFunction; | ||
816 | compiler->currentFunction = NULL; | ||
806 | } | 817 | } |
807 | } | 818 | return block; |
808 | |||
809 | void endBlock(LuaSL_compiler *compiler, LSL_Leaf *block) | ||
810 | { | ||
811 | compiler->currentBlock = compiler->currentBlock->outerBlock; | ||
812 | } | 819 | } |
813 | 820 | ||
814 | static void secondPass(LuaSL_compiler *compiler, LSL_Leaf *leaf) | 821 | static void secondPass(LuaSL_compiler *compiler, LSL_Leaf *leaf) |
diff --git a/LuaSL/src/LuaSL_lemon_yaccer.y b/LuaSL/src/LuaSL_lemon_yaccer.y index 125b384..ed53fd4 100644 --- a/LuaSL/src/LuaSL_lemon_yaccer.y +++ b/LuaSL/src/LuaSL_lemon_yaccer.y | |||
@@ -31,7 +31,7 @@ script ::= . | |||
31 | // State definitions. | 31 | // State definitions. |
32 | 32 | ||
33 | %nonassoc LSL_BLOCK_OPEN LSL_BLOCK_CLOSE LSL_STATE. | 33 | %nonassoc LSL_BLOCK_OPEN LSL_BLOCK_CLOSE LSL_STATE. |
34 | stateBlock(A) ::= LSL_BLOCK_OPEN functionList(B) LSL_BLOCK_CLOSE. { A = B; } | 34 | stateBlock(A) ::= beginBlock(L) functionList(B) LSL_BLOCK_CLOSE(R). { A = addBlock(compiler, L, B, R); } |
35 | state(S) ::= LSL_DEFAULT(I) stateBlock(B). { S = addState(compiler, I, B); } | 35 | state(S) ::= LSL_DEFAULT(I) stateBlock(B). { S = addState(compiler, I, B); } |
36 | state(S) ::= LSL_STATE_CHANGE LSL_IDENTIFIER(I) stateBlock(B). { S = addState(compiler, I, B); } | 36 | state(S) ::= LSL_STATE_CHANGE LSL_IDENTIFIER(I) stateBlock(B). { S = addState(compiler, I, B); } |
37 | 37 | ||
@@ -57,6 +57,8 @@ function(A) ::= type(B) LSL_IDENTIFIER(C) LSL_PARENTHESIS_OPEN(D) parameterList( | |||
57 | block(A) ::= funcBlock(B). { A = B; } | 57 | block(A) ::= funcBlock(B). { A = B; } |
58 | block(A) ::= statement(B). { A = B; } | 58 | block(A) ::= statement(B). { A = B; } |
59 | funcBlock(A) ::= LSL_BLOCK_OPEN statementList(B) LSL_BLOCK_CLOSE. { A = B; } | 59 | funcBlock(A) ::= LSL_BLOCK_OPEN statementList(B) LSL_BLOCK_CLOSE. { A = B; } |
60 | // Perhaps change this to block? No ,this is what differentiates it from a single statement, which functions can't handle. | ||
61 | funcBlock(A) ::= beginBlock(L) statementList(B) LSL_BLOCK_CLOSE(R). { A = addBlock(compiler, L, B, R); } | ||
60 | 62 | ||
61 | // Various forms of statement. | 63 | // Various forms of statement. |
62 | 64 | ||
@@ -85,6 +87,8 @@ statement(A) ::= LSL_WHILE(F) LSL_PARENTHESIS_OPEN(L) expr(E) LSL_PARENTHESIS_CL | |||
85 | %nonassoc LSL_LABEL. | 87 | %nonassoc LSL_LABEL. |
86 | statement(A) ::= LSL_LABEL(F) LSL_IDENTIFIER(I) LSL_STATEMENT(S). { A = addStatement(compiler, S, F->toKen->type, NULL, NULL, NULL, NULL, I); } | 88 | statement(A) ::= LSL_LABEL(F) LSL_IDENTIFIER(I) LSL_STATEMENT(S). { A = addStatement(compiler, S, F->toKen->type, NULL, NULL, NULL, NULL, I); } |
87 | 89 | ||
90 | beginBlock(A) ::= LSL_BLOCK_OPEN(B). { A = beginBlock(compiler, B); } | ||
91 | |||
88 | // This might be bogus, or might be valid LSL, but it lets us test the expression parser by evaluating them. | 92 | // This might be bogus, or might be valid LSL, but it lets us test the expression parser by evaluating them. |
89 | statement(A) ::= expr(E) LSL_STATEMENT(S). { A = addStatement(compiler, S, LSL_EXPRESSION, NULL, E, NULL, NULL, NULL); } | 93 | statement(A) ::= expr(E) LSL_STATEMENT(S). { A = addStatement(compiler, S, LSL_EXPRESSION, NULL, E, NULL, NULL, NULL); } |
90 | 94 | ||
diff --git a/LuaSL/src/LuaSL_lexer.l b/LuaSL/src/LuaSL_lexer.l index c66a3a8..0c7d627 100644 --- a/LuaSL/src/LuaSL_lexer.l +++ b/LuaSL/src/LuaSL_lexer.l | |||
@@ -76,8 +76,8 @@ STRING \"(\\.|[^\\"\n])*\" | |||
76 | 76 | ||
77 | /* Other symbols. */ | 77 | /* Other symbols. */ |
78 | "@" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_LABEL); %} | 78 | "@" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_LABEL); %} |
79 | "{" %{ beginBlock(yyextra, yylval); return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_BLOCK_OPEN); %} | 79 | "{" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_BLOCK_OPEN); %} |
80 | "}" %{ endBlock(yyextra, yylval); return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_BLOCK_CLOSE); %} | 80 | "}" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_BLOCK_CLOSE); %} |
81 | ";" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_STATEMENT); %} | 81 | ";" %{ return common(yylval, yytext, yyleng, yyextra, TRUE, LSL_STATEMENT); %} |
82 | 82 | ||
83 | /* Type keywords. */ | 83 | /* Type keywords. */ |