diff options
Diffstat (limited to '')
-rw-r--r-- | LuaSL/src/LuaSL.edc | 6 | ||||
-rw-r--r-- | LuaSL/src/LuaSL.h | 1 | ||||
-rw-r--r-- | LuaSL/src/LuaSL_LSL_lexer.l | 281 | ||||
-rw-r--r-- | LuaSL/src/LuaSL_LSL_tree.c | 1047 | ||||
-rw-r--r-- | LuaSL/src/LuaSL_LSL_tree.h | 14 | ||||
-rw-r--r-- | LuaSL/src/LuaSL_LSL_yaccer.y | 1474 | ||||
-rw-r--r-- | LuaSL/src/LuaSL_compile.c | 1126 | ||||
-rw-r--r-- | LuaSL/src/LuaSL_lexer.l | 2 | ||||
-rw-r--r-- | LuaSL/src/LuaSL_main.c | 7 |
9 files changed, 1143 insertions, 2815 deletions
diff --git a/LuaSL/src/LuaSL.edc b/LuaSL/src/LuaSL.edc index f74395b..852de08 100644 --- a/LuaSL/src/LuaSL.edc +++ b/LuaSL/src/LuaSL.edc | |||
@@ -2,9 +2,9 @@ color_classes { | |||
2 | color_class { name: "test_colour"; color: 255 255 255 255; } | 2 | color_class { name: "test_colour"; color: 255 255 255 255; } |
3 | } | 3 | } |
4 | 4 | ||
5 | fonts { | 5 | //fonts { |
6 | font: "Vera.ttf" "default"; | 6 | // font: "Vera.ttf" "default"; |
7 | } | 7 | //} |
8 | 8 | ||
9 | images { | 9 | images { |
10 | image: "bubble.png" COMP; | 10 | image: "bubble.png" COMP; |
diff --git a/LuaSL/src/LuaSL.h b/LuaSL/src/LuaSL.h index 2bb2b4a..509f155 100644 --- a/LuaSL/src/LuaSL.h +++ b/LuaSL/src/LuaSL.h | |||
@@ -56,6 +56,7 @@ typedef struct | |||
56 | } gameGlobals; | 56 | } gameGlobals; |
57 | 57 | ||
58 | 58 | ||
59 | Eina_Bool compilerSetup(); | ||
59 | Eina_Bool compileLSL(gameGlobals *game, char *script); | 60 | Eina_Bool compileLSL(gameGlobals *game, char *script); |
60 | 61 | ||
61 | void loggingStartup(gameGlobals *game); | 62 | void loggingStartup(gameGlobals *game); |
diff --git a/LuaSL/src/LuaSL_LSL_lexer.l b/LuaSL/src/LuaSL_LSL_lexer.l deleted file mode 100644 index 473a427..0000000 --- a/LuaSL/src/LuaSL_LSL_lexer.l +++ /dev/null | |||
@@ -1,281 +0,0 @@ | |||
1 | |||
2 | N [0-9] | ||
3 | L [a-zA-Z_] | ||
4 | H [a-fA-F0-9] | ||
5 | E [Ee][+-]?{N}+ | ||
6 | FS (f|F) | ||
7 | %e 10000 | ||
8 | %n 4000 | ||
9 | %p 5000 | ||
10 | |||
11 | %{ | ||
12 | |||
13 | #define excludeLexer | ||
14 | #include "LuaSL_LSL_tree.h" | ||
15 | #include "LuaSL_LSLS_yaccer.tab.h" | ||
16 | |||
17 | |||
18 | // Deal with the fact that lex/yacc generates unreachable code | ||
19 | #ifdef LL_WINDOWS | ||
20 | #pragma warning (disable : 4018) // warning C4018: signed/unsigned mismatch | ||
21 | #pragma warning (disable : 4702) // warning C4702: unreachable code | ||
22 | #endif // LL_WINDOWS | ||
23 | |||
24 | void count(); | ||
25 | void line_comment(); | ||
26 | void block_comment(); | ||
27 | void parse_string(); | ||
28 | |||
29 | #define YYLMAX 16384 | ||
30 | #define YY_NEVER_INTERACTIVE 1 /* stops flex from calling isatty() */ | ||
31 | #ifdef LL_WINDOWS | ||
32 | #define isatty(x) 0 /* hack for bug in cygwin flex 2.5.35 */ | ||
33 | #endif | ||
34 | |||
35 | #ifdef ECHO | ||
36 | #undef ECHO | ||
37 | #endif | ||
38 | |||
39 | #define ECHO do { } while (0) | ||
40 | |||
41 | %} | ||
42 | |||
43 | %option reentrant noyywrap never-interactive nounistd | ||
44 | %option bison-bridge | ||
45 | |||
46 | %% | ||
47 | "//" { gInternalLine++; gInternalColumn = 0; line_comment(); } | ||
48 | "/*" { block_comment(); } | ||
49 | |||
50 | "integer" { count(); return(INTEGER); } | ||
51 | "float" { count(); return(FLOAT_TYPE); } | ||
52 | "string" { count(); return(STRING); } | ||
53 | "key" { count(); return(LLKEY); } | ||
54 | "vector" { count(); return(VECTOR); } | ||
55 | "quaternion" { count(); return(QUATERNION); } | ||
56 | "rotation" { count(); return(QUATERNION); } | ||
57 | "list" { count(); return(LIST); } | ||
58 | |||
59 | "default" { count(); yylval.sval = new char[strlen(yytext) + 1]; strcpy(yylval.sval, yytext); return(STATE_DEFAULT); } | ||
60 | "state" { count(); return(STATE); } | ||
61 | "event" { count(); return(EVENT); } | ||
62 | "jump" { count(); return(JUMP); } | ||
63 | "return" { count(); return(RETURN); } | ||
64 | "if" { count(); return(IF); } | ||
65 | "else" { count(); return(ELSE); } | ||
66 | "for" { count(); return(FOR); } | ||
67 | "do" { count(); return(DO); } | ||
68 | "while" { count(); return(WHILE); } | ||
69 | |||
70 | "state_entry" { count(); return(STATE_ENTRY); } | ||
71 | "state_exit" { count(); return(STATE_EXIT); } | ||
72 | "touch_start" { count(); return(TOUCH_START); } | ||
73 | "touch" { count(); return(TOUCH); } | ||
74 | "touch_end" { count(); return(TOUCH_END); } | ||
75 | "collision_start" { count(); return(COLLISION_START); } | ||
76 | "collision" { count(); return(COLLISION); } | ||
77 | "collision_end" { count(); return(COLLISION_END); } | ||
78 | "land_collision_start" { count(); return(LAND_COLLISION_START); } | ||
79 | "land_collision" { count(); return(LAND_COLLISION); } | ||
80 | "land_collision_end" { count(); return(LAND_COLLISION_END); } | ||
81 | "timer" { count(); return(TIMER); } | ||
82 | "listen" { count(); return(CHAT); } | ||
83 | "sensor" { count(); return(SENSOR); } | ||
84 | "no_sensor" { count(); return(NO_SENSOR); } | ||
85 | "control" { count(); return(CONTROL); } | ||
86 | "print" { count(); return(PRINT); } | ||
87 | "at_target" { count(); return(AT_TARGET); } | ||
88 | "not_at_target" { count(); return(NOT_AT_TARGET); } | ||
89 | "at_rot_target" { count(); return(AT_ROT_TARGET); } | ||
90 | "not_at_rot_target" { count(); return(NOT_AT_ROT_TARGET); } | ||
91 | "money" { count(); return(MONEY); } | ||
92 | "email" { count(); return(EMAIL); } | ||
93 | "run_time_permissions" { count(); return(RUN_TIME_PERMISSIONS); } | ||
94 | "changed" { count(); return(INVENTORY); } | ||
95 | "attach" { count(); return(ATTACH); } | ||
96 | "dataserver" { count(); return(DATASERVER); } | ||
97 | "moving_start" { count(); return(MOVING_START); } | ||
98 | "moving_end" { count(); return(MOVING_END); } | ||
99 | "link_message" { count(); return(LINK_MESSAGE); } | ||
100 | "on_rez" { count(); return(REZ); } | ||
101 | "object_rez" { count(); return(OBJECT_REZ); } | ||
102 | "remote_data" { count(); return(REMOTE_DATA); } | ||
103 | "http_response" { count(); return(HTTP_RESPONSE); } | ||
104 | "http_request" { count(); return(HTTP_REQUEST); } | ||
105 | "." { count(); return(PERIOD); } | ||
106 | |||
107 | 0[xX]{H}+ { count(); yylval.ival = strtoul(yytext, NULL, 0); return(INTEGER_CONSTANT); } | ||
108 | {N}+ { count(); yylval.ival = strtoul(yytext, NULL, 10); return(INTEGER_CONSTANT); } | ||
109 | "TRUE" { count(); yylval.ival = 1; return(INTEGER_TRUE); } | ||
110 | "FALSE" { count(); yylval.ival = 0; return(INTEGER_FALSE); } | ||
111 | |||
112 | "TOUCH_INVALID_FACE" { count(); yylval.ival = -1; return(INTEGER_CONSTANT); } | ||
113 | "TOUCH_INVALID_VECTOR" { count(); return(TOUCH_INVALID_VECTOR); } | ||
114 | "TOUCH_INVALID_TEXCOORD" { count(); return(TOUCH_INVALID_TEXCOORD); } | ||
115 | |||
116 | {L}({L}|{N})* { count(); yylval.sval = new char[strlen(yytext) + 1]; strcpy(yylval.sval, yytext); return(IDENTIFIER); } | ||
117 | |||
118 | {N}+{E} { count(); yylval.fval = (F32)atof(yytext); return(FP_CONSTANT); } | ||
119 | {N}*"."{N}+({E})?{FS}? { count(); yylval.fval = (F32)atof(yytext); return(FP_CONSTANT); } | ||
120 | {N}+"."{N}*({E})?{FS}? { count(); yylval.fval = (F32)atof(yytext); return(FP_CONSTANT); } | ||
121 | |||
122 | L?\"(\\.|[^\\"])*\" { parse_string(); count(); return(STRING_CONSTANT); } | ||
123 | |||
124 | "++" { count(); return(INC_OP); } | ||
125 | "--" { count(); return(DEC_OP); } | ||
126 | "+=" { count(); return(ADD_ASSIGN); } | ||
127 | "-=" { count(); return(SUB_ASSIGN); } | ||
128 | "*=" { count(); return(MUL_ASSIGN); } | ||
129 | "/=" { count(); return(DIV_ASSIGN); } | ||
130 | "%=" { count(); return(MOD_ASSIGN); } | ||
131 | ";" { count(); return(';'); } | ||
132 | "{" { count(); return('{'); } | ||
133 | "}" { count(); return('}'); } | ||
134 | "," { count(); return(','); } | ||
135 | "=" { count(); return('='); } | ||
136 | "(" { count(); return('('); } | ||
137 | ")" { count(); return(')'); } | ||
138 | "-" { count(); return('-'); } | ||
139 | "+" { count(); return('+'); } | ||
140 | "*" { count(); return('*'); } | ||
141 | "/" { count(); return('/'); } | ||
142 | "%" { count(); return('%'); } | ||
143 | "@" { count(); return('@'); } | ||
144 | ":" { count(); return(':'); } | ||
145 | ">" { count(); return('>'); } | ||
146 | "<" { count(); return('<'); } | ||
147 | "]" { count(); return(']'); } | ||
148 | "[" { count(); return('['); } | ||
149 | "==" { count(); return(EQ); } | ||
150 | "!=" { count(); return(NEQ); } | ||
151 | ">=" { count(); return(GEQ); } | ||
152 | "<=" { count(); return(LEQ); } | ||
153 | "&" { count(); return('&'); } | ||
154 | "|" { count(); return('|'); } | ||
155 | "^" { count(); return('^'); } | ||
156 | "~" { count(); return('~'); } | ||
157 | "!" { count(); return('!'); } | ||
158 | "&&" { count(); return(BOOLEAN_AND); } | ||
159 | "||" { count(); return(BOOLEAN_OR); } | ||
160 | "<<" { count(); return(SHIFT_LEFT); } | ||
161 | ">>" { count(); return(SHIFT_RIGHT); } | ||
162 | |||
163 | [ \t\v\n\f] { count(); } | ||
164 | . { /* ignore bad characters */ } | ||
165 | |||
166 | %% | ||
167 | |||
168 | |||
169 | // Prototype for the yacc parser entry point | ||
170 | int yyparse(void); | ||
171 | |||
172 | |||
173 | S32 yywrap() | ||
174 | { | ||
175 | #if defined(FLEX_SCANNER) && !defined(LL_WINDOWS) | ||
176 | // get gcc to stop complaining about lack of use of yyunput | ||
177 | (void) yyunput; | ||
178 | #endif | ||
179 | return(1); | ||
180 | } | ||
181 | |||
182 | void line_comment() | ||
183 | { | ||
184 | char c; | ||
185 | |||
186 | while ((c = yyinput()) != '\n' && c != 0 && c != EOF) | ||
187 | ; | ||
188 | } | ||
189 | |||
190 | void block_comment() | ||
191 | { | ||
192 | char c1 = 0; | ||
193 | char c2 = yyinput(); | ||
194 | while (c2 != 0 && c2 != EOF && !(c1 == '*' && c2 == '/')) { | ||
195 | if (c2 == '\n') | ||
196 | { | ||
197 | gInternalLine++; | ||
198 | gInternalColumn = 0; | ||
199 | } | ||
200 | else if (c2 == '\t') | ||
201 | gInternalColumn += 4 - (gInternalColumn % 8); | ||
202 | else | ||
203 | gInternalColumn++; | ||
204 | c1 = c2; | ||
205 | c2 = yyinput(); | ||
206 | } | ||
207 | } | ||
208 | |||
209 | void count() | ||
210 | { | ||
211 | S32 i; | ||
212 | |||
213 | gColumn = gInternalColumn; | ||
214 | gLine = gInternalLine; | ||
215 | |||
216 | for (i = 0; yytext[i] != '\0'; i++) | ||
217 | if (yytext[i] == '\n') | ||
218 | { | ||
219 | gInternalLine++; | ||
220 | gInternalColumn = 0; | ||
221 | } | ||
222 | else if (yytext[i] == '\t') | ||
223 | gInternalColumn += 4 - (gInternalColumn % 8); | ||
224 | else | ||
225 | gInternalColumn++; | ||
226 | } | ||
227 | |||
228 | void parse_string() | ||
229 | { | ||
230 | S32 length = (S32)strlen(yytext); | ||
231 | length = length - 2; | ||
232 | char *temp = yytext + 1; | ||
233 | |||
234 | S32 i; | ||
235 | S32 escapes = 0; | ||
236 | S32 tabs = 0; | ||
237 | for (i = 0; i < length; i++) | ||
238 | { | ||
239 | if (temp[i] == '\\') | ||
240 | { | ||
241 | escapes++; | ||
242 | i++; | ||
243 | if (temp[i] == 't') | ||
244 | tabs++; | ||
245 | } | ||
246 | } | ||
247 | |||
248 | S32 newlength = length - escapes + tabs*3; | ||
249 | yylval.sval = new char[newlength + 1]; | ||
250 | |||
251 | char *dest = yylval.sval; | ||
252 | |||
253 | for (i = 0; i < length; i++) | ||
254 | { | ||
255 | if (temp[i] == '\\') | ||
256 | { | ||
257 | i++; | ||
258 | // linefeed | ||
259 | if (temp[i] == 'n') | ||
260 | { | ||
261 | *dest++ = 10; | ||
262 | } | ||
263 | else if (temp[i] == 't') | ||
264 | { | ||
265 | *dest++ = ' '; | ||
266 | *dest++ = ' '; | ||
267 | *dest++ = ' '; | ||
268 | *dest++ = ' '; | ||
269 | } | ||
270 | else | ||
271 | { | ||
272 | *dest++ = temp[i]; | ||
273 | } | ||
274 | } | ||
275 | else | ||
276 | { | ||
277 | *dest++ = temp[i]; | ||
278 | } | ||
279 | } | ||
280 | yylval.sval[newlength] = 0; | ||
281 | } | ||
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 | |||
6 | static LSL_Leaf *evaluateFloatToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right); | ||
7 | static LSL_Leaf *evaluateIntegerToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right); | ||
8 | static LSL_Leaf *evaluateNoToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right); | ||
9 | static LSL_Leaf *evaluateOperationToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right); | ||
10 | static LSL_Leaf *eveluateParenthesisToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right); | ||
11 | static LSL_Leaf *evaluateStatementToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right); | ||
12 | static void outputFloatToken(FILE *file, outputMode mode, LSL_Leaf *content); | ||
13 | static void outputFunctionToken(FILE *file, outputMode mode, LSL_Leaf *content); | ||
14 | static void outputIntegerToken(FILE *file, outputMode mode, LSL_Leaf *content); | ||
15 | static void outputParameterToken(FILE *file, outputMode mode, LSL_Leaf *content); | ||
16 | static void outputParameterListToken(FILE *file, outputMode mode, LSL_Leaf *content); | ||
17 | static void outputParenthesisToken(FILE *file, outputMode mode, LSL_Leaf *content); | ||
18 | static void outputStateToken(FILE *file, outputMode mode, LSL_Leaf *content); | ||
19 | static void outputStatementToken(FILE *file, outputMode mode, LSL_Leaf *content); | ||
20 | static void outputVariableToken(FILE *file, outputMode mode, LSL_Leaf *content); | ||
21 | |||
22 | LSL_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 | |||
132 | allowedTypes 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 | |||
168 | opType 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 | |||
184 | LSL_Token **tokens = NULL; | ||
185 | int lowestToken = 999999; | ||
186 | |||
187 | |||
188 | static 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 | |||
202 | void 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 | |||
214 | LSL_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 | |||
294 | LSL_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 | |||
313 | LSL_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 | |||
330 | LSL_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 | |||
355 | LSL_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 | |||
375 | LSL_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 | |||
392 | LSL_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 | |||
407 | LSL_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 | |||
432 | LSL_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 | |||
466 | void 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 | |||
478 | void endBlock(LuaSL_yyparseParam *param, LSL_Leaf *block) | ||
479 | { | ||
480 | param->currentBlock = param->currentBlock->outerBlock; | ||
481 | } | ||
482 | |||
483 | static 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 | |||
523 | static 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 | |||
538 | static 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 | |||
553 | static 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 | |||
562 | LSL is statically typed, so stored values are not converted, only the values used in expressions are. | ||
563 | Lua is dynamically typed, so stored values are changed (sometimes I think). | ||
564 | |||
565 | LSL 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 | |||
573 | Explicit 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 | |||
584 | QUIRK - I have seen cases where a double explicit typecast was needed in SL, but was considered to be invalid syntax in OS. | ||
585 | |||
586 | Any binary operation involving a float and an integer implicitly casts the integer to float. | ||
587 | |||
588 | A boolean operation deals with TRUE (1) and FALSE (0). Any non zero value is a TRUE (generally sigh). | ||
589 | Bitwise operations only apply to integers. The shifts are arithmatic, not logical. Right shifted bits are dropped, left shifts the sign bit. | ||
590 | |||
591 | integer = integer0 % integer1; // Apparently only applies to integers, but works fine on floats in OS. | ||
592 | string = string0 + string1; // Concatenation. | ||
593 | list = list0 + list1; // Concatenation. Also works if either is not a list, it's promoted to a list first. | ||
594 | list = (list=[]) + list + ["new_item"]; // Voodoo needed for old LSL, works in Mono but not needed, does not work in OS. Works for strings to. | ||
595 | bool = list == != int // Only compares the lengths, probably applies to the other conditionals to. | ||
596 | vector = vector0 + vector1; // Add elements together. | ||
597 | vector = vector0 - vector1; // Subtract elements of vector1 from elements of vector0. | ||
598 | float = vector0 * vector1; // A dot product of the vectors. | ||
599 | vector = vector0 % vector1; // A cross product of the vectors. | ||
600 | vector = 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. | ||
601 | vector = 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. | ||
602 | vector = vector * rotation; // Rotate the vector by the rotation. Other way around wont compile. | ||
603 | vector = vector / rotation; // Rotate the vector by the rotation, in the opposite direction. Other way around wont compile. | ||
604 | rotation = llGetRot() * rotation; // Rotate an object around the global axis. | ||
605 | rotation = rotation * llGetLocalRot(); // Rotate an object around the local axis. | ||
606 | rotation = 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. | ||
608 | rotation = rotation0 + rotation1; // Similar to vector, but it's a meaningless thing as far as rotations go. | ||
609 | rotation = rotation0 - rotation1; // Similar to vector, but it's a meaningless thing as far as rotations go. | ||
610 | |||
611 | A boolean operator results in a boolean value. (any types) | ||
612 | A comparison operator results in a boolean value. (any types) | ||
613 | A bitwise operator results in an integer value. (intInt or int) | ||
614 | A dot product operator results in a float value. (vector * vector) | ||
615 | A vectorFloat results in a vector value. | ||
616 | |||
617 | */ | ||
618 | |||
619 | static 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 | |||
743 | static 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 | |||
756 | static 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 | |||
782 | static 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 | |||
797 | static void outputFloatToken(FILE *file, outputMode mode, LSL_Leaf *content) | ||
798 | { | ||
799 | if (content) | ||
800 | fprintf(file, "%g", content->value.floatValue); | ||
801 | } | ||
802 | |||
803 | static 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 | |||
816 | static void outputIntegerToken(FILE *file, outputMode mode, LSL_Leaf *content) | ||
817 | { | ||
818 | if (content) | ||
819 | fprintf(file, "%d", content->value.integerValue); | ||
820 | } | ||
821 | |||
822 | static void outputParameterToken(FILE *file, outputMode mode, LSL_Leaf *content) | ||
823 | { | ||
824 | if (content) | ||
825 | fprintf(file, "%s", content->value.parameterValue->name); | ||
826 | } | ||
827 | |||
828 | static void outputParameterListToken(FILE *file, outputMode mode, LSL_Leaf *content) | ||
829 | { | ||
830 | if (content) | ||
831 | outputLeaf(file, mode, content->value.listValue); | ||
832 | } | ||
833 | |||
834 | static 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 | |||
844 | static 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 | |||
855 | static 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 | |||
866 | static void outputVariableToken(FILE *file, outputMode mode, LSL_Leaf *content) | ||
867 | { | ||
868 | if (content) | ||
869 | fprintf(file, "%s", content->value.variableValue->name); | ||
870 | } | ||
871 | |||
872 | static 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 | |||
915 | static 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 | |||
969 | char *test[] = {"test2.lsl", "test2.lsl"}; | ||
970 | |||
971 | int 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(¶m, 0, sizeof(param)); | ||
1003 | param.argc = argc; | ||
1004 | param.argv = argv; | ||
1005 | |||
1006 | // Loop through the files. | ||
1007 | while (nextFile(¶m)) | ||
1008 | { | ||
1009 | void *pParser = ParseAlloc(malloc); | ||
1010 | int yv; | ||
1011 | |||
1012 | #ifdef LUASL_DEBUG | ||
1013 | // yydebug= 5; | ||
1014 | #endif | ||
1015 | if (yylex_init_extra(¶m, &(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, ¶m); | ||
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, ¶m); | ||
1035 | ParseFree(pParser, free); | ||
1036 | doneParsing(¶m); | ||
1037 | } | ||
1038 | } | ||
1039 | else | ||
1040 | { | ||
1041 | fprintf(stderr, "No memory for tokens!"); | ||
1042 | return 1; | ||
1043 | } | ||
1044 | |||
1045 | return 0; | ||
1046 | } | ||
1047 | |||
diff --git a/LuaSL/src/LuaSL_LSL_tree.h b/LuaSL/src/LuaSL_LSL_tree.h index 84610b6..b287b8f 100644 --- a/LuaSL/src/LuaSL_LSL_tree.h +++ b/LuaSL/src/LuaSL_LSL_tree.h | |||
@@ -54,13 +54,13 @@ typedef enum | |||
54 | typedef void (*outputToken) (FILE *file, outputMode mode, LSL_Leaf *content); | 54 | typedef void (*outputToken) (FILE *file, outputMode mode, LSL_Leaf *content); |
55 | typedef LSL_Leaf * (*evaluateToken) (LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right); | 55 | typedef LSL_Leaf * (*evaluateToken) (LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right); |
56 | 56 | ||
57 | #ifndef FALSE | 57 | //#ifndef FALSE |
58 | typedef enum | 58 | //typedef enum |
59 | { | 59 | //{ |
60 | FALSE = 0, | 60 | // FALSE = 0, |
61 | TRUE = 1 | 61 | // TRUE = 1 |
62 | } boolean; | 62 | //} boolean; |
63 | #endif | 63 | //#endif |
64 | 64 | ||
65 | typedef enum | 65 | typedef enum |
66 | { | 66 | { |
diff --git a/LuaSL/src/LuaSL_LSL_yaccer.y b/LuaSL/src/LuaSL_LSL_yaccer.y deleted file mode 100644 index 8cc433d..0000000 --- a/LuaSL/src/LuaSL_LSL_yaccer.y +++ /dev/null | |||
@@ -1,1474 +0,0 @@ | |||
1 | %{ | ||
2 | |||
3 | #include "LuaSL_LSL_tree.h" | ||
4 | |||
5 | //int yylex(void); | ||
6 | //int yyparse( void ); | ||
7 | //int yyerror(const char *fmt, ...); | ||
8 | |||
9 | #if LL_LINUX | ||
10 | // broken yacc codegen... --ryan. | ||
11 | #define getenv getenv_workaround | ||
12 | #endif | ||
13 | |||
14 | #ifdef LL_WINDOWS | ||
15 | #pragma warning (disable : 4702) // warning C4702: unreachable code | ||
16 | #pragma warning( disable : 4065 ) // warning: switch statement contains 'default' but no 'case' labels | ||
17 | #endif | ||
18 | |||
19 | %} | ||
20 | |||
21 | |||
22 | %token INTEGER | ||
23 | %token FLOAT_TYPE | ||
24 | %token STRING | ||
25 | %token LLKEY | ||
26 | %token VECTOR | ||
27 | %token QUATERNION | ||
28 | %token LIST | ||
29 | |||
30 | %token STATE | ||
31 | %token EVENT | ||
32 | %token JUMP | ||
33 | %token RETURN | ||
34 | |||
35 | %token STATE_ENTRY | ||
36 | %token STATE_EXIT | ||
37 | %token TOUCH_START | ||
38 | %token TOUCH | ||
39 | %token TOUCH_END | ||
40 | %token COLLISION_START | ||
41 | %token COLLISION | ||
42 | %token COLLISION_END | ||
43 | %token LAND_COLLISION_START | ||
44 | %token LAND_COLLISION | ||
45 | %token LAND_COLLISION_END | ||
46 | %token TIMER | ||
47 | %token CHAT | ||
48 | %token SENSOR | ||
49 | %token NO_SENSOR | ||
50 | %token CONTROL | ||
51 | %token AT_TARGET | ||
52 | %token NOT_AT_TARGET | ||
53 | %token AT_ROT_TARGET | ||
54 | %token NOT_AT_ROT_TARGET | ||
55 | %token MONEY | ||
56 | %token EMAIL | ||
57 | %token RUN_TIME_PERMISSIONS | ||
58 | %token INVENTORY | ||
59 | %token ATTACH | ||
60 | %token DATASERVER | ||
61 | %token MOVING_START | ||
62 | %token MOVING_END | ||
63 | %token REZ | ||
64 | %token OBJECT_REZ | ||
65 | %token LINK_MESSAGE | ||
66 | %token REMOTE_DATA | ||
67 | %token HTTP_RESPONSE | ||
68 | %token HTTP_REQUEST | ||
69 | |||
70 | %token <sval> IDENTIFIER | ||
71 | %token <sval> STATE_DEFAULT | ||
72 | |||
73 | %token <ival> INTEGER_CONSTANT | ||
74 | %token <ival> INTEGER_TRUE | ||
75 | %token <ival> INTEGER_FALSE | ||
76 | |||
77 | %token <fval> FP_CONSTANT | ||
78 | |||
79 | %token <sval> STRING_CONSTANT | ||
80 | |||
81 | %token INC_OP | ||
82 | %token DEC_OP | ||
83 | %token ADD_ASSIGN | ||
84 | %token SUB_ASSIGN | ||
85 | %token MUL_ASSIGN | ||
86 | %token DIV_ASSIGN | ||
87 | %token MOD_ASSIGN | ||
88 | |||
89 | %token EQ | ||
90 | %token NEQ | ||
91 | %token GEQ | ||
92 | %token LEQ | ||
93 | |||
94 | %token BOOLEAN_AND | ||
95 | %token BOOLEAN_OR | ||
96 | |||
97 | %token SHIFT_LEFT | ||
98 | %token SHIFT_RIGHT | ||
99 | |||
100 | %token IF | ||
101 | %token ELSE | ||
102 | %token FOR | ||
103 | %token DO | ||
104 | %token WHILE | ||
105 | |||
106 | %token PRINT | ||
107 | |||
108 | %token PERIOD | ||
109 | |||
110 | %token ZERO_VECTOR | ||
111 | %token ZERO_ROTATION | ||
112 | |||
113 | %token TOUCH_INVALID_VECTOR | ||
114 | %token TOUCH_INVALID_TEXCOORD | ||
115 | |||
116 | %nonassoc LOWER_THAN_ELSE | ||
117 | %nonassoc ELSE | ||
118 | |||
119 | |||
120 | %type <script> lscript_program | ||
121 | %type <global_store> globals | ||
122 | %type <global_store> global | ||
123 | %type <global> global_variable | ||
124 | %type <assignable> simple_assignable | ||
125 | %type <assignable> simple_assignable_no_list | ||
126 | %type <constant> constant | ||
127 | %type <ival> integer_constant | ||
128 | %type <fval> fp_constant | ||
129 | %type <assignable> special_constant | ||
130 | %type <assignable> vector_constant | ||
131 | %type <assignable> quaternion_constant | ||
132 | %type <assignable> list_constant | ||
133 | %type <assignable> list_entries | ||
134 | %type <assignable> list_entry | ||
135 | %type <type> typename | ||
136 | %type <global_funcs> global_function | ||
137 | %type <global_decl> function_parameters | ||
138 | %type <global_decl> function_parameter | ||
139 | %type <state> states | ||
140 | %type <state> other_states | ||
141 | %type <state> default | ||
142 | %type <state> state | ||
143 | %type <handler> state_body | ||
144 | %type <handler> event | ||
145 | %type <event> state_entry | ||
146 | %type <event> state_exit | ||
147 | %type <event> touch_start | ||
148 | %type <event> touch | ||
149 | %type <event> touch_end | ||
150 | %type <event> collision_start | ||
151 | %type <event> collision | ||
152 | %type <event> collision_end | ||
153 | %type <event> land_collision_start | ||
154 | %type <event> land_collision | ||
155 | %type <event> land_collision_end | ||
156 | %type <event> at_target | ||
157 | %type <event> not_at_target | ||
158 | %type <event> at_rot_target | ||
159 | %type <event> not_at_rot_target | ||
160 | %type <event> money | ||
161 | %type <event> email | ||
162 | %type <event> run_time_permissions | ||
163 | %type <event> inventory | ||
164 | %type <event> attach | ||
165 | %type <event> dataserver | ||
166 | %type <event> moving_start | ||
167 | %type <event> moving_end | ||
168 | %type <event> rez | ||
169 | %type <event> object_rez | ||
170 | %type <event> remote_data | ||
171 | %type <event> http_response | ||
172 | %type <event> http_request | ||
173 | %type <event> link_message | ||
174 | %type <event> timer | ||
175 | %type <event> chat | ||
176 | %type <event> sensor | ||
177 | %type <event> no_sensor | ||
178 | %type <event> control | ||
179 | %type <statement> compound_statement | ||
180 | %type <statement> statement | ||
181 | %type <statement> statements | ||
182 | %type <statement> declaration | ||
183 | %type <statement> ';' | ||
184 | %type <statement> '@' | ||
185 | %type <expression> nextforexpressionlist | ||
186 | %type <expression> forexpressionlist | ||
187 | %type <expression> nextfuncexpressionlist | ||
188 | %type <expression> funcexpressionlist | ||
189 | %type <expression> nextlistexpressionlist | ||
190 | %type <expression> listexpressionlist | ||
191 | %type <expression> unarypostfixexpression | ||
192 | %type <expression> vector_initializer | ||
193 | %type <expression> quaternion_initializer | ||
194 | %type <expression> list_initializer | ||
195 | %type <expression> lvalue | ||
196 | %type <expression> '-' | ||
197 | %type <expression> '!' | ||
198 | %type <expression> '~' | ||
199 | %type <expression> '=' | ||
200 | %type <expression> '<' | ||
201 | %type <expression> '>' | ||
202 | %type <expression> '+' | ||
203 | %type <expression> '*' | ||
204 | %type <expression> '/' | ||
205 | %type <expression> '%' | ||
206 | %type <expression> '&' | ||
207 | %type <expression> '|' | ||
208 | %type <expression> '^' | ||
209 | %type <expression> ADD_ASSIGN | ||
210 | %type <expression> SUB_ASSIGN | ||
211 | %type <expression> MUL_ASSIGN | ||
212 | %type <expression> DIV_ASSIGN | ||
213 | %type <expression> MOD_ASSIGN | ||
214 | %type <expression> EQ | ||
215 | %type <expression> NEQ | ||
216 | %type <expression> LEQ | ||
217 | %type <expression> GEQ | ||
218 | %type <expression> BOOLEAN_AND | ||
219 | %type <expression> BOOLEAN_OR | ||
220 | %type <expression> SHIFT_LEFT | ||
221 | %type <expression> SHIFT_RIGHT | ||
222 | %type <expression> INC_OP | ||
223 | %type <expression> DEC_OP | ||
224 | %type <expression> '(' | ||
225 | %type <expression> ')' | ||
226 | %type <expression> PRINT | ||
227 | %type <identifier> name_type | ||
228 | %type <expression> expression | ||
229 | %type <expression> unaryexpression | ||
230 | %type <expression> typecast | ||
231 | |||
232 | %right '=' MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN SUB_ASSIGN | ||
233 | %left BOOLEAN_AND BOOLEAN_OR | ||
234 | %left '|' | ||
235 | %left '^' | ||
236 | %left '&' | ||
237 | %left EQ NEQ | ||
238 | %left '<' LEQ '>' GEQ | ||
239 | %left SHIFT_LEFT SHIFT_RIGHT | ||
240 | %left '+' '-' | ||
241 | %left '*' '/' '%' | ||
242 | %right '!' '~' INC_OP DEC_OP | ||
243 | %nonassoc INITIALIZER | ||
244 | |||
245 | %% | ||
246 | |||
247 | lscript_program | ||
248 | : globals states | ||
249 | { | ||
250 | $$ = new LLScriptScript($1, $2); | ||
251 | gScriptp = $$; | ||
252 | } | ||
253 | | states | ||
254 | { | ||
255 | $$ = new LLScriptScript(NULL, $1); | ||
256 | gScriptp = $$; | ||
257 | } | ||
258 | ; | ||
259 | |||
260 | globals | ||
261 | : global | ||
262 | { | ||
263 | $$ = $1; | ||
264 | } | ||
265 | | global globals | ||
266 | { | ||
267 | $$ = $1; | ||
268 | $1->addGlobal($2); | ||
269 | } | ||
270 | ; | ||
271 | |||
272 | global | ||
273 | : global_variable | ||
274 | { | ||
275 | $$ = new LLScritpGlobalStorage($1); | ||
276 | } | ||
277 | | global_function | ||
278 | { | ||
279 | $$ = new LLScritpGlobalStorage($1); | ||
280 | } | ||
281 | ; | ||
282 | |||
283 | name_type | ||
284 | : typename IDENTIFIER | ||
285 | { | ||
286 | $$ = new LLScriptIdentifier(gLine, gColumn, $2, $1); | ||
287 | } | ||
288 | ; | ||
289 | |||
290 | global_variable | ||
291 | : name_type ';' | ||
292 | { | ||
293 | $$ = new LLScriptGlobalVariable(gLine, gColumn, $1->mType, $1, NULL); | ||
294 | } | ||
295 | | name_type '=' simple_assignable ';' | ||
296 | { | ||
297 | $$ = new LLScriptGlobalVariable(gLine, gColumn, $1->mType, $1, $3); | ||
298 | } | ||
299 | ; | ||
300 | |||
301 | simple_assignable | ||
302 | : simple_assignable_no_list | ||
303 | { | ||
304 | $$ = $1; | ||
305 | } | ||
306 | | list_constant | ||
307 | { | ||
308 | $$ = $1; | ||
309 | } | ||
310 | ; | ||
311 | |||
312 | simple_assignable_no_list | ||
313 | : IDENTIFIER | ||
314 | { | ||
315 | LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $1); | ||
316 | $$ = new LLScriptSAIdentifier(gLine, gColumn, id); | ||
317 | } | ||
318 | | constant | ||
319 | { | ||
320 | $$ = new LLScriptSAConstant(gLine, gColumn, $1); | ||
321 | } | ||
322 | | special_constant | ||
323 | { | ||
324 | $$ = $1; | ||
325 | } | ||
326 | ; | ||
327 | |||
328 | constant | ||
329 | : integer_constant | ||
330 | { | ||
331 | $$ = new LLScriptConstantInteger(gLine, gColumn, $1); | ||
332 | } | ||
333 | | fp_constant | ||
334 | { | ||
335 | $$ = new LLScriptConstantFloat(gLine, gColumn, $1); | ||
336 | } | ||
337 | | STRING_CONSTANT | ||
338 | { | ||
339 | $$ = new LLScriptConstantString(gLine, gColumn, $1); | ||
340 | } | ||
341 | ; | ||
342 | |||
343 | fp_constant | ||
344 | : FP_CONSTANT | ||
345 | { | ||
346 | $$ = $1; | ||
347 | } | ||
348 | | '-' FP_CONSTANT | ||
349 | { | ||
350 | $$ = -$2; | ||
351 | } | ||
352 | ; | ||
353 | |||
354 | integer_constant | ||
355 | : INTEGER_CONSTANT | ||
356 | { | ||
357 | $$ = $1; | ||
358 | } | ||
359 | | INTEGER_TRUE | ||
360 | { | ||
361 | $$ = $1; | ||
362 | } | ||
363 | | INTEGER_FALSE | ||
364 | { | ||
365 | $$ = $1; | ||
366 | } | ||
367 | | '-' INTEGER_CONSTANT | ||
368 | { | ||
369 | $$ = -$2; | ||
370 | } | ||
371 | ; | ||
372 | |||
373 | special_constant | ||
374 | : vector_constant | ||
375 | { | ||
376 | $$ = $1; | ||
377 | } | ||
378 | | quaternion_constant | ||
379 | { | ||
380 | $$ = $1; | ||
381 | } | ||
382 | ; | ||
383 | |||
384 | vector_constant | ||
385 | : '<' simple_assignable ',' simple_assignable ',' simple_assignable '>' | ||
386 | { | ||
387 | $$ = new LLScriptSAVector(gLine, gColumn, $2, $4, $6); | ||
388 | } | ||
389 | | ZERO_VECTOR | ||
390 | { | ||
391 | LLScriptConstantFloat *cf0 = new LLScriptConstantFloat(gLine, gColumn, 0.f); | ||
392 | LLScriptSAConstant *sa0 = new LLScriptSAConstant(gLine, gColumn, cf0); | ||
393 | LLScriptConstantFloat *cf1 = new LLScriptConstantFloat(gLine, gColumn, 0.f); | ||
394 | LLScriptSAConstant *sa1 = new LLScriptSAConstant(gLine, gColumn, cf1); | ||
395 | LLScriptConstantFloat *cf2 = new LLScriptConstantFloat(gLine, gColumn, 0.f); | ||
396 | LLScriptSAConstant *sa2 = new LLScriptSAConstant(gLine, gColumn, cf2); | ||
397 | $$ = new LLScriptSAVector(gLine, gColumn, sa0, sa1, sa2); | ||
398 | } | ||
399 | | TOUCH_INVALID_VECTOR | ||
400 | { | ||
401 | LLScriptConstantFloat *cf0 = new LLScriptConstantFloat(gLine, gColumn, 0.f); | ||
402 | LLScriptSAConstant *sa0 = new LLScriptSAConstant(gLine, gColumn, cf0); | ||
403 | LLScriptConstantFloat *cf1 = new LLScriptConstantFloat(gLine, gColumn, 0.f); | ||
404 | LLScriptSAConstant *sa1 = new LLScriptSAConstant(gLine, gColumn, cf1); | ||
405 | LLScriptConstantFloat *cf2 = new LLScriptConstantFloat(gLine, gColumn, 0.f); | ||
406 | LLScriptSAConstant *sa2 = new LLScriptSAConstant(gLine, gColumn, cf2); | ||
407 | $$ = new LLScriptSAVector(gLine, gColumn, sa0, sa1, sa2); | ||
408 | } | ||
409 | | TOUCH_INVALID_TEXCOORD | ||
410 | { | ||
411 | LLScriptConstantFloat *cf0 = new LLScriptConstantFloat(gLine, gColumn, -1.f); | ||
412 | LLScriptSAConstant *sa0 = new LLScriptSAConstant(gLine, gColumn, cf0); | ||
413 | LLScriptConstantFloat *cf1 = new LLScriptConstantFloat(gLine, gColumn, -1.f); | ||
414 | LLScriptSAConstant *sa1 = new LLScriptSAConstant(gLine, gColumn, cf1); | ||
415 | LLScriptConstantFloat *cf2 = new LLScriptConstantFloat(gLine, gColumn, 0.f); | ||
416 | LLScriptSAConstant *sa2 = new LLScriptSAConstant(gLine, gColumn, cf2); | ||
417 | $$ = new LLScriptSAVector(gLine, gColumn, sa0, sa1, sa2); | ||
418 | } | ||
419 | ; | ||
420 | |||
421 | quaternion_constant | ||
422 | : '<' simple_assignable ',' simple_assignable ',' simple_assignable ',' simple_assignable '>' | ||
423 | { | ||
424 | $$ = new LLScriptSAQuaternion(gLine, gColumn, $2, $4, $6, $8); | ||
425 | } | ||
426 | | ZERO_ROTATION | ||
427 | { | ||
428 | LLScriptConstantFloat *cf0 = new LLScriptConstantFloat(gLine, gColumn, 0.f); | ||
429 | LLScriptSAConstant *sa0 = new LLScriptSAConstant(gLine, gColumn, cf0); | ||
430 | LLScriptConstantFloat *cf1 = new LLScriptConstantFloat(gLine, gColumn, 0.f); | ||
431 | LLScriptSAConstant *sa1 = new LLScriptSAConstant(gLine, gColumn, cf1); | ||
432 | LLScriptConstantFloat *cf2 = new LLScriptConstantFloat(gLine, gColumn, 0.f); | ||
433 | LLScriptSAConstant *sa2 = new LLScriptSAConstant(gLine, gColumn, cf2); | ||
434 | LLScriptConstantFloat *cf3 = new LLScriptConstantFloat(gLine, gColumn, 1.f); | ||
435 | LLScriptSAConstant *sa3 = new LLScriptSAConstant(gLine, gColumn, cf3); | ||
436 | $$ = new LLScriptSAQuaternion(gLine, gColumn, sa0, sa1, sa2, sa3); | ||
437 | } | ||
438 | ; | ||
439 | |||
440 | list_constant | ||
441 | : '[' list_entries ']' | ||
442 | { | ||
443 | $$ = new LLScriptSAList(gLine, gColumn, $2); | ||
444 | } | ||
445 | | '[' ']' | ||
446 | { | ||
447 | $$ = new LLScriptSAList(gLine, gColumn, NULL); | ||
448 | } | ||
449 | ; | ||
450 | |||
451 | list_entries | ||
452 | : list_entry | ||
453 | { | ||
454 | $$ = $1; | ||
455 | } | ||
456 | | list_entry ',' list_entries | ||
457 | { | ||
458 | $$ = $1; | ||
459 | $1->addAssignable($3); | ||
460 | } | ||
461 | ; | ||
462 | |||
463 | list_entry | ||
464 | : simple_assignable_no_list | ||
465 | { | ||
466 | $$ = $1; | ||
467 | } | ||
468 | ; | ||
469 | |||
470 | typename | ||
471 | : INTEGER | ||
472 | { | ||
473 | $$ = new LLScriptType(gLine, gColumn, LST_INTEGER); | ||
474 | } | ||
475 | | FLOAT_TYPE | ||
476 | { | ||
477 | $$ = new LLScriptType(gLine, gColumn, LST_FLOATINGPOINT); | ||
478 | } | ||
479 | | STRING | ||
480 | { | ||
481 | $$ = new LLScriptType(gLine, gColumn, LST_STRING); | ||
482 | } | ||
483 | | LLKEY | ||
484 | { | ||
485 | $$ = new LLScriptType(gLine, gColumn, LST_KEY); | ||
486 | } | ||
487 | | VECTOR | ||
488 | { | ||
489 | $$ = new LLScriptType(gLine, gColumn, LST_VECTOR); | ||
490 | } | ||
491 | | QUATERNION | ||
492 | { | ||
493 | $$ = new LLScriptType(gLine, gColumn, LST_QUATERNION); | ||
494 | } | ||
495 | | LIST | ||
496 | { | ||
497 | $$ = new LLScriptType(gLine, gColumn, LST_LIST); | ||
498 | } | ||
499 | ; | ||
500 | |||
501 | global_function | ||
502 | : IDENTIFIER '(' ')' compound_statement | ||
503 | { | ||
504 | LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $1); | ||
505 | $$ = new LLScriptGlobalFunctions(gLine, gColumn, NULL, id, NULL, $4); | ||
506 | } | ||
507 | | name_type '(' ')' compound_statement | ||
508 | { | ||
509 | $$ = new LLScriptGlobalFunctions(gLine, gColumn, $1->mType, $1, NULL, $4); | ||
510 | } | ||
511 | | IDENTIFIER '(' function_parameters ')' compound_statement | ||
512 | { | ||
513 | LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $1); | ||
514 | $$ = new LLScriptGlobalFunctions(gLine, gColumn, NULL, id, $3, $5); | ||
515 | } | ||
516 | | name_type '(' function_parameters ')' compound_statement | ||
517 | { | ||
518 | $$ = new LLScriptGlobalFunctions(gLine, gColumn, $1->mType, $1, $3, $5); | ||
519 | } | ||
520 | ; | ||
521 | |||
522 | function_parameters | ||
523 | : function_parameter | ||
524 | { | ||
525 | $$ = $1; | ||
526 | } | ||
527 | | function_parameter ',' function_parameters | ||
528 | { | ||
529 | $$ = $1; | ||
530 | $1->addFunctionParameter($3); | ||
531 | } | ||
532 | ; | ||
533 | |||
534 | function_parameter | ||
535 | : typename IDENTIFIER | ||
536 | { | ||
537 | LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $2); | ||
538 | $$ = new LLScriptFunctionDec(gLine, gColumn, $1, id); | ||
539 | } | ||
540 | ; | ||
541 | |||
542 | states | ||
543 | : default | ||
544 | { | ||
545 | $$ = $1; | ||
546 | } | ||
547 | | default other_states | ||
548 | { | ||
549 | $$ = $1; | ||
550 | $1->mNextp = $2; | ||
551 | } | ||
552 | ; | ||
553 | |||
554 | other_states | ||
555 | : state | ||
556 | { | ||
557 | $$ = $1; | ||
558 | } | ||
559 | | state other_states | ||
560 | { | ||
561 | $$ = $1; | ||
562 | $1->addState($2); | ||
563 | } | ||
564 | ; | ||
565 | |||
566 | default | ||
567 | : STATE_DEFAULT '{' state_body '}' | ||
568 | { | ||
569 | LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $1); | ||
570 | $$ = new LLScriptState(gLine, gColumn, LSSTYPE_DEFAULT, id, $3); | ||
571 | } | ||
572 | ; | ||
573 | |||
574 | state | ||
575 | : STATE IDENTIFIER '{' state_body '}' | ||
576 | { | ||
577 | LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $2); | ||
578 | $$ = new LLScriptState(gLine, gColumn, LSSTYPE_USER, id, $4); | ||
579 | } | ||
580 | ; | ||
581 | |||
582 | state_body | ||
583 | : event | ||
584 | { | ||
585 | $$ = $1; | ||
586 | } | ||
587 | | event state_body | ||
588 | { | ||
589 | $$ = $1; | ||
590 | $1->addEvent($2); | ||
591 | } | ||
592 | ; | ||
593 | |||
594 | event | ||
595 | : state_entry compound_statement | ||
596 | { | ||
597 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
598 | } | ||
599 | | state_exit compound_statement | ||
600 | { | ||
601 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
602 | } | ||
603 | | touch_start compound_statement | ||
604 | { | ||
605 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
606 | } | ||
607 | | touch compound_statement | ||
608 | { | ||
609 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
610 | } | ||
611 | | touch_end compound_statement | ||
612 | { | ||
613 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
614 | } | ||
615 | | collision_start compound_statement | ||
616 | { | ||
617 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
618 | } | ||
619 | | collision compound_statement | ||
620 | { | ||
621 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
622 | } | ||
623 | | collision_end compound_statement | ||
624 | { | ||
625 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
626 | } | ||
627 | | land_collision_start compound_statement | ||
628 | { | ||
629 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
630 | } | ||
631 | | land_collision compound_statement | ||
632 | { | ||
633 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
634 | } | ||
635 | | land_collision_end compound_statement | ||
636 | { | ||
637 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
638 | } | ||
639 | | timer compound_statement | ||
640 | { | ||
641 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
642 | } | ||
643 | | chat compound_statement | ||
644 | { | ||
645 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
646 | } | ||
647 | | sensor compound_statement | ||
648 | { | ||
649 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
650 | } | ||
651 | | no_sensor compound_statement | ||
652 | { | ||
653 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
654 | } | ||
655 | | at_target compound_statement | ||
656 | { | ||
657 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
658 | } | ||
659 | | not_at_target compound_statement | ||
660 | { | ||
661 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
662 | } | ||
663 | | at_rot_target compound_statement | ||
664 | { | ||
665 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
666 | } | ||
667 | | not_at_rot_target compound_statement | ||
668 | { | ||
669 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
670 | } | ||
671 | | money compound_statement | ||
672 | { | ||
673 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
674 | } | ||
675 | | email compound_statement | ||
676 | { | ||
677 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
678 | } | ||
679 | | run_time_permissions compound_statement | ||
680 | { | ||
681 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
682 | } | ||
683 | | inventory compound_statement | ||
684 | { | ||
685 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
686 | } | ||
687 | | attach compound_statement | ||
688 | { | ||
689 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
690 | } | ||
691 | | dataserver compound_statement | ||
692 | { | ||
693 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
694 | } | ||
695 | | control compound_statement | ||
696 | { | ||
697 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
698 | } | ||
699 | | moving_start compound_statement | ||
700 | { | ||
701 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
702 | } | ||
703 | | moving_end compound_statement | ||
704 | { | ||
705 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
706 | } | ||
707 | | rez compound_statement | ||
708 | { | ||
709 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
710 | } | ||
711 | | object_rez compound_statement | ||
712 | { | ||
713 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
714 | } | ||
715 | | link_message compound_statement | ||
716 | { | ||
717 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
718 | } | ||
719 | | remote_data compound_statement | ||
720 | { | ||
721 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
722 | } | ||
723 | | http_response compound_statement | ||
724 | { | ||
725 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
726 | } | ||
727 | | http_request compound_statement | ||
728 | { | ||
729 | $$ = new LLScriptEventHandler(gLine, gColumn, $1, $2); | ||
730 | } | ||
731 | ; | ||
732 | |||
733 | state_entry | ||
734 | : STATE_ENTRY '(' ')' | ||
735 | { | ||
736 | $$ = new LLScriptStateEntryEvent(gLine, gColumn); | ||
737 | } | ||
738 | ; | ||
739 | |||
740 | state_exit | ||
741 | : STATE_EXIT '(' ')' | ||
742 | { | ||
743 | $$ = new LLScriptStateExitEvent(gLine, gColumn); | ||
744 | } | ||
745 | ; | ||
746 | |||
747 | touch_start | ||
748 | : TOUCH_START '(' INTEGER IDENTIFIER ')' | ||
749 | { | ||
750 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
751 | $$ = new LLScriptTouchStartEvent(gLine, gColumn, id1); | ||
752 | } | ||
753 | ; | ||
754 | |||
755 | touch | ||
756 | : TOUCH '(' INTEGER IDENTIFIER ')' | ||
757 | { | ||
758 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
759 | $$ = new LLScriptTouchEvent(gLine, gColumn, id1); | ||
760 | } | ||
761 | ; | ||
762 | |||
763 | touch_end | ||
764 | : TOUCH_END '(' INTEGER IDENTIFIER ')' | ||
765 | { | ||
766 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
767 | $$ = new LLScriptTouchEndEvent(gLine, gColumn, id1); | ||
768 | } | ||
769 | ; | ||
770 | |||
771 | collision_start | ||
772 | : COLLISION_START '(' INTEGER IDENTIFIER ')' | ||
773 | { | ||
774 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
775 | $$ = new LLScriptCollisionStartEvent(gLine, gColumn, id1); | ||
776 | } | ||
777 | ; | ||
778 | |||
779 | collision | ||
780 | : COLLISION '(' INTEGER IDENTIFIER ')' | ||
781 | { | ||
782 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
783 | $$ = new LLScriptCollisionEvent(gLine, gColumn, id1); | ||
784 | } | ||
785 | ; | ||
786 | |||
787 | collision_end | ||
788 | : COLLISION_END '(' INTEGER IDENTIFIER ')' | ||
789 | { | ||
790 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
791 | $$ = new LLScriptCollisionEndEvent(gLine, gColumn, id1); | ||
792 | } | ||
793 | ; | ||
794 | |||
795 | land_collision_start | ||
796 | : LAND_COLLISION_START '(' VECTOR IDENTIFIER ')' | ||
797 | { | ||
798 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
799 | $$ = new LLScriptLandCollisionStartEvent(gLine, gColumn, id1); | ||
800 | } | ||
801 | ; | ||
802 | |||
803 | land_collision | ||
804 | : LAND_COLLISION '(' VECTOR IDENTIFIER ')' | ||
805 | { | ||
806 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
807 | $$ = new LLScriptLandCollisionEvent(gLine, gColumn, id1); | ||
808 | } | ||
809 | ; | ||
810 | |||
811 | land_collision_end | ||
812 | : LAND_COLLISION_END '(' VECTOR IDENTIFIER ')' | ||
813 | { | ||
814 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
815 | $$ = new LLScriptLandCollisionEndEvent(gLine, gColumn, id1); | ||
816 | } | ||
817 | ; | ||
818 | |||
819 | at_target | ||
820 | : AT_TARGET '(' INTEGER IDENTIFIER ',' VECTOR IDENTIFIER ',' VECTOR IDENTIFIER ')' | ||
821 | { | ||
822 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
823 | LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7); | ||
824 | LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10); | ||
825 | $$ = new LLScriptAtTarget(gLine, gColumn, id1, id2, id3); | ||
826 | } | ||
827 | ; | ||
828 | |||
829 | not_at_target | ||
830 | : NOT_AT_TARGET '(' ')' | ||
831 | { | ||
832 | $$ = new LLScriptNotAtTarget(gLine, gColumn); | ||
833 | } | ||
834 | ; | ||
835 | |||
836 | at_rot_target | ||
837 | : AT_ROT_TARGET '(' INTEGER IDENTIFIER ',' QUATERNION IDENTIFIER ',' QUATERNION IDENTIFIER ')' | ||
838 | { | ||
839 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
840 | LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7); | ||
841 | LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10); | ||
842 | $$ = new LLScriptAtRotTarget(gLine, gColumn, id1, id2, id3); | ||
843 | } | ||
844 | ; | ||
845 | |||
846 | not_at_rot_target | ||
847 | : NOT_AT_ROT_TARGET '(' ')' | ||
848 | { | ||
849 | $$ = new LLScriptNotAtRotTarget(gLine, gColumn); | ||
850 | } | ||
851 | ; | ||
852 | |||
853 | money | ||
854 | : MONEY '(' LLKEY IDENTIFIER ',' INTEGER IDENTIFIER ')' | ||
855 | { | ||
856 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
857 | LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7); | ||
858 | $$ = new LLScriptMoneyEvent(gLine, gColumn, id1, id2); | ||
859 | } | ||
860 | ; | ||
861 | |||
862 | |||
863 | : EMAIL '(' STRING IDENTIFIER ',' STRING IDENTIFIER ',' STRING IDENTIFIER ',' STRING IDENTIFIER ',' INTEGER IDENTIFIER ')' | ||
864 | { | ||
865 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
866 | LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7); | ||
867 | LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10); | ||
868 | LLScriptIdentifier *id4 = new LLScriptIdentifier(gLine, gColumn, $13); | ||
869 | LLScriptIdentifier *id5 = new LLScriptIdentifier(gLine, gColumn, $16); | ||
870 | $$ = new LLScriptEmailEvent(gLine, gColumn, id1, id2, id3, id4, id5); | ||
871 | } | ||
872 | ; | ||
873 | |||
874 | run_time_permissions | ||
875 | : RUN_TIME_PERMISSIONS '(' INTEGER IDENTIFIER ')' | ||
876 | { | ||
877 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
878 | $$ = new LLScriptRTPEvent(gLine, gColumn, id1); | ||
879 | } | ||
880 | ; | ||
881 | |||
882 | inventory | ||
883 | : INVENTORY '(' INTEGER IDENTIFIER ')' | ||
884 | { | ||
885 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
886 | $$ = new LLScriptInventoryEvent(gLine, gColumn, id1); | ||
887 | } | ||
888 | ; | ||
889 | |||
890 | attach | ||
891 | : ATTACH '(' LLKEY IDENTIFIER ')' | ||
892 | { | ||
893 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
894 | $$ = new LLScriptAttachEvent(gLine, gColumn, id1); | ||
895 | } | ||
896 | ; | ||
897 | |||
898 | dataserver | ||
899 | : DATASERVER '(' LLKEY IDENTIFIER ',' STRING IDENTIFIER')' | ||
900 | { | ||
901 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
902 | LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7); | ||
903 | $$ = new LLScriptDataserverEvent(gLine, gColumn, id1, id2); | ||
904 | } | ||
905 | ; | ||
906 | |||
907 | moving_start | ||
908 | : MOVING_START '(' ')' | ||
909 | { | ||
910 | $$ = new LLScriptMovingStartEvent(gLine, gColumn); | ||
911 | } | ||
912 | ; | ||
913 | |||
914 | moving_end | ||
915 | : MOVING_END '(' ')' | ||
916 | { | ||
917 | $$ = new LLScriptMovingEndEvent(gLine, gColumn); | ||
918 | } | ||
919 | ; | ||
920 | |||
921 | timer | ||
922 | : TIMER '(' ')' | ||
923 | { | ||
924 | $$ = new LLScriptTimerEvent(gLine, gColumn); | ||
925 | } | ||
926 | ; | ||
927 | |||
928 | chat | ||
929 | : CHAT '(' INTEGER IDENTIFIER ',' STRING IDENTIFIER ',' LLKEY IDENTIFIER ',' STRING IDENTIFIER ')' | ||
930 | { | ||
931 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
932 | LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7); | ||
933 | LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10); | ||
934 | LLScriptIdentifier *id4 = new LLScriptIdentifier(gLine, gColumn, $13); | ||
935 | $$ = new LLScriptChatEvent(gLine, gColumn, id1, id2, id3, id4); | ||
936 | } | ||
937 | ; | ||
938 | |||
939 | sensor | ||
940 | : SENSOR '(' INTEGER IDENTIFIER ')' | ||
941 | { | ||
942 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
943 | $$ = new LLScriptSensorEvent(gLine, gColumn, id1); | ||
944 | } | ||
945 | ; | ||
946 | |||
947 | no_sensor | ||
948 | : NO_SENSOR '(' ')' | ||
949 | { | ||
950 | $$ = new LLScriptNoSensorEvent(gLine, gColumn); | ||
951 | } | ||
952 | ; | ||
953 | |||
954 | control | ||
955 | : CONTROL '(' LLKEY IDENTIFIER ',' INTEGER IDENTIFIER ',' INTEGER IDENTIFIER ')' | ||
956 | { | ||
957 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
958 | LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7); | ||
959 | LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10); | ||
960 | $$ = new LLScriptControlEvent(gLine, gColumn, id1, id2, id3); | ||
961 | } | ||
962 | ; | ||
963 | |||
964 | rez | ||
965 | : REZ '(' INTEGER IDENTIFIER ')' | ||
966 | { | ||
967 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
968 | $$ = new LLScriptRezEvent(gLine, gColumn, id1); | ||
969 | } | ||
970 | ; | ||
971 | |||
972 | object_rez | ||
973 | : OBJECT_REZ '(' LLKEY IDENTIFIER ')' | ||
974 | { | ||
975 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
976 | $$ = new LLScriptObjectRezEvent(gLine, gColumn, id1); | ||
977 | } | ||
978 | ; | ||
979 | |||
980 | link_message | ||
981 | : LINK_MESSAGE '(' INTEGER IDENTIFIER ',' INTEGER IDENTIFIER ',' STRING IDENTIFIER ',' LLKEY IDENTIFIER ')' | ||
982 | { | ||
983 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
984 | LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7); | ||
985 | LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10); | ||
986 | LLScriptIdentifier *id4 = new LLScriptIdentifier(gLine, gColumn, $13); | ||
987 | $$ = new LLScriptLinkMessageEvent(gLine, gColumn, id1, id2, id3, id4); | ||
988 | } | ||
989 | ; | ||
990 | |||
991 | remote_data | ||
992 | : REMOTE_DATA '(' INTEGER IDENTIFIER ',' LLKEY IDENTIFIER ',' LLKEY IDENTIFIER ',' STRING IDENTIFIER ',' INTEGER IDENTIFIER ',' STRING IDENTIFIER ')' | ||
993 | { | ||
994 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
995 | LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7); | ||
996 | LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10); | ||
997 | LLScriptIdentifier *id4 = new LLScriptIdentifier(gLine, gColumn, $13); | ||
998 | LLScriptIdentifier *id5 = new LLScriptIdentifier(gLine, gColumn, $16); | ||
999 | LLScriptIdentifier *id6 = new LLScriptIdentifier(gLine, gColumn, $19); | ||
1000 | $$ = new LLScriptRemoteEvent(gLine, gColumn, id1, id2, id3, id4, id5, id6); | ||
1001 | } | ||
1002 | ; | ||
1003 | |||
1004 | http_response | ||
1005 | : HTTP_RESPONSE '(' LLKEY IDENTIFIER ',' INTEGER IDENTIFIER ',' LIST IDENTIFIER ',' STRING IDENTIFIER ')' | ||
1006 | { | ||
1007 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
1008 | LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7); | ||
1009 | LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10); | ||
1010 | LLScriptIdentifier *id4 = new LLScriptIdentifier(gLine, gColumn, $13); | ||
1011 | $$ = new LLScriptHTTPResponseEvent(gLine, gColumn, id1, id2, id3, id4); | ||
1012 | } | ||
1013 | ; | ||
1014 | |||
1015 | http_request | ||
1016 | : HTTP_REQUEST '(' LLKEY IDENTIFIER ',' STRING IDENTIFIER ',' STRING IDENTIFIER ')' | ||
1017 | { | ||
1018 | LLScriptIdentifier *id1 = new LLScriptIdentifier(gLine, gColumn, $4); | ||
1019 | LLScriptIdentifier *id2 = new LLScriptIdentifier(gLine, gColumn, $7); | ||
1020 | LLScriptIdentifier *id3 = new LLScriptIdentifier(gLine, gColumn, $10); | ||
1021 | $$ = new LLScriptHTTPRequestEvent(gLine, gColumn, id1, id2, id3); | ||
1022 | } | ||
1023 | ; | ||
1024 | |||
1025 | compound_statement | ||
1026 | : '{' '}' | ||
1027 | { | ||
1028 | $$ = new LLScriptCompoundStatement(gLine, gColumn, NULL); | ||
1029 | } | ||
1030 | | '{' statements '}' | ||
1031 | { | ||
1032 | $$ = new LLScriptCompoundStatement(gLine, gColumn, $2); | ||
1033 | } | ||
1034 | ; | ||
1035 | |||
1036 | statements | ||
1037 | : statement | ||
1038 | { | ||
1039 | $$ = $1; | ||
1040 | } | ||
1041 | | statements statement | ||
1042 | { | ||
1043 | $$ = new LLScriptStatementSequence(gLine, gColumn, $1, $2); | ||
1044 | } | ||
1045 | ; | ||
1046 | |||
1047 | statement | ||
1048 | : ';' | ||
1049 | { | ||
1050 | $$ = new LLScriptNOOP(gLine, gColumn); | ||
1051 | } | ||
1052 | | STATE IDENTIFIER ';' | ||
1053 | { | ||
1054 | LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $2); | ||
1055 | $$ = new LLScriptStateChange(gLine, gColumn, id); | ||
1056 | } | ||
1057 | | STATE STATE_DEFAULT ';' | ||
1058 | { | ||
1059 | LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $2); | ||
1060 | $$ = new LLScriptStateChange(gLine, gColumn, id); | ||
1061 | } | ||
1062 | | JUMP IDENTIFIER ';' | ||
1063 | { | ||
1064 | LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $2); | ||
1065 | $$ = new LLScriptJump(gLine, gColumn, id); | ||
1066 | } | ||
1067 | | '@' IDENTIFIER ';' | ||
1068 | { | ||
1069 | LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $2); | ||
1070 | $$ = new LLScriptLabel(gLine, gColumn, id); | ||
1071 | } | ||
1072 | | RETURN expression ';' | ||
1073 | { | ||
1074 | $$ = new LLScriptReturn(gLine, gColumn, $2); | ||
1075 | } | ||
1076 | | RETURN ';' | ||
1077 | { | ||
1078 | $$ = new LLScriptReturn(gLine, gColumn, NULL); | ||
1079 | } | ||
1080 | | expression ';' | ||
1081 | { | ||
1082 | $$ = new LLScriptExpressionStatement(gLine, gColumn, $1); | ||
1083 | } | ||
1084 | | declaration ';' | ||
1085 | { | ||
1086 | $$ = $1; | ||
1087 | } | ||
1088 | | compound_statement | ||
1089 | { | ||
1090 | $$ = $1; | ||
1091 | } | ||
1092 | | IF '(' expression ')' statement %prec LOWER_THAN_ELSE | ||
1093 | { | ||
1094 | $$ = new LLScriptIf(gLine, gColumn, $3, $5); | ||
1095 | $5->mAllowDeclarations = FALSE; | ||
1096 | } | ||
1097 | | IF '(' expression ')' statement ELSE statement | ||
1098 | { | ||
1099 | $$ = new LLScriptIfElse(gLine, gColumn, $3, $5, $7); | ||
1100 | $5->mAllowDeclarations = FALSE; | ||
1101 | $7->mAllowDeclarations = FALSE; | ||
1102 | } | ||
1103 | | FOR '(' forexpressionlist ';' expression ';' forexpressionlist ')' statement | ||
1104 | { | ||
1105 | $$ = new LLScriptFor(gLine, gColumn, $3, $5, $7, $9); | ||
1106 | $9->mAllowDeclarations = FALSE; | ||
1107 | } | ||
1108 | | DO statement WHILE '(' expression ')' ';' | ||
1109 | { | ||
1110 | $$ = new LLScriptDoWhile(gLine, gColumn, $2, $5); | ||
1111 | $2->mAllowDeclarations = FALSE; | ||
1112 | } | ||
1113 | | WHILE '(' expression ')' statement | ||
1114 | { | ||
1115 | $$ = new LLScriptWhile(gLine, gColumn, $3, $5); | ||
1116 | $5->mAllowDeclarations = FALSE; | ||
1117 | } | ||
1118 | ; | ||
1119 | |||
1120 | declaration | ||
1121 | : typename IDENTIFIER | ||
1122 | { | ||
1123 | LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $2); | ||
1124 | $$ = new LLScriptDeclaration(gLine, gColumn, $1, id, NULL); | ||
1125 | } | ||
1126 | | typename IDENTIFIER '=' expression | ||
1127 | { | ||
1128 | LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $2); | ||
1129 | $$ = new LLScriptDeclaration(gLine, gColumn, $1, id, $4); | ||
1130 | } | ||
1131 | ; | ||
1132 | |||
1133 | forexpressionlist | ||
1134 | : /* empty */ | ||
1135 | { | ||
1136 | $$ = NULL; | ||
1137 | } | ||
1138 | | nextforexpressionlist | ||
1139 | { | ||
1140 | $$ = $1; | ||
1141 | } | ||
1142 | ; | ||
1143 | |||
1144 | nextforexpressionlist | ||
1145 | : expression | ||
1146 | { | ||
1147 | $$ = new LLScriptForExpressionList(gLine, gColumn, $1, NULL); | ||
1148 | } | ||
1149 | | expression ',' nextforexpressionlist | ||
1150 | { | ||
1151 | $$ = new LLScriptForExpressionList(gLine, gColumn, $1, $3); | ||
1152 | } | ||
1153 | ; | ||
1154 | |||
1155 | funcexpressionlist | ||
1156 | : /* empty */ | ||
1157 | { | ||
1158 | $$ = NULL; | ||
1159 | } | ||
1160 | | nextfuncexpressionlist | ||
1161 | { | ||
1162 | $$ = $1; | ||
1163 | } | ||
1164 | ; | ||
1165 | |||
1166 | nextfuncexpressionlist | ||
1167 | : expression | ||
1168 | { | ||
1169 | $$ = new LLScriptFuncExpressionList(gLine, gColumn, $1, NULL); | ||
1170 | } | ||
1171 | | expression ',' nextfuncexpressionlist | ||
1172 | { | ||
1173 | $$ = new LLScriptFuncExpressionList(gLine, gColumn, $1, $3); | ||
1174 | } | ||
1175 | ; | ||
1176 | |||
1177 | listexpressionlist | ||
1178 | : /* empty */ | ||
1179 | { | ||
1180 | $$ = NULL; | ||
1181 | } | ||
1182 | | nextlistexpressionlist | ||
1183 | { | ||
1184 | $$ = $1; | ||
1185 | } | ||
1186 | ; | ||
1187 | |||
1188 | nextlistexpressionlist | ||
1189 | : expression | ||
1190 | { | ||
1191 | $$ = new LLScriptListExpressionList(gLine, gColumn, $1, NULL); | ||
1192 | } | ||
1193 | | expression ',' nextlistexpressionlist | ||
1194 | { | ||
1195 | $$ = new LLScriptListExpressionList(gLine, gColumn, $1, $3); | ||
1196 | } | ||
1197 | ; | ||
1198 | |||
1199 | expression | ||
1200 | : unaryexpression | ||
1201 | { | ||
1202 | $$ = $1; | ||
1203 | } | ||
1204 | | lvalue '=' expression | ||
1205 | { | ||
1206 | $$ = new LLScriptAssignment(gLine, gColumn, $1, $3); | ||
1207 | } | ||
1208 | | lvalue ADD_ASSIGN expression | ||
1209 | { | ||
1210 | $$ = new LLScriptAddAssignment(gLine, gColumn, $1, $3); | ||
1211 | } | ||
1212 | | lvalue SUB_ASSIGN expression | ||
1213 | { | ||
1214 | $$ = new LLScriptSubAssignment(gLine, gColumn, $1, $3); | ||
1215 | } | ||
1216 | | lvalue MUL_ASSIGN expression | ||
1217 | { | ||
1218 | $$ = new LLScriptMulAssignment(gLine, gColumn, $1, $3); | ||
1219 | } | ||
1220 | | lvalue DIV_ASSIGN expression | ||
1221 | { | ||
1222 | $$ = new LLScriptDivAssignment(gLine, gColumn, $1, $3); | ||
1223 | } | ||
1224 | | lvalue MOD_ASSIGN expression | ||
1225 | { | ||
1226 | $$ = new LLScriptModAssignment(gLine, gColumn, $1, $3); | ||
1227 | } | ||
1228 | | expression EQ expression | ||
1229 | { | ||
1230 | $$ = new LLScriptEquality(gLine, gColumn, $1, $3); | ||
1231 | } | ||
1232 | | expression NEQ expression | ||
1233 | { | ||
1234 | $$ = new LLScriptNotEquals(gLine, gColumn, $1, $3); | ||
1235 | } | ||
1236 | | expression LEQ expression | ||
1237 | { | ||
1238 | $$ = new LLScriptLessEquals(gLine, gColumn, $1, $3); | ||
1239 | } | ||
1240 | | expression GEQ expression | ||
1241 | { | ||
1242 | $$ = new LLScriptGreaterEquals(gLine, gColumn, $1, $3); | ||
1243 | } | ||
1244 | | expression '<' expression | ||
1245 | { | ||
1246 | $$ = new LLScriptLessThan(gLine, gColumn, $1, $3); | ||
1247 | } | ||
1248 | | expression '>' expression | ||
1249 | { | ||
1250 | $$ = new LLScriptGreaterThan(gLine, gColumn, $1, $3); | ||
1251 | } | ||
1252 | | expression '+' expression | ||
1253 | { | ||
1254 | $$ = new LLScriptPlus(gLine, gColumn, $1, $3); | ||
1255 | } | ||
1256 | | expression '-' expression | ||
1257 | { | ||
1258 | $$ = new LLScriptMinus(gLine, gColumn, $1, $3); | ||
1259 | } | ||
1260 | | expression '*' expression | ||
1261 | { | ||
1262 | $$ = new LLScriptTimes(gLine, gColumn, $1, $3); | ||
1263 | } | ||
1264 | | expression '/' expression | ||
1265 | { | ||
1266 | $$ = new LLScriptDivide(gLine, gColumn, $1, $3); | ||
1267 | } | ||
1268 | | expression '%' expression | ||
1269 | { | ||
1270 | $$ = new LLScriptMod(gLine, gColumn, $1, $3); | ||
1271 | } | ||
1272 | | expression '&' expression | ||
1273 | { | ||
1274 | $$ = new LLScriptBitAnd(gLine, gColumn, $1, $3); | ||
1275 | } | ||
1276 | | expression '|' expression | ||
1277 | { | ||
1278 | $$ = new LLScriptBitOr(gLine, gColumn, $1, $3); | ||
1279 | } | ||
1280 | | expression '^' expression | ||
1281 | { | ||
1282 | $$ = new LLScriptBitXor(gLine, gColumn, $1, $3); | ||
1283 | } | ||
1284 | | expression BOOLEAN_AND expression | ||
1285 | { | ||
1286 | $$ = new LLScriptBooleanAnd(gLine, gColumn, $1, $3); | ||
1287 | } | ||
1288 | | expression BOOLEAN_OR expression | ||
1289 | { | ||
1290 | $$ = new LLScriptBooleanOr(gLine, gColumn, $1, $3); | ||
1291 | } | ||
1292 | | expression SHIFT_LEFT expression | ||
1293 | { | ||
1294 | $$ = new LLScriptShiftLeft(gLine, gColumn, $1, $3); | ||
1295 | } | ||
1296 | | expression SHIFT_RIGHT expression | ||
1297 | { | ||
1298 | $$ = new LLScriptShiftRight(gLine, gColumn, $1, $3); | ||
1299 | } | ||
1300 | ; | ||
1301 | |||
1302 | unaryexpression | ||
1303 | : '-' expression | ||
1304 | { | ||
1305 | $$ = new LLScriptUnaryMinus(gLine, gColumn, $2); | ||
1306 | } | ||
1307 | | '!' expression | ||
1308 | { | ||
1309 | $$ = new LLScriptBooleanNot(gLine, gColumn, $2); | ||
1310 | } | ||
1311 | | '~' expression | ||
1312 | { | ||
1313 | $$ = new LLScriptBitNot(gLine, gColumn, $2); | ||
1314 | } | ||
1315 | | INC_OP lvalue | ||
1316 | { | ||
1317 | $$ = new LLScriptPreIncrement(gLine, gColumn, $2); | ||
1318 | } | ||
1319 | | DEC_OP lvalue | ||
1320 | { | ||
1321 | $$ = new LLScriptPreDecrement(gLine, gColumn, $2); | ||
1322 | } | ||
1323 | | typecast | ||
1324 | { | ||
1325 | $$ = $1; | ||
1326 | } | ||
1327 | | unarypostfixexpression | ||
1328 | { | ||
1329 | $$ = $1; | ||
1330 | } | ||
1331 | | '(' expression ')' | ||
1332 | { | ||
1333 | $$ = new LLScriptParenthesis(gLine, gColumn, $2); | ||
1334 | } | ||
1335 | ; | ||
1336 | |||
1337 | typecast | ||
1338 | : '(' typename ')' lvalue | ||
1339 | { | ||
1340 | $$ = new LLScriptTypeCast(gLine, gColumn, $2, $4); | ||
1341 | } | ||
1342 | | '(' typename ')' constant | ||
1343 | { | ||
1344 | LLScriptConstantExpression *temp = new LLScriptConstantExpression(gLine, gColumn, $4); | ||
1345 | $$ = new LLScriptTypeCast(gLine, gColumn, $2, temp); | ||
1346 | } | ||
1347 | | '(' typename ')' unarypostfixexpression | ||
1348 | { | ||
1349 | $$ = new LLScriptTypeCast(gLine, gColumn, $2, $4); | ||
1350 | } | ||
1351 | | '(' typename ')' '(' expression ')' | ||
1352 | { | ||
1353 | $$ = new LLScriptTypeCast(gLine, gColumn, $2, $5); | ||
1354 | } | ||
1355 | ; | ||
1356 | |||
1357 | unarypostfixexpression | ||
1358 | : vector_initializer | ||
1359 | { | ||
1360 | $$ = $1; | ||
1361 | } | ||
1362 | | quaternion_initializer | ||
1363 | { | ||
1364 | $$ = $1; | ||
1365 | } | ||
1366 | | list_initializer | ||
1367 | { | ||
1368 | $$ = $1; | ||
1369 | } | ||
1370 | | lvalue | ||
1371 | { | ||
1372 | $$ = $1; | ||
1373 | } | ||
1374 | | lvalue INC_OP | ||
1375 | { | ||
1376 | $$ = new LLScriptPostIncrement(gLine, gColumn, $1); | ||
1377 | } | ||
1378 | | lvalue DEC_OP | ||
1379 | { | ||
1380 | $$ = new LLScriptPostDecrement(gLine, gColumn, $1); | ||
1381 | } | ||
1382 | | IDENTIFIER '(' funcexpressionlist ')' | ||
1383 | { | ||
1384 | LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $1); | ||
1385 | $$ = new LLScriptFunctionCall(gLine, gColumn, id, $3); | ||
1386 | } | ||
1387 | | PRINT '(' expression ')' | ||
1388 | { | ||
1389 | $$ = new LLScriptPrint(gLine, gColumn, $3); | ||
1390 | } | ||
1391 | | constant | ||
1392 | { | ||
1393 | $$ = new LLScriptConstantExpression(gLine, gColumn, $1); | ||
1394 | } | ||
1395 | ; | ||
1396 | |||
1397 | vector_initializer | ||
1398 | : '<' expression ',' expression ',' expression '>' %prec INITIALIZER | ||
1399 | { | ||
1400 | $$ = new LLScriptVectorInitializer(gLine, gColumn, $2, $4, $6); | ||
1401 | } | ||
1402 | | ZERO_VECTOR | ||
1403 | { | ||
1404 | LLScriptConstantFloat *cf0 = new LLScriptConstantFloat(gLine, gColumn, 0.f); | ||
1405 | LLScriptConstantExpression *sa0 = new LLScriptConstantExpression(gLine, gColumn, cf0); | ||
1406 | LLScriptConstantFloat *cf1 = new LLScriptConstantFloat(gLine, gColumn, 0.f); | ||
1407 | LLScriptConstantExpression *sa1 = new LLScriptConstantExpression(gLine, gColumn, cf1); | ||
1408 | LLScriptConstantFloat *cf2 = new LLScriptConstantFloat(gLine, gColumn, 0.f); | ||
1409 | LLScriptConstantExpression *sa2 = new LLScriptConstantExpression(gLine, gColumn, cf2); | ||
1410 | $$ = new LLScriptVectorInitializer(gLine, gColumn, sa0, sa1, sa2); | ||
1411 | } | ||
1412 | | TOUCH_INVALID_VECTOR | ||
1413 | { | ||
1414 | LLScriptConstantFloat *cf0 = new LLScriptConstantFloat(gLine, gColumn, 0.f); | ||
1415 | LLScriptConstantExpression *sa0 = new LLScriptConstantExpression(gLine, gColumn, cf0); | ||
1416 | LLScriptConstantFloat *cf1 = new LLScriptConstantFloat(gLine, gColumn, 0.f); | ||
1417 | LLScriptConstantExpression *sa1 = new LLScriptConstantExpression(gLine, gColumn, cf1); | ||
1418 | LLScriptConstantFloat *cf2 = new LLScriptConstantFloat(gLine, gColumn, 0.f); | ||
1419 | LLScriptConstantExpression *sa2 = new LLScriptConstantExpression(gLine, gColumn, cf2); | ||
1420 | $$ = new LLScriptVectorInitializer(gLine, gColumn, sa0, sa1, sa2); | ||
1421 | } | ||
1422 | | TOUCH_INVALID_TEXCOORD | ||
1423 | { | ||
1424 | LLScriptConstantFloat *cf0 = new LLScriptConstantFloat(gLine, gColumn, -1.f); | ||
1425 | LLScriptConstantExpression *sa0 = new LLScriptConstantExpression(gLine, gColumn, cf0); | ||
1426 | LLScriptConstantFloat *cf1 = new LLScriptConstantFloat(gLine, gColumn, -1.f); | ||
1427 | LLScriptConstantExpression *sa1 = new LLScriptConstantExpression(gLine, gColumn, cf1); | ||
1428 | LLScriptConstantFloat *cf2 = new LLScriptConstantFloat(gLine, gColumn, 0.f); | ||
1429 | LLScriptConstantExpression *sa2 = new LLScriptConstantExpression(gLine, gColumn, cf2); | ||
1430 | $$ = new LLScriptVectorInitializer(gLine, gColumn, sa0, sa1, sa2); | ||
1431 | } | ||
1432 | ; | ||
1433 | |||
1434 | quaternion_initializer | ||
1435 | : '<' expression ',' expression ',' expression ',' expression '>' %prec INITIALIZER | ||
1436 | { | ||
1437 | $$ = new LLScriptQuaternionInitializer(gLine, gColumn, $2, $4, $6, $8); | ||
1438 | } | ||
1439 | | ZERO_ROTATION | ||
1440 | { | ||
1441 | LLScriptConstantFloat *cf0 = new LLScriptConstantFloat(gLine, gColumn, 0.f); | ||
1442 | LLScriptConstantExpression *sa0 = new LLScriptConstantExpression(gLine, gColumn, cf0); | ||
1443 | LLScriptConstantFloat *cf1 = new LLScriptConstantFloat(gLine, gColumn, 0.f); | ||
1444 | LLScriptConstantExpression *sa1 = new LLScriptConstantExpression(gLine, gColumn, cf1); | ||
1445 | LLScriptConstantFloat *cf2 = new LLScriptConstantFloat(gLine, gColumn, 0.f); | ||
1446 | LLScriptConstantExpression *sa2 = new LLScriptConstantExpression(gLine, gColumn, cf2); | ||
1447 | LLScriptConstantFloat *cf3 = new LLScriptConstantFloat(gLine, gColumn, 1.f); | ||
1448 | LLScriptConstantExpression *sa3 = new LLScriptConstantExpression(gLine, gColumn, cf3); | ||
1449 | $$ = new LLScriptQuaternionInitializer(gLine, gColumn, sa0, sa1, sa2, sa3); | ||
1450 | } | ||
1451 | ; | ||
1452 | |||
1453 | list_initializer | ||
1454 | : '[' listexpressionlist ']' %prec INITIALIZER | ||
1455 | { | ||
1456 | $$ = new LLScriptListInitializer(gLine, gColumn, $2); | ||
1457 | } | ||
1458 | ; | ||
1459 | |||
1460 | lvalue | ||
1461 | : IDENTIFIER | ||
1462 | { | ||
1463 | LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $1); | ||
1464 | $$ = new LLScriptLValue(gLine, gColumn, id, NULL); | ||
1465 | } | ||
1466 | | IDENTIFIER PERIOD IDENTIFIER | ||
1467 | { | ||
1468 | LLScriptIdentifier *id = new LLScriptIdentifier(gLine, gColumn, $1); | ||
1469 | LLScriptIdentifier *ac = new LLScriptIdentifier(gLine, gColumn, $3); | ||
1470 | $$ = new LLScriptLValue(gLine, gColumn, id, ac); | ||
1471 | } | ||
1472 | ; | ||
1473 | |||
1474 | %% | ||
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 | ||
5 | static LSL_Leaf *evaluateFloatToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right); | ||
6 | static LSL_Leaf *evaluateIntegerToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right); | ||
7 | static LSL_Leaf *evaluateNoToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right); | ||
8 | static LSL_Leaf *evaluateOperationToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right); | ||
9 | static LSL_Leaf *eveluateParenthesisToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right); | ||
10 | static LSL_Leaf *evaluateStatementToken(LSL_Leaf *content, LSL_Leaf *left, LSL_Leaf *right); | ||
11 | static void outputFloatToken(FILE *file, outputMode mode, LSL_Leaf *content); | ||
12 | static void outputFunctionToken(FILE *file, outputMode mode, LSL_Leaf *content); | ||
13 | static void outputIntegerToken(FILE *file, outputMode mode, LSL_Leaf *content); | ||
14 | static void outputParameterToken(FILE *file, outputMode mode, LSL_Leaf *content); | ||
15 | static void outputParameterListToken(FILE *file, outputMode mode, LSL_Leaf *content); | ||
16 | static void outputParenthesisToken(FILE *file, outputMode mode, LSL_Leaf *content); | ||
17 | static void outputStateToken(FILE *file, outputMode mode, LSL_Leaf *content); | ||
18 | static void outputStatementToken(FILE *file, outputMode mode, LSL_Leaf *content); | ||
19 | static void outputVariableToken(FILE *file, outputMode mode, LSL_Leaf *content); | ||
20 | |||
21 | LSL_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 | |||
131 | allowedTypes 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 | |||
167 | opType 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 | |||
183 | LSL_Token **tokens = NULL; | ||
184 | int lowestToken = 999999; | ||
185 | |||
186 | |||
187 | static 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 | |||
201 | void 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 | |||
213 | LSL_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 | |||
293 | LSL_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 | |||
312 | LSL_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 | |||
329 | LSL_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 | |||
354 | LSL_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 | |||
374 | LSL_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 | |||
391 | LSL_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 | |||
406 | LSL_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 | |||
431 | LSL_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 | |||
465 | void 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 | |||
477 | void endBlock(LuaSL_yyparseParam *param, LSL_Leaf *block) | ||
478 | { | ||
479 | param->currentBlock = param->currentBlock->outerBlock; | ||
480 | } | ||
481 | |||
482 | static 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 | |||
522 | static 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 | |||
537 | static 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 | |||
552 | static 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 | |||
561 | LSL is statically typed, so stored values are not converted, only the values used in expressions are. | ||
562 | Lua is dynamically typed, so stored values are changed (sometimes I think). | ||
563 | |||
564 | LSL 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 | |||
572 | Explicit 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 | |||
583 | QUIRK - I have seen cases where a double explicit typecast was needed in SL, but was considered to be invalid syntax in OS. | ||
584 | |||
585 | Any binary operation involving a float and an integer implicitly casts the integer to float. | ||
586 | |||
587 | A boolean operation deals with TRUE (1) and FALSE (0). Any non zero value is a TRUE (generally sigh). | ||
588 | Bitwise operations only apply to integers. The shifts are arithmatic, not logical. Right shifted bits are dropped, left shifts the sign bit. | ||
589 | |||
590 | integer = integer0 % integer1; // Apparently only applies to integers, but works fine on floats in OS. | ||
591 | string = string0 + string1; // Concatenation. | ||
592 | list = list0 + list1; // Concatenation. Also works if either is not a list, it's promoted to a list first. | ||
593 | list = (list=[]) + list + ["new_item"]; // Voodoo needed for old LSL, works in Mono but not needed, does not work in OS. Works for strings to. | ||
594 | bool = list == != int // Only compares the lengths, probably applies to the other conditionals to. | ||
595 | vector = vector0 + vector1; // Add elements together. | ||
596 | vector = vector0 - vector1; // Subtract elements of vector1 from elements of vector0. | ||
597 | float = vector0 * vector1; // A dot product of the vectors. | ||
598 | vector = vector0 % vector1; // A cross product of the vectors. | ||
599 | vector = 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. | ||
600 | vector = 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. | ||
601 | vector = vector * rotation; // Rotate the vector by the rotation. Other way around wont compile. | ||
602 | vector = vector / rotation; // Rotate the vector by the rotation, in the opposite direction. Other way around wont compile. | ||
603 | rotation = llGetRot() * rotation; // Rotate an object around the global axis. | ||
604 | rotation = rotation * llGetLocalRot(); // Rotate an object around the local axis. | ||
605 | rotation = 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. | ||
607 | rotation = rotation0 + rotation1; // Similar to vector, but it's a meaningless thing as far as rotations go. | ||
608 | rotation = rotation0 - rotation1; // Similar to vector, but it's a meaningless thing as far as rotations go. | ||
609 | |||
610 | A boolean operator results in a boolean value. (any types) | ||
611 | A comparison operator results in a boolean value. (any types) | ||
612 | A bitwise operator results in an integer value. (intInt or int) | ||
613 | A dot product operator results in a float value. (vector * vector) | ||
614 | A vectorFloat results in a vector value. | ||
615 | |||
616 | */ | ||
617 | |||
618 | static 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 | |||
742 | static 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 | |||
755 | static 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 | |||
781 | static 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 | |||
796 | static void outputFloatToken(FILE *file, outputMode mode, LSL_Leaf *content) | ||
797 | { | ||
798 | if (content) | ||
799 | fprintf(file, "%g", content->value.floatValue); | ||
800 | } | ||
801 | |||
802 | static 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 | |||
815 | static void outputIntegerToken(FILE *file, outputMode mode, LSL_Leaf *content) | ||
816 | { | ||
817 | if (content) | ||
818 | fprintf(file, "%d", content->value.integerValue); | ||
819 | } | ||
820 | |||
821 | static void outputParameterToken(FILE *file, outputMode mode, LSL_Leaf *content) | ||
822 | { | ||
823 | if (content) | ||
824 | fprintf(file, "%s", content->value.parameterValue->name); | ||
825 | } | ||
826 | |||
827 | static void outputParameterListToken(FILE *file, outputMode mode, LSL_Leaf *content) | ||
828 | { | ||
829 | if (content) | ||
830 | outputLeaf(file, mode, content->value.listValue); | ||
831 | } | ||
832 | |||
833 | static 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 | |||
843 | static 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 | |||
854 | static 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 | |||
865 | static void outputVariableToken(FILE *file, outputMode mode, LSL_Leaf *content) | ||
866 | { | ||
867 | if (content) | ||
868 | fprintf(file, "%s", content->value.variableValue->name); | ||
869 | } | ||
870 | |||
871 | static 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 | |||
914 | Eina_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 | |||
4 | Eina_Bool compileLSL(gameGlobals *game, char *script) | 942 | Eina_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(¶m, 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(¶m, &(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, ¶m); | ||
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, ¶m); | ||
991 | ParseFree(pParser, free); | ||
992 | doneParsing(¶m); | ||
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 | ||
1014 | static 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 | |||
1068 | char *test[] = {"test2.lsl", "test2.lsl"}; | ||
1069 | |||
1070 | int 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(¶m, 0, sizeof(param)); | ||
1102 | param.argc = argc; | ||
1103 | param.argv = argv; | ||
1104 | |||
1105 | // Loop through the files. | ||
1106 | while (nextFile(¶m)) | ||
1107 | { | ||
1108 | void *pParser = ParseAlloc(malloc); | ||
1109 | int yv; | ||
1110 | |||
1111 | #ifdef LUASL_DEBUG | ||
1112 | // yydebug= 5; | ||
1113 | #endif | ||
1114 | if (yylex_init_extra(¶m, &(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, ¶m); | ||
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, ¶m); | ||
1134 | ParseFree(pParser, free); | ||
1135 | doneParsing(¶m); | ||
1136 | } | ||
1137 | } | ||
1138 | else | ||
1139 | { | ||
1140 | fprintf(stderr, "No memory for tokens!"); | ||
1141 | return 1; | ||
1142 | } | ||
1143 | |||
1144 | return 0; | ||
1145 | } | ||
1146 | #endif | ||
diff --git a/LuaSL/src/LuaSL_lexer.l b/LuaSL/src/LuaSL_lexer.l index 4dde0ac..2661b76 100644 --- a/LuaSL/src/LuaSL_lexer.l +++ b/LuaSL/src/LuaSL_lexer.l | |||
@@ -1,5 +1,6 @@ | |||
1 | %{ | 1 | %{ |
2 | 2 | ||
3 | #include "LuaSL.h" | ||
3 | #define excludeLexer | 4 | #define excludeLexer |
4 | #include "LuaSL_LSL_tree.h" | 5 | #include "LuaSL_LSL_tree.h" |
5 | 6 | ||
@@ -127,7 +128,6 @@ int common(YYSTYPE *lval, char *text, LuaSL_yyparseParam *param, boolean checkIg | |||
127 | else | 128 | else |
128 | param->column++; | 129 | param->column++; |
129 | } | 130 | } |
130 | |||
131 | lval->token = tokens[type - lowestToken]; | 131 | lval->token = tokens[type - lowestToken]; |
132 | lval->line = param->line; | 132 | lval->line = param->line; |
133 | lval->column = param->column; | 133 | lval->column = param->column; |
diff --git a/LuaSL/src/LuaSL_main.c b/LuaSL/src/LuaSL_main.c index 9a6c256..fb2a8ba 100644 --- a/LuaSL/src/LuaSL_main.c +++ b/LuaSL/src/LuaSL_main.c | |||
@@ -160,13 +160,16 @@ main(int argc, char **argv) | |||
160 | ecore_evas_callback_delete_request_set(game.ee, _on_delete); | 160 | ecore_evas_callback_delete_request_set(game.ee, _on_delete); |
161 | edje_object_signal_callback_add(game.edje, "*", "game_*", _edje_signal_cb, &game); | 161 | edje_object_signal_callback_add(game.edje, "*", "game_*", _edje_signal_cb, &game); |
162 | 162 | ||
163 | snprintf(buf, sizeof(buf), "%s/Test sim/objects/onefang's test bed/~run", PACKAGE_DATA_DIR); | 163 | // Setup for the compler. |
164 | compilerSetup(); | ||
165 | // snprintf(buf, sizeof(buf), "%s/Test sim/objects/onefang's test bed/~run", PACKAGE_DATA_DIR); | ||
166 | snprintf(buf, sizeof(buf), "%s/test2.lsl", PACKAGE_DATA_DIR); | ||
164 | if (compileLSL(&game, buf)) | 167 | if (compileLSL(&game, buf)) |
165 | PIm("Against all odds, the compile of %s worked! lol", buf); | 168 | PIm("Against all odds, the compile of %s worked! lol", buf); |
166 | else | 169 | else |
167 | PEm("The compile of %s failed, as expected!", buf); | 170 | PEm("The compile of %s failed, as expected!", buf); |
168 | 171 | ||
169 | ecore_main_loop_begin(); | 172 | // ecore_main_loop_begin(); |
170 | 173 | ||
171 | ecore_animator_del(ani); | 174 | ecore_animator_del(ani); |
172 | ecore_evas_free(game.ee); | 175 | ecore_evas_free(game.ee); |