diff options
author | David Walter Seikel | 2012-02-04 12:23:48 +1000 |
---|---|---|
committer | David Walter Seikel | 2012-02-04 12:23:48 +1000 |
commit | 0d50ad8a31ea5ed07b83946d39e31b3f1a20bdfa (patch) | |
tree | a474c283b6b9a5e2d37ae6808d22df6cd175c46c /LuaSL/src/LuaSL_compile.c | |
parent | Restore this thing so I can debug it now. (diff) | |
download | SledjHamr-0d50ad8a31ea5ed07b83946d39e31b3f1a20bdfa.zip SledjHamr-0d50ad8a31ea5ed07b83946d39e31b3f1a20bdfa.tar.gz SledjHamr-0d50ad8a31ea5ed07b83946d39e31b3f1a20bdfa.tar.bz2 SledjHamr-0d50ad8a31ea5ed07b83946d39e31b3f1a20bdfa.tar.xz |
Fix up "assignments in the middle of expressions is legal in LSL, but not in Lua" problem.
Note, only got one of these in the test scripts, so leaving copious debugging shat laying around for further testing.
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) |