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