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