aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/LuaSL
diff options
context:
space:
mode:
authorDavid Walter Seikel2012-01-28 14:54:41 +1000
committerDavid Walter Seikel2012-01-28 14:54:41 +1000
commit0d060b7ef6ea3cdd3ae505f41826d96d3ca12070 (patch)
tree32b477bc406dd30ed119e5f1de97ea1750ff4353 /LuaSL
parentDocument the other Clist use, and change it's name while I'm at it. (diff)
downloadSledjHamr-0d060b7ef6ea3cdd3ae505f41826d96d3ca12070.zip
SledjHamr-0d060b7ef6ea3cdd3ae505f41826d96d3ca12070.tar.gz
SledjHamr-0d060b7ef6ea3cdd3ae505f41826d96d3ca12070.tar.bz2
SledjHamr-0d060b7ef6ea3cdd3ae505f41826d96d3ca12070.tar.xz
Add some of the flow control stuff, still needs lots of work.
Diffstat (limited to 'LuaSL')
-rw-r--r--LuaSL/src/LuaSL_LSL_tree.h20
-rw-r--r--LuaSL/src/LuaSL_compile.c306
-rw-r--r--LuaSL/src/LuaSL_lemon_yaccer.y28
3 files changed, 279 insertions, 75 deletions
diff --git a/LuaSL/src/LuaSL_LSL_tree.h b/LuaSL/src/LuaSL_LSL_tree.h
index f2fccd0..349d74f 100644
--- a/LuaSL/src/LuaSL_LSL_tree.h
+++ b/LuaSL/src/LuaSL_LSL_tree.h
@@ -179,7 +179,7 @@ struct _LSL_Leaf
179 LSL_Leaf *listValue; 179 LSL_Leaf *listValue;
180 const char *stringValue; 180 const char *stringValue;
181 opType operationValue; 181 opType operationValue;
182 LSL_Parenthesis *parenthesis; 182 LSL_Parenthesis *parenthesis;
183 LSL_Identifier *identifierValue; 183 LSL_Identifier *identifierValue;
184 LSL_Statement *statementValue; 184 LSL_Statement *statementValue;
185 LSL_Block *blockValue; 185 LSL_Block *blockValue;
@@ -208,17 +208,21 @@ struct _LSL_Identifier // For variables and function parameters.
208struct _LSL_Statement 208struct _LSL_Statement
209{ 209{
210 Eina_Clist statement; // For block statement lists, this is the entry. 210 Eina_Clist statement; // For block statement lists, this is the entry.
211 union 211// union
212 { 212// {
213 LSL_Identifier *identifier; 213 LSL_Identifier *identifier;
214 LSL_Parenthesis *parenthesis; 214 LSL_Parenthesis *parenthesis;
215 } stuff; // Nothing has an identifier AND parenthesis, and there will be LOTS of statements, so save some space. 215// } stuff; // Nothing has an identifier AND parenthesis, and there will be LOTS of statements, so save some space.
216 // Damn, function identifiers do.
216 LSL_Leaf *expressions; // A for statement will have three expressions, everything else has zero or one. 217 LSL_Leaf *expressions; // A for statement will have three expressions, everything else has zero or one.
217 LSL_Block *block; 218 LSL_Leaf *block;
218 LSL_Type type; // Expression type. 219 LSL_Type type; // Expression type.
219/* 220/*
220expr expr 221LSL_Leaf *addStatement(LSL_Leaf *lval, LSL_Type type, LSL_Leaf *left, LSL_Leaf *expr, LSL_Leaf *right, LSL_Leaf *block);
221Variable defines identifier, optional expr 222
223expr expr // Might be bogus,
224Variable defines identifier, optional expr // For these we only store the variable leaf in expressions.
225Function define identifier, block, parens // Also function params, but that's stored in the function anyway.
222state change identifier 226state change identifier
223Labels identifier 227Labels identifier
224goto identifier 228goto identifier
@@ -376,7 +380,7 @@ LSL_Leaf *addOperation(LuaSL_compiler *compiler, LSL_Leaf *left, LSL_Leaf *lval,
376LSL_Leaf *addParameter(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *newParam); 380LSL_Leaf *addParameter(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *newParam);
377LSL_Leaf *addParenthesis(LSL_Leaf *lval, LSL_Leaf *expr, LSL_Type type, LSL_Leaf *rval); 381LSL_Leaf *addParenthesis(LSL_Leaf *lval, LSL_Leaf *expr, LSL_Type type, LSL_Leaf *rval);
378LSL_Leaf *addState(LuaSL_compiler *compiler, LSL_Leaf *identifier, LSL_Leaf *block); 382LSL_Leaf *addState(LuaSL_compiler *compiler, LSL_Leaf *identifier, LSL_Leaf *block);
379LSL_Leaf *addStatement(LSL_Leaf *lval, LSL_Type type, LSL_Leaf *expr); 383LSL_Leaf *addStatement(LuaSL_compiler *compiler, LSL_Leaf *lval, LSL_Type type, LSL_Leaf *left, LSL_Leaf *expr, LSL_Leaf *right, LSL_Leaf *block, LSL_Leaf *identifier);
380LSL_Leaf *addTypecast(LSL_Leaf *lval, LSL_Leaf *type, LSL_Leaf *rval, LSL_Leaf *expr); 384LSL_Leaf *addTypecast(LSL_Leaf *lval, LSL_Leaf *type, LSL_Leaf *rval, LSL_Leaf *expr);
381LSL_Leaf *addVariable(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *identifier, LSL_Leaf *assignment, LSL_Leaf *expr); 385LSL_Leaf *addVariable(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *identifier, LSL_Leaf *assignment, LSL_Leaf *expr);
382 386
diff --git a/LuaSL/src/LuaSL_compile.c b/LuaSL/src/LuaSL_compile.c
index c1a1a5e..8fc3cb5 100644
--- a/LuaSL/src/LuaSL_compile.c
+++ b/LuaSL/src/LuaSL_compile.c
@@ -551,15 +551,12 @@ LSL_Leaf *addFunction(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *identi
551 551
552LSL_Leaf *addFunctionBody(LuaSL_compiler *compiler, LSL_Leaf *function, LSL_Leaf *block) 552LSL_Leaf *addFunctionBody(LuaSL_compiler *compiler, LSL_Leaf *function, LSL_Leaf *block)
553{ 553{
554 LSL_Leaf *statement = newLeaf(LSL_STATEMENT, NULL, NULL); 554 LSL_Leaf *statement = NULL;
555 555
556 if (function) 556 if (function)
557 { 557 {
558 function->value.functionValue->block = block; 558 function->value.functionValue->block = block;
559 if (statement) 559 statement = addStatement(compiler, NULL, LSL_FUNCTION, NULL, function, NULL, NULL, NULL);
560 {
561 addStatement(statement, LSL_FUNCTION, function);
562 }
563 } 560 }
564 561
565 return statement; 562 return statement;
@@ -639,19 +636,90 @@ LSL_Leaf *addState(LuaSL_compiler *compiler, LSL_Leaf *identifier, LSL_Leaf *blo
639 return identifier; 636 return identifier;
640} 637}
641 638
642LSL_Leaf *addStatement(LSL_Leaf *lval, LSL_Type type, LSL_Leaf *expr) 639LSL_Leaf *addStatement(LuaSL_compiler *compiler, LSL_Leaf *lval, LSL_Type type, LSL_Leaf *left, LSL_Leaf *expr, LSL_Leaf *right, LSL_Leaf *block, LSL_Leaf *identifier)
643{ 640{
641 gameGlobals *game = compiler->game;
644 LSL_Statement *stat = calloc(1, sizeof(LSL_Statement)); 642 LSL_Statement *stat = calloc(1, sizeof(LSL_Statement));
645 643
644 if (NULL == lval)
645 lval = newLeaf(LSL_STATEMENT, NULL, NULL);
646
646 if (stat) 647 if (stat)
647 { 648 {
648 stat->type = type; 649 stat->type = type;
649 stat->expressions = expr; 650 stat->expressions = expr;
651 stat->block = block;
650 eina_clist_element_init(&(stat->statement)); 652 eina_clist_element_init(&(stat->statement));
653 if (identifier)
654 stat->identifier = identifier->value.identifierValue;
655 if (left)
656 {
657 LSL_Leaf *parens = addParenthesis(left, expr, LSL_TYPECAST_OPEN, right);
658
659 if (parens)
660 stat->parenthesis = parens->value.parenthesis;
661 }
662
663 switch (type)
664 {
665 case LSL_EXPRESSION :
666 {
667 break;
668 }
669 case LSL_FUNCTION :
670 {
671 break;
672 }
673 case LSL_DO :
674 {
675 break;
676 }
677 case LSL_FOR :
678 {
679 break;
680 }
681 case LSL_IF :
682 {
683 break;
684 }
685 case LSL_ELSE :
686 {
687 break;
688 }
689 case LSL_JUMP :
690 {
691 break;
692 }
693 case LSL_RETURN :
694 {
695 break;
696 }
697 case LSL_STATE_CHANGE :
698 {
699 break;
700 }
701 case LSL_WHILE :
702 {
703 stat->identifier = NULL;
704 // TODO - need to stash the while's white space somewhere.
705 break;
706 }
707 case LSL_IDENTIFIER :
708 {
709 break;
710 }
711 default :
712 {
713 PE("Should not be here %d.", type);
714 break;
715 }
716 }
717
651 if (lval) 718 if (lval)
652 lval->value.statementValue = stat; 719 lval->value.statementValue = stat;
653 } 720 }
654 721
722
655 return lval; 723 return lval;
656} 724}
657 725
@@ -1028,7 +1096,60 @@ static LSL_Leaf *evaluateStatementToken(LSL_Leaf *content, LSL_Leaf *left, LSL_L
1028 1096
1029 if (content) 1097 if (content)
1030 { 1098 {
1031 result = evaluateLeaf(content->value.statementValue->expressions, left, right); 1099 switch (content->value.statementValue->type)
1100 {
1101 case LSL_EXPRESSION :
1102 {
1103 result = evaluateLeaf(content->value.statementValue->expressions, left, right);
1104 break;
1105 }
1106 case LSL_FUNCTION :
1107 {
1108 break;
1109 }
1110 case LSL_DO :
1111 {
1112 break;
1113 }
1114 case LSL_FOR :
1115 {
1116 break;
1117 }
1118 case LSL_IF :
1119 {
1120 break;
1121 }
1122 case LSL_ELSE :
1123 {
1124 break;
1125 }
1126 case LSL_JUMP :
1127 {
1128 break;
1129 }
1130 case LSL_RETURN :
1131 {
1132 break;
1133 }
1134 case LSL_STATE_CHANGE :
1135 {
1136 break;
1137 }
1138 case LSL_WHILE :
1139 {
1140 break;
1141 }
1142 case LSL_IDENTIFIER :
1143 {
1144 break;
1145 }
1146 default :
1147 {
1148// PE("Should not be here %d.", type);
1149 break;
1150 }
1151 }
1152
1032 if (result) 1153 if (result)
1033 { 1154 {
1034 switch (result->basicType) 1155 switch (result->basicType)
@@ -1065,37 +1186,6 @@ static void outputLeaf(FILE *file, outputMode mode, LSL_Leaf *leaf)
1065 } 1186 }
1066} 1187}
1067 1188
1068static void outputBlockToken(FILE *file, outputMode mode, LSL_Leaf *content)
1069{
1070 if (content)
1071 {
1072 if (LUASL_DIFF_CHECK)
1073 fprintf(file, "\n{");
1074 else
1075 fprintf(file, "\n{\n");
1076 if (content->value.blockValue)
1077 {
1078 LSL_Statement *statement = NULL;
1079
1080 EINA_CLIST_FOR_EACH_ENTRY(statement, &(content->value.blockValue->statements), LSL_Statement, statement)
1081 {
1082 outputLeaf(file, mode, statement->expressions);
1083 if (LSL_FUNCTION != statement->type)
1084 {
1085 if (LUASL_DIFF_CHECK)
1086 fprintf(file, ";");
1087 else
1088 fprintf(file, ";\n");
1089 }
1090 }
1091 }
1092 if (LUASL_DIFF_CHECK)
1093 fprintf(file, "\n}");
1094 else
1095 fprintf(file, "}");
1096 }
1097}
1098
1099static void outputFloatToken(FILE *file, outputMode mode, LSL_Leaf *content) 1189static void outputFloatToken(FILE *file, outputMode mode, LSL_Leaf *content)
1100{ 1190{
1101 if (content) 1191 if (content)
@@ -1165,23 +1255,26 @@ static void outputParameterListToken(FILE *file, outputMode mode, LSL_Leaf *cont
1165 outputLeaf(file, mode, content->value.listValue); 1255 outputLeaf(file, mode, content->value.listValue);
1166} 1256}
1167 1257
1168static void outputParenthesisToken(FILE *file, outputMode mode, LSL_Leaf *content) 1258static void outputRawParenthesisToken(FILE *file, outputMode mode, LSL_Parenthesis *parenthesis, const char *typeName)
1169{ 1259{
1170 if (content)
1171 {
1172 fprintf(file, "("); 1260 fprintf(file, "(");
1173 if (LSL_TYPECAST_OPEN == content->value.parenthesis->type) 1261 if (LSL_TYPECAST_OPEN == parenthesis->type)
1174 fprintf(file, "%s", allowed[content->basicType].name); // TODO - We are missing the type ignorable text here. 1262 fprintf(file, "%s", typeName); // TODO - We are missing the type ignorable text here.
1175 else 1263 else
1176 outputLeaf(file, mode, content->value.parenthesis->contents); 1264 outputLeaf(file, mode, parenthesis->contents);
1177#if LUASL_DIFF_CHECK 1265#if LUASL_DIFF_CHECK
1178 fprintf(file, "%s)", eina_strbuf_string_get(content->value.parenthesis->rightIgnorableText)); 1266 fprintf(file, "%s)", eina_strbuf_string_get(parenthesis->rightIgnorableText));
1179#else 1267#else
1180 fprintf(file, ")"); 1268 fprintf(file, ")");
1181#endif 1269#endif
1182 if (LSL_TYPECAST_OPEN == content->value.parenthesis->type) 1270 if (LSL_TYPECAST_OPEN == parenthesis->type)
1183 outputLeaf(file, mode, content->value.parenthesis->contents); 1271 outputLeaf(file, mode, parenthesis->contents);
1184 } 1272}
1273
1274static void outputParenthesisToken(FILE *file, outputMode mode, LSL_Leaf *content)
1275{
1276 if (content)
1277 outputRawParenthesisToken(file, mode, content->value.parenthesis, allowed[content->basicType].name);
1185} 1278}
1186 1279
1187static void outputStateToken(FILE *file, outputMode mode, LSL_Leaf *content) 1280static void outputStateToken(FILE *file, outputMode mode, LSL_Leaf *content)
@@ -1202,19 +1295,126 @@ static void outputStateToken(FILE *file, outputMode mode, LSL_Leaf *content)
1202 } 1295 }
1203} 1296}
1204 1297
1298// Circular references, so declare this one first.
1299static void outputBlockToken(FILE *file, outputMode mode, LSL_Leaf *content);
1300
1301static void outputRawStatement(FILE *file, outputMode mode, LSL_Statement *statement)
1302{
1303 boolean isBlock = FALSE;
1304
1305 switch (statement->type)
1306 {
1307 case LSL_EXPRESSION :
1308 {
1309 break;
1310 }
1311 case LSL_FUNCTION :
1312 {
1313 isBlock = TRUE;
1314 break;
1315 }
1316 case LSL_DO :
1317 {
1318 fprintf(file, "%s", tokens[statement->type - lowestToken]->token);
1319 break;
1320 }
1321 case LSL_FOR :
1322 {
1323 fprintf(file, "%s", tokens[statement->type - lowestToken]->token);
1324 break;
1325 }
1326 case LSL_IF :
1327 {
1328 fprintf(file, "%s", tokens[statement->type - lowestToken]->token);
1329 break;
1330 }
1331 case LSL_ELSE :
1332 {
1333 fprintf(file, "%s", tokens[statement->type - lowestToken]->token);
1334 break;
1335 }
1336 case LSL_JUMP :
1337 {
1338 fprintf(file, "%s", tokens[statement->type - lowestToken]->token);
1339 break;
1340 }
1341 case LSL_RETURN :
1342 {
1343 fprintf(file, "%s", tokens[statement->type - lowestToken]->token);
1344 break;
1345 }
1346 case LSL_STATE_CHANGE :
1347 {
1348 fprintf(file, "%s", tokens[statement->type - lowestToken]->token);
1349 break;
1350 }
1351 case LSL_WHILE :
1352 {
1353 isBlock = TRUE;
1354 fprintf(file, "%s", tokens[statement->type - lowestToken]->token);
1355 break;
1356 }
1357 case LSL_IDENTIFIER :
1358 {
1359 break;
1360 }
1361 default :
1362 {
1363 fprintf(file, "@@Should not be here %s.@@", tokens[statement->type - lowestToken]->token);
1364 break;
1365 }
1366 }
1367
1368 if (statement->parenthesis)
1369 outputRawParenthesisToken(file, mode, statement->parenthesis, "");
1370 else
1371 outputLeaf(file, mode, statement->expressions);
1372
1373 if (statement->block)
1374 outputBlockToken(file, mode, statement->block);
1375
1376 if (!isBlock)
1377 {
1378 fprintf(file, ";");
1379 if (!LUASL_DIFF_CHECK)
1380 fprintf(file, "\n");
1381 }
1382
1383}
1384
1205static void outputStatementToken(FILE *file, outputMode mode, LSL_Leaf *content) 1385static void outputStatementToken(FILE *file, outputMode mode, LSL_Leaf *content)
1206{ 1386{
1207 if (content) 1387 if (content)
1208 { 1388 {
1209 outputLeaf(file, mode, content->value.statementValue->expressions); 1389 outputRawStatement(file, mode, content->value.statementValue);
1210#if LUASL_DIFF_CHECK 1390#if LUASL_DIFF_CHECK
1211 if (content->ignorableText) 1391 if (content->ignorableText)
1212 fwrite(eina_strbuf_string_get(content->ignorableText), 1, eina_strbuf_length_get(content->ignorableText), file); 1392 fwrite(eina_strbuf_string_get(content->ignorableText), 1, eina_strbuf_length_get(content->ignorableText), file);
1213#endif 1393#endif
1214 if (LSL_FUNCTION != content->value.statementValue->type) 1394 }
1215 fprintf(file, "%s", content->token->token); 1395}
1216 if (!LUASL_DIFF_CHECK) 1396
1217 fprintf(file, "\n"); 1397static void outputBlockToken(FILE *file, outputMode mode, LSL_Leaf *content)
1398{
1399 if (content)
1400 {
1401 if (LUASL_DIFF_CHECK)
1402 fprintf(file, "\n{");
1403 else
1404 fprintf(file, "\n{\n");
1405 if (content->value.blockValue)
1406 {
1407 LSL_Statement *statement = NULL;
1408
1409 EINA_CLIST_FOR_EACH_ENTRY(statement, &(content->value.blockValue->statements), LSL_Statement, statement)
1410 {
1411 outputRawStatement(file, mode, statement);
1412 }
1413 }
1414 if (LUASL_DIFF_CHECK)
1415 fprintf(file, "\n}");
1416 else
1417 fprintf(file, "}");
1218 } 1418 }
1219} 1419}
1220 1420
diff --git a/LuaSL/src/LuaSL_lemon_yaccer.y b/LuaSL/src/LuaSL_lemon_yaccer.y
index 42b02c7..f5b5981 100644
--- a/LuaSL/src/LuaSL_lemon_yaccer.y
+++ b/LuaSL/src/LuaSL_lemon_yaccer.y
@@ -42,7 +42,7 @@ functionList(A) ::= functionList(B) functionBody(C). { A = collectStatements(
42//functionList(A) ::= functionBody(C). { A = collectStatements(compiler, NULL, C); } 42//functionList(A) ::= functionBody(C). { A = collectStatements(compiler, NULL, C); }
43functionList(A) ::= . { A = collectStatements(compiler, NULL, NULL); } 43functionList(A) ::= . { A = collectStatements(compiler, NULL, NULL); }
44 44
45functionBody(A) ::= function(B) funcBlock(C). { A = addFunctionBody(compiler, B, C); } 45functionBody(A) ::= function(F) funcBlock(B). { A = addFunctionBody(compiler, F, B); } // addFunctionBody has an implied addStatement(compiler, NULL, LSL_FUNCTION, NULL, B, NULL, NULL);
46 46
47parameterList(A) ::= parameterList(B) LSL_COMMA(C) parameter(D). { A = collectParameters(compiler, B, C, D); } 47parameterList(A) ::= parameterList(B) LSL_COMMA(C) parameter(D). { A = collectParameters(compiler, B, C, D); }
48parameterList(A) ::= parameter(D). { A = collectParameters(compiler, NULL, NULL, D); } 48parameterList(A) ::= parameter(D). { A = collectParameters(compiler, NULL, NULL, D); }
@@ -67,26 +67,26 @@ statementList(A) ::= . { A = collectStatements(compiler, NULL, NULL); }
67 67
68%nonassoc LSL_DO LSL_FOR LSL_ELSE_IF LSL_IF LSL_JUMP LSL_RETURN LSL_STATE_CHANGE LSL_WHILE. 68%nonassoc LSL_DO LSL_FOR LSL_ELSE_IF LSL_IF LSL_JUMP LSL_RETURN LSL_STATE_CHANGE LSL_WHILE.
69%nonassoc LSL_ELSE. 69%nonassoc LSL_ELSE.
70statement ::= LSL_DO block LSL_WHILE LSL_PARENTHESIS_OPEN expr LSL_PARENTHESIS_CLOSE LSL_STATEMENT. 70statement(A) ::= LSL_DO(F) block(B) LSL_WHILE(W) LSL_PARENTHESIS_OPEN(L) expr(E) LSL_PARENTHESIS_CLOSE(R) LSL_STATEMENT(S). { A = addStatement(compiler, S, F->token->type, L, E, R, B, W); }
71statement ::= LSL_FOR LSL_PARENTHESIS_OPEN expr LSL_STATEMENT expr LSL_STATEMENT expr LSL_PARENTHESIS_CLOSE block. 71statement(A) ::= LSL_FOR(F) LSL_PARENTHESIS_OPEN(L) expr(E0) LSL_STATEMENT(S0) expr(E1) LSL_STATEMENT(S1) expr(E2) LSL_PARENTHESIS_CLOSE(R) block(B). { A = addStatement(compiler, NULL, F->token->type, L, NULL, R, B, NULL); } // three expressions, two semi colons
72 72
73ifBlock ::= ifBlock LSL_ELSE block. 73ifBlock ::= ifBlock LSL_ELSE block.
74ifBlock ::= block. 74ifBlock ::= block.
75// The [LSL_ELSE] part causes a conflict. 75// The [LSL_ELSE] part causes a conflict.
76statement ::= LSL_IF LSL_PARENTHESIS_OPEN expr LSL_PARENTHESIS_CLOSE ifBlock. [LSL_ELSE] 76statement(A) ::= LSL_IF(F) LSL_PARENTHESIS_OPEN(L) expr(E) LSL_PARENTHESIS_CLOSE(R) ifBlock(B). [LSL_ELSE] { A = addStatement(compiler, NULL, F->token->type, L, E, R, B, NULL); } // optional else, optional else if
77 77
78statement ::= LSL_JUMP LSL_IDENTIFIER LSL_STATEMENT. 78statement(A) ::= LSL_JUMP(F) LSL_IDENTIFIER(I) LSL_STATEMENT(S). { A = addStatement(compiler, S, F->token->type, NULL, NULL, NULL, NULL, I); }
79statement ::= LSL_RETURN expr LSL_STATEMENT. 79statement(A) ::= LSL_RETURN(F) expr(E) LSL_STATEMENT(S). { A = addStatement(compiler, S, F->token->type, NULL, E, NULL, NULL, NULL); }
80statement ::= LSL_RETURN LSL_STATEMENT. 80statement(A) ::= LSL_RETURN(F) LSL_STATEMENT(S). { A = addStatement(compiler, S, F->token->type, NULL, NULL, NULL, NULL, NULL); }
81statement ::= LSL_STATE_CHANGE LSL_DEFAULT LSL_STATEMENT. 81statement(A) ::= LSL_STATE_CHANGE(F) LSL_DEFAULT(I) LSL_STATEMENT(S). { A = addStatement(compiler, S, F->token->type, NULL, NULL, NULL, NULL, I); }
82statement ::= LSL_STATE_CHANGE LSL_IDENTIFIER LSL_STATEMENT. 82statement(A) ::= LSL_STATE_CHANGE(F) LSL_IDENTIFIER(I) LSL_STATEMENT(S). { A = addStatement(compiler, S, F->token->type, NULL, NULL, NULL, NULL, I); }
83statement ::= LSL_WHILE LSL_PARENTHESIS_OPEN expr LSL_PARENTHESIS_CLOSE block. 83statement(A) ::= LSL_WHILE(F) LSL_PARENTHESIS_OPEN(L) expr(E) LSL_PARENTHESIS_CLOSE(R) block(B). { A = addStatement(compiler, NULL, F->token->type, L, E, R, B, NULL); }
84 84
85%nonassoc LSL_LABEL. 85%nonassoc LSL_LABEL.
86statement ::= LSL_LABEL LSL_IDENTIFIER LSL_STATEMENT. 86statement(A) ::= LSL_LABEL(F) LSL_IDENTIFIER(I) LSL_STATEMENT(S). { A = addStatement(compiler, S, F->token->type, NULL, NULL, NULL, NULL, I); }
87 87
88// This might be bogus, or might be valid LSL, but it let us test the expression parser by evaluating them. 88// This might be bogus, or might be valid LSL, but it let us test the expression parser by evaluating them.
89statement(A) ::= expr(B) LSL_STATEMENT(D). { A = addStatement(D, LSL_EXPRESSION, B); } 89statement(A) ::= expr(E) LSL_STATEMENT(S). { A = addStatement(compiler, S, LSL_EXPRESSION, NULL, E, NULL, NULL, NULL); }
90 90
91// Various forms of expression. 91// Various forms of expression.
92 92
@@ -171,8 +171,8 @@ expr(A) ::= identifier(B) LSL_ASSIGNMENT_PLAIN(C) expr(D). { A = addOperation(c
171 171
172// 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. 172// 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.
173// Well, not in OpenSim at least, nor in SL. So we are safe. B-) 173// Well, not in OpenSim at least, nor in SL. So we are safe. B-)
174statement(A) ::= type(B) LSL_IDENTIFIER(C) LSL_ASSIGNMENT_PLAIN(D) expr(E) LSL_STATEMENT(F). { A = addStatement(F, LSL_IDENTIFIER, addVariable(compiler, B, C, D, E)); } 174statement(A) ::= type(T) LSL_IDENTIFIER(I) LSL_ASSIGNMENT_PLAIN(D) expr(E) LSL_STATEMENT(S). { A = addStatement(compiler, S, LSL_IDENTIFIER, NULL, addVariable(compiler, T, I, D, E), NULL, NULL, I); }
175statement(A) ::= type(B) LSL_IDENTIFIER(C) LSL_STATEMENT(F). { A = addStatement(F, LSL_IDENTIFIER, addVariable(compiler, B, C, NULL, NULL)); } 175statement(A) ::= type(T) LSL_IDENTIFIER(I) LSL_STATEMENT(S). { A = addStatement(compiler, S, LSL_IDENTIFIER, NULL, addVariable(compiler, T, I, NULL, NULL), NULL, NULL, I); }
176 176
177%right LSL_DOT LSL_IDENTIFIER LSL_FUNCTION_CALL. 177%right LSL_DOT LSL_IDENTIFIER LSL_FUNCTION_CALL.
178identifier(A) ::= identifier LSL_DOT LSL_IDENTIFIER(B). { A = checkVariable(compiler, B); A->basicType = OT_float; } // Just a stub to get it to work for now. 178identifier(A) ::= identifier LSL_DOT LSL_IDENTIFIER(B). { A = checkVariable(compiler, B); A->basicType = OT_float; } // Just a stub to get it to work for now.