aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/LuaSL/LuaSL_LSL_tree.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/LuaSL/LuaSL_LSL_tree.h')
-rw-r--r--src/LuaSL/LuaSL_LSL_tree.h443
1 files changed, 443 insertions, 0 deletions
diff --git a/src/LuaSL/LuaSL_LSL_tree.h b/src/LuaSL/LuaSL_LSL_tree.h
new file mode 100644
index 0000000..5415228
--- /dev/null
+++ b/src/LuaSL/LuaSL_LSL_tree.h
@@ -0,0 +1,443 @@
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
29typedef struct _allowedTypes allowedTypes;
30typedef struct _LSL_Token LSL_Token;
31typedef struct _LSL_Text LSL_Text;
32typedef struct _LSL_Leaf LSL_Leaf;
33typedef struct _LSL_Numby LSL_Numby;
34typedef struct _LSL_Parenthesis LSL_Parenthesis;
35typedef struct _LSL_Identifier LSL_Identifier;
36typedef struct _LSL_Statement LSL_Statement;
37typedef struct _LSL_Block LSL_Block;
38typedef struct _LSL_Function LSL_Function;
39typedef struct _LSL_FunctionCall LSL_FunctionCall;
40typedef struct _LSL_State LSL_State;
41typedef struct _LSL_Script LSL_Script;
42
43extern LSL_Token **tokens;
44extern int lowestToken;
45
46typedef int LSL_Type;
47
48typedef enum
49{
50 OM_LSL,
51 OM_LUA
52} outputMode;
53
54typedef 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
64typedef 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!
79typedef 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
120typedef 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
138typedef 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
153struct _allowedTypes
154{
155 opType result;
156 const char *name;
157 int subTypes;
158};
159
160struct _LSL_Token
161{
162 LSL_Type type;
163 opSubType subType;
164 const char *toKen;
165 LSL_Flags flags;
166 outputToken output;
167};
168
169struct _LSL_Text
170{
171 const char *text;
172#if LUASL_DIFF_CHECK
173 Eina_Strbuf *ignorable;
174#endif
175};
176
177struct _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
209struct _LSL_Numby
210{
211 LSL_Text text;
212 LSL_Type type;
213 union
214 {
215 float floatValue;
216 int integerValue;
217 } value;
218};
219
220struct _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
230struct _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
240struct _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
256struct _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
268struct _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
282struct _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
293struct _LSL_State
294{
295 LSL_Text name;
296 LSL_Text state;
297 LSL_Block *block;
298 Eina_Hash *handlers;
299};
300
301struct _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
312There are global variables, block local variables, and function parameters.
313
314For outputting Lua, which is the ultimate goal -
315 track order, name, and type.
316
317For looking them up during the compile -
318 quick access from name.
319
320For validating them during compile -
321 track type.
322
323For outputting LSL to double check -
324 track order, name, type, and white space.
325
326For executing directly from the AST -
327 track order, name, type, and value.
328 In this case, order is only important for functions.
329
330We can assume that names are stringshared. This means we only have to
331compare pointers. It also means the same name stored at diffferent
332scopes, must be stored in separate structures, coz the pointers are the
333same.
334
335Order is taken care of by the AST anyway, but for somethings we want to
336condense the AST down to something more efficient.
337
338On the other hand, no need to micro optimise it just yet, we should be
339able to try out other data structures at a later date, then benchmark
340them with typical scripts.
341
342Right now I see nothing wrong with the current use of hash for script
343and block variables. The same for script states and functions, as well
344as state functions. Though in the near future, they will have similar
345problems to functions I think - the need to track order and white
346space.
347
348Function params got unwieldy. Cleaned that up now.
349
350*/
351
352/* General design.
353
354NOTE We can remove the white space tracking at compile time, as it's
355only a debugging aid. Will be a performance and memory gain for
356productidon use. Tracking values on the other hand will still be useful
357for constants.
358
359The compile process starts with turning tokens into AST nodes connected
360in a tree. During that process the parser wants to condense nodes down
361to more efficient data structures. This is a good idea, as we will
362spend a fair amount of time looking up names, no matter which part of
363the process is important at the time.
364
365Once the parser has condensed things down, it only deals with the
366condensed nodes. So we can get rid of some of the AST parts at this
367time, so long as we keep the relevant information. This is what the
368other data structures above are for. Lemon tries to free the no longer
369needed AST nodes itself, even if we are still using them internally.
370Need to do something about that.
371
372*/
373
374// Define the type for flex and lemon.
375#define YYSTYPE LSL_Leaf
376
377typedef 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
409boolean compilerSetup(gameGlobals *ourGlobals);
410boolean compileLSL(gameGlobals *ourGlobals, Ecore_Con_Client *client, char *SID, char *script, boolean doConstants);
411void burnLeaf(void *data);
412
413LSL_Leaf *addBlock(LuaSL_compiler *compiler, LSL_Leaf *left, LSL_Leaf *lval, LSL_Leaf *right);
414LSL_Leaf *addCrement(LuaSL_compiler *compiler, LSL_Leaf *variable, LSL_Leaf *crement, LSL_Type type);
415LSL_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);
416LSL_Leaf *addFunction(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *identifier, LSL_Leaf *open, LSL_Leaf *params, LSL_Leaf *close);
417LSL_Leaf *addFunctionBody(LuaSL_compiler *compiler, LSL_Leaf *function, LSL_Leaf *block);
418LSL_Leaf *addFunctionCall(LuaSL_compiler *compiler, LSL_Leaf *identifier, LSL_Leaf *open, LSL_Leaf *params, LSL_Leaf *close);
419LSL_Leaf *addIfElse(LuaSL_compiler *compiler, LSL_Leaf *ifBlock, LSL_Leaf *elseBlock);
420LSL_Leaf *addList(LSL_Leaf *left, LSL_Leaf *list, LSL_Leaf *right);
421LSL_Leaf *addNumby(LSL_Leaf *numby);
422LSL_Leaf *addOperation(LuaSL_compiler *compiler, LSL_Leaf *left, LSL_Leaf *lval, LSL_Leaf *right);
423LSL_Leaf *addParameter(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *newParam);
424LSL_Leaf *addParenthesis(LSL_Leaf *lval, LSL_Leaf *expr, LSL_Type type, LSL_Leaf *rval);
425LSL_Leaf *addRotVec(LSL_Leaf *left, LSL_Leaf *list, LSL_Leaf *right);
426LSL_Leaf *addState(LuaSL_compiler *compiler, LSL_Leaf *state, LSL_Leaf *identifier, LSL_Leaf *block);
427LSL_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);
428LSL_Leaf *addTypecast(LSL_Leaf *lval, LSL_Leaf *type, LSL_Leaf *rval, LSL_Leaf *expr);
429LSL_Leaf *addVariable(LuaSL_compiler *compiler, LSL_Leaf *type, LSL_Leaf *identifier, LSL_Leaf *assignment, LSL_Leaf *expr);
430
431LSL_Leaf *beginBlock(LuaSL_compiler *compiler, LSL_Leaf *block);
432LSL_Leaf *checkVariable(LuaSL_compiler *compiler, LSL_Leaf *identifier, LSL_Leaf *dot, LSL_Leaf *sub);
433LSL_Leaf *collectArguments(LuaSL_compiler *compiler, LSL_Leaf *list, LSL_Leaf *comma, LSL_Leaf *arg);
434LSL_Leaf *collectParameters(LuaSL_compiler *compiler, LSL_Leaf *list, LSL_Leaf *comma, LSL_Leaf *newParam);
435LSL_Leaf *collectStatements(LuaSL_compiler *compiler, LSL_Leaf *list, LSL_Leaf *newStatement);
436
437void *ParseAlloc(void *(*mallocProc)(size_t));
438void ParseTrace(FILE *TraceFILE, char *zTracePrompt);
439void Parse(void *yyp, int yymajor, LSL_Leaf *yyminor, LuaSL_compiler *compiler);
440void ParseFree(void *p, void (*freeProc)(void*));
441
442
443#endif // __LUASL_LSL_TREE_H__