fix crashes reported by Debian Cylab Mayhem Team
[swftools.git] / lib / action / swf4compiler.y
blob2ecd42a81205374f6fc9aaf8d89d4af87425d0e9
1 /* $Id: swf4compiler.y,v 1.1 2004/05/08 17:17:35 kramm Exp $ */
3 %start program
5 %{
7 #include <time.h>
8 #include <string.h>
9 #include <stdlib.h>
10 #include "compile.h"
11 #include "action.h"
13 #define YYPARSE_PARAM buffer
17 %union {
18 Buffer action;
19 char *str;
20 SWFActionFunction function;
21 SWFGetUrl2Method getURLMethod;
24 /* tokens etc. */
25 %token BREAK
26 %token FOR
27 %token CONTINUE
28 %token IF
29 %token ELSE
30 %token DO
31 %token WHILE
33 %token THIS
35 /* functions */
36 %token EVAL
37 %token TIME
38 %token RANDOM
39 %token LENGTH
40 %token INT
41 %token CONCAT
42 %token DUPLICATECLIP
43 %token REMOVECLIP
44 %token TRACE
45 %token STARTDRAG
46 %token STOPDRAG
47 %token ORD
48 %token CHR
49 %token CALLFRAME
50 %token GETURL
51 %token GETURL1
52 %token LOADMOVIE
53 %token LOADVARIABLES
54 %token POSTURL
55 %token SUBSTR
57 %token GETPROPERTY
59 /* v3 functions */
60 %token NEXTFRAME
61 %token PREVFRAME
62 %token PLAY
63 %token STOP
64 %token TOGGLEQUALITY
65 %token STOPSOUNDS
66 %token GOTOFRAME
67 %token GOTOANDPLAY
68 %token FRAMELOADED
69 %token SETTARGET
71 /* high level functions */
72 %token TELLTARGET
74 /* these three are strdup'ed in compiler.flex, so free them here */
75 %token <str> STRING
76 %token <str> NUMBER
77 %token <str> IDENTIFIER
78 %token <str> PATH
80 %token <getURLMethod> GETURL_METHOD
82 %token EQ "=="
83 %token LE "<="
84 %token GE ">="
85 %token NE "!="
86 %token LAN "&&"
87 %token LOR "||"
88 %token INC "++"
89 %token DEC "--"
90 %token IEQ "+="
91 %token DEQ "/="
92 %token MEQ "*="
93 %token SEQ "-="
94 %token STREQ "==="
95 %token STRNE "!=="
96 %token STRCMP "<=>"
97 %token PARENT ".."
99 %token END "end"
101 /* ascending order of ops ..? */
102 %left ','
103 %right '=' "*=" "/=" "+=" "-="
104 %right '?' ':'
105 %left "&&" "||"
106 %left "==" "!=" "===" "!=="
107 %left '<' '>' "<=" ">=" "<=>"
108 %left '&'
109 %left '+' '-'
110 %left '*' '/'
111 %right "++" "--" UMINUS '!'
112 %right POSTFIX
113 %right NEGATE
115 %type <action> elem
116 %type <action> elems
117 %type <action> stmt
118 %type <action> statements
119 %type <action> if_stmt
120 %type <action> iter_stmt
121 %type <action> cont_stmt
122 %type <action> break_stmt
123 %type <action> expr_opt
124 %type <action> void_function_call
125 %type <action> function_call
126 %type <action> lhs_expr
127 %type <action> pf_expr
128 %type <action> rhs_expr
129 %type <action> assign_stmt
130 %type <action> assign_stmts
131 %type <action> assign_stmts_opt
132 %type <action> expr
133 %type <action> program
135 /* make sure to free these, too! */
136 %type <str> sprite
137 %type <str> variable
141 /* rules */
143 program
144 : elems
145 { *((Buffer *)buffer) = $1; }
149 elems
150 : elem
151 | elems elem
152 { bufferConcat($1, $2); }
155 elem
156 : stmt
159 stmt
160 : '{' '}' { $$ = NULL; }
161 | '{' statements '}' { $$ = $2; }
162 | ';' { $$ = NULL; }
163 | assign_stmt ';'
164 | if_stmt
165 | iter_stmt
166 | cont_stmt
167 | break_stmt
170 assign_stmts
171 : assign_stmt
172 | assign_stmts ',' assign_stmt { bufferConcat($1, $3); }
175 statements
176 : /* empty */ { $$ = NULL; }
177 | stmt
178 | statements stmt
179 { bufferConcat($1, $2); }
182 if_stmt
183 /* XXX- I haven't tested the frameloaded() stuff yet.. */
185 : IF '(' FRAMELOADED '(' NUMBER ')' ')' stmt ELSE stmt
186 { $$ = newBuffer();
187 bufferWriteU8($$, SWFACTION_WAITFORFRAME);
188 bufferWriteS16($$, 3);
189 bufferWriteS16($$, atoi($5));
190 free($5);
191 bufferWriteU8($$, 1); /* if not loaded, jump to.. */
192 bufferWriteU8($$, SWFACTION_BRANCHALWAYS);
193 bufferWriteS16($$, 2);
194 bufferWriteS16($$, bufferLength($10)+5);
195 bufferConcat($$, $10); /* ..here */
196 bufferWriteU8($$, SWFACTION_BRANCHALWAYS);
197 bufferWriteS16($$, 2);
198 bufferWriteS16($$, bufferLength($8));
199 bufferConcat($$, $8); }
201 | IF '(' FRAMELOADED '(' NUMBER ')' ')' stmt
202 { $$ = newBuffer();
203 bufferWriteU8($$, SWFACTION_WAITFORFRAME);
204 bufferWriteS16($$, 3);
205 bufferWriteS16($$, atoi($5));
206 free($5);
207 bufferWriteU8($$, 1); /* if not loaded, jump to.. */
208 bufferWriteU8($$, SWFACTION_BRANCHALWAYS);
209 bufferWriteS16($$, 2);
210 bufferWriteS16($$, 5);
211 bufferWriteU8($$, SWFACTION_BRANCHALWAYS); /* ..here */
212 bufferWriteS16($$, 2);
213 bufferWriteS16($$, bufferLength($8)); /* ..and then out */
214 bufferConcat($$, $8); }
216 /* make this case cleaner.. */
217 | IF '(' '!' FRAMELOADED '(' NUMBER ')' ')' stmt
218 { $$ = newBuffer();
219 bufferWriteU8($$, SWFACTION_WAITFORFRAME);
220 bufferWriteS16($$, 3);
221 bufferWriteS16($$, atoi($6));
222 free($6);
223 bufferWriteU8($$, 1); /* if not loaded, jump to.. */
224 bufferWriteU8($$, SWFACTION_BRANCHALWAYS);
225 bufferWriteS16($$, 2);
226 bufferWriteS16($$, bufferLength($9));
227 bufferConcat($$, $9); } /* ..here */
229 | IF '(' FRAMELOADED '(' expr ')' ')' stmt ELSE stmt
230 { $$ = $5;
231 bufferWriteU8($$, SWFACTION_WAITFORFRAMEEXPRESSION);
232 bufferWriteS16($$, 1);
233 bufferWriteU8($$, 1); /* if not loaded, jump to.. */
234 bufferWriteU8($$, SWFACTION_BRANCHALWAYS);
235 bufferWriteS16($$, 2);
236 bufferWriteS16($$, bufferLength($10)+5);
237 bufferConcat($$, $10); /* ..here */
238 bufferWriteU8($$, SWFACTION_BRANCHALWAYS);
239 bufferWriteS16($$, 2);
240 bufferWriteS16($$, bufferLength($8));
241 bufferConcat($$, $8); }
243 | IF '(' FRAMELOADED '(' expr ')' ')' stmt
244 { $$ = $5;
245 bufferWriteU8($$, SWFACTION_WAITFORFRAMEEXPRESSION);
246 bufferWriteS16($$, 1);
247 bufferWriteU8($$, 1); /* if not loaded, jump to.. */
248 bufferWriteU8($$, SWFACTION_BRANCHALWAYS);
249 bufferWriteS16($$, 2);
250 bufferWriteS16($$, 5);
251 bufferWriteU8($$, SWFACTION_BRANCHALWAYS); /* ..here */
252 bufferWriteS16($$, 2);
253 bufferWriteS16($$, bufferLength($8)); /* ..and then out */
254 bufferConcat($$, $8); }
256 /* make this case cleaner.. */
257 | IF '(' '!' FRAMELOADED '(' expr ')' ')' stmt
258 { $$ = $6;
259 bufferWriteU8($$, SWFACTION_WAITFORFRAMEEXPRESSION);
260 bufferWriteS16($$, 1);
261 bufferWriteU8($$, 1); /* if not loaded, jump to.. */
262 bufferWriteU8($$, SWFACTION_BRANCHALWAYS);
263 bufferWriteS16($$, 2);
264 bufferWriteS16($$, bufferLength($9));
265 bufferConcat($$, $9); } /* ..here */
267 | IF '(' expr ')' stmt ELSE stmt
268 { bufferWriteU8($3, SWFACTION_BRANCHIFTRUE);
269 bufferWriteS16($3, 2);
270 bufferWriteS16($3, bufferLength($7)+5);
271 bufferConcat($3, $7);
272 bufferWriteU8($3, SWFACTION_BRANCHALWAYS);
273 bufferWriteS16($3, 2);
274 bufferWriteS16($3, bufferLength($5));
275 bufferConcat($3, $5);
276 $$ = $3; }
278 | IF '(' expr ')' stmt
279 { bufferWriteU8($3, SWFACTION_LOGICALNOT);
280 bufferWriteU8($3, SWFACTION_BRANCHIFTRUE);
281 bufferWriteS16($3, 2);
282 bufferWriteS16($3, bufferLength($5));
283 bufferConcat($3, $5);
284 $$ = $3; }
287 expr_opt
288 : /* empty */ { $$ = NULL; }
289 | expr { $$ = $1; }
292 /* not thought out yet..
293 switch_stmt
294 : SWITCH '(' expr ')' '{'
295 { $$ = $3;
296 pushLoop(); }
297 switch_cases '}'
298 { bufferConcat($$, $7); }
301 switch_cases
302 : switch_cases switch_case
303 | switch_case
306 switch_case
307 : CASE INTEGER ':' stmt
308 { $$ = newBuffer(); }
312 iter_stmt
313 : WHILE '(' '!' FRAMELOADED '(' NUMBER ')' ')' stmt
314 { $$ = newBuffer();
315 bufferWriteU8($$, SWFACTION_WAITFORFRAME);
316 bufferWriteS16($$, 3);
317 bufferWriteS16($$, atoi($6));
318 free($6);
319 bufferWriteU8($$, 1); /* if not loaded, jump to.. */
320 bufferWriteU8($$, SWFACTION_BRANCHALWAYS);
321 bufferWriteS16($$, 2);
322 bufferWriteS16($$, bufferLength($9)+5);
323 bufferConcat($$, $9); /* ..here */
324 bufferWriteU8($$, SWFACTION_BRANCHALWAYS);
325 bufferWriteS16($$, 2);
326 bufferWriteS16($$, -(bufferLength($$)+2)); }
328 | WHILE '(' expr ')' stmt
329 { $$ = $3;
330 bufferWriteU8($$, SWFACTION_LOGICALNOT);
331 bufferWriteU8($$, SWFACTION_BRANCHIFTRUE);
332 bufferWriteS16($$, 2);
333 bufferWriteS16($$, bufferLength($5)+5);
334 bufferConcat($$, $5);
335 bufferWriteU8($$, SWFACTION_BRANCHALWAYS);
336 bufferWriteS16($$, 2);
337 bufferWriteS16($$, -(bufferLength($$)+2));
338 bufferResolveJumps($$); }
340 | DO stmt WHILE '(' expr ')'
341 { $$ = $2;
342 bufferConcat($$, $5);
343 bufferWriteU8($$, SWFACTION_BRANCHIFTRUE);
344 bufferWriteS16($$, 2);
345 bufferWriteS16($$, -(bufferLength($$)+2));
346 bufferResolveJumps($$); }
348 | FOR '(' assign_stmts_opt ';' expr_opt ';' assign_stmts_opt ')' stmt
349 { if (!$5)
350 $5 = newBuffer();
351 else {
352 bufferWriteU8($5, SWFACTION_LOGICALNOT);
353 bufferWriteU8($5, SWFACTION_BRANCHIFTRUE);
354 bufferWriteS16($5, 2);
355 bufferWriteS16($5, bufferLength($9)+bufferLength($7)+5);
357 bufferConcat($5, $9);
358 bufferConcat($5, $7);
359 bufferWriteU8($5, SWFACTION_BRANCHALWAYS);
360 bufferWriteS16($5, 2);
361 bufferWriteS16($5, -(bufferLength($5)+2));
362 bufferResolveJumps($5);
363 $$ = $3;
364 if(!$$) $$ = newBuffer();
365 bufferConcat($$, $5);
369 assign_stmts_opt
370 : /* empty */ { $$ = NULL; }
371 | assign_stmts
374 cont_stmt
375 : CONTINUE ';'
376 { $$ = newBuffer();
377 bufferWriteU8($$, SWFACTION_BRANCHALWAYS);
378 bufferWriteS16($$, 2);
379 bufferWriteS16($$, MAGIC_CONTINUE_NUMBER); }
382 break_stmt
383 : BREAK ';'
384 { $$ = newBuffer();
385 bufferWriteU8($$, SWFACTION_BRANCHALWAYS);
386 bufferWriteS16($$, 2);
387 bufferWriteS16($$, MAGIC_BREAK_NUMBER); }
390 void_function_call
391 : STOPDRAG '(' ')' /* no args */
392 { $$ = newBuffer();
393 bufferWriteU8($$, SWFACTION_STOPDRAGMOVIE); }
395 | CALLFRAME '(' variable ')'
396 { $$ = newBuffer();
397 bufferWriteString($$, $3, strlen($3)+1);
398 bufferWriteU8($$, SWFACTION_CALLFRAME);
399 bufferWriteS16($$, 0);
400 free($3); }
402 | CALLFRAME '(' STRING ')'
403 { $$ = newBuffer();
404 bufferWriteString($$, $3, strlen($3)+1);
405 bufferWriteU8($$, SWFACTION_CALLFRAME);
406 bufferWriteS16($$, 0);
407 free($3); }
409 | REMOVECLIP '(' expr ')'
410 { $$ = $3;
411 bufferWriteU8($$, SWFACTION_REMOVECLIP); }
413 | TRACE '(' expr ')'
414 { $$ = $3;
415 bufferWriteU8($$, SWFACTION_TRACE); }
417 /* getURL2(url, window, [method]) */
418 | GETURL '(' expr ',' expr ')'
419 { $$ = $3;
420 bufferConcat($$, $5);
421 bufferWriteU8($$, SWFACTION_GETURL2);
422 bufferWriteS16($$, 1);
423 bufferWriteU8($$, GETURL_METHOD_NOSEND); }
425 | GETURL '(' expr ',' expr ',' GETURL_METHOD ')'
426 { $$ = $3;
427 bufferConcat($$, $5);
428 bufferWriteU8($$, SWFACTION_GETURL2);
429 bufferWriteS16($$, 1);
430 bufferWriteU8($$, $7); }
432 | GETURL1 '(' STRING ',' STRING ')'
433 { $$ = newBuffer();
434 bufferWriteU8($$, SWFACTION_GETURL);
435 bufferWriteS16($$, strlen($3) + strlen($5) + 2);
436 bufferWriteHardString($$, (byte*)$3, strlen($3));
437 bufferWriteU8($$, 0);
438 bufferWriteHardString($$, (byte*)$5, strlen($5));
439 bufferWriteU8($$, 0); }
441 | LOADMOVIE '(' expr ',' expr ')'
442 { $$ = $3;
443 bufferConcat($$, $5);
444 bufferWriteU8($$, SWFACTION_GETURL2);
445 bufferWriteS16($$, 1);
446 bufferWriteU8($$, GETURL_METHOD_NOSEND | GETURL_LOADMOVIE); }
448 | LOADMOVIE '(' expr ',' expr ',' GETURL_METHOD ')'
449 { $$ = $3;
450 bufferConcat($$, $5);
451 bufferWriteU8($$, SWFACTION_GETURL2);
452 bufferWriteS16($$, 1);
453 bufferWriteU8($$, $7 | GETURL_LOADMOVIE); }
455 | LOADVARIABLES '(' expr ',' expr ')'
456 { $$ = $3;
457 bufferConcat($$, $5);
458 bufferWriteU8($$, SWFACTION_GETURL2);
459 bufferWriteS16($$, 1);
460 bufferWriteU8($$, GETURL_METHOD_NOSEND | GETURL_LOADVARIABLES); }
462 | LOADVARIABLES '(' expr ',' expr ',' GETURL_METHOD ')'
463 { $$ = $3;
464 bufferConcat($$, $5);
465 bufferWriteU8($$, SWFACTION_GETURL2);
466 bufferWriteS16($$, 1);
467 bufferWriteU8($$, $7 | GETURL_LOADVARIABLES); }
469 /* startDrag(target, lock, [left, right, top, bottom]) */
470 | STARTDRAG '(' expr ',' expr ')'
471 { $$ = newBuffer();
472 bufferWriteString($$, "0", 2); /* no constraint */
473 bufferConcat($$, $5);
474 bufferConcat($$, $3);
475 bufferWriteU8($$, SWFACTION_STARTDRAGMOVIE); }
477 | STARTDRAG '(' expr ',' expr ',' expr ',' expr ',' expr ',' expr ')'
478 { $$ = newBuffer();
479 bufferConcat($$, $7);
480 bufferConcat($$, $11);
481 bufferConcat($$, $9);
482 bufferConcat($$, $13);
483 bufferWriteString($$, "1", 2); /* has constraint */
484 bufferConcat($$, $5);
485 bufferConcat($$, $3);
486 bufferWriteU8($$, SWFACTION_STARTDRAGMOVIE); }
488 /* duplicateClip(target, new, depth) */
489 | DUPLICATECLIP '(' expr ',' expr ',' expr ')'
490 { $$ = $3;
491 bufferConcat($$, $5);
492 bufferConcat($$, $7);
493 bufferWriteWTHITProperty($$);
494 bufferWriteU8($$, SWFACTION_ADD); /* see docs for explanation */
495 bufferWriteU8($$, SWFACTION_DUPLICATECLIP); }
497 /* v3 actions */
498 | NEXTFRAME '(' ')'
499 { $$ = newBuffer();
500 bufferWriteU8($$, SWFACTION_NEXTFRAME); }
502 | PREVFRAME '(' ')'
503 { $$ = newBuffer();
504 bufferWriteU8($$, SWFACTION_PREVFRAME); }
506 | PLAY '(' ')'
507 { $$ = newBuffer();
508 bufferWriteU8($$, SWFACTION_PLAY); }
510 | STOP '(' ')'
511 { $$ = newBuffer();
512 bufferWriteU8($$, SWFACTION_STOP); }
514 | TOGGLEQUALITY '(' ')'
515 { $$ = newBuffer();
516 bufferWriteU8($$, SWFACTION_TOGGLEQUALITY); }
518 | STOPSOUNDS '(' ')'
519 { $$ = newBuffer();
520 bufferWriteU8($$, SWFACTION_STOPSOUNDS); }
522 | GOTOFRAME '(' NUMBER ')'
523 { $$ = newBuffer();
524 bufferWriteU8($$, SWFACTION_GOTOFRAME);
525 bufferWriteS16($$, 2);
526 bufferWriteS16($$, atoi($3));
527 free($3); }
529 | GOTOFRAME '(' STRING ')'
530 { $$ = newBuffer();
531 bufferWriteU8($$, SWFACTION_GOTOLABEL);
532 bufferWriteS16($$, strlen($3)+1);
533 bufferWriteHardString($$, (byte*)$3, strlen($3)+1);
534 free($3); }
536 | GOTOFRAME '(' expr ')'
537 { $$ = $3;
538 bufferWriteU8($$, SWFACTION_GOTOEXPRESSION);
539 bufferWriteS16($$, 1);
540 bufferWriteU8($$, 0); } /* XXX - and stop */
542 | GOTOANDPLAY '(' expr ')'
543 { $$ = $3;
544 bufferWriteU8($$, SWFACTION_GOTOEXPRESSION);
545 bufferWriteS16($$, 1);
546 bufferWriteU8($$, 1); } /* XXX - and play */
548 | SETTARGET '(' STRING ')'
549 { $$ = newBuffer();
550 bufferWriteU8($$, SWFACTION_SETTARGET);
551 bufferWriteS16($$, strlen($3)+1);
552 bufferWriteHardString($$, (byte*)$3, strlen($3)+1);
553 free($3); }
555 | SETTARGET '(' expr ')'
556 { $$ = $3;
557 bufferWriteU8($$, SWFACTION_SETTARGETEXPRESSION); }
559 | TELLTARGET '(' STRING ')' stmt
560 { $$ = newBuffer();
561 /* SetTarget(STRING) */
562 bufferWriteU8($$, SWFACTION_SETTARGET);
563 bufferWriteS16($$, strlen($3)+1);
564 bufferWriteHardString($$, (byte*)$3, strlen($3)+1);
565 /* stmt */
566 bufferConcat($$, $5);
567 /* SetTarget('') */
568 bufferWriteU8($$, SWFACTION_SETTARGET);
569 bufferWriteS16($$, 1);
570 bufferWriteU8($$, 0);
571 free($3); }
573 | TELLTARGET '(' expr ')' stmt
574 { $$ = $3;
575 /* SetTarget(expr) */
576 bufferWriteU8($$, SWFACTION_SETTARGETEXPRESSION);
577 /* stmt */
578 bufferConcat($$, $5);
579 /* SetTarget('') */
580 bufferWriteU8($$, SWFACTION_SETTARGET);
581 bufferWriteS16($$, 1);
582 bufferWriteU8($$, 0); }
585 function_call
586 : EVAL '(' expr ')'
587 { $$ = $3;
588 bufferWriteU8($$, SWFACTION_GETVARIABLE); }
590 | TIME '(' ')'
591 { $$ = newBuffer();
592 bufferWriteU8($$, SWFACTION_GETTIMER); }
594 | RANDOM '(' expr ')'
595 { $$ = $3;
596 bufferWriteU8($$, SWFACTION_RANDOM); }
598 | LENGTH '(' expr ')'
599 { $$ = $3;
600 bufferWriteU8($$, SWFACTION_STRINGLENGTH); }
602 | INT '(' expr ')'
603 { $$ = $3;
604 bufferWriteU8($$, SWFACTION_INT); }
606 | ORD '(' expr ')'
607 { $$ = $3;
608 bufferWriteU8($$, SWFACTION_ORD); }
610 | CHR '(' expr ')'
611 { $$ = $3;
612 bufferWriteU8($$, SWFACTION_CHR); }
614 | CONCAT '(' expr ',' expr ')'
615 { $$ = $3;
616 bufferConcat($$, $5);
617 bufferWriteU8($$, SWFACTION_STRINGCONCAT); }
619 | SUBSTR '(' expr ',' expr ',' expr ')'
620 { $$ = $3;
621 bufferConcat($$, $5);
622 bufferConcat($$, $7);
623 bufferWriteU8($$, SWFACTION_SUBSTRING); }
625 | GETPROPERTY '(' expr ',' STRING ')'
626 { $$ = newBuffer();
627 bufferConcat($$, $3);
628 bufferWriteGetProperty($$, $5);
629 bufferWriteU8($$, SWFACTION_GETPROPERTY);
630 free($5); }
633 pf_expr
634 : lhs_expr "++" %prec POSTFIX
635 { $$ = newBuffer();
636 bufferWriteBuffer($$, $1);
637 bufferWriteU8($$, SWFACTION_GETVARIABLE);
638 bufferWriteBuffer($$, $1);
639 bufferConcat($$, $1);
640 bufferWriteU8($$, SWFACTION_GETVARIABLE);
641 bufferWriteString($$, "1", 2);
642 bufferWriteU8($$, SWFACTION_ADD);
643 bufferWriteU8($$, SWFACTION_SETVARIABLE); }
645 | lhs_expr "--" %prec POSTFIX
646 { $$ = newBuffer();
647 bufferWriteBuffer($$, $1);
648 bufferWriteU8($$, SWFACTION_GETVARIABLE);
649 bufferWriteBuffer($$, $1);
650 bufferConcat($$, $1);
651 bufferWriteU8($$, SWFACTION_GETVARIABLE);
652 bufferWriteString($$, "1", 2);
653 bufferWriteU8($$, SWFACTION_SUBTRACT);
654 bufferWriteU8($$, SWFACTION_SETVARIABLE); }
657 /* these leave a value on the stack */
658 rhs_expr
659 : function_call
661 | '(' rhs_expr ')'
662 { $$ = $2; }
664 | NUMBER
665 { $$ = newBuffer();
666 bufferWriteString($$, $1, strlen($1)+1);
667 free($1); }
669 | '-' NUMBER %prec NEGATE
670 { $$ = newBuffer();
671 bufferWriteString($$, "-", 2);
672 bufferWriteString($$, $2, strlen($2)+1);
673 free($2); }
675 | STRING
676 { $$ = newBuffer();
677 bufferWriteString($$, $1, strlen($1)+1);
678 free($1); }
680 | variable
681 { $$ = newBuffer();
682 bufferWriteString($$, $1, strlen($1)+1);
683 bufferWriteU8($$, SWFACTION_GETVARIABLE);
684 free($1); }
686 | sprite
687 { $$ = newBuffer();
688 bufferWriteString($$, $1, strlen($1)+1);
689 free($1); }
691 | sprite '.' IDENTIFIER
692 { $$ = newBuffer();
693 bufferWriteString($$, $1, strlen($1)+1);
694 bufferWriteGetProperty($$, $3);
695 bufferWriteU8($$, SWFACTION_GETPROPERTY);
696 free($3);
697 free($1); }
699 | "++" sprite '.' IDENTIFIER
700 { $$ = newBuffer();
701 bufferWriteString($$, $2, strlen($2)+1);
702 bufferWriteGetProperty($$, $4);
703 bufferWriteString($$, $2, strlen($2)+1);
704 bufferWriteSetProperty($$, $4);
705 bufferWriteString($$, $2, strlen($2)+1);
706 bufferWriteGetProperty($$, $4);
707 bufferWriteString($$, "1", 2);
708 bufferWriteU8($$, SWFACTION_ADD);
709 bufferWriteU8($$, SWFACTION_SETPROPERTY);
710 bufferWriteU8($$, SWFACTION_GETPROPERTY);
711 free($2);
712 free($4); }
714 | "++" lhs_expr
715 { $$ = $2;
716 bufferWriteU8($$, SWFACTION_DUP);
717 bufferWriteU8($$, SWFACTION_DUP);
718 bufferWriteU8($$, SWFACTION_GETVARIABLE);
719 bufferWriteString($$, "1", 2);
720 bufferWriteU8($$, SWFACTION_ADD);
721 bufferWriteU8($$, SWFACTION_SETVARIABLE);
722 bufferWriteU8($$, SWFACTION_GETVARIABLE); }
724 | "--" sprite '.' IDENTIFIER
725 { $$ = newBuffer();
726 bufferWriteString($$, $2, strlen($2)+1);
727 bufferWriteGetProperty($$, $4);
728 bufferWriteString($$, $2, strlen($2)+1);
729 bufferWriteSetProperty($$, $4);
730 bufferWriteString($$, $2, strlen($2)+1);
731 bufferWriteGetProperty($$, $4);
732 bufferWriteString($$, "1", 2);
733 bufferWriteU8($$, SWFACTION_ADD);
734 bufferWriteU8($$, SWFACTION_SETPROPERTY);
735 bufferWriteU8($$, SWFACTION_GETPROPERTY);
736 free($2);
737 free($4); }
739 | "--" lhs_expr
740 { $$ = $2;
741 bufferWriteU8($$, SWFACTION_DUP);
742 bufferWriteU8($$, SWFACTION_DUP);
743 bufferWriteU8($$, SWFACTION_GETVARIABLE);
744 bufferWriteString($$, "1", 2);
745 bufferWriteU8($$, SWFACTION_SUBTRACT);
746 bufferWriteU8($$, SWFACTION_SETVARIABLE);
747 bufferWriteU8($$, SWFACTION_GETVARIABLE); }
749 | '-' rhs_expr %prec UMINUS
750 { $$ = $2;
751 bufferWriteString($2, "-1", 3);
752 bufferWriteU8($2, SWFACTION_MULTIPLY); }
754 | '!' rhs_expr
755 { $$ = $2;
756 bufferWriteU8($2, SWFACTION_LOGICALNOT); }
758 | lhs_expr '=' rhs_expr /* assign and leave copy on stack */
759 { $$ = $1;
760 bufferConcat($$, $3);
761 bufferWriteU8($$, SWFACTION_DUP);
762 bufferWriteU8($$, SWFACTION_SETVARIABLE); }
764 | rhs_expr '*' rhs_expr
765 { $$ = $1;
766 bufferConcat($$, $3);
767 bufferWriteU8($$, SWFACTION_MULTIPLY); }
769 | rhs_expr '/' rhs_expr
770 { $$ = $1;
771 bufferConcat($$, $3);
772 bufferWriteU8($$, SWFACTION_DIVIDE); }
774 | rhs_expr '+' rhs_expr
775 { $$ = $1;
776 bufferConcat($$, $3);
777 bufferWriteU8($$, SWFACTION_ADD); }
779 | rhs_expr '-' rhs_expr
780 { $$ = $1;
781 bufferConcat($$, $3);
782 bufferWriteU8($$, SWFACTION_SUBTRACT); }
784 | rhs_expr '&' rhs_expr
785 { $$ = $1;
786 bufferConcat($$, $3);
787 bufferWriteU8($$, SWFACTION_STRINGCONCAT); }
789 | rhs_expr '<' rhs_expr
790 { $$ = $1;
791 bufferConcat($$, $3);
792 bufferWriteU8($$, SWFACTION_LESSTHAN); }
794 | rhs_expr '>' rhs_expr
795 { $$ = $3;
796 bufferConcat($$, $1);
797 bufferWriteU8($$, SWFACTION_LESSTHAN); }
799 | rhs_expr "<=" rhs_expr
800 { $$ = $3;
801 bufferConcat($$, $1);
802 bufferWriteU8($$, SWFACTION_LESSTHAN);
803 bufferWriteU8($$, SWFACTION_LOGICALNOT); }
805 | rhs_expr ">=" rhs_expr
806 { bufferConcat($1, $3);
807 bufferWriteU8($1, SWFACTION_LESSTHAN);
808 bufferWriteU8($1, SWFACTION_LOGICALNOT); }
810 | rhs_expr "!==" rhs_expr
811 { bufferConcat($1, $3);
812 bufferWriteU8($1, SWFACTION_STRINGEQ);
813 bufferWriteU8($1, SWFACTION_LOGICALNOT); }
815 | rhs_expr "===" rhs_expr
816 { bufferConcat($1, $3);
817 bufferWriteU8($1, SWFACTION_STRINGEQ); }
819 | rhs_expr "<=>" rhs_expr
820 { bufferConcat($1, $3);
821 bufferWriteU8($1, SWFACTION_STRINGCOMPARE); }
823 | rhs_expr "==" rhs_expr
824 { bufferConcat($1, $3);
825 bufferWriteU8($1, SWFACTION_EQUAL); }
827 | rhs_expr "!=" rhs_expr
828 { bufferConcat($1, $3);
829 bufferWriteU8($1, SWFACTION_EQUAL);
830 bufferWriteU8($1, SWFACTION_LOGICALNOT); }
832 | rhs_expr "&&" rhs_expr
833 { bufferConcat($1, $3);
834 bufferWriteU8($1, SWFACTION_LOGICALAND); }
836 | rhs_expr "||" rhs_expr
837 { bufferConcat($1, $3);
838 bufferWriteU8($1, SWFACTION_LOGICALOR); }
840 | rhs_expr '?' rhs_expr ':' rhs_expr
841 { bufferWriteU8($1, SWFACTION_BRANCHIFTRUE);
842 bufferWriteS16($1, 2);
843 bufferWriteS16($1, bufferLength($5)+5);
844 bufferConcat($1, $5);
845 bufferWriteU8($1, SWFACTION_BRANCHALWAYS);
846 bufferWriteS16($1, 2);
847 bufferWriteS16($1, bufferLength($3));
848 bufferConcat($1, $3); }
851 variable
852 : IDENTIFIER
854 | sprite ':' IDENTIFIER
855 { $$ = $1;
856 $$ = stringConcat($$, strdup(":"));
857 $$ = stringConcat($$, $3); }
860 sprite
861 : THIS
862 { $$ = strdup(""); }
864 | '.'
865 { $$ = strdup(""); }
867 | '/'
868 { $$ = strdup("/"); }
870 | PARENT
871 { $$ = strdup(".."); }
873 | IDENTIFIER
874 { $$ = $1; }
876 | PATH
877 { $$ = $1; }
880 lhs_expr
881 : variable
882 { $$ = newBuffer();
883 bufferWriteString($$, $1, strlen($1)+1);
884 free($1); }
886 | STRING
887 { $$ = newBuffer();
888 bufferWriteString($$, $1, strlen($1)+1);
889 free($1); }
891 | '(' rhs_expr ')' { $$ = $2; }
894 assign_stmt
895 : pf_expr
897 | void_function_call
899 | "++" lhs_expr
900 { $$ = $2;
901 bufferWriteBuffer($$, $2);
902 bufferWriteU8($$, SWFACTION_GETVARIABLE);
903 bufferWriteString($$, "1", 2);
904 bufferWriteU8($$, SWFACTION_ADD);
905 bufferWriteU8($$, SWFACTION_SETVARIABLE); }
907 | "--" lhs_expr
908 { $$ = $2;
909 bufferWriteBuffer($$, $2);
910 bufferWriteU8($$, SWFACTION_GETVARIABLE);
911 bufferWriteString($$, "1", 2);
912 bufferWriteU8($$, SWFACTION_SUBTRACT);
913 bufferWriteU8($$, SWFACTION_SETVARIABLE); }
915 | "++" sprite '.' IDENTIFIER
916 { $$ = newBuffer();
917 bufferWriteString($$, $2, strlen($2)+1);
918 bufferWriteGetProperty($$, $4);
919 bufferWriteU8($$, SWFACTION_GETPROPERTY);
920 bufferWriteString($$, "1", 2);
921 bufferWriteU8($$, SWFACTION_ADD);
922 bufferWriteString($$, $2, strlen($2)+1);
923 bufferWriteSetProperty($$, $4);
924 bufferWriteU8($$, SWFACTION_SETPROPERTY);
925 free($2);
926 free($4); }
928 | "--" sprite '.' IDENTIFIER
929 { $$ = newBuffer();
930 bufferWriteString($$, $2, strlen($2)+1);
931 bufferWriteGetProperty($$, $4);
932 bufferWriteU8($$, SWFACTION_GETPROPERTY);
933 bufferWriteString($$, "1", 2);
934 bufferWriteU8($$, SWFACTION_SUBTRACT);
935 bufferWriteString($$, $2, strlen($2)+1);
936 bufferWriteSetProperty($$, $4);
937 bufferWriteU8($$, SWFACTION_SETPROPERTY);
938 free($2);
939 free($4); }
941 | lhs_expr '=' rhs_expr
942 { bufferConcat($1, $3);
943 bufferWriteU8($1, SWFACTION_SETVARIABLE); }
945 | lhs_expr "*=" rhs_expr
946 { bufferWriteBuffer($1, $1);
947 bufferWriteU8($1, SWFACTION_GETVARIABLE);
948 bufferConcat($1, $3);
949 bufferWriteU8($1, SWFACTION_MULTIPLY);
950 bufferWriteU8($1, SWFACTION_SETVARIABLE); }
952 | lhs_expr "/=" rhs_expr
953 { bufferWriteBuffer($1, $1);
954 bufferWriteU8($1, SWFACTION_GETVARIABLE);
955 bufferConcat($1, $3);
956 bufferWriteU8($1, SWFACTION_DIVIDE);
957 bufferWriteU8($1, SWFACTION_SETVARIABLE); }
959 | lhs_expr "+=" rhs_expr
960 { bufferWriteBuffer($1, $1);
961 bufferWriteU8($1, SWFACTION_GETVARIABLE);
962 bufferConcat($1, $3);
963 bufferWriteU8($1, SWFACTION_ADD);
964 bufferWriteU8($1, SWFACTION_SETVARIABLE); }
966 | lhs_expr "-=" rhs_expr
967 { bufferWriteBuffer($1, $1);
968 bufferWriteU8($1, SWFACTION_GETVARIABLE);
969 bufferConcat($1, $3);
970 bufferWriteU8($1, SWFACTION_SUBTRACT);
971 bufferWriteU8($1, SWFACTION_SETVARIABLE); }
973 | sprite '.' IDENTIFIER '=' rhs_expr
974 { $$ = newBuffer();
975 bufferWriteString($$, $1, strlen($1)+1);
976 bufferWriteSetProperty($$, $3);
977 bufferConcat($$,$5);
978 bufferWriteU8($$, SWFACTION_SETPROPERTY);
979 free($1);
980 free($3); }
982 | sprite '.' IDENTIFIER "*=" rhs_expr
983 { $$ = newBuffer();
984 bufferWriteString($$, $1, strlen($1)+1);
985 bufferWriteSetProperty($$, $3);
986 bufferWriteString($$, $1, strlen($1)+1);
987 bufferWriteGetProperty($$, $3);
988 bufferWriteU8($$, SWFACTION_GETPROPERTY);
989 bufferConcat($$, $5);
990 bufferWriteU8($$, SWFACTION_MULTIPLY);
991 bufferWriteU8($$, SWFACTION_SETPROPERTY);
992 free($1);
993 free($3); }
995 | sprite '.' IDENTIFIER "/=" rhs_expr
996 { $$ = newBuffer();
997 bufferWriteString($$, $1, strlen($1)+1);
998 bufferWriteSetProperty($$, $3);
999 bufferWriteString($$, $1, strlen($1)+1);
1000 bufferWriteGetProperty($$, $3);
1001 bufferWriteU8($$, SWFACTION_GETPROPERTY);
1002 bufferConcat($$, $5);
1003 bufferWriteU8($$, SWFACTION_DIVIDE);
1004 bufferWriteU8($$, SWFACTION_SETPROPERTY);
1005 free($1);
1006 free($3); }
1008 | sprite '.' IDENTIFIER "+=" rhs_expr
1009 { $$ = newBuffer();
1010 bufferWriteString($$, $1, strlen($1)+1);
1011 bufferWriteSetProperty($$, $3);
1012 bufferWriteString($$, $1, strlen($1)+1);
1013 bufferWriteGetProperty($$, $3);
1014 bufferWriteU8($$, SWFACTION_GETPROPERTY);
1015 bufferConcat($$, $5);
1016 bufferWriteU8($$, SWFACTION_ADD);
1017 bufferWriteU8($$, SWFACTION_SETPROPERTY);
1018 free($1);
1019 free($3); }
1021 | sprite '.' IDENTIFIER "-=" rhs_expr
1022 { $$ = newBuffer();
1023 bufferWriteString($$, $1, strlen($1)+1);
1024 bufferWriteSetProperty($$, $3);
1025 bufferWriteString($$, $1, strlen($1)+1);
1026 bufferWriteGetProperty($$, $3);
1027 bufferWriteU8($$, SWFACTION_GETPROPERTY);
1028 bufferConcat($$, $5);
1029 bufferWriteU8($$, SWFACTION_SUBTRACT);
1030 bufferWriteU8($$, SWFACTION_SETPROPERTY);
1031 free($1);
1032 free($3); }
1035 expr
1036 : rhs_expr