diff options
Diffstat (limited to '')
-rw-r--r-- | LuaSL/src/LuaSL_compile.c | 170 |
1 files changed, 124 insertions, 46 deletions
diff --git a/LuaSL/src/LuaSL_compile.c b/LuaSL/src/LuaSL_compile.c index cef6713..9d2456b 100644 --- a/LuaSL/src/LuaSL_compile.c +++ b/LuaSL/src/LuaSL_compile.c | |||
@@ -1,39 +1,5 @@ | |||
1 | #include "LuaSL.h" | 1 | #include "LuaSL.h" |
2 | 2 | ||
3 | /* TODO - | ||
4 | |||
5 | Assignments in the middle of expressions is legal in LSL, but not in Lua. | ||
6 | The big complication is that they often happen in the conditionals of flow control statements. That's a big bitch. | ||
7 | |||
8 | So things like - | ||
9 | |||
10 | while ((x = doSomething()) == foo) | ||
11 | { | ||
12 | buggerAround(); | ||
13 | } | ||
14 | |||
15 | Turns into - | ||
16 | |||
17 | x = doSomething(); | ||
18 | while (x == foo) | ||
19 | { | ||
20 | buggerAround(); | ||
21 | x = doSomething(); | ||
22 | } | ||
23 | |||
24 | http://lua-users.org/wiki/StatementsInExpressions might be helpful. Which suggests something like this - | ||
25 | |||
26 | while ( (function() x = doSomething(); return x; end)() == foo) | ||
27 | { | ||
28 | buggerAround(); | ||
29 | } | ||
30 | |||
31 | The remaining problem is when to recognise the need to do that. | ||
32 | Note that assignments are really low precedence. | ||
33 | While adding operations | ||
34 | Flag the assignment expressions | ||
35 | If there is an assignment expression (not operation) on the RHS of an operation, we need to do this? | ||
36 | */ | ||
37 | 3 | ||
38 | 4 | ||
39 | static LSL_Leaf *evaluateFloatToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right); | 5 | static LSL_Leaf *evaluateFloatToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right); |
@@ -506,6 +472,90 @@ LSL_Leaf *addOperation(LuaSL_compiler *compiler, LSL_Leaf *left, LSL_Leaf *lval, | |||
506 | } | 472 | } |
507 | break; | 473 | break; |
508 | } | 474 | } |
475 | |||
476 | /* Flag assignments for the "assignments are statements, which can't happen inside expressions" test. | ||
477 | * | ||
478 | * Assignments in the middle of expressions are legal in LSL, but not in Lua. | ||
479 | * The big complication is that they often happen in the conditionals of flow control statements. That's a big bitch. | ||
480 | * | ||
481 | * So things like - | ||
482 | * | ||
483 | * while ((x = doSomething()) == foo) | ||
484 | * { | ||
485 | * buggerAround(); | ||
486 | * } | ||
487 | * | ||
488 | * Turns into - | ||
489 | * | ||
490 | * x = doSomething(); | ||
491 | * while (x == foo) | ||
492 | * { | ||
493 | * buggerAround(); | ||
494 | * x = doSomething(); | ||
495 | * } | ||
496 | * | ||
497 | * http://lua-users.org/wiki/StatementsInExpressions was helpful. Which suggests something like this - | ||
498 | * | ||
499 | * while ( (function() x = doSomething(); return x; end)() == foo) | ||
500 | * { | ||
501 | * buggerAround(); | ||
502 | * } | ||
503 | * | ||
504 | * The remaining problem is when to recognise the need to do that. | ||
505 | * That's what this code and the matching code in addParenthesis() does. | ||
506 | */ | ||
507 | // TODO - Only got one of these in my test scripts, so leave all this debugging shit in until it's been tested more. | ||
508 | if (left) | ||
509 | { | ||
510 | if (left->flags & MF_ASSIGNEXP) | ||
511 | { | ||
512 | //if ((left) && (right)) | ||
513 | // printf("%s %s %s\n", left->toKen->toKen, lval->toKen->toKen, right->toKen->toKen); | ||
514 | //else if (left) | ||
515 | // printf("%s %s NORIGHT\n", left->toKen->toKen, lval->toKen->toKen); | ||
516 | //else if (right) | ||
517 | // printf("NOLEFT %s %s\n", lval->toKen->toKen, right->toKen->toKen); | ||
518 | //else | ||
519 | // printf("NOLEFT %s NORIGHT\n", lval->toKen->toKen); | ||
520 | // printf("############################################################################## left\n"); | ||
521 | left->flags |= MF_WRAPFUNC; | ||
522 | if (LSL_PARENTHESIS_OPEN == left->toKen->type) | ||
523 | left->value.parenthesis->flags |= MF_WRAPFUNC; | ||
524 | } | ||
525 | } | ||
526 | if (lval) | ||
527 | { | ||
528 | // if (lval->flags & MF_ASSIGNEXP) | ||
529 | // printf("############################################################################## lval %s %s\n", left->toKen->toKen, right->toKen->toKen); | ||
530 | if (LSL_ASSIGNMENT & lval->toKen->flags) | ||
531 | { | ||
532 | lval->flags |= MF_ASSIGNEXP; | ||
533 | //// printf("******************* lval %s %s\n", left->toKen->toKen, right->toKen->toKen); | ||
534 | if (LSL_IDENTIFIER == left->toKen->type) // It always should be. | ||
535 | { | ||
536 | left->flags |= MF_ASSIGNEXP; | ||
537 | //// printf("$$$$$$$$$$$$$$$$$ lval\n"); | ||
538 | } | ||
539 | } | ||
540 | } | ||
541 | // TODO - Don't think I have to do this on the right. | ||
542 | if (right) | ||
543 | { | ||
544 | if (right->flags & MF_ASSIGNEXP) | ||
545 | { | ||
546 | if ((left) && (right)) | ||
547 | printf("%s %s %s\n", left->toKen->toKen, lval->toKen->toKen, right->toKen->toKen); | ||
548 | else if (left) | ||
549 | printf("%s %s NORIGHT\n", left->toKen->toKen, lval->toKen->toKen); | ||
550 | else if (right) | ||
551 | printf("NOLEFT %s %s\n", lval->toKen->toKen, right->toKen->toKen); | ||
552 | else | ||
553 | printf("NOLEFT %s NORIGHT\n", lval->toKen->toKen); | ||
554 | printf("############################################################################## right\n"); | ||
555 | right->flags |= MF_WRAPFUNC; | ||
556 | } | ||
557 | } | ||
558 | |||
509 | if (OT_invalid == lval->basicType) | 559 | if (OT_invalid == lval->basicType) |
510 | { | 560 | { |
511 | const char *leftType = "", *rightType = "", *leftToken = "", *rightToken = ""; | 561 | const char *leftType = "", *rightType = "", *leftToken = "", *rightToken = ""; |
@@ -844,7 +894,14 @@ LSL_Leaf *addParenthesis(LSL_Leaf *lval, LSL_Leaf *expr, LSL_Type type, LSL_Leaf | |||
844 | { | 894 | { |
845 | lval->value.parenthesis = parens; | 895 | lval->value.parenthesis = parens; |
846 | if (expr) | 896 | if (expr) |
897 | { | ||
847 | lval->basicType = expr->basicType; | 898 | lval->basicType = expr->basicType; |
899 | // Propagate these flag inwards and outwards. | ||
900 | if (MF_ASSIGNEXP & expr->flags) | ||
901 | lval->flags |= MF_ASSIGNEXP; | ||
902 | if (MF_WRAPFUNC & expr->flags) | ||
903 | parens->flags |= MF_WRAPFUNC; | ||
904 | } | ||
848 | } | 905 | } |
849 | } | 906 | } |
850 | return lval; | 907 | return lval; |
@@ -1600,6 +1657,18 @@ static void outputLeaf(FILE *file, outputMode mode, LSL_Leaf *leaf) | |||
1600 | { | 1657 | { |
1601 | if (OM_LUA == mode) | 1658 | if (OM_LUA == mode) |
1602 | { | 1659 | { |
1660 | if (MF_WRAPFUNC & leaf->flags) | ||
1661 | { | ||
1662 | // TODO - Leaving this here in case we trip over one. | ||
1663 | if ((leaf->left) && (leaf->right)) | ||
1664 | printf("%s %s %s\n", leaf->left->toKen->toKen, leaf->toKen->toKen, leaf->right->toKen->toKen); | ||
1665 | else if (leaf->left) | ||
1666 | printf("%s %s NORIGHT\n", leaf->left->toKen->toKen, leaf->toKen->toKen); | ||
1667 | else if (leaf->right) | ||
1668 | printf("NOLEFT %s %s\n", leaf->toKen->toKen, leaf->right->toKen->toKen); | ||
1669 | else | ||
1670 | printf("NOLEFT %s NORIGHT\n", leaf->toKen->toKen); | ||
1671 | } | ||
1603 | if ((LSL_ASSIGNMENT & leaf->toKen->flags) && (LSL_ASSIGNMENT_PLAIN != leaf->toKen->type)) | 1672 | if ((LSL_ASSIGNMENT & leaf->toKen->flags) && (LSL_ASSIGNMENT_PLAIN != leaf->toKen->type)) |
1604 | { | 1673 | { |
1605 | fprintf(file, " --[[%s]] = %s %.1s ", leaf->toKen->toKen, leaf->left->value.identifierValue->name.text, leaf->toKen->toKen); | 1674 | fprintf(file, " --[[%s]] = %s %.1s ", leaf->toKen->toKen, leaf->left->value.identifierValue->name.text, leaf->toKen->toKen); |
@@ -1668,25 +1737,34 @@ static void outputRawBlock(FILE *file, outputMode mode, LSL_Block *block, boolea | |||
1668 | 1737 | ||
1669 | static void outputRawParenthesisToken(FILE *file, outputMode mode, LSL_Parenthesis *parenthesis, const char *typeName) | 1738 | static void outputRawParenthesisToken(FILE *file, outputMode mode, LSL_Parenthesis *parenthesis, const char *typeName) |
1670 | { | 1739 | { |
1671 | if ((OM_LUA == mode) && (LSL_TYPECAST_OPEN == parenthesis->type)) | 1740 | if ((OM_LUA == mode) && (LSL_TYPECAST_OPEN == parenthesis->type)) |
1672 | { | 1741 | { |
1673 | fprintf(file, " --[[(%s)]] ", typeName); | 1742 | fprintf(file, " --[[(%s)]] ", typeName); |
1674 | outputLeaf(file, mode, parenthesis->contents); | 1743 | outputLeaf(file, mode, parenthesis->contents); |
1675 | return; | 1744 | return; |
1676 | } | 1745 | } |
1677 | 1746 | ||
1747 | if ((OM_LUA == mode) && (MF_WRAPFUNC & parenthesis->flags)) | ||
1748 | fprintf(file, " (function() "); | ||
1749 | else | ||
1678 | fprintf(file, "("); | 1750 | fprintf(file, "("); |
1679 | if (LSL_TYPECAST_OPEN == parenthesis->type) | 1751 | if (LSL_TYPECAST_OPEN == parenthesis->type) |
1680 | fprintf(file, "%s", typeName); // TODO - We are missing the type ignorable text here. | 1752 | fprintf(file, "%s", typeName); // TODO - We are missing the type ignorable text here. |
1681 | else | 1753 | else |
1682 | outputLeaf(file, mode, parenthesis->contents); | 1754 | outputLeaf(file, mode, parenthesis->contents); |
1755 | if ((OM_LUA == mode) && (MF_WRAPFUNC & parenthesis->flags)) | ||
1756 | fprintf(file, "; return x; end)() "); | ||
1757 | else | ||
1758 | { | ||
1683 | #if LUASL_DIFF_CHECK | 1759 | #if LUASL_DIFF_CHECK |
1684 | fprintf(file, "%s)", eina_strbuf_string_get(parenthesis->rightIgnorable)); | 1760 | fprintf(file, "%s)", eina_strbuf_string_get(parenthesis->rightIgnorable)); |
1685 | #else | 1761 | #else |
1686 | fprintf(file, ")"); | 1762 | fprintf(file, ")"); |
1687 | #endif | 1763 | #endif |
1688 | if (LSL_TYPECAST_OPEN == parenthesis->type) | 1764 | } |
1689 | outputLeaf(file, mode, parenthesis->contents); | 1765 | |
1766 | if (LSL_TYPECAST_OPEN == parenthesis->type) | ||
1767 | outputLeaf(file, mode, parenthesis->contents); | ||
1690 | } | 1768 | } |
1691 | 1769 | ||
1692 | static void outputText(FILE *file, LSL_Text *text, boolean ignore) | 1770 | static void outputText(FILE *file, LSL_Text *text, boolean ignore) |