diff options
Diffstat (limited to 'LuaSL/src/LuaSL_LSL_tree.h')
-rw-r--r-- | LuaSL/src/LuaSL_LSL_tree.h | 443 |
1 files changed, 0 insertions, 443 deletions
diff --git a/LuaSL/src/LuaSL_LSL_tree.h b/LuaSL/src/LuaSL_LSL_tree.h deleted file mode 100644 index 5415228..0000000 --- a/LuaSL/src/LuaSL_LSL_tree.h +++ /dev/null | |||
@@ -1,443 +0,0 @@ | |||
1 | |||
2 | #ifndef __LUASL_TREE_H__ | ||
3 | #define __LUASL_TREE_H__ | ||
4 | |||
5 | #define LUASL_DEBUG 0 | ||
6 | #define LUASL_DIFF_CHECK 0 | ||
7 | |||
8 | |||
9 | #include <stddef.h> // So we can have NULL defined. | ||
10 | #include <sys/types.h> | ||
11 | #include <sys/stat.h> | ||
12 | #include <fcntl.h> | ||
13 | |||
14 | #include "assert.h" | ||
15 | #include <unistd.h> | ||
16 | #include <stdlib.h> | ||
17 | #include <stdio.h> | ||
18 | #include <limits.h> // For PATH_MAX. | ||
19 | |||
20 | #include "LuaSL_lemon_yaccer.h" | ||
21 | |||
22 | #define YYERRCODE 256 | ||
23 | #define YYDEBUG 1 | ||
24 | |||
25 | |||
26 | // http://w-hat.com/stackdepth is a useful discussion about some aspects of the LL parser. | ||
27 | |||
28 | |||
29 | typedef struct _allowedTypes allowedTypes; | ||
30 | typedef struct _LSL_Token LSL_Token; | ||
31 | typedef struct _LSL_Text LSL_Text; | ||
32 | typedef struct _LSL_Leaf LSL_Leaf; | ||
33 | typedef struct _LSL_Numby LSL_Numby; | ||
34 | typedef struct _LSL_Parenthesis LSL_Parenthesis; | ||
35 | typedef struct _LSL_Identifier LSL_Identifier; | ||
36 | typedef struct _LSL_Statement LSL_Statement; | ||
37 | typedef struct _LSL_Block LSL_Block; | ||
38 | typedef struct _LSL_Function LSL_Function; | ||
39 | typedef struct _LSL_FunctionCall LSL_FunctionCall; | ||
40 | typedef struct _LSL_State LSL_State; | ||
41 | typedef struct _LSL_Script LSL_Script; | ||
42 | |||
43 | extern LSL_Token **tokens; | ||
44 | extern int lowestToken; | ||
45 | |||
46 | typedef int LSL_Type; | ||
47 | |||
48 | typedef enum | ||
49 | { | ||
50 | OM_LSL, | ||
51 | OM_LUA | ||
52 | } outputMode; | ||
53 | |||
54 | typedef void (*outputToken) (FILE *file, outputMode mode, LSL_Leaf *content); | ||
55 | |||
56 | //#ifndef FALSE | ||
57 | //typedef enum | ||
58 | //{ | ||
59 | // FALSE = 0, | ||
60 | // TRUE = 1 | ||
61 | //} boolean; | ||
62 | //#endif | ||
63 | |||
64 | typedef enum | ||
65 | { | ||
66 | LSL_NONE = 0, | ||
67 | LSL_LEFT2RIGHT = 1, | ||
68 | LSL_RIGHT2LEFT = 2, | ||
69 | LSL_INNER2OUTER = 4, | ||
70 | LSL_UNARY = 8, | ||
71 | LSL_ASSIGNMENT = 16, | ||
72 | LSL_CREATION = 32, | ||
73 | LSL_NOIGNORE = 64, | ||
74 | LSL_TYPE = 128 | ||
75 | } LSL_Flags; | ||
76 | |||
77 | |||
78 | // VERY IMPORTANT to keep this in sync with allowedTypes allowed[] from LuaSL_compile.c! | ||
79 | typedef enum | ||
80 | { | ||
81 | OT_nothing, | ||
82 | |||
83 | OT_bool, | ||
84 | OT_integer, | ||
85 | OT_float, | ||
86 | OT_key, | ||
87 | OT_list, | ||
88 | OT_rotation, | ||
89 | OT_string, | ||
90 | OT_vector, | ||
91 | OT_other, | ||
92 | |||
93 | OT_boolBool, | ||
94 | OT_intBool, | ||
95 | OT_intInt, | ||
96 | OT_intFloat, | ||
97 | OT_floatInt, | ||
98 | OT_floatFloat, | ||
99 | OT_keyKey, | ||
100 | OT_keyString, | ||
101 | OT_stringKey, | ||
102 | OT_stringString, | ||
103 | OT_listList, | ||
104 | OT_listBool, | ||
105 | OT_listInt, | ||
106 | OT_listFloat, | ||
107 | OT_listString, | ||
108 | OT_intList, | ||
109 | OT_floatList, | ||
110 | OT_listOther, | ||
111 | OT_vectorVector, | ||
112 | OT_vectorFloat, | ||
113 | OT_vectorRotation, | ||
114 | OT_rotationRotation, | ||
115 | OT_otherOther, | ||
116 | OT_undeclared, | ||
117 | OT_invalid | ||
118 | } opType; | ||
119 | |||
120 | typedef enum | ||
121 | { | ||
122 | ST_NONE = 0, | ||
123 | ST_ASSIGNMENT = 1, // -= *= /= | ||
124 | ST_BIT_NOT = 2, // ~ | ||
125 | ST_BOOL_NOT = 4, // ! | ||
126 | ST_BITWISE = 8, // & | ^ << >> | ||
127 | ST_BOOLEAN = 16, // && !! | ||
128 | ST_COMPARISON = 32, // < > <= >= | ||
129 | ST_CONCATENATION = 64, // = += | ||
130 | ST_EQUALITY = 128, // == != | ||
131 | ST_ADD = 512, // + | ||
132 | ST_SUBTRACT = 1024, // - | ||
133 | ST_NEGATE = 2048, // - | ||
134 | ST_MULTIPLY = 4096, // * / | ||
135 | ST_MODULO = 8192 // % %= | ||
136 | } opSubType; | ||
137 | |||
138 | typedef enum | ||
139 | { | ||
140 | MF_NONE = 0, | ||
141 | MF_LOCAL = 1, | ||
142 | MF_NOASSIGN = 2, // These two are for completely different purposes. This one is for variable definitions with no assignment. | ||
143 | MF_ASSIGNEXP = 4, // These two are for completely different purposes. This one is for assignments being used as expressions. | ||
144 | MF_WRAPFUNC = 8, | ||
145 | MF_PREDEC = 16, | ||
146 | MF_PREINC = 32, | ||
147 | MF_POSTDEC = 64, | ||
148 | MF_POSTINC = 128, | ||
149 | MF_LSLCONST = 256, | ||
150 | MF_TYPECAST = 512 | ||
151 | } miscFlags; | ||
152 | |||
153 | struct _allowedTypes | ||
154 | { | ||
155 | opType result; | ||
156 | const char *name; | ||
157 | int subTypes; | ||
158 | }; | ||
159 | |||
160 | struct _LSL_Token | ||
161 | { | ||
162 | LSL_Type type; | ||
163 | opSubType subType; | ||
164 | const char *toKen; | ||
165 | LSL_Flags flags; | ||
166 | outputToken output; | ||
167 | }; | ||
168 | |||
169 | struct _LSL_Text | ||
170 | { | ||
171 | const char *text; | ||
172 | #if LUASL_DIFF_CHECK | ||
173 | Eina_Strbuf *ignorable; | ||
174 | #endif | ||
175 | }; | ||
176 | |||
177 | struct _LSL_Leaf | ||
178 | { | ||
179 | LSL_Leaf *left; | ||
180 | LSL_Leaf *right; | ||
181 | LSL_Token *toKen; | ||
182 | #if LUASL_DIFF_CHECK | ||
183 | Eina_Strbuf *ignorable; | ||
184 | #endif | ||
185 | int line, column, len; | ||
186 | opType basicType; | ||
187 | miscFlags flags; | ||
188 | union | ||
189 | { | ||
190 | float floatValue; | ||
191 | float vectorValue[3]; | ||
192 | float rotationValue[4]; | ||
193 | int integerValue; | ||
194 | LSL_Numby *numbyValue; | ||
195 | LSL_Leaf *listValue; | ||
196 | const char *stringValue; | ||
197 | opType operationValue; | ||
198 | LSL_Parenthesis *parenthesis; | ||
199 | LSL_Identifier *identifierValue; | ||
200 | LSL_Statement *statementValue; | ||
201 | LSL_Block *blockValue; | ||
202 | LSL_Function *functionValue; | ||
203 | LSL_FunctionCall *functionCallValue; | ||
204 | LSL_State *stateValue; | ||
205 | LSL_Script *scriptValue; | ||
206 | } value; | ||
207 | }; | ||
208 | |||
209 | struct _LSL_Numby | ||
210 | { | ||
211 | LSL_Text text; | ||
212 | LSL_Type type; | ||
213 | union | ||
214 | { | ||
215 | float floatValue; | ||
216 | int integerValue; | ||
217 | } value; | ||
218 | }; | ||
219 | |||
220 | struct _LSL_Parenthesis | ||
221 | { | ||
222 | LSL_Leaf *contents; | ||
223 | #if LUASL_DIFF_CHECK | ||
224 | Eina_Strbuf *rightIgnorable; | ||
225 | #endif | ||
226 | LSL_Type type; | ||
227 | miscFlags flags; | ||
228 | }; | ||
229 | |||
230 | struct _LSL_Identifier // For variables and function parameters. | ||
231 | { | ||
232 | LSL_Text name; | ||
233 | LSL_Statement *definition; | ||
234 | Eina_Strbuf *ignorable; | ||
235 | const char *sub; | ||
236 | LSL_Leaf value; | ||
237 | miscFlags flags; | ||
238 | }; | ||
239 | |||
240 | struct _LSL_Statement | ||
241 | { | ||
242 | Eina_Clist statement; // For block statement lists, this is the entry. | ||
243 | LSL_Text identifier; | ||
244 | LSL_Parenthesis *parenthesis; | ||
245 | LSL_Leaf *expressions; // A for statement will have three expressions, and two semicolons, everything else has zero or one. | ||
246 | LSL_Block *block; | ||
247 | LSL_Statement *single; // For single statement "blocks". | ||
248 | LSL_Statement *elseBlock; | ||
249 | LSL_Type type; // Expression type. | ||
250 | #if LUASL_DIFF_CHECK | ||
251 | Eina_Strbuf **ignorable; // Can be up to five of these I think. | ||
252 | #endif | ||
253 | miscFlags flags; | ||
254 | }; | ||
255 | |||
256 | struct _LSL_Block | ||
257 | { | ||
258 | LSL_Block *outerBlock; | ||
259 | Eina_Clist statements; // For statement lists, this is the HEAD. | ||
260 | Eina_Hash *variables; // Those variables in this scope. | ||
261 | LSL_Function *function; // A pointer to the function if this block is a function. | ||
262 | #if LUASL_DIFF_CHECK | ||
263 | Eina_Strbuf *openIgnorable; | ||
264 | Eina_Strbuf *closeIgnorable; | ||
265 | #endif | ||
266 | }; | ||
267 | |||
268 | struct _LSL_Function | ||
269 | { | ||
270 | LSL_Text name; | ||
271 | LSL_Text type; | ||
272 | const char *state; | ||
273 | #if LUASL_DIFF_CHECK | ||
274 | // LSL_Leaf *params; // So we store the parenthesis, and their ignorables. | ||
275 | // This points to the params leaf, which is a function, pointing to this structure. The actual params are in vars. | ||
276 | #endif | ||
277 | Eina_Inarray vars; // Eina Inarray has not been released yet (Eina 1.2). | ||
278 | LSL_Block *block; | ||
279 | miscFlags flags; | ||
280 | }; | ||
281 | |||
282 | struct _LSL_FunctionCall | ||
283 | { | ||
284 | LSL_Function *function; | ||
285 | Eina_Inarray params; // Eina Inarray has not been released yet (Eina 1.2). | ||
286 | Eina_Clist dangler; // Entry for function calls used before the function is defined. | ||
287 | LSL_Leaf *call; // This is to stash the details for dangling ones, to search later. | ||
288 | // The line and column details are needed for bitching, so we need the leaf. | ||
289 | // Also need the stringValue for the search. | ||
290 | // On top of all that, the leaf is still used in expressions, so need to keep it around and update it when resolving danglers. | ||
291 | }; | ||
292 | |||
293 | struct _LSL_State | ||
294 | { | ||
295 | LSL_Text name; | ||
296 | LSL_Text state; | ||
297 | LSL_Block *block; | ||
298 | Eina_Hash *handlers; | ||
299 | }; | ||
300 | |||
301 | struct _LSL_Script | ||
302 | { | ||
303 | const char *name; | ||
304 | Eina_Hash *functions; | ||
305 | Eina_Hash *states; | ||
306 | Eina_Hash *variables; | ||
307 | int bugCount, warningCount; | ||
308 | }; | ||
309 | |||
310 | /* Tracking variables. | ||
311 | |||
312 | There are global variables, block local variables, and function parameters. | ||
313 | |||
314 | For outputting Lua, which is the ultimate goal - | ||
315 | track order, name, and type. | ||
316 | |||
317 | For looking them up during the compile - | ||
318 | quick access from name. | ||
319 | |||
320 | For validating them during compile - | ||
321 | track type. | ||
322 | |||
323 | For outputting LSL to double check - | ||
324 | track order, name, type, and white space. | ||
325 | |||
326 | For executing directly from the AST - | ||
327 | track order, name, type, and value. | ||
328 | In this case, order is only important for functions. | ||
329 | |||
330 | We can assume that names are stringshared. This means we only have to | ||
331 | compare pointers. It also means the same name stored at diffferent | ||
332 | scopes, must be stored in separate structures, coz the pointers are the | ||
333 | same. | ||
334 | |||
335 | Order is taken care of by the AST anyway, but for somethings we want to | ||
336 | condense the AST down to something more efficient. | ||
337 | |||
338 | On the other hand, no need to micro optimise it just yet, we should be | ||
339 | able to try out other data structures at a later date, then benchmark | ||
340 | them with typical scripts. | ||
341 | |||
342 | Right now I see nothing wrong with the current use of hash for script | ||
343 | and block variables. The same for script states and functions, as well | ||
344 | as state functions. Though in the near future, they will have similar | ||
345 | problems to functions I think - the need to track order and white | ||
346 | space. | ||
347 | |||
348 | Function params got unwieldy. Cleaned that up now. | ||
349 | |||
350 | */ | ||
351 | |||
352 | /* General design. | ||
353 | |||
354 | NOTE We can remove the white space tracking at compile time, as it's | ||
355 | only a debugging aid. Will be a performance and memory gain for | ||
356 | productidon use. Tracking values on the other hand will still be useful | ||
357 | for constants. | ||
358 | |||
359 | The compile process starts with turning tokens into AST nodes connected | ||
360 | in a tree. During that process the parser wants to condense nodes down | ||
361 | to more efficient data structures. This is a good idea, as we will | ||
362 | spend a fair amount of time looking up names, no matter which part of | ||
363 | the process is important at the time. | ||
364 | |||
365 | Once the parser has condensed things down, it only deals with the | ||
366 | condensed nodes. So we can get rid of some of the AST parts at this | ||
367 | time, so long as we keep the relevant information. This is what the | ||
368 | other data structures above are for. Lemon tries to free the no longer | ||
369 | needed AST nodes itself, even if we are still using them internally. | ||
370 | Need to do something about that. | ||
371 | |||
372 | */ | ||
373 | |||
374 | // Define the type for flex and lemon. | ||
375 | #define YYSTYPE LSL_Leaf | ||
376 | |||
377 | typedef struct | ||
378 | { | ||
379 | gameGlobals *game; | ||
380 | Ecore_Con_Client *client; | ||
381 | void *scanner; // This should be of type yyscan_t, which is typedef to void * anyway, but that does not get defined until LuaSL_lexer.h, which depends on this struct being defined first. | ||
382 | int argc; | ||
383 | char **argv; | ||
384 | char SID[37]; | ||
385 | char fileName[PATH_MAX]; | ||
386 | FILE *file; | ||
387 | LSL_Leaf *ast; | ||
388 | LSL_Script script; | ||
389 | LSL_State state; | ||
390 | #if LUASL_DIFF_CHECK | ||
391 | Eina_Strbuf *ignorable; | ||
392 | #endif | ||
393 | LSL_Leaf *lval; | ||
394 | LSL_Block *currentBlock; | ||
395 | LSL_Function *currentFunction; | ||
396 | Eina_Clist danglingCalls; // HEAD for function calls used before the function is defined. | ||
397 | int column, line; | ||
398 | int undeclared; | ||
399 | boolean inState; | ||
400 | } LuaSL_compiler; | ||
401 | |||
402 | |||
403 | #ifndef excludeLexer | ||
404 | #include "LuaSL_lexer.h" | ||
405 | #endif | ||
406 | |||
407 | |||
408 | |||
409 | boolean compilerSetup(gameGlobals *ourGlobals); | ||
410 | boolean compileLSL(gameGlobals *ourGlobals, Ecore_Con_Client *client, char *SID, char *script, boolean doConstants); | ||
411 | void burnLeaf(void *data); | ||
412 | |||
413 | LSL_Leaf *addBlock(LuaSL_compiler *compiler, LSL_Leaf *left, LSL_Leaf *lval, LSL_Leaf *right); | ||
414 | LSL_Leaf *addCrement(LuaSL_compiler *compiler, LSL_Leaf *variable, LSL_Leaf *crement, LSL_Type type); | ||
415 | LSL_Leaf *addFor(LuaSL_compiler *compiler, LSL_Leaf *lval, LSL_Leaf *flow, LSL_Leaf *left, LSL_Leaf *expr0, LSL_Leaf *stat0, LSL_Leaf *expr1, LSL_Leaf *stat1, LSL_Leaf *expr2, LSL_Leaf *right, LSL_Leaf *block); | ||
416 | LSL_Leaf *addFunction(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *identifier, LSL_Leaf *open, LSL_Leaf *params, LSL_Leaf *close); | ||
417 | LSL_Leaf *addFunctionBody(LuaSL_compiler *compiler, LSL_Leaf *function, LSL_Leaf *block); | ||
418 | LSL_Leaf *addFunctionCall(LuaSL_compiler *compiler, LSL_Leaf *identifier, LSL_Leaf *open, LSL_Leaf *params, LSL_Leaf *close); | ||
419 | LSL_Leaf *addIfElse(LuaSL_compiler *compiler, LSL_Leaf *ifBlock, LSL_Leaf *elseBlock); | ||
420 | LSL_Leaf *addList(LSL_Leaf *left, LSL_Leaf *list, LSL_Leaf *right); | ||
421 | LSL_Leaf *addNumby(LSL_Leaf *numby); | ||
422 | LSL_Leaf *addOperation(LuaSL_compiler *compiler, LSL_Leaf *left, LSL_Leaf *lval, LSL_Leaf *right); | ||
423 | LSL_Leaf *addParameter(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *newParam); | ||
424 | LSL_Leaf *addParenthesis(LSL_Leaf *lval, LSL_Leaf *expr, LSL_Type type, LSL_Leaf *rval); | ||
425 | LSL_Leaf *addRotVec(LSL_Leaf *left, LSL_Leaf *list, LSL_Leaf *right); | ||
426 | LSL_Leaf *addState(LuaSL_compiler *compiler, LSL_Leaf *state, LSL_Leaf *identifier, LSL_Leaf *block); | ||
427 | LSL_Leaf *addStatement(LuaSL_compiler *compiler, LSL_Leaf *lval, LSL_Leaf *flow, LSL_Leaf *left, LSL_Leaf *expr, LSL_Leaf *right, LSL_Leaf *block, LSL_Leaf *identifier); | ||
428 | LSL_Leaf *addTypecast(LSL_Leaf *lval, LSL_Leaf *type, LSL_Leaf *rval, LSL_Leaf *expr); | ||
429 | LSL_Leaf *addVariable(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *identifier, LSL_Leaf *assignment, LSL_Leaf *expr); | ||
430 | |||
431 | LSL_Leaf *beginBlock(LuaSL_compiler *compiler, LSL_Leaf *block); | ||
432 | LSL_Leaf *checkVariable(LuaSL_compiler *compiler, LSL_Leaf *identifier, LSL_Leaf *dot, LSL_Leaf *sub); | ||
433 | LSL_Leaf *collectArguments(LuaSL_compiler *compiler, LSL_Leaf *list, LSL_Leaf *comma, LSL_Leaf *arg); | ||
434 | LSL_Leaf *collectParameters(LuaSL_compiler *compiler, LSL_Leaf *list, LSL_Leaf *comma, LSL_Leaf *newParam); | ||
435 | LSL_Leaf *collectStatements(LuaSL_compiler *compiler, LSL_Leaf *list, LSL_Leaf *newStatement); | ||
436 | |||
437 | void *ParseAlloc(void *(*mallocProc)(size_t)); | ||
438 | void ParseTrace(FILE *TraceFILE, char *zTracePrompt); | ||
439 | void Parse(void *yyp, int yymajor, LSL_Leaf *yyminor, LuaSL_compiler *compiler); | ||
440 | void ParseFree(void *p, void (*freeProc)(void*)); | ||
441 | |||
442 | |||
443 | #endif // __LUASL_LSL_TREE_H__ | ||