aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDavid Walter Seikel2012-02-04 12:23:48 +1000
committerDavid Walter Seikel2012-02-04 12:23:48 +1000
commit0d50ad8a31ea5ed07b83946d39e31b3f1a20bdfa (patch)
treea474c283b6b9a5e2d37ae6808d22df6cd175c46c
parentRestore this thing so I can debug it now. (diff)
downloadSledjHamr-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.
-rw-r--r--LuaSL/src/LuaSL_LSL_tree.h13
-rw-r--r--LuaSL/src/LuaSL_compile.c170
2 files changed, 132 insertions, 51 deletions
diff --git a/LuaSL/src/LuaSL_LSL_tree.h b/LuaSL/src/LuaSL_LSL_tree.h
index 8909c7e..1092f26 100644
--- a/LuaSL/src/LuaSL_LSL_tree.h
+++ b/LuaSL/src/LuaSL_LSL_tree.h
@@ -150,11 +150,13 @@ typedef enum
150{ 150{
151 MF_NONE = 0, 151 MF_NONE = 0,
152 MF_LOCAL = 1, 152 MF_LOCAL = 1,
153 MF_NOASSIGN = 2, 153 MF_NOASSIGN = 2, // These two are for completely different purposes. This one is for variable definitions with no assignment.
154 MF_PREDEC = 4, 154 MF_ASSIGNEXP = 4, // These two are for completely different purposes. This one is for assignments being used as expressions.
155 MF_PREINC = 8, 155 MF_WRAPFUNC = 8,
156 MF_POSTDEC = 16, 156 MF_PREDEC = 16,
157 MF_POSTINC = 32 157 MF_PREINC = 32,
158 MF_POSTDEC = 64,
159 MF_POSTINC = 128
158} miscFlags; 160} miscFlags;
159 161
160struct _allowedTypes 162struct _allowedTypes
@@ -232,6 +234,7 @@ struct _LSL_Parenthesis
232 Eina_Strbuf *rightIgnorable; 234 Eina_Strbuf *rightIgnorable;
233#endif 235#endif
234 LSL_Type type; 236 LSL_Type type;
237 miscFlags flags;
235}; 238};
236 239
237struct _LSL_Identifier // For variables and function parameters. 240struct _LSL_Identifier // For variables and function parameters.
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
5Assignments in the middle of expressions is legal in LSL, but not in Lua.
6The big complication is that they often happen in the conditionals of flow control statements. That's a big bitch.
7
8So things like -
9
10 while ((x = doSomething()) == foo)
11 {
12 buggerAround();
13 }
14
15Turns into -
16
17 x = doSomething();
18 while (x == foo)
19 {
20 buggerAround();
21 x = doSomething();
22 }
23
24http://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
31The remaining problem is when to recognise the need to do that.
32Note 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
39static LSL_Leaf *evaluateFloatToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right); 5static 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 {
546if ((left) && (right))
547 printf("%s %s %s\n", left->toKen->toKen, lval->toKen->toKen, right->toKen->toKen);
548else if (left)
549 printf("%s %s NORIGHT\n", left->toKen->toKen, lval->toKen->toKen);
550else if (right)
551 printf("NOLEFT %s %s\n", lval->toKen->toKen, right->toKen->toKen);
552else
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.
1663if ((leaf->left) && (leaf->right))
1664 printf("%s %s %s\n", leaf->left->toKen->toKen, leaf->toKen->toKen, leaf->right->toKen->toKen);
1665else if (leaf->left)
1666 printf("%s %s NORIGHT\n", leaf->left->toKen->toKen, leaf->toKen->toKen);
1667else if (leaf->right)
1668 printf("NOLEFT %s %s\n", leaf->toKen->toKen, leaf->right->toKen->toKen);
1669else
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
1669static void outputRawParenthesisToken(FILE *file, outputMode mode, LSL_Parenthesis *parenthesis, const char *typeName) 1738static 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
1692static void outputText(FILE *file, LSL_Text *text, boolean ignore) 1770static void outputText(FILE *file, LSL_Text *text, boolean ignore)