From 860a32f27a44542a4a97134cf57028276c33851c Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Fri, 3 Feb 2012 21:08:47 +1000 Subject: Put assignments in their right place. --- LuaSL/src/LuaSL_compile.c | 18 +++++++------- LuaSL/src/LuaSL_lemon_yaccer.y | 54 +++++++++++++++++++++++------------------- 2 files changed, 39 insertions(+), 33 deletions(-) diff --git a/LuaSL/src/LuaSL_compile.c b/LuaSL/src/LuaSL_compile.c index ea3a2ef..898f33b 100644 --- a/LuaSL/src/LuaSL_compile.c +++ b/LuaSL/src/LuaSL_compile.c @@ -31,7 +31,16 @@ LSL_Token LSL_Tokens[] = // Operators, in order of precedence, low to high // Left to right, unless otherwise stated. - // According to http://wiki.secondlife.com/wiki/Category:LSL_Operators + // According to http://wiki.secondlife.com/wiki/Category:LSL_Operators, which was obsoleted by http://wiki.secondlife.com/wiki/LSL_Operators but that has less info. + + {LSL_ASSIGNMENT_CONCATENATE,ST_CONCATENATION, "+=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, evaluateOperationToken}, + {LSL_ASSIGNMENT_ADD, ST_CONCATENATION, "+=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, evaluateOperationToken}, + {LSL_ASSIGNMENT_SUBTRACT, ST_ASSIGNMENT, "-=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, evaluateOperationToken}, + {LSL_ASSIGNMENT_MULTIPLY, ST_ASSIGNMENT, "*=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, evaluateOperationToken}, + {LSL_ASSIGNMENT_MODULO, ST_MODULO, "%=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, evaluateOperationToken}, + {LSL_ASSIGNMENT_DIVIDE, ST_ASSIGNMENT, "/=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, evaluateOperationToken}, + {LSL_ASSIGNMENT_PLAIN, ST_CONCATENATION, "=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, evaluateOperationToken}, + {LSL_BOOL_AND, ST_BOOLEAN, "&&", LSL_RIGHT2LEFT, NULL, evaluateOperationToken}, // QUIRK - Seems to be some disagreement about BOOL_AND/BOOL_OR precedence. Either they are equal, or OR is higher. // QUIRK - No boolean short circuiting. @@ -84,13 +93,6 @@ LSL_Token LSL_Tokens[] = {LSL_BRACKET_OPEN, ST_NONE, "[", LSL_INNER2OUTER | LSL_CREATION, NULL, evaluateOperationToken}, {LSL_PARENTHESIS_CLOSE, ST_NONE, ")", LSL_INNER2OUTER, NULL, evaluateNoToken}, {LSL_PARENTHESIS_OPEN, ST_NONE, "(", LSL_INNER2OUTER, outputParenthesisToken, eveluateParenthesisToken}, - {LSL_ASSIGNMENT_CONCATENATE,ST_CONCATENATION, "+=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, evaluateOperationToken}, - {LSL_ASSIGNMENT_ADD, ST_CONCATENATION, "+=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, evaluateOperationToken}, - {LSL_ASSIGNMENT_SUBTRACT, ST_ASSIGNMENT, "-=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, evaluateOperationToken}, - {LSL_ASSIGNMENT_MULTIPLY, ST_ASSIGNMENT, "*=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, evaluateOperationToken}, - {LSL_ASSIGNMENT_MODULO, ST_MODULO, "%=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, evaluateOperationToken}, - {LSL_ASSIGNMENT_DIVIDE, ST_ASSIGNMENT, "/=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, evaluateOperationToken}, - {LSL_ASSIGNMENT_PLAIN, ST_CONCATENATION, "=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, evaluateOperationToken}, {LSL_DOT, ST_NONE, ".", LSL_RIGHT2LEFT, NULL, evaluateOperationToken}, {LSL_DECREMENT_POST, ST_NONE, "--", LSL_RIGHT2LEFT | LSL_UNARY, outputCrementsToken, evaluateOperationToken}, {LSL_DECREMENT_PRE, ST_NONE, "--", LSL_RIGHT2LEFT | LSL_UNARY, outputCrementsToken, evaluateOperationToken}, diff --git a/LuaSL/src/LuaSL_lemon_yaccer.y b/LuaSL/src/LuaSL_lemon_yaccer.y index 716c65a..1290832 100644 --- a/LuaSL/src/LuaSL_lemon_yaccer.y +++ b/LuaSL/src/LuaSL_lemon_yaccer.y @@ -104,6 +104,30 @@ exprList(A) ::= exprList(B) LSL_COMMA(C) expr(D). { A = collectArguments(com exprList(A) ::= expr(D). { A = collectArguments(compiler, NULL, NULL, D); } exprList(A) ::= . { A = collectArguments(compiler, NULL, NULL, NULL); } +// Assignments and variable declarations. + +%right LSL_ASSIGNMENT_CONCATENATE LSL_ASSIGNMENT_ADD LSL_ASSIGNMENT_SUBTRACT LSL_ASSIGNMENT_MULTIPLY LSL_ASSIGNMENT_MODULO LSL_ASSIGNMENT_DIVIDE LSL_ASSIGNMENT_PLAIN. +// Variables and dealing with them. + +expr(A) ::= identifier(B). { A = B; } + +// Yes, these can be expressions, and can happen in if statements and such. In Lua they are NOT expressions. sigh +expr(A) ::= identifier(B) LSL_ASSIGNMENT_CONCATENATE(C) expr(D). { A = addOperation(compiler, B, C, D); } +expr(A) ::= identifier(B) LSL_ASSIGNMENT_ADD(C) expr(D). { A = addOperation(compiler, B, C, D); } +expr(A) ::= identifier(B) LSL_ASSIGNMENT_SUBTRACT(C) expr(D). { A = addOperation(compiler, B, C, D); } +expr(A) ::= identifier(B) LSL_ASSIGNMENT_MULTIPLY(C) expr(D). { A = addOperation(compiler, B, C, D); } +expr(A) ::= identifier(B) LSL_ASSIGNMENT_MODULO(C) expr(D). { A = addOperation(compiler, B, C, D); } +expr(A) ::= identifier(B) LSL_ASSIGNMENT_DIVIDE(C) expr(D). { A = addOperation(compiler, B, C, D); } +expr(A) ::= identifier(B) LSL_ASSIGNMENT_PLAIN(C) expr(D). { A = addOperation(compiler, B, C, D); } + +// Hmm think this can have commas seperating the assignment parts, or is that only in C?. If so, best to separate them when converting to Lua, as it uses that syntax for something else. +// Well, not in OpenSim at least, nor in SL. So we are safe. B-) +// On the other hand, it might be legal to have comma separated bits in a for loop - for ((i = 1), (j=1); ... +statement(A) ::= type(T) LSL_IDENTIFIER(I) LSL_ASSIGNMENT_PLAIN(D) expr(E) LSL_STATEMENT(S). { A = addStatement(compiler, S, I, NULL, addVariable(compiler, T, I, D, E, S), NULL, NULL, I); } +statement(A) ::= type(T) LSL_IDENTIFIER(I) LSL_STATEMENT(S). { A = addStatement(compiler, S, I, NULL, addVariable(compiler, T, I, NULL, NULL, S), NULL, NULL, I); } + +// Basic operators. + %right LSL_BOOL_AND. expr(A) ::= expr(B) LSL_BOOL_AND(C) expr(D). { A = addOperation(compiler, B, C, D); } %right LSL_BOOL_OR. @@ -159,31 +183,6 @@ type(A) ::= LSL_TYPE_VECTOR(B). { B->basicType = OT_vector; A = B; } expr(A) ::= LSL_PARENTHESIS_OPEN(B) expr(C) LSL_PARENTHESIS_CLOSE(D). { A = addParenthesis(B, C, LSL_EXPRESSION, D); } expr(A) ::= LSL_PARENTHESIS_OPEN(B) type(C) LSL_PARENTHESIS_CLOSE(D) expr(E). { A = addTypecast(B, C, D, E); } -// Function call. - -// Causes a conflict when exprList is empty with a function definition with no type and no parameters. -expr(A) ::= LSL_IDENTIFIER(B) LSL_PARENTHESIS_OPEN(C) exprList(D) LSL_PARENTHESIS_CLOSE(E). { A = addFunctionCall(compiler, B, C, D, E); } - -// Variables and dealing with them. - -expr(A) ::= identifier(B). { A = B; } - -%right LSL_ASSIGNMENT_CONCATENATE LSL_ASSIGNMENT_ADD LSL_ASSIGNMENT_SUBTRACT LSL_ASSIGNMENT_MULTIPLY LSL_ASSIGNMENT_MODULO LSL_ASSIGNMENT_DIVIDE LSL_ASSIGNMENT_PLAIN. -// Yes, these can be expressions, and can happen in if statements and such. -expr(A) ::= identifier(B) LSL_ASSIGNMENT_CONCATENATE(C) expr(D). { A = addOperation(compiler, B, C, D); } -expr(A) ::= identifier(B) LSL_ASSIGNMENT_ADD(C) expr(D). { A = addOperation(compiler, B, C, D); } -expr(A) ::= identifier(B) LSL_ASSIGNMENT_SUBTRACT(C) expr(D). { A = addOperation(compiler, B, C, D); } -expr(A) ::= identifier(B) LSL_ASSIGNMENT_MULTIPLY(C) expr(D). { A = addOperation(compiler, B, C, D); } -expr(A) ::= identifier(B) LSL_ASSIGNMENT_MODULO(C) expr(D). { A = addOperation(compiler, B, C, D); } -expr(A) ::= identifier(B) LSL_ASSIGNMENT_DIVIDE(C) expr(D). { A = addOperation(compiler, B, C, D); } -expr(A) ::= identifier(B) LSL_ASSIGNMENT_PLAIN(C) expr(D). { A = addOperation(compiler, B, C, D); } - -// Hmm think this can have commas seperating the assignment parts, or is that only in C?. If so, best to separate them when converting to Lua, as it uses that syntax for something else. -// Well, not in OpenSim at least, nor in SL. So we are safe. B-) -// On the other hand, it might be legal to have comma separated bits in a for loop - for ((i = 1), (j=1); ... -statement(A) ::= type(T) LSL_IDENTIFIER(I) LSL_ASSIGNMENT_PLAIN(D) expr(E) LSL_STATEMENT(S). { A = addStatement(compiler, S, I, NULL, addVariable(compiler, T, I, D, E), NULL, NULL, I); } -statement(A) ::= type(T) LSL_IDENTIFIER(I) LSL_STATEMENT(S). { A = addStatement(compiler, S, I, NULL, addVariable(compiler, T, I, NULL, NULL), NULL, NULL, I); } - %right LSL_DOT LSL_IDENTIFIER LSL_FUNCTION_CALL LSL_VARIABLE. identifier(A) ::= identifier(I) LSL_DOT(D) LSL_IDENTIFIER(B). { A = checkVariable(compiler, I, D, B); } identifier(A) ::= LSL_IDENTIFIER(B). { A = checkVariable(compiler, B, NULL, NULL); } @@ -194,6 +193,11 @@ expr(A) ::= identifier(B) LSL_INCREMENT_PRE(C). { A = addCrement(compiler, expr(A) ::= LSL_DECREMENT_PRE(C) identifier(B). { A = addCrement(compiler, B, C, LSL_DECREMENT_PRE); } expr(A) ::= LSL_INCREMENT_PRE(C) identifier(B). { A = addCrement(compiler, B, C, LSL_INCREMENT_PRE); } +// Function call. + +// Causes a conflict when exprList is empty with a function definition with no type and no parameters. +expr(A) ::= LSL_IDENTIFIER(B) LSL_PARENTHESIS_OPEN(C) exprList(D) LSL_PARENTHESIS_CLOSE(E). { A = addFunctionCall(compiler, B, C, D, E); } + %nonassoc LSL_COMMA. // Values. -- cgit v1.1