aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/LuaSL/src/LuaSL_compile.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--LuaSL/src/LuaSL_compile.c1126
1 files changed, 1126 insertions, 0 deletions
diff --git a/LuaSL/src/LuaSL_compile.c b/LuaSL/src/LuaSL_compile.c
index 679af3d..01657bc 100644
--- a/LuaSL/src/LuaSL_compile.c
+++ b/LuaSL/src/LuaSL_compile.c
@@ -1,13 +1,996 @@
1#include "LuaSL.h" 1#include "LuaSL.h"
2#include "LuaSL_LSL_tree.h"
2 3
3 4
5static LSL_Leaf *evaluateFloatToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right);
6static LSL_Leaf *evaluateIntegerToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right);
7static LSL_Leaf *evaluateNoToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right);
8static LSL_Leaf *evaluateOperationToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right);
9static LSL_Leaf *eveluateParenthesisToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right);
10static LSL_Leaf *evaluateStatementToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right);
11static void outputFloatToken(FILE *file, outputMode mode, LSL_Leaf *content);
12static void outputFunctionToken(FILE *file, outputMode mode, LSL_Leaf *content);
13static void outputIntegerToken(FILE *file, outputMode mode, LSL_Leaf *content);
14static void outputParameterToken(FILE *file, outputMode mode, LSL_Leaf *content);
15static void outputParameterListToken(FILE *file, outputMode mode, LSL_Leaf *content);
16static void outputParenthesisToken(FILE *file, outputMode mode, LSL_Leaf *content);
17static void outputStateToken(FILE *file, outputMode mode, LSL_Leaf *content);
18static void outputStatementToken(FILE *file, outputMode mode, LSL_Leaf *content);
19static void outputVariableToken(FILE *file, outputMode mode, LSL_Leaf *content);
20
21LSL_Token LSL_Tokens[] =
22{
23 // Various forms of "space".
24 {LSL_COMMENT, ST_NONE, "/*", LSL_NONE, NULL, NULL},
25 {LSL_COMMENT_LINE, ST_NONE, "//", LSL_NONE, NULL, NULL},
26 {LSL_SPACE, ST_NONE, " ", LSL_NONE, NULL, NULL},
27
28 // Operators, in order of precedence, low to high
29 // Left to right, unless otherwise stated.
30 // According to http://wiki.secondlife.com/wiki/Category:LSL_Operators
31 {LSL_BOOL_AND, ST_BOOLEAN, "&&", LSL_RIGHT2LEFT, NULL, evaluateOperationToken},
32// QUIRK - Seems to be some disagreement about BOOL_AND/BOOL_OR precedence. Either they are equal, or OR is higher.
33// QUIRK - No boolean short circuiting.
34// QUIRK - Booleans and conditionals are executed right to left. Or maybe not, depending on who you believe.
35 {LSL_BOOL_OR, ST_BOOLEAN, "||", LSL_RIGHT2LEFT, NULL, evaluateOperationToken},
36 {LSL_BIT_OR, ST_BITWISE, "|", LSL_LEFT2RIGHT, NULL, evaluateOperationToken},
37 {LSL_BIT_XOR, ST_BITWISE, "^", LSL_LEFT2RIGHT, NULL, evaluateOperationToken},
38 {LSL_BIT_AND, ST_BITWISE, "&", LSL_LEFT2RIGHT, NULL, evaluateOperationToken},
39// QUIRK - Booleans and conditionals are executed right to left. Or maybe not, depending on who you believe.
40 {LSL_NOT_EQUAL, ST_EQUALITY, "!=", LSL_RIGHT2LEFT, NULL, evaluateOperationToken},
41 {LSL_EQUAL, ST_EQUALITY, "==", LSL_RIGHT2LEFT, NULL, evaluateOperationToken},
42 {LSL_GREATER_EQUAL, ST_COMPARISON, ">=", LSL_RIGHT2LEFT, NULL, evaluateOperationToken},
43 {LSL_LESS_EQUAL, ST_COMPARISON, "<=", LSL_RIGHT2LEFT, NULL, evaluateOperationToken},
44 {LSL_GREATER_THAN, ST_COMPARISON, ">", LSL_RIGHT2LEFT, NULL, evaluateOperationToken},
45 {LSL_LESS_THAN, ST_COMPARISON, "<", LSL_RIGHT2LEFT, NULL, evaluateOperationToken},
46 {LSL_RIGHT_SHIFT, ST_BITWISE, ">>", LSL_LEFT2RIGHT, NULL, evaluateOperationToken},
47 {LSL_LEFT_SHIFT, ST_BITWISE, "<<", LSL_LEFT2RIGHT, NULL, evaluateOperationToken},
48 {LSL_CONCATENATE, ST_ADD, "+", LSL_LEFT2RIGHT, NULL, evaluateOperationToken},
49 {LSL_ADD, ST_ADD, "+", LSL_LEFT2RIGHT, NULL, evaluateOperationToken},
50 {LSL_SUBTRACT, ST_SUBTRACT, "-", LSL_LEFT2RIGHT, NULL, evaluateOperationToken},
51 {LSL_CROSS_PRODUCT, ST_NONE, "%", LSL_LEFT2RIGHT, NULL, evaluateOperationToken},
52 {LSL_DOT_PRODUCT, ST_NONE, "*", LSL_LEFT2RIGHT, NULL, evaluateOperationToken},
53 {LSL_MULTIPLY, ST_MULTIPLY, "*", LSL_LEFT2RIGHT, NULL, evaluateOperationToken},
54 {LSL_MODULO, ST_MODULO, "%", LSL_LEFT2RIGHT, NULL, evaluateOperationToken},
55 {LSL_DIVIDE, ST_MULTIPLY, "/", LSL_LEFT2RIGHT, NULL, evaluateOperationToken},
56 {LSL_NEGATION, ST_NEGATE, "-", LSL_RIGHT2LEFT | LSL_UNARY, NULL, evaluateOperationToken},
57 {LSL_BOOL_NOT, ST_BOOL_NOT, "!", LSL_RIGHT2LEFT | LSL_UNARY, NULL, evaluateOperationToken},
58 {LSL_BIT_NOT, ST_BIT_NOT, "~", LSL_RIGHT2LEFT | LSL_UNARY, NULL, evaluateOperationToken},
59 {LSL_TYPECAST_CLOSE, ST_NONE, ")", LSL_RIGHT2LEFT | LSL_UNARY, NULL, evaluateNoToken},
60 {LSL_TYPECAST_OPEN, ST_NONE, "(", LSL_RIGHT2LEFT | LSL_UNARY, NULL, evaluateOperationToken},
61 {LSL_ANGLE_CLOSE, ST_NONE, ">", LSL_LEFT2RIGHT | LSL_CREATION, NULL, evaluateNoToken},
62 {LSL_ANGLE_OPEN, ST_NONE, "<", LSL_LEFT2RIGHT | LSL_CREATION, NULL, evaluateOperationToken},
63 {LSL_BRACKET_CLOSE, ST_NONE, "]", LSL_INNER2OUTER | LSL_CREATION, NULL, evaluateNoToken},
64 {LSL_BRACKET_OPEN, ST_NONE, "[", LSL_INNER2OUTER | LSL_CREATION, NULL, evaluateOperationToken},
65 {LSL_PARENTHESIS_CLOSE, ST_NONE, ")", LSL_INNER2OUTER, NULL, evaluateNoToken},
66 {LSL_PARENTHESIS_OPEN, ST_NONE, "(", LSL_INNER2OUTER, outputParenthesisToken, eveluateParenthesisToken},
67 {LSL_ASSIGNMENT_CONCATENATE,ST_CONCATENATION, "+=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, evaluateOperationToken},
68 {LSL_ASSIGNMENT_ADD, ST_CONCATENATION, "+=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, evaluateOperationToken},
69 {LSL_ASSIGNMENT_SUBTRACT, ST_ASSIGNMENT, "-=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, evaluateOperationToken},
70 {LSL_ASSIGNMENT_MULTIPLY, ST_ASSIGNMENT, "*=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, evaluateOperationToken},
71 {LSL_ASSIGNMENT_MODULO, ST_MODULO, "%=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, evaluateOperationToken},
72 {LSL_ASSIGNMENT_DIVIDE, ST_ASSIGNMENT, "/=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, evaluateOperationToken},
73 {LSL_ASSIGNMENT_PLAIN, ST_CONCATENATION, "=", LSL_RIGHT2LEFT | LSL_ASSIGNMENT, NULL, evaluateOperationToken},
74 {LSL_DOT, ST_NONE, ".", LSL_RIGHT2LEFT, NULL, evaluateOperationToken},
75 {LSL_DECREMENT_POST, ST_NONE, "--", LSL_RIGHT2LEFT | LSL_UNARY, NULL, evaluateOperationToken},
76 {LSL_DECREMENT_PRE, ST_NONE, "--", LSL_RIGHT2LEFT | LSL_UNARY, NULL, evaluateOperationToken},
77 {LSL_INCREMENT_POST, ST_NONE, "++", LSL_RIGHT2LEFT | LSL_UNARY, NULL, evaluateOperationToken},
78 {LSL_INCREMENT_PRE, ST_NONE, "++", LSL_RIGHT2LEFT | LSL_UNARY, NULL, evaluateOperationToken},
79 {LSL_COMMA, ST_NONE, ",", LSL_LEFT2RIGHT, NULL, evaluateOperationToken},
80
81 {LSL_EXPRESSION, ST_NONE, "expression", LSL_NONE , NULL, NULL},
82
83 // Types.
84 {LSL_FLOAT, ST_NONE, "float", LSL_NONE, outputFloatToken, evaluateFloatToken},
85 {LSL_INTEGER, ST_NONE, "integer", LSL_NONE, outputIntegerToken, evaluateIntegerToken},
86 {LSL_KEY, ST_NONE, "key", LSL_NONE, NULL, NULL},
87 {LSL_LIST, ST_NONE, "list", LSL_NONE, NULL, NULL},
88 {LSL_ROTATION, ST_NONE, "rotation", LSL_NONE, NULL, NULL},
89 {LSL_STRING, ST_NONE, "string", LSL_NONE, NULL, NULL},
90 {LSL_VECTOR, ST_NONE, "vector", LSL_NONE, NULL, NULL},
91
92 // Types names.
93 {LSL_TYPE_FLOAT, ST_NONE, "float", LSL_NONE, NULL, NULL},
94 {LSL_TYPE_INTEGER, ST_NONE, "integer", LSL_NONE, NULL, NULL},
95 {LSL_TYPE_KEY, ST_NONE, "key", LSL_NONE, NULL, NULL},
96 {LSL_TYPE_LIST, ST_NONE, "list", LSL_NONE, NULL, NULL},
97 {LSL_TYPE_ROTATION, ST_NONE, "rotation", LSL_NONE, NULL, NULL},
98 {LSL_TYPE_STRING, ST_NONE, "string", LSL_NONE, NULL, NULL},
99 {LSL_TYPE_VECTOR, ST_NONE, "vector", LSL_NONE, NULL, NULL},
100
101 // Then the rest of the syntax tokens.
102 {LSL_IDENTIFIER, ST_NONE, "identifier", LSL_NONE, outputVariableToken, NULL},
103
104 {LSL_LABEL, ST_NONE, "@", LSL_NONE, NULL, NULL},
105
106 {LSL_DO, ST_NONE, "do", LSL_NONE, NULL, NULL},
107 {LSL_FOR, ST_NONE, "for", LSL_NONE, NULL, NULL},
108 {LSL_ELSE_IF, ST_NONE, "else if", LSL_NONE, NULL, NULL},
109 {LSL_ELSE, ST_NONE, "else", LSL_NONE, NULL, NULL},
110 {LSL_IF, ST_NONE, "if", LSL_NONE, NULL, NULL},
111 {LSL_JUMP, ST_NONE, "jump", LSL_NONE, NULL, NULL},
112 {LSL_RETURN, ST_NONE, "return", LSL_NONE, NULL, NULL},
113 {LSL_STATE_CHANGE, ST_NONE, "state", LSL_NONE, NULL, NULL},
114 {LSL_WHILE, ST_NONE, "while", LSL_NONE, NULL, NULL},
115 {LSL_STATEMENT, ST_NONE, ";", LSL_NOIGNORE, outputStatementToken, evaluateStatementToken},
116
117 {LSL_BLOCK_CLOSE, ST_NONE, "}", LSL_NONE, NULL, NULL},
118 {LSL_BLOCK_OPEN, ST_NONE, "{", LSL_NONE, NULL, NULL},
119 {LSL_PARAMETER, ST_NONE, "parameter", LSL_NONE, outputParameterToken, NULL},
120 {LSL_PARAMETER_LIST, ST_NONE, "plist", LSL_NONE, outputParameterListToken, NULL},
121 {LSL_FUNCTION, ST_NONE, "function", LSL_NONE, outputFunctionToken, NULL},
122 {LSL_STATE, ST_NONE, "state", LSL_NONE, outputStateToken, NULL},
123 {LSL_SCRIPT, ST_NONE, "", LSL_NONE, NULL, NULL},
124
125 {LSL_UNKNOWN, ST_NONE, "unknown", LSL_NONE, NULL, NULL},
126
127 // A sentinal.
128 {999999, ST_NONE, NULL, LSL_NONE, NULL, NULL}
129};
130
131allowedTypes allowed[] =
132{
133 {OT_nothing, "nothing", (ST_NONE)},
134
135 {OT_bool, "boolean", (ST_BOOL_NOT)},
136 {OT_integer, "integer", (ST_BIT_NOT | ST_NEGATE)},
137 {OT_float, "float", (ST_NONE)},
138 {OT_key, "key", (ST_NONE)},
139 {OT_list, "list", (ST_NONE)},
140 {OT_rotation, "rotation", (ST_NONE)},
141 {OT_string, "string", (ST_NONE)},
142 {OT_vector, "vector", (ST_NONE)},
143 {OT_other, "other", (ST_NONE)},
144
145 {OT_bool, "boolean", (ST_BOOLEAN | ST_EQUALITY)},
146 {OT_integer, "integer", (ST_MULTIPLY | ST_ADD | ST_SUBTRACT | ST_EQUALITY | ST_COMPARISON | ST_CONCATENATION | ST_ASSIGNMENT | ST_MODULO | ST_BITWISE)},
147 {OT_float, "float", (ST_MULTIPLY | ST_ADD | ST_SUBTRACT | ST_EQUALITY | ST_COMPARISON | ST_CONCATENATION | ST_ASSIGNMENT)},
148 {OT_float, "float", (ST_MULTIPLY | ST_ADD | ST_SUBTRACT | ST_EQUALITY | ST_COMPARISON | ST_CONCATENATION | ST_ASSIGNMENT)},
149 {OT_float, "float", (ST_MULTIPLY | ST_ADD | ST_SUBTRACT | ST_EQUALITY | ST_COMPARISON | ST_CONCATENATION | ST_ASSIGNMENT)},
150 {OT_string, "string", (ST_ADD | ST_EQUALITY | ST_CONCATENATION)},
151 {OT_string, "string", (ST_ADD | ST_EQUALITY | ST_CONCATENATION)},
152 {OT_string, "string", (ST_ADD | ST_EQUALITY | ST_CONCATENATION)},
153 {OT_list, "list", (ST_ADD | ST_EQUALITY | ST_CONCATENATION)},
154 {OT_list, "list", (ST_ADD | ST_COMPARISON | ST_CONCATENATION)},
155 {OT_list, "list", (ST_ADD | ST_COMPARISON | ST_CONCATENATION)},
156 {OT_integer, "integer", (ST_ADD | ST_COMPARISON)},
157 {OT_float, "float", (ST_ADD | ST_COMPARISON)},
158 {OT_list, "list", (ST_ADD | ST_CONCATENATION)},
159 {OT_vector, "vector", (ST_MULTIPLY | ST_ADD | ST_SUBTRACT | ST_EQUALITY | ST_CONCATENATION | ST_ASSIGNMENT | ST_MODULO)},
160 {OT_vector, "vector", (ST_MULTIPLY)},
161 {OT_vector, "vector", (ST_MULTIPLY)},
162 {OT_rotation, "rotation", (ST_MULTIPLY | ST_ADD | ST_SUBTRACT | ST_EQUALITY | ST_CONCATENATION | ST_ASSIGNMENT)},
163 {OT_other, "other", (ST_NONE)},
164 {OT_invalid, "invalid", (ST_NONE)}
165};
166
167opType opExpr[][10] =
168{
169 {OT_nothing, OT_bool, OT_integer, OT_float, OT_key, OT_list, OT_rotation, OT_string, OT_vector, OT_other},
170 {OT_bool, OT_boolBool, OT_invalid, OT_invalid, OT_invalid, OT_invalid, OT_invalid, OT_invalid, OT_invalid, OT_invalid},
171 {OT_integer, OT_invalid, OT_intInt, OT_intFloat, OT_invalid, OT_intList, OT_invalid, OT_invalid, OT_invalid, OT_invalid},
172 {OT_float, OT_invalid, OT_floatInt, OT_floatFloat, OT_invalid, OT_floatList, OT_invalid, OT_invalid, OT_invalid, OT_invalid},
173 {OT_key, OT_invalid, OT_invalid, OT_invalid, OT_invalid, OT_invalid, OT_invalid, OT_keyString, OT_invalid, OT_invalid},
174 {OT_list, OT_invalid, OT_listInt, OT_listFloat, OT_invalid, OT_listList, OT_invalid, OT_invalid, OT_invalid, OT_listOther},
175 {OT_rotation, OT_invalid, OT_invalid, OT_invalid, OT_invalid, OT_invalid, OT_rotationRotation, OT_invalid, OT_invalid, OT_invalid},
176 {OT_string, OT_invalid, OT_invalid, OT_invalid, OT_stringKey, OT_invalid, OT_invalid, OT_stringString, OT_invalid, OT_invalid},
177 {OT_vector, OT_invalid, OT_invalid, OT_vectorFloat, OT_invalid, OT_invalid, OT_vectorRotation, OT_invalid, OT_vectorVector, OT_invalid},
178 {OT_other, OT_invalid, OT_invalid, OT_invalid, OT_invalid, OT_invalid, OT_invalid, OT_invalid, OT_invalid, OT_otherOther}
179
180};
181
182
183LSL_Token **tokens = NULL;
184int lowestToken = 999999;
185
186
187static LSL_Leaf *newLeaf(LSL_Type type, LSL_Leaf *left, LSL_Leaf *right)
188{
189 LSL_Leaf *leaf = calloc(1, sizeof(LSL_Leaf));
190
191 if (leaf)
192 {
193 leaf->left = left;
194 leaf->right = right;
195 leaf->token = tokens[type - lowestToken];
196 }
197
198 return leaf;
199}
200
201void burnLeaf(LSL_Leaf *leaf)
202{
203 if (leaf)
204 {
205 burnLeaf(leaf->left);
206 burnLeaf(leaf->right);
207 // TODO - Should free up the value to.
208 free(leaf->ignorableText);
209 free(leaf);
210 }
211}
212
213LSL_Leaf *addOperation(LSL_Leaf *left, LSL_Leaf *lval, LSL_Leaf *right)
214{
215 if (lval)
216 {
217 opType lType, rType;
218
219 lval->left = left;
220 lval->right = right;
221
222 // Try to figure out what type of operation this is.
223 if (NULL == left)
224 lType = OT_nothing;
225 else
226 {
227 lType = left->basicType;
228 if (OT_vector < lType)
229 lType = allowed[lType].result;
230 }
231 if (NULL == right)
232 rType = OT_nothing;
233 else
234 {
235 rType = right->basicType;
236 if (OT_vector < rType)
237 rType = allowed[rType].result;
238 }
239
240 // The basic lookup.
241 lval->basicType = opExpr[lType][rType];
242 if (OT_invalid != lval->basicType)
243 {
244 // Check if it's an allowed operation.
245 if (0 == (lval->token->subType & allowed[lval->basicType].subTypes))
246 {
247 lval->basicType = OT_invalid;
248 }
249 else
250 {
251 // Double check the corner cases.
252 switch (lval->token->subType)
253 {
254 case ST_BOOLEAN :
255 lval->basicType = OT_bool;
256 break;
257 case ST_COMPARISON :
258 lval->basicType = OT_bool;
259 break;
260 case ST_MULTIPLY :
261 if (OT_vectorVector == lval->basicType)
262 {
263 if (LSL_MULTIPLY == lval->token->type)
264 {
265 lval->basicType = OT_float;
266 lval->token = tokens[LSL_DOT_PRODUCT - lowestToken];
267 }
268 else
269 lval->basicType = OT_vector;
270 }
271 break;
272 default :
273 break;
274 }
275 }
276 }
277 if (OT_invalid == lval->basicType)
278 {
279 char *leftType = "", *rightType = "";
280
281 if (left)
282 leftType = allowed[left->basicType].name;
283 if (right)
284 rightType = allowed[right->basicType].name;
285
286 fprintf(stderr, "Invalid operation [%s %s %s] @ line %d column %d\n", leftType, lval->token->token, rightType, lval->line, lval->column);
287 }
288 }
289
290 return lval;
291}
292
293LSL_Leaf *addParameter(LSL_Leaf *type, LSL_Leaf *identifier)
294{
295 LSL_Identifier *result = calloc(1, sizeof(LSL_Identifier));
296
297 if ( (identifier) && (result))
298 {
299 result->name = identifier->value.stringValue;
300 identifier->value.variableValue = result;
301 identifier->token = tokens[LSL_PARAMETER - lowestToken];
302 identifier->left = type;
303 if (type)
304 {
305 identifier->basicType = type->basicType;
306 result->value.basicType = type->basicType;
307 }
308 }
309 return identifier;
310}
311
312LSL_Leaf *collectParameters(LSL_Leaf *list, LSL_Leaf *comma, LSL_Leaf *newParam)
313{
314 LSL_Leaf *newList = newLeaf(LSL_PARAMETER_LIST, NULL, NULL);
315
316 if (newList)
317 {
318 newList->left = list;
319 newList->value.listValue = newParam;
320 if ((list) && (list->value.listValue))
321 {
322 list->value.listValue->right = comma;
323 }
324 }
325
326 return newList;
327}
328
329LSL_Leaf *addFunction(LSL_Leaf *type, LSL_Leaf *identifier, LSL_Leaf *open, LSL_Leaf *params, LSL_Leaf *close, LSL_Leaf *block)
330{
331 LSL_Function *func = calloc(1, sizeof(LSL_Function));
332
333 if (func)
334 {
335 if (identifier)
336 {
337 char *temp = identifier->value.stringValue;
338
339 identifier->token = tokens[LSL_FUNCTION - lowestToken];
340 identifier->value.functionValue = func;
341 identifier->value.functionValue->name = temp;
342 identifier->value.functionValue->block = block;
343 func->type = type;
344 if (type)
345 identifier->basicType = type->basicType;
346 else
347 identifier->basicType = OT_nothing;
348 func->params = addParenthesis(open, params, LSL_PARAMETER_LIST, close);
349 }
350 }
351 return identifier;
352}
353
354LSL_Leaf *addParenthesis(LSL_Leaf *lval, LSL_Leaf *expr, LSL_Type type, LSL_Leaf *rval)
355{
356 LSL_Parenthesis *parens = malloc(sizeof(LSL_Parenthesis));
357
358 if (parens)
359 {
360 parens->left = lval;
361 parens->contents = expr;
362 parens->type = type;
363 parens->right = rval;
364 if (lval)
365 {
366 lval->value.parenthesis = parens;
367 if (expr)
368 lval->basicType = expr->basicType;
369 }
370 }
371 return lval;
372}
373
374LSL_Leaf *addState(LuaSL_yyparseParam *param, LSL_Leaf *identifier, LSL_Leaf *block)
375{
376 LSL_State *result = calloc(1, sizeof(LSL_State));
377
378 if ((identifier) && (result))
379 {
380 result->name = identifier->value.stringValue;
381 result->block = block;
382 identifier->value.stateValue = result;
383 param->script.scount++;
384 param->script.states = realloc(param->script.states, param->script.scount * sizeof(LSL_State *));
385 param->script.states[param->script.scount - 1] = result;
386 }
387
388 return identifier;
389}
390
391LSL_Leaf *addStatement(LSL_Leaf *lval, LSL_Type type, LSL_Leaf *expr)
392{
393 LSL_Statement *stat = malloc(sizeof(LSL_Statement));
394
395 if (stat)
396 {
397 stat->type = type;
398 stat->expressions = expr;
399 if (lval)
400 lval->value.statementValue = stat;
401 }
402
403 return lval;
404}
405
406LSL_Leaf *addTypecast(LSL_Leaf *lval, LSL_Leaf *type, LSL_Leaf *rval, LSL_Leaf *expr)
407{
408 LSL_Parenthesis *parens = malloc(sizeof(LSL_Parenthesis));
409
410 if (parens)
411 {
412 parens->left = lval;
413 parens->contents = expr;
414 parens->type = LSL_TYPECAST_OPEN;
415 parens->right = rval;
416 if (lval)
417 {
418 lval->value.parenthesis = parens;
419 if (type)
420 lval->basicType = type->basicType;
421 lval->token = tokens[LSL_TYPECAST_OPEN - lowestToken];
422 }
423 if (rval)
424 {
425 rval->token = tokens[LSL_TYPECAST_CLOSE - lowestToken];
426 }
427 }
428 return lval;
429}
430
431LSL_Leaf *addVariable(LuaSL_yyparseParam *param, LSL_Leaf *type, LSL_Leaf *identifier, LSL_Leaf *assignment, LSL_Leaf *expr)
432{
433 LSL_Identifier *result = calloc(1, sizeof(LSL_Identifier));
434
435 if ( (identifier) && (result))
436 {
437 result->name = identifier->value.stringValue;
438 identifier->value.variableValue = result;
439 identifier->left = type;
440 identifier->right = assignment;
441 if (assignment)
442 assignment->right = expr;
443 if (type)
444 {
445 identifier->basicType = type->basicType;
446 result->value.basicType = type->basicType;
447 }
448 if (param->currentBlock)
449 {
450 param->currentBlock->vcount++;
451 param->currentBlock->variables = realloc(param->currentBlock->variables, param->currentBlock->vcount * sizeof(LSL_Identifier *));
452 param->currentBlock->variables[param->currentBlock->vcount - 1] = result;
453 }
454 else
455 {
456 param->script.vcount++;
457 param->script.variables = realloc(param->script.variables, param->script.vcount * sizeof(LSL_Identifier *));
458 param->script.variables[param->script.vcount - 1] = result;
459 }
460 }
461
462 return identifier;
463}
464
465void beginBlock(LuaSL_yyparseParam *param, LSL_Leaf *block)
466{
467 LSL_Block *blok = malloc(sizeof(LSL_Block));
468
469 if (blok)
470 {
471 block->value.blockValue = blok;
472 blok->outerBlock = param->currentBlock;
473 param->currentBlock = blok;
474 }
475}
476
477void endBlock(LuaSL_yyparseParam *param, LSL_Leaf *block)
478{
479 param->currentBlock = param->currentBlock->outerBlock;
480}
481
482static LSL_Leaf *evaluateLeaf(LSL_Leaf *leaf, LSL_Leaf *left, LSL_Leaf *right)
483{
484 LSL_Leaf *result = NULL;
485
486 if (leaf)
487 {
488 LSL_Leaf *lresult = NULL;
489 LSL_Leaf *rresult = NULL;
490
491 if (LSL_RIGHT2LEFT & leaf->token->flags)
492 {
493 rresult = evaluateLeaf(leaf->right, left, right);
494 if (!(LSL_UNARY & leaf->token->flags))
495 lresult = evaluateLeaf(leaf->left, left, right);
496 }
497 else // Assume left to right.
498 {
499 lresult = evaluateLeaf(leaf->left, left, right);
500 if (!(LSL_UNARY & leaf->token->flags))
501 rresult = evaluateLeaf(leaf->right, left, right);
502 }
503
504 if (leaf->token->evaluate)
505 result = leaf->token->evaluate(leaf, lresult, rresult);
506 else
507 {
508 result = calloc(1, sizeof(LSL_Leaf));
509 if (rresult && result)
510 memcpy(result, rresult, sizeof(LSL_Leaf));
511 }
512
513 if (lresult)
514 free(lresult);
515 if (rresult)
516 free(rresult);
517 }
518
519 return result;
520}
521
522static LSL_Leaf *evaluateFloatToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right)
523{
524 LSL_Leaf *result = malloc(sizeof(LSL_Leaf));
525
526 if (content && result)
527 {
528#ifdef LUASL_DEBUG
529 printf(" <%g> ", content->value.floatValue);
530#endif
531 memcpy(result, content, sizeof(LSL_Leaf));
532 result->basicType = OT_float;
533 }
534 return result;
535}
536
537static LSL_Leaf *evaluateIntegerToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right)
538{
539 LSL_Leaf *result = malloc(sizeof(LSL_Leaf));
540
541 if (content && result)
542 {
543#ifdef LUASL_DEBUG
544 printf(" <%d> ", content->value.integerValue);
545#endif
546 memcpy(result, content, sizeof(LSL_Leaf));
547 result->basicType = OT_integer;
548 }
549 return result;
550}
551
552static LSL_Leaf *evaluateNoToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right)
553{
554 // Do nothing, that's the point.
555
556 return content;
557}
558
559/* Typecasting
560
561LSL is statically typed, so stored values are not converted, only the values used in expressions are.
562Lua is dynamically typed, so stored values are changed (sometimes I think).
563
564LSL implicitly typecasts - There is a shitload of QUIRKs about this. Apparently some don't work anyway.
565 integer -> float (Says in lslwiki that precision is never lost, which is bullshit, since they are both 32 bit. Would be true if the float is 64 bit. Lua suggest to use 64 bit floats to emulate 32 bit integers.)
566 string -> key
567 Some functions need help with this or the other way around.
568 string -> vector (Maybe, should test that.)
569 vector -> string (Maybe, should test that.)
570 Also happens when getting stuff from lists.
571
572Explicit type casting -
573 string -> integer
574 Leading spaces are ignored, as are any characters after the run of digits.
575 All other strings convert to 0.
576 Which means "" and " " convert to 0.
577 Strings in hexadecimal format will work.
578 keys <-> string
579 No other typecasting can be done with keys.
580 float -> string
581 You get a bunch of trailing 0s.
582
583QUIRK - I have seen cases where a double explicit typecast was needed in SL, but was considered to be invalid syntax in OS.
584
585Any binary operation involving a float and an integer implicitly casts the integer to float.
586
587A boolean operation deals with TRUE (1) and FALSE (0). Any non zero value is a TRUE (generally sigh).
588Bitwise operations only apply to integers. The shifts are arithmatic, not logical. Right shifted bits are dropped, left shifts the sign bit.
589
590integer = integer0 % integer1; // Apparently only applies to integers, but works fine on floats in OS.
591string = string0 + string1; // Concatenation.
592list = list0 + list1; // Concatenation. Also works if either is not a list, it's promoted to a list first.
593list = (list=[]) + list + ["new_item"]; // Voodoo needed for old LSL, works in Mono but not needed, does not work in OS. Works for strings to.
594bool = list == != int // Only compares the lengths, probably applies to the other conditionals to.
595vector = vector0 + vector1; // Add elements together.
596vector = vector0 - vector1; // Subtract elements of vector1 from elements of vector0.
597float = vector0 * vector1; // A dot product of the vectors.
598vector = vector0 % vector1; // A cross product of the vectors.
599vector = vector * float; // Scale the vector, works the other way around I think. Works for integer to, but it will end up being cast to float.
600vector = vector / float; // Scale the vector, works the other way around I think. Works for integer to, but it will end up being cast to float.
601vector = vector * rotation; // Rotate the vector by the rotation. Other way around wont compile.
602vector = vector / rotation; // Rotate the vector by the rotation, in the opposite direction. Other way around wont compile.
603rotation = llGetRot() * rotation; // Rotate an object around the global axis.
604rotation = rotation * llGetLocalRot(); // Rotate an object around the local axis.
605rotation = rotation0 * rotation1; // Add two rotations, so the result is as if you applied each rotation one after the other.
606 // Division rotates in the opposite direction.
607rotation = rotation0 + rotation1; // Similar to vector, but it's a meaningless thing as far as rotations go.
608rotation = rotation0 - rotation1; // Similar to vector, but it's a meaningless thing as far as rotations go.
609
610A boolean operator results in a boolean value. (any types)
611A comparison operator results in a boolean value. (any types)
612A bitwise operator results in an integer value. (intInt or int)
613A dot product operator results in a float value. (vector * vector)
614A vectorFloat results in a vector value.
615
616*/
617
618static LSL_Leaf *evaluateOperationToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right)
619{
620 LSL_Leaf *result = calloc(1, sizeof(LSL_Leaf));
621
622 if (content && result)
623 {
624#ifdef LUASL_DEBUG
625 printf(" [%s] ", content->token->token);
626#endif
627
628 memcpy(result, content, sizeof(LSL_Leaf));
629
630 // Figure out the type of the operation.
631 if (OT_vector < result->basicType)
632 result->basicType = allowed[result->basicType].result;
633
634 switch (result->basicType)
635 {
636 case OT_float :
637 {
638 float fleft = left->value.floatValue;
639 float fright = right->value.floatValue;
640
641 // Do the casting.
642 if (OT_floatInt == content->basicType)
643 fright = right->value.integerValue;
644 if (OT_intFloat == content->basicType)
645 fleft = left->value.integerValue;
646 switch (result->token->type)
647 {
648 case LSL_COMMA :
649 case LSL_INCREMENT_PRE :
650 case LSL_INCREMENT_POST :
651 case LSL_DECREMENT_PRE :
652 case LSL_DECREMENT_POST :
653 case LSL_ASSIGNMENT_PLAIN :
654 case LSL_ASSIGNMENT_DIVIDE :
655 case LSL_ASSIGNMENT_MULTIPLY :
656 case LSL_ASSIGNMENT_SUBTRACT :
657 case LSL_ASSIGNMENT_ADD :
658 case LSL_BRACKET_OPEN :
659 case LSL_BRACKET_CLOSE :
660 case LSL_ANGLE_OPEN :
661 case LSL_ANGLE_CLOSE :
662 case LSL_TYPECAST_OPEN :
663 case LSL_TYPECAST_CLOSE :
664 case LSL_DOT_PRODUCT :
665 break;
666 case LSL_NEGATION : result->value.floatValue = 0 - fright; break;
667 case LSL_DIVIDE : result->value.floatValue = fleft / fright; break;
668 case LSL_MULTIPLY : result->value.floatValue = fleft * fright; break;
669 case LSL_SUBTRACT : result->value.floatValue = fleft - fright; break;
670 case LSL_ADD : result->value.floatValue = fleft + fright; break;
671 case LSL_LESS_THAN : result->value.floatValue = fleft < fright; break;
672 case LSL_GREATER_THAN : result->value.floatValue = fleft > fright; break;
673 case LSL_LESS_EQUAL : result->value.floatValue = fleft <= fright; break;
674 case LSL_GREATER_EQUAL : result->value.floatValue = fleft >= fright; break;
675 case LSL_EQUAL : result->value.floatValue = fleft == fright; break;
676 case LSL_NOT_EQUAL : result->value.floatValue = fleft != fright; break;
677 }
678#ifdef LUASL_DEBUG
679 printf(" (=%g) ", result->value.floatValue);
680#endif
681 break;
682 }
683
684 case OT_integer :
685 {
686 switch (result->token->type)
687 {
688 case LSL_COMMA :
689 case LSL_INCREMENT_PRE :
690 case LSL_INCREMENT_POST :
691 case LSL_DECREMENT_PRE :
692 case LSL_DECREMENT_POST :
693 case LSL_DOT :
694 case LSL_ASSIGNMENT_PLAIN :
695 case LSL_ASSIGNMENT_DIVIDE :
696 case LSL_ASSIGNMENT_MODULO :
697 case LSL_ASSIGNMENT_MULTIPLY :
698 case LSL_ASSIGNMENT_SUBTRACT :
699 case LSL_ASSIGNMENT_ADD :
700 case LSL_BRACKET_OPEN :
701 case LSL_BRACKET_CLOSE :
702 case LSL_ANGLE_OPEN :
703 case LSL_ANGLE_CLOSE :
704 case LSL_TYPECAST_OPEN :
705 case LSL_TYPECAST_CLOSE :
706 break;
707 case LSL_BIT_NOT : result->value.integerValue = ~ right->value.integerValue; break;
708 case LSL_BOOL_NOT : result->value.integerValue = ! right->value.integerValue; break;
709 case LSL_NEGATION : result->value.integerValue = 0 - right->value.integerValue; break;
710 case LSL_DIVIDE : result->value.integerValue = left->value.integerValue / right->value.integerValue; break;
711 case LSL_MODULO : result->value.integerValue = left->value.integerValue % right->value.integerValue; break;
712 case LSL_MULTIPLY : result->value.integerValue = left->value.integerValue * right->value.integerValue; break;
713 case LSL_SUBTRACT : result->value.integerValue = left->value.integerValue - right->value.integerValue; break;
714 case LSL_ADD : result->value.integerValue = left->value.integerValue + right->value.integerValue; break;
715 case LSL_LEFT_SHIFT : result->value.integerValue = left->value.integerValue << right->value.integerValue; break;
716 case LSL_RIGHT_SHIFT : result->value.integerValue = left->value.integerValue >> right->value.integerValue; break;
717 case LSL_LESS_THAN : result->value.integerValue = left->value.integerValue < right->value.integerValue; break;
718 case LSL_GREATER_THAN : result->value.integerValue = left->value.integerValue > right->value.integerValue; break;
719 case LSL_LESS_EQUAL : result->value.integerValue = left->value.integerValue <= right->value.integerValue; break;
720 case LSL_GREATER_EQUAL : result->value.integerValue = left->value.integerValue >= right->value.integerValue; break;
721 case LSL_EQUAL : result->value.integerValue = left->value.integerValue == right->value.integerValue; break;
722 case LSL_NOT_EQUAL : result->value.integerValue = left->value.integerValue != right->value.integerValue; break;
723 case LSL_BIT_AND : result->value.integerValue = left->value.integerValue & right->value.integerValue; break;
724 case LSL_BIT_XOR : result->value.integerValue = left->value.integerValue ^ right->value.integerValue; break;
725 case LSL_BIT_OR : result->value.integerValue = left->value.integerValue | right->value.integerValue; break;
726 case LSL_BOOL_OR : result->value.integerValue = left->value.integerValue || right->value.integerValue; break;
727 case LSL_BOOL_AND : result->value.integerValue = left->value.integerValue && right->value.integerValue; break;
728 }
729#ifdef LUASL_DEBUG
730 printf(" (=%d) ", result->value.integerValue);
731#endif
732 break;
733 }
734
735 default :
736 break;
737 }
738 }
739 return result;
740}
741
742static LSL_Leaf *eveluateParenthesisToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right)
743{
744 LSL_Leaf *result = NULL;
745
746 if (content)
747 {
748 if (LSL_PARAMETER_LIST != content->value.parenthesis->type)
749 result = evaluateLeaf(content->value.parenthesis->contents, left, right);
750 }
751 return result;
752}
753
754
755static LSL_Leaf *evaluateStatementToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right)
756{
757 LSL_Leaf *result = NULL;
758
759 if (content)
760 {
761 result = evaluateLeaf(content->value.statementValue->expressions, left, right);
762 if (result)
763 {
764 switch (result->basicType)
765 {
766 case OT_float : printf("\nResult is the float %g.\n", result->value.floatValue); break;
767 case OT_integer : printf("\nResult is the integer %d.\n", result->value.integerValue); break;
768 default : printf("\nResult of an unknown type [%d] %d!\n", result->basicType, result->value.integerValue); break;
769 }
770 free(result);
771 result = NULL;
772 }
773 if (left)
774 left->value.integerValue = 0;
775 if (right)
776 right->value.integerValue = 0;
777 }
778 return result;
779}
780
781static void outputLeaf(FILE *file, outputMode mode, LSL_Leaf *leaf)
782{
783 if (leaf)
784 {
785 outputLeaf(file, mode, leaf->left);
786 if ((!(LSL_NOIGNORE & leaf->token->flags)) && (leaf->ignorableText))
787 fprintf(file, "%s", leaf->ignorableText);
788 if (leaf->token->output)
789 leaf->token->output(file, mode, leaf);
790 else
791 fprintf(file, "%s", leaf->token->token);
792 outputLeaf(file, mode, leaf->right);
793 }
794}
795
796static void outputFloatToken(FILE *file, outputMode mode, LSL_Leaf *content)
797{
798 if (content)
799 fprintf(file, "%g", content->value.floatValue);
800}
801
802static void outputFunctionToken(FILE *file, outputMode mode, LSL_Leaf *content)
803{
804 if (content)
805 {
806 LSL_Function *func = content->value.functionValue;
807
808 outputLeaf(file, mode, func->type);
809 fprintf(file, "%s", func->name);
810 outputLeaf(file, mode, func->params);
811 outputLeaf(file, mode, func->block);
812 }
813}
814
815static void outputIntegerToken(FILE *file, outputMode mode, LSL_Leaf *content)
816{
817 if (content)
818 fprintf(file, "%d", content->value.integerValue);
819}
820
821static void outputParameterToken(FILE *file, outputMode mode, LSL_Leaf *content)
822{
823 if (content)
824 fprintf(file, "%s", content->value.parameterValue->name);
825}
826
827static void outputParameterListToken(FILE *file, outputMode mode, LSL_Leaf *content)
828{
829 if (content)
830 outputLeaf(file, mode, content->value.listValue);
831}
832
833static void outputParenthesisToken(FILE *file, outputMode mode, LSL_Leaf *content)
834{
835 if (content)
836 {
837 fprintf(file, "%s", content->token->token);
838 outputLeaf(file, mode, content->value.parenthesis->contents);
839 outputLeaf(file, mode, content->value.parenthesis->right);
840 }
841}
842
843static void outputStateToken(FILE *file, outputMode mode, LSL_Leaf *content)
844{
845 if (content)
846 {
847 LSL_State *state = content->value.stateValue;
848
849 fprintf(file, "%s", state->name);
850 outputLeaf(file, mode, state->block);
851 }
852}
853
854static void outputStatementToken(FILE *file, outputMode mode, LSL_Leaf *content)
855{
856 if (content)
857 {
858 outputLeaf(file, mode, content->value.statementValue->expressions);
859 if (content->ignorableText)
860 fprintf(file, "%s", content->ignorableText);
861 fprintf(file, "%s", content->token->token);
862 }
863}
864
865static void outputVariableToken(FILE *file, outputMode mode, LSL_Leaf *content)
866{
867 if (content)
868 fprintf(file, "%s", content->value.variableValue->name);
869}
870
871static void doneParsing(LuaSL_yyparseParam *param)
872{
873 if (param->ast)
874 {
875 FILE *out;
876 char buffer[PATH_MAX];
877 char outName[PATH_MAX];
878 char luaName[PATH_MAX];
879
880 outputLeaf(stdout, OM_LSL, param->ast);
881 printf("\n");
882 evaluateLeaf(param->ast, NULL, NULL);
883 printf("\n");
884
885 strcpy(outName, param->fileName);
886 strcat(outName, "2");
887 strcpy(luaName, param->fileName);
888 strcat(luaName, ".lua");
889 out = fopen(outName, "w");
890 if (out)
891 {
892// int count;
893 outputLeaf(out, OM_LSL, param->ast);
894 fclose(out);
895 sprintf(buffer, "diff %s %s", param->fileName, outName);
896// count = system(buffer);
897// printf("Return value of %s is %d\n", buffer, count);
898// if (0 != count)
899// fprintf(stderr, "%s says they are different!\n", buffer);
900 }
901 else
902 fprintf(stderr, "Unable to open file %s for writing!\n", outName);
903 out = fopen(luaName, "w");
904 if (out)
905 {
906 outputLeaf(out, OM_LUA, param->ast);
907 fclose(out);
908 }
909 else
910 fprintf(stderr, "Unable to open file %s for writing!\n", luaName);
911 }
912}
913
914Eina_Bool compilerSetup()
915{
916 int i;
917
918 // Figure out what numbers lemon gave to our tokens.
919 for (i = 0; LSL_Tokens[i].token != NULL; i++)
920 {
921 if (lowestToken > LSL_Tokens[i].type)
922 lowestToken = LSL_Tokens[i].type;
923 }
924 tokens = calloc(i + 1, sizeof(LSL_Token *));
925 if (tokens)
926 {
927 // Sort the token table.
928 for (i = 0; LSL_Tokens[i].token != NULL; i++)
929 {
930 int j = LSL_Tokens[i].type - lowestToken;
931
932 tokens[j] = &(LSL_Tokens[i]);
933 }
934 return EINA_TRUE;
935 }
936 else
937 fprintf(stderr, "No memory for tokens!");
938
939 return EINA_FALSE;
940}
941
4Eina_Bool compileLSL(gameGlobals *game, char *script) 942Eina_Bool compileLSL(gameGlobals *game, char *script)
5{ 943{
6 Eina_Bool result = EINA_FALSE; 944 Eina_Bool result = EINA_FALSE;
945 LuaSL_yyparseParam param;
946 void *pParser = ParseAlloc(malloc);
947 int yv;
7 948
8// Parse the LSL script, validating it and reporting errors. 949// Parse the LSL script, validating it and reporting errors.
9// Just pass all constants and function names through to Lua, assume they are globals there. 950// Just pass all constants and function names through to Lua, assume they are globals there.
10 951
952 memset(&param, 0, sizeof(LuaSL_yyparseParam));
953 strncpy(param.fileName, script, PATH_MAX - 1);
954 param.fileName[PATH_MAX - 1] = '\0';
955 param.file = fopen(param.fileName, "r");
956 if (NULL == param.file)
957 {
958 fprintf(stderr, "Error opening file %s.\n", param.fileName);
959 return FALSE;
960 }
961 printf("Opened %s.\n", param.fileName);
962 param.ast = NULL;
963 param.lval = calloc(1, sizeof(LSL_Leaf));
964 // Text editors usually start counting at 1, even programmers editors.
965 param.column = 1;
966 param.line = 1;
967
968#ifdef LUASL_DEBUG
969// yydebug= 5;
970#endif
971 if (yylex_init_extra(&param, &(param.scanner)))
972 return result;
973#ifdef LUASL_DEBUG
974 yyset_debug(1, param.scanner);
975#endif
976 yyset_in(param.file, param.scanner);
977#ifdef LUASL_DEBUG
978 ParseTrace(stdout, "LSL_lemon ");
979#endif
980 // on EOF yylex will return 0
981 while((yv = yylex(param.lval, param.scanner)) != 0)
982 {
983 Parse(pParser, yv, param.lval, &param);
984 if (LSL_SCRIPT == yv)
985 break;
986 param.lval = calloc(1, sizeof(LSL_Leaf));
987 }
988
989 yylex_destroy(param.scanner);
990 Parse (pParser, 0, param.lval, &param);
991 ParseFree(pParser, free);
992 doneParsing(&param);
993
11// Take the result of the parse, and convert it into Lua source. 994// Take the result of the parse, and convert it into Lua source.
12// Each LSL script becomes a Lua state. 995// Each LSL script becomes a Lua state.
13// LSL states are handled as Lua tables, with each LSL state function being a table function in a common metatable. 996// LSL states are handled as Lua tables, with each LSL state function being a table function in a common metatable.
@@ -15,6 +998,149 @@ Eina_Bool compileLSL(gameGlobals *game, char *script)
15 998
16// Compile the Lua source by the Lua compiler. 999// Compile the Lua source by the Lua compiler.
17 1000
1001 if (NULL != param.file)
1002 {
1003 fclose(param.file);
1004 param.file = NULL;
1005 }
1006 burnLeaf(param.ast);
1007
18 return result; 1008 return result;
19} 1009}
20 1010
1011
1012// Code for running it stand alone, and with files input on the command line.
1013#if 0
1014static int nextFile(LuaSL_yyparseParam *param)
1015{
1016 if (NULL != param->file)
1017 {
1018 fclose(param->file);
1019 param->file = NULL;
1020 }
1021 if (--(param->argc) > 0 && *++(param->argv) != '\0')
1022 {
1023 strncpy(param->fileName, *(param->argv), PATH_MAX - 1);
1024 param->fileName[PATH_MAX - 1] = '\0';
1025 param->file = fopen(param->fileName, "r");
1026 if (NULL == param->file)
1027 {
1028 fprintf(stderr, "Error opening file %s.\n", param->fileName);
1029 return FALSE;
1030 }
1031 printf("Opened %s.\n", param->fileName);
1032 burnLeaf(param->ast);
1033 param->ast = NULL;
1034 param->lval = calloc(1, sizeof(LSL_Leaf));
1035 // Text editors usually start counting at 1, even programmers editors.
1036 param->column = 1;
1037 param->line = 1;
1038 return TRUE;
1039 }
1040/*
1041 if ('\0' == fileName[0])
1042 {
1043//strcpy(fileName, "test.lsl");
1044
1045 count = read(STDIN_FILENO, fileName, PATH_MAX - 1);
1046 if (0 > count)
1047 {
1048 printf("Error in stdin!\n");
1049 return 1;
1050 }
1051 else if (0 == count)
1052 {
1053 printf("No bytes in stdin!\n");
1054 return 1;
1055 }
1056 else
1057 {
1058 fileName[count] = '\0';
1059 printf("Filename %s in stdin.\n", fileName);
1060 }
1061
1062 }
1063*/
1064
1065 return FALSE;
1066}
1067
1068char *test[] = {"test2.lsl", "test2.lsl"};
1069
1070int main(int argc, char **argv)
1071{
1072// char *programName = argv[0];
1073 int i;
1074
1075 // Figure out what numbers yacc gave to our tokens.
1076 for (i = 0; LSL_Tokens[i].token != NULL; i++)
1077 {
1078 if (lowestToken > LSL_Tokens[i].type)
1079 lowestToken = LSL_Tokens[i].type;
1080 }
1081 tokens = calloc(i + 1, sizeof(LSL_Token *));
1082 if (tokens)
1083 {
1084 LuaSL_yyparseParam param;
1085
1086 // Sort the token table.
1087 for (i = 0; LSL_Tokens[i].token != NULL; i++)
1088 {
1089 int j = LSL_Tokens[i].type - lowestToken;
1090
1091 tokens[j] = &(LSL_Tokens[i]);
1092 }
1093
1094 // First time setup.
1095 if (1 == argc)
1096 {
1097 // Fake a test file if there is none. Mostly for ddd.
1098 argc++;
1099 argv = test;
1100 }
1101 memset(&param, 0, sizeof(param));
1102 param.argc = argc;
1103 param.argv = argv;
1104
1105 // Loop through the files.
1106 while (nextFile(&param))
1107 {
1108 void *pParser = ParseAlloc(malloc);
1109 int yv;
1110
1111#ifdef LUASL_DEBUG
1112// yydebug= 5;
1113#endif
1114 if (yylex_init_extra(&param, &(param.scanner)))
1115 return 1;
1116#ifdef LUASL_DEBUG
1117 yyset_debug(1, param.scanner);
1118#endif
1119 yyset_in(param.file, param.scanner);
1120#ifdef LUASL_DEBUG
1121 ParseTrace(stdout, "LSL_lemon ");
1122#endif
1123 // on EOF yylex will return 0
1124 while((yv = yylex(param.lval, param.scanner)) != 0)
1125 {
1126 Parse(pParser, yv, param.lval, &param);
1127 if (LSL_SCRIPT == yv)
1128 break;
1129 param.lval = calloc(1, sizeof(LSL_Leaf));
1130 }
1131
1132 yylex_destroy(param.scanner);
1133 Parse (pParser, 0, param.lval, &param);
1134 ParseFree(pParser, free);
1135 doneParsing(&param);
1136 }
1137 }
1138 else
1139 {
1140 fprintf(stderr, "No memory for tokens!");
1141 return 1;
1142 }
1143
1144 return 0;
1145}
1146#endif