aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/LuaSL
diff options
context:
space:
mode:
authorDavid Walter Seikel2012-01-21 18:50:51 +1000
committerDavid Walter Seikel2012-01-21 18:50:51 +1000
commit4ef9d7848f126f1c982a5aae7cb27e18ab2b8aa3 (patch)
treee987c5bcc2e5b7f639aea24d1e4f60511c3afd02 /LuaSL
parentStandardise error messages. (diff)
downloadSledjHamr-4ef9d7848f126f1c982a5aae7cb27e18ab2b8aa3.zip
SledjHamr-4ef9d7848f126f1c982a5aae7cb27e18ab2b8aa3.tar.gz
SledjHamr-4ef9d7848f126f1c982a5aae7cb27e18ab2b8aa3.tar.bz2
SledjHamr-4ef9d7848f126f1c982a5aae7cb27e18ab2b8aa3.tar.xz
More function call, and first part of dealing with using functions before declaring them.
Diffstat (limited to 'LuaSL')
-rw-r--r--LuaSL/src/LuaSL_LSL_tree.h75
-rw-r--r--LuaSL/src/LuaSL_compile.c77
2 files changed, 103 insertions, 49 deletions
diff --git a/LuaSL/src/LuaSL_LSL_tree.h b/LuaSL/src/LuaSL_LSL_tree.h
index 21fc696..d537948 100644
--- a/LuaSL/src/LuaSL_LSL_tree.h
+++ b/LuaSL/src/LuaSL_LSL_tree.h
@@ -29,16 +29,17 @@
29// http://w-hat.com/stackdepth is a useful discussion about some aspects of the LL parser. 29// http://w-hat.com/stackdepth is a useful discussion about some aspects of the LL parser.
30 30
31 31
32typedef struct _allowedTypes allowedTypes; 32typedef struct _allowedTypes allowedTypes;
33typedef struct _LSL_Token LSL_Token; 33typedef struct _LSL_Token LSL_Token;
34typedef struct _LSL_Leaf LSL_Leaf; 34typedef struct _LSL_Leaf LSL_Leaf;
35typedef struct _LSL_Parenthesis LSL_Parenthesis; 35typedef struct _LSL_Parenthesis LSL_Parenthesis;
36typedef struct _LSL_Identifier LSL_Identifier; 36typedef struct _LSL_Identifier LSL_Identifier;
37typedef struct _LSL_Statement LSL_Statement; 37typedef struct _LSL_Statement LSL_Statement;
38typedef struct _LSL_Block LSL_Block; 38typedef struct _LSL_Block LSL_Block;
39typedef struct _LSL_Function LSL_Function; 39typedef struct _LSL_Function LSL_Function;
40typedef struct _LSL_State LSL_State; 40typedef struct _LSL_FunctionCall LSL_FunctionCall;
41typedef struct _LSL_Script LSL_Script; 41typedef struct _LSL_State LSL_State;
42typedef struct _LSL_Script LSL_Script;
42 43
43extern LSL_Token **tokens; 44extern LSL_Token **tokens;
44extern int lowestToken; 45extern int lowestToken;
@@ -108,6 +109,7 @@ typedef enum
108 OT_vectorRotation, 109 OT_vectorRotation,
109 OT_rotationRotation, 110 OT_rotationRotation,
110 OT_otherOther, 111 OT_otherOther,
112 OT_undeclared,
111 OT_invalid 113 OT_invalid
112} opType; 114} opType;
113 115
@@ -148,30 +150,31 @@ struct _LSL_Token
148 150
149struct _LSL_Leaf 151struct _LSL_Leaf
150{ 152{
151 LSL_Leaf *left; 153 LSL_Leaf *left;
152 LSL_Leaf *right; 154 LSL_Leaf *right;
153 LSL_Token *token; 155 LSL_Token *token;
154#ifdef LUASL_DIFF_CHECK 156#ifdef LUASL_DIFF_CHECK
155 Eina_Strbuf *ignorableText; 157 Eina_Strbuf *ignorableText;
156#endif 158#endif
157 int line, column, len; 159 int line, column, len;
158 opType basicType; 160 opType basicType;
159 union 161 union
160 { 162 {
161 float floatValue; 163 float floatValue;
162 float vectorValue[3]; 164 float vectorValue[3];
163 float rotationValue[4]; 165 float rotationValue[4];
164 int integerValue; 166 int integerValue;
165 LSL_Leaf *listValue; 167 LSL_Leaf *listValue;
166 const char *stringValue; 168 const char *stringValue;
167 opType operationValue; 169 opType operationValue;
168 LSL_Parenthesis *parenthesis; 170 LSL_Parenthesis *parenthesis;
169 LSL_Identifier *identifierValue; 171 LSL_Identifier *identifierValue;
170 LSL_Statement *statementValue; 172 LSL_Statement *statementValue;
171 LSL_Block *blockValue; 173 LSL_Block *blockValue;
172 LSL_Function *functionValue; 174 LSL_Function *functionValue;
173 LSL_State *stateValue; 175 LSL_FunctionCall *functionCallValue;
174 LSL_Script *scriptValue; 176 LSL_State *stateValue;
177 LSL_Script *scriptValue;
175 } value; 178 } value;
176}; 179};
177 180
@@ -216,6 +219,14 @@ struct _LSL_Function
216 LSL_Leaf *block; 219 LSL_Leaf *block;
217}; 220};
218 221
222struct _LSL_FunctionCall
223{
224 LSL_Function *function;
225 Eina_Inarray params; // Eina Inarray has not been released yet (Eina 1.2).
226 Eina_Clist functionCall;
227 LSL_Leaf *call;
228};
229
219struct _LSL_State 230struct _LSL_State
220{ 231{
221 const char *name; 232 const char *name;
@@ -312,8 +323,10 @@ typedef struct
312 Eina_Strbuf *ignorableText; 323 Eina_Strbuf *ignorableText;
313#endif 324#endif
314 LSL_Leaf *lval; 325 LSL_Leaf *lval;
315 int column, line;
316 LSL_Block *currentBlock; 326 LSL_Block *currentBlock;
327 Eina_Clist danglingCalls;
328 int column, line;
329 int undeclared;
317} LuaSL_compiler; 330} LuaSL_compiler;
318 331
319 332
diff --git a/LuaSL/src/LuaSL_compile.c b/LuaSL/src/LuaSL_compile.c
index 06c55ef..a410152 100644
--- a/LuaSL/src/LuaSL_compile.c
+++ b/LuaSL/src/LuaSL_compile.c
@@ -185,6 +185,7 @@ allowedTypes allowed[] =
185 {OT_rotation, "rotation", (ST_MULTIPLY | ST_ADD | ST_SUBTRACT | ST_EQUALITY | ST_CONCATENATION | ST_ASSIGNMENT)}, // rotation rotation * / + - == != = += -= *= /= 185 {OT_rotation, "rotation", (ST_MULTIPLY | ST_ADD | ST_SUBTRACT | ST_EQUALITY | ST_CONCATENATION | ST_ASSIGNMENT)}, // rotation rotation * / + - == != = += -= *= /=
186 186
187 {OT_other, "other", (ST_NONE)}, // 187 {OT_other, "other", (ST_NONE)}, //
188 {OT_undeclared, "undeclared", (ST_NONE)}, //
188 {OT_invalid, "invalid", (ST_NONE)} // 189 {OT_invalid, "invalid", (ST_NONE)} //
189}; 190};
190 191
@@ -291,22 +292,6 @@ static LSL_Leaf *findVariable(LuaSL_compiler *compiler, const char *name)
291 return var; 292 return var;
292} 293}
293 294
294// TODO - Damn, you can reference functions declared later.
295LSL_Leaf *checkFunction(LuaSL_compiler *compiler, LSL_Leaf *identifier)
296{
297 gameGlobals *game = compiler->game;
298 LSL_Leaf *func = findFunction(compiler, identifier->value.stringValue);
299
300 if (NULL == func)
301 PE("NOT found %s @ line %d column %d!", identifier->value.stringValue, identifier->line, identifier->column);
302#ifdef LUASL_DEBUG
303 else
304 PI("Found %s!", identifier->value.stringValue);
305#endif
306
307 return func;
308}
309
310LSL_Leaf *checkVariable(LuaSL_compiler *compiler, LSL_Leaf *identifier) 295LSL_Leaf *checkVariable(LuaSL_compiler *compiler, LSL_Leaf *identifier)
311{ 296{
312 gameGlobals *game = compiler->game; 297 gameGlobals *game = compiler->game;
@@ -351,6 +336,11 @@ LSL_Leaf *addOperation(LuaSL_compiler *compiler, LSL_Leaf *left, LSL_Leaf *lval,
351 } 336 }
352 else 337 else
353 lType = left->basicType; 338 lType = left->basicType;
339 if (OT_undeclared == lType)
340 {
341 lval->basicType = OT_undeclared;
342 return lval;
343 }
354 if (OT_vector < lType) 344 if (OT_vector < lType)
355 lType = allowed[lType].result; 345 lType = allowed[lType].result;
356 } 346 }
@@ -367,6 +357,11 @@ LSL_Leaf *addOperation(LuaSL_compiler *compiler, LSL_Leaf *left, LSL_Leaf *lval,
367 } 357 }
368 else 358 else
369 rType = right->basicType; 359 rType = right->basicType;
360 if (OT_undeclared == rType)
361 {
362 lval->basicType = OT_undeclared;
363 return lval;
364 }
370 if (OT_vector < rType) 365 if (OT_vector < rType)
371 rType = allowed[rType].result; 366 rType = allowed[rType].result;
372 } 367 }
@@ -537,16 +532,35 @@ LSL_Leaf *addFunctionBody(LuaSL_compiler *compiler, LSL_Leaf *function, LSL_Leaf
537 532
538LSL_Leaf *addFunctionCall(LuaSL_compiler *compiler, LSL_Leaf *identifier, LSL_Leaf *open, LSL_Leaf *params, LSL_Leaf *close) 533LSL_Leaf *addFunctionCall(LuaSL_compiler *compiler, LSL_Leaf *identifier, LSL_Leaf *open, LSL_Leaf *params, LSL_Leaf *close)
539{ 534{
540 LSL_Leaf *func = checkFunction(compiler, identifier); 535 LSL_Leaf *func = findFunction(compiler, identifier->value.stringValue);
536 LSL_FunctionCall *call = calloc(1, sizeof(LSL_FunctionCall));
541 537
542 identifier->token = tokens[LSL_UNKNOWN - lowestToken]; 538 identifier->token = tokens[LSL_UNKNOWN - lowestToken];
543 539
544 if (func) 540 if (func)
545 { 541 {
546 // TODO - Add some structure here to hold the params. 542 if (call)
543 {
544 call->function = func->value.functionValue;
545 eina_clist_element_init(&(call->functionCall));
546 call->call = identifier;
547 }
548 identifier->value.functionCallValue = call;
549 // TODO - Put the params in call.
547 identifier->token = tokens[LSL_FUNCTION_CALL - lowestToken]; 550 identifier->token = tokens[LSL_FUNCTION_CALL - lowestToken];
548 identifier->basicType = func->basicType; 551 identifier->basicType = func->basicType;
549 } 552 }
553 else
554 {
555 // It may be declared later, so store it and check later.
556 if (call)
557 {
558 eina_clist_add_tail(&(compiler->danglingCalls), &(call->functionCall));
559 call->call = identifier;
560 }
561 identifier->basicType = OT_undeclared;
562 compiler->undeclared = TRUE;
563 }
550 564
551 return identifier; 565 return identifier;
552} 566}
@@ -1235,6 +1249,7 @@ Eina_Bool compileLSL(gameGlobals *game, char *script, boolean doConstants)
1235 compiler.script.functions = eina_hash_stringshared_new(burnLeaf); 1249 compiler.script.functions = eina_hash_stringshared_new(burnLeaf);
1236 compiler.script.states = eina_hash_stringshared_new(burnLeaf); 1250 compiler.script.states = eina_hash_stringshared_new(burnLeaf);
1237 compiler.script.variables = eina_hash_stringshared_new(burnLeaf); 1251 compiler.script.variables = eina_hash_stringshared_new(burnLeaf);
1252 eina_clist_init(&(compiler.danglingCalls));
1238#ifdef LUASL_DIFF_CHECK 1253#ifdef LUASL_DIFF_CHECK
1239 compiler.ignorableText = eina_strbuf_new(); 1254 compiler.ignorableText = eina_strbuf_new();
1240#endif 1255#endif
@@ -1274,6 +1289,32 @@ Eina_Bool compileLSL(gameGlobals *game, char *script, boolean doConstants)
1274 Parse (pParser, 0, compiler.lval, &compiler); 1289 Parse (pParser, 0, compiler.lval, &compiler);
1275 ParseFree(pParser, free); 1290 ParseFree(pParser, free);
1276 1291
1292 if (compiler.undeclared)
1293 {
1294 PI("A second pass will be needed to check if functions where declared after they where used. To avoid this second pass, don't do that.");
1295 if (eina_clist_count(&(compiler.danglingCalls)))
1296 {
1297 LSL_FunctionCall *call = NULL;
1298
1299 EINA_CLIST_FOR_EACH_ENTRY(call, &(compiler.danglingCalls), LSL_FunctionCall, functionCall)
1300 {
1301 LSL_Leaf *func = findFunction(&(compiler), call->call->value.stringValue);
1302
1303 if (func)
1304 {
1305 call->function = func->value.functionValue;
1306 call->call->value.functionCallValue = call;
1307 call->call->token = tokens[LSL_FUNCTION_CALL - lowestToken];
1308 call->call->basicType = func->basicType;
1309 }
1310 else
1311 PE("Undeclared function %s called @ line %d, column %d!", call->call->value.stringValue, call->call->line, call->call->column);
1312 }
1313 }
1314// TODO - Run through the expressions, cleaning up the function calls.
1315 PI("Second pass completed.");
1316 }
1317
1277 if (doConstants) 1318 if (doConstants)
1278 { 1319 {
1279 memcpy(&constants, &(compiler.script), sizeof(LSL_Script)); 1320 memcpy(&constants, &(compiler.script), sizeof(LSL_Script));