1 /* $Id$ */ 2 3 %start program 4 5 %{ 6 7 #include <time.h> 8 #include <string.h> 9 #include <stdlib.h> 10 #include "compile.h" 11 #include "actiontypes.h" 12 #include "assembler.h" 13 14 #define YYPARSE_PARAM buffer 15 #define YYERROR_VERBOSE 1 16 17 %} 18 19 %union { 20 Buffer action; 21 char *str; 22 SWFActionFunction function; 23 SWFGetUrl2Method getURLMethod; 24 int len; 25 } 26 27 /* tokens etc. */ 28 %token BREAK 29 %token FOR 30 %token CONTINUE 31 %token IF 32 %token ELSE 33 %token DO 34 %token WHILE 35 36 %token THIS 37 38 /* functions */ 39 %token EVAL 40 %token TIME 41 %token RANDOM 42 %token LENGTH 43 %token INT 44 %token CONCAT 45 %token DUPLICATECLIP 46 %token REMOVECLIP 47 %token TRACE 48 %token STARTDRAG 49 %token STOPDRAG 50 %token ORD 51 %token CHR 52 %token CALLFRAME 53 %token GETURL 54 %token GETURL1 55 %token LOADMOVIE 56 %token LOADMOVIENUM 57 %token LOADVARIABLES 58 %token POSTURL 59 %token SUBSTR 60 61 %token GETPROPERTY 62 63 /* v3 functions */ 64 %token NEXTFRAME 65 %token PREVFRAME 66 %token PLAY 67 %token STOP 68 %token TOGGLEQUALITY 69 %token STOPSOUNDS 70 %token GOTOFRAME 71 %token GOTOANDPLAY 72 %token FRAMELOADED 73 %token SETTARGET 74 75 %token ASM 76 77 /* v4 ASM */ 78 %token ASMADD ASMDIVIDE ASMMULTIPLY ASMEQUALS ASMLESS ASMLOGICALAND ASMLOGICALOR ASMLOGICALNOT 79 %token ASMSTRINGAND ASMSTRINGEQUALS ASMSTRINGEXTRACT ASMSTRINGLENGTH ASMMBSTRINGEXTRACT 80 %token ASMMBSTRINGLENGTH ASMPOP ASMPUSH ASMASCIITOCHAR ASMCHARTOASCII ASMTOINTEGER 81 %token ASMCALL ASMIF ASMJUMP ASMGETVARIABLE ASMSETVARIABLE ASMGETURL2 ASMGETPROPERTY 82 %token ASMGOTOFRAME2 ASMREMOVESPRITE ASMSETPROPERTY ASMSETTARGET2 ASMSTARTDRAG 83 %token ASMWAITFORFRAME2 ASMCLONESPRITE ASMENDDRAG ASMGETTIME ASMRANDOMNUMBER ASMTRACE 84 %token ASMMBASCIITOCHAR ASMMBCHARTOASCII ASMSUBSTRACT ASMSTRINGLESS 85 86 /* high level functions */ 87 %token TELLTARGET 88 89 %token BROKENSTRING 90 /* these three are strdup'ed in compiler.flex, so free them here */ 91 %token <str> STRING 92 %token <str> NUMBER 93 %token <str> IDENTIFIER 94 %token <str> PATH 95 96 %type <getURLMethod> urlmethod 97 98 %token EQ "==" 99 %token LE "<=" 100 %token GE ">=" 101 %token NE "!=" 102 %token LAN "&&" 103 %token LOR "||" 104 %token INC "++" 105 %token DEC "--" 106 %token IEQ "+=" 107 %token DEQ "/=" 108 %token MEQ "*=" 109 %token SEQ "-=" 110 %token STREQ "===" 111 %token STRNE "!==" 112 %token STRCMP "<=>" 113 %token PARENT ".." 114 115 %token END "end" 116 117 /* ascending order of ops ..? */ 118 %left ',' 119 %right '=' "*=" "/=" "+=" "-=" 120 %right '?' ':' 121 %left "&&" "||" 122 %left "==" "!=" "===" "!==" 123 %left '<' '>' "<=" ">=" "<=>" 124 %left '&' 125 %left '+' '-' 126 %left '*' '/' 127 %right "++" "--" UMINUS '!' 128 %right POSTFIX 129 %right NEGATE 130 131 %type <action> elem 132 %type <action> elems 133 %type <action> stmt 134 %type <action> statements 135 %type <action> if_stmt 136 %type <action> iter_stmt 137 %type <action> cont_stmt 138 %type <action> break_stmt 139 %type <action> expr_opt 140 %type <action> void_function_call 141 %type <action> function_call 142 %type <action> lhs_expr 143 %type <action> pf_expr 144 %type <action> rhs_expr 145 %type <action> assign_stmt 146 %type <action> assign_stmts 147 %type <action> assign_stmts_opt 148 %type <action> expr 149 %type <action> program 150 %type <action> level 151 152 %type <len> opcode opcode_list push_item push_list 153 154 /* make sure to free these, too! */ 155 %type <str> sprite 156 %type <str> variable 157 158 %% 159 160 /* rules */ 161 162 program 163 : elems 164 { *((Buffer *)buffer) = $1; } 165 166 ; 167 168 elems 169 : elem 170 | elems elem 171 { bufferConcat($1, $2); } 172 ; 173 174 elem 175 : stmt 176 ; 177 178 stmt 179 : '{' '}' { $$ = NULL; } 180 | '{' statements '}' { $$ = $2; } 181 | ';' { $$ = NULL; } 182 | assign_stmt ';' 183 | if_stmt 184 | iter_stmt 185 | cont_stmt 186 | break_stmt 187 ; 188 189 assign_stmts 190 : assign_stmt 191 | assign_stmts ',' assign_stmt { bufferConcat($1, $3); } 192 ; 193 194 statements 195 : /* empty */ { $$ = NULL; } 196 | stmt 197 | statements stmt 198 { bufferConcat($1, $2); } 199 ; 200 201 if_stmt 202 /* XXX- I haven't tested the frameloaded() stuff yet.. */ 203 204 : IF '(' FRAMELOADED '(' NUMBER ')' ')' stmt ELSE stmt 205 { $$ = newBuffer(); 206 bufferWriteU8($$, SWFACTION_WAITFORFRAME); 207 bufferWriteS16($$, 3); 208 bufferWriteS16($$, atoi($5)); 209 free($5); 210 bufferWriteU8($$, 1); /* if not loaded, jump to.. */ 211 bufferWriteU8($$, SWFACTION_JUMP); 212 bufferWriteS16($$, 2); 213 bufferWriteS16($$, bufferLength($10)+5); 214 bufferConcat($$, $10); /* ..here */ 215 bufferWriteU8($$, SWFACTION_JUMP); 216 bufferWriteS16($$, 2); 217 bufferWriteS16($$, bufferLength($8)); 218 bufferConcat($$, $8); } 219 220 | IF '(' FRAMELOADED '(' NUMBER ')' ')' stmt 221 { $$ = newBuffer(); 222 bufferWriteU8($$, SWFACTION_WAITFORFRAME); 223 bufferWriteS16($$, 3); 224 bufferWriteS16($$, atoi($5)); 225 free($5); 226 bufferWriteU8($$, 1); /* if not loaded, jump to.. */ 227 bufferWriteU8($$, SWFACTION_JUMP); 228 bufferWriteS16($$, 2); 229 bufferWriteS16($$, 5); 230 bufferWriteU8($$, SWFACTION_JUMP); /* ..here */ 231 bufferWriteS16($$, 2); 232 bufferWriteS16($$, bufferLength($8)); /* ..and then out */ 233 bufferConcat($$, $8); } 234 235 /* make this case cleaner.. */ 236 | IF '(' '!' FRAMELOADED '(' NUMBER ')' ')' stmt 237 { $$ = newBuffer(); 238 bufferWriteU8($$, SWFACTION_WAITFORFRAME); 239 bufferWriteS16($$, 3); 240 bufferWriteS16($$, atoi($6)); 241 free($6); 242 bufferWriteU8($$, 1); /* if not loaded, jump to.. */ 243 bufferWriteU8($$, SWFACTION_JUMP); 244 bufferWriteS16($$, 2); 245 bufferWriteS16($$, bufferLength($9)); 246 bufferConcat($$, $9); } /* ..here */ 247 248 | IF '(' FRAMELOADED '(' expr ')' ')' stmt ELSE stmt 249 { $$ = $5; 250 bufferWriteU8($$, SWFACTION_WAITFORFRAME2); 251 bufferWriteS16($$, 1); 252 bufferWriteU8($$, 1); /* if not loaded, jump to.. */ 253 bufferWriteU8($$, SWFACTION_JUMP); 254 bufferWriteS16($$, 2); 255 bufferWriteS16($$, bufferLength($10)+5); 256 bufferConcat($$, $10); /* ..here */ 257 bufferWriteU8($$, SWFACTION_JUMP); 258 bufferWriteS16($$, 2); 259 bufferWriteS16($$, bufferLength($8)); 260 bufferConcat($$, $8); } 261 262 | IF '(' FRAMELOADED '(' expr ')' ')' stmt 263 { $$ = $5; 264 bufferWriteU8($$, SWFACTION_WAITFORFRAME2); 265 bufferWriteS16($$, 1); 266 bufferWriteU8($$, 1); /* if not loaded, jump to.. */ 267 bufferWriteU8($$, SWFACTION_JUMP); 268 bufferWriteS16($$, 2); 269 bufferWriteS16($$, 5); 270 bufferWriteU8($$, SWFACTION_JUMP); /* ..here */ 271 bufferWriteS16($$, 2); 272 bufferWriteS16($$, bufferLength($8)); /* ..and then out */ 273 bufferConcat($$, $8); } 274 275 /* make this case cleaner.. */ 276 | IF '(' '!' FRAMELOADED '(' expr ')' ')' stmt 277 { $$ = $6; 278 bufferWriteU8($$, SWFACTION_WAITFORFRAME2); 279 bufferWriteS16($$, 1); 280 bufferWriteU8($$, 1); /* if not loaded, jump to.. */ 281 bufferWriteU8($$, SWFACTION_JUMP); 282 bufferWriteS16($$, 2); 283 bufferWriteS16($$, bufferLength($9)); 284 bufferConcat($$, $9); } /* ..here */ 285 286 | IF '(' expr ')' stmt ELSE stmt 287 { bufferWriteU8($3, SWFACTION_IF); 288 bufferWriteS16($3, 2); 289 bufferWriteS16($3, bufferLength($7)+5); 290 bufferConcat($3, $7); 291 bufferWriteU8($3, SWFACTION_JUMP); 292 bufferWriteS16($3, 2); 293 bufferWriteS16($3, bufferLength($5)); 294 bufferConcat($3, $5); 295 $$ = $3; } 296 297 | IF '(' expr ')' stmt 298 { bufferWriteU8($3, SWFACTION_LOGICALNOT); 299 bufferWriteU8($3, SWFACTION_IF); 300 bufferWriteS16($3, 2); 301 bufferWriteS16($3, bufferLength($5)); 302 bufferConcat($3, $5); 303 $$ = $3; } 304 ; 305 306 expr_opt 307 : /* empty */ { $$ = NULL; } 308 | expr { $$ = $1; } 309 ; 310 311 /* not thought out yet.. 312 switch_stmt 313 : SWITCH '(' expr ')' '{' 314 { $$ = $3; 315 pushLoop(); } 316 switch_cases '}' 317 { bufferConcat($$, $7); } 318 ; 319 320 switch_cases 321 : switch_cases switch_case 322 | switch_case 323 ; 324 325 switch_case 326 : CASE INTEGER ':' stmt 327 { $$ = newBuffer(); } 328 ; 329 */ 330 331 iter_stmt 332 : WHILE '(' '!' FRAMELOADED '(' NUMBER ')' ')' stmt 333 { $$ = newBuffer(); 334 bufferWriteU8($$, SWFACTION_WAITFORFRAME); 335 bufferWriteS16($$, 3); 336 bufferWriteS16($$, atoi($6)); 337 free($6); 338 bufferWriteU8($$, 1); /* if not loaded, jump to.. */ 339 bufferWriteU8($$, SWFACTION_JUMP); 340 bufferWriteS16($$, 2); 341 bufferWriteS16($$, bufferLength($9)+5); 342 bufferConcat($$, $9); /* ..here */ 343 bufferWriteU8($$, SWFACTION_JUMP); 344 bufferWriteS16($$, 2); 345 bufferWriteS16($$, -(bufferLength($$)+2)); } 346 347 | WHILE '(' expr ')' stmt 348 { $$ = $3; 349 bufferWriteU8($$, SWFACTION_LOGICALNOT); 350 bufferWriteU8($$, SWFACTION_IF); 351 bufferWriteS16($$, 2); 352 bufferWriteS16($$, bufferLength($5)+5); 353 bufferConcat($$, $5); 354 bufferWriteU8($$, SWFACTION_JUMP); 355 bufferWriteS16($$, 2); 356 bufferWriteS16($$, -(bufferLength($$)+2)); 357 bufferResolveJumps($$); } 358 359 | DO stmt WHILE '(' expr ')' 360 { $$ = $2; 361 bufferConcat($$, $5); 362 bufferWriteU8($$, SWFACTION_IF); 363 bufferWriteS16($$, 2); 364 bufferWriteS16($$, -(bufferLength($$)+2)); 365 bufferResolveJumps($$); } 366 367 | FOR '(' assign_stmts_opt ';' expr_opt ';' assign_stmts_opt ')' stmt 368 { if (!$5) 369 $5 = newBuffer(); 370 else { 371 bufferWriteU8($5, SWFACTION_LOGICALNOT); 372 bufferWriteU8($5, SWFACTION_IF); 373 bufferWriteS16($5, 2); 374 bufferWriteS16($5, bufferLength($9)+bufferLength($7)+5); 375 } 376 bufferConcat($5, $9); 377 bufferConcat($5, $7); 378 bufferWriteU8($5, SWFACTION_JUMP); 379 bufferWriteS16($5, 2); 380 bufferWriteS16($5, -(bufferLength($5)+2)); 381 bufferResolveJumps($5); 382 $$ = $3; 383 if(!$$) $$ = newBuffer(); 384 bufferConcat($$, $5); 385 } 386 ; 387 388 assign_stmts_opt 389 : /* empty */ { $$ = NULL; } 390 | assign_stmts 391 ; 392 393 cont_stmt 394 : CONTINUE ';' 395 { $$ = newBuffer(); 396 bufferWriteU8($$, SWFACTION_JUMP); 397 bufferWriteS16($$, 2); 398 bufferWriteS16($$, MAGIC_CONTINUE_NUMBER); } 399 ; 400 401 break_stmt 402 : BREAK ';' 403 { $$ = newBuffer(); 404 bufferWriteU8($$, SWFACTION_JUMP); 405 bufferWriteS16($$, 2); 406 bufferWriteS16($$, MAGIC_BREAK_NUMBER); } 407 ; 408 409 410 urlmethod 411 : /* empty */ { $$ = GETURL_METHOD_NOSEND; } 412 413 | ',' STRING { if(strcmp($2, "GET") == 0) 414 $$ = GETURL_METHOD_GET; 415 else if(strcmp($2, "POST") == 0) 416 $$ = GETURL_METHOD_POST; } 417 ; 418 419 level 420 : expr 421 { $$ = newBuffer(); 422 bufferWriteString($$, "_level", 7); 423 bufferConcat($$, $1); 424 bufferWriteOp($$, SWFACTION_STRINGCONCAT); } 425 ; 426 427 void_function_call 428 : STOPDRAG '(' ')' /* no args */ 429 { $$ = newBuffer(); 430 bufferWriteU8($$, SWFACTION_ENDDRAG); } 431 432 | CALLFRAME '(' variable ')' 433 { $$ = newBuffer(); 434 bufferWriteString($$, $3, strlen($3)+1); 435 bufferWriteU8($$, SWFACTION_CALLFRAME); 436 bufferWriteS16($$, 0); 437 free($3); } 438 439 | CALLFRAME '(' STRING ')' 440 { $$ = newBuffer(); 441 bufferWriteString($$, $3, strlen($3)+1); 442 bufferWriteU8($$, SWFACTION_CALLFRAME); 443 bufferWriteS16($$, 0); 444 free($3); } 445 446 | REMOVECLIP '(' expr ')' 447 { $$ = $3; 448 bufferWriteU8($$, SWFACTION_REMOVECLIP); } 449 450 | TRACE '(' expr ')' 451 { $$ = $3; 452 bufferWriteU8($$, SWFACTION_TRACE); } 453 454 /* getURL2(url, window, [method]) */ 455 | GETURL '(' expr ',' expr ')' 456 { $$ = $3; 457 bufferConcat($$, $5); 458 bufferWriteU8($$, SWFACTION_GETURL2); 459 bufferWriteS16($$, 1); 460 bufferWriteU8($$, GETURL_METHOD_NOSEND); } 461 462 | GETURL '(' expr ',' expr urlmethod ')' 463 { $$ = $3; 464 bufferConcat($$, $5); 465 bufferWriteU8($$, SWFACTION_GETURL2); 466 bufferWriteS16($$, 1); 467 bufferWriteU8($$, $6); } 468 469 | GETURL1 '(' STRING ',' STRING ')' 470 { $$ = newBuffer(); 471 bufferWriteU8($$, SWFACTION_GETURL); 472 bufferWriteS16($$, strlen($3) + strlen($5) + 2); 473 bufferWriteHardString($$, $3, strlen($3)); 474 bufferWriteU8($$, 0); 475 bufferWriteHardString($$, $5, strlen($5)); 476 bufferWriteU8($$, 0); } 477 478 | LOADMOVIE '(' expr ',' expr urlmethod ')' 479 { $$ = $3; 480 bufferConcat($$, $5); 481 bufferWriteU8($$, SWFACTION_GETURL2); 482 bufferWriteS16($$, 1); 483 bufferWriteU8($$, $6 | GETURL_LOADMOVIE); } 484 485 | LOADMOVIENUM '(' expr ',' level urlmethod ')' 486 { $$ = $3; 487 bufferConcat($$, $5); 488 bufferWriteOp($$, SWFACTION_GETURL2); 489 bufferWriteS16($$, 1); 490 bufferWriteU8($$, $6); } 491 492 | LOADVARIABLES '(' expr ',' expr urlmethod ')' 493 { $$ = $3; 494 bufferConcat($$, $5); 495 bufferWriteU8($$, SWFACTION_GETURL2); 496 bufferWriteS16($$, 1); 497 bufferWriteU8($$, 0xc0 + $6); } 498 499 /* startDrag(target, lock, [left, right, top, bottom]) */ 500 | STARTDRAG '(' expr ',' expr ')' 501 { $$ = newBuffer(); 502 bufferWriteString($$, "0", 2); /* no constraint */ 503 bufferConcat($$, $5); 504 bufferConcat($$, $3); 505 bufferWriteU8($$, SWFACTION_STARTDRAG); } 506 507 | STARTDRAG '(' expr ',' expr ',' expr ',' expr ',' expr ',' expr ')' 508 { $$ = newBuffer(); 509 bufferConcat($$, $7); 510 bufferConcat($$, $11); 511 bufferConcat($$, $9); 512 bufferConcat($$, $13); 513 bufferWriteString($$, "1", 2); /* has constraint */ 514 bufferConcat($$, $5); 515 bufferConcat($$, $3); 516 bufferWriteU8($$, SWFACTION_STARTDRAG); } 517 518 /* duplicateClip(target, new, depth) */ 519 | DUPLICATECLIP '(' expr ',' expr ',' expr ')' 520 { $$ = $3; 521 bufferConcat($$, $5); 522 bufferConcat($$, $7); 523 bufferWriteWTHITProperty($$); 524 bufferWriteU8($$, SWFACTION_ADD); /* see docs for explanation */ 525 bufferWriteU8($$, SWFACTION_DUPLICATECLIP); } 526 527 /* v3 actions */ 528 | NEXTFRAME '(' ')' 529 { $$ = newBuffer(); 530 bufferWriteU8($$, SWFACTION_NEXTFRAME); } 531 532 | PREVFRAME '(' ')' 533 { $$ = newBuffer(); 534 bufferWriteU8($$, SWFACTION_PREVFRAME); } 535 536 | PLAY '(' ')' 537 { $$ = newBuffer(); 538 bufferWriteU8($$, SWFACTION_PLAY); } 539 540 | STOP '(' ')' 541 { $$ = newBuffer(); 542 bufferWriteU8($$, SWFACTION_STOP); } 543 544 | TOGGLEQUALITY '(' ')' 545 { $$ = newBuffer(); 546 bufferWriteU8($$, SWFACTION_TOGGLEQUALITY); } 547 548 | STOPSOUNDS '(' ')' 549 { $$ = newBuffer(); 550 bufferWriteU8($$, SWFACTION_STOPSOUNDS); } 551 552 | GOTOFRAME '(' NUMBER ')' 553 { $$ = newBuffer(); 554 bufferWriteU8($$, SWFACTION_GOTOFRAME); 555 bufferWriteS16($$, 2); 556 bufferWriteS16($$, atoi($3)); 557 free($3); } 558 559 | GOTOFRAME '(' STRING ')' 560 { $$ = newBuffer(); 561 bufferWriteU8($$, SWFACTION_GOTOLABEL); 562 bufferWriteS16($$, strlen($3)+1); 563 bufferWriteHardString($$, $3, strlen($3)+1); 564 free($3); } 565 566 | GOTOFRAME '(' expr ')' 567 { $$ = $3; 568 bufferWriteU8($$, SWFACTION_GOTOFRAME2); 569 bufferWriteS16($$, 1); 570 bufferWriteU8($$, 0); } /* XXX - and stop */ 571 572 | GOTOANDPLAY '(' expr ')' 573 { $$ = $3; 574 bufferWriteU8($$, SWFACTION_GOTOFRAME2); 575 bufferWriteS16($$, 1); 576 bufferWriteU8($$, 1); } /* XXX - and play */ 577 578 | SETTARGET '(' STRING ')' 579 { $$ = newBuffer(); 580 bufferWriteU8($$, SWFACTION_SETTARGET); 581 bufferWriteS16($$, strlen($3)+1); 582 bufferWriteHardString($$, $3, strlen($3)+1); 583 free($3); } 584 585 | SETTARGET '(' expr ')' 586 { $$ = $3; 587 bufferWriteU8($$, SWFACTION_SETTARGET2); } 588 589 | TELLTARGET '(' STRING ')' stmt 590 { $$ = newBuffer(); 591 /* SetTarget(STRING) */ 592 bufferWriteU8($$, SWFACTION_SETTARGET); 593 bufferWriteS16($$, strlen($3)+1); 594 bufferWriteHardString($$, $3, strlen($3)+1); 595 /* stmt */ 596 bufferConcat($$, $5); 597 /* SetTarget('') */ 598 bufferWriteU8($$, SWFACTION_SETTARGET); 599 bufferWriteS16($$, 1); 600 bufferWriteU8($$, 0); 601 free($3); } 602 603 | TELLTARGET '(' expr ')' stmt 604 { $$ = $3; 605 /* SetTarget(expr) */ 606 bufferWriteU8($$, SWFACTION_SETTARGET2); 607 /* stmt */ 608 bufferConcat($$, $5); 609 /* SetTarget('') */ 610 bufferWriteU8($$, SWFACTION_SETTARGET); 611 bufferWriteS16($$, 1); 612 bufferWriteU8($$, 0); } 613 ; 614 615 function_call 616 : EVAL '(' expr ')' 617 { $$ = $3; 618 bufferWriteU8($$, SWFACTION_GETVARIABLE); } 619 620 | TIME '(' ')' 621 { $$ = newBuffer(); 622 bufferWriteU8($$, SWFACTION_GETTIME); } 623 624 | RANDOM '(' expr ')' 625 { $$ = $3; 626 bufferWriteU8($$, SWFACTION_RANDOMNUMBER); } 627 628 | LENGTH '(' expr ')' 629 { $$ = $3; 630 bufferWriteU8($$, SWFACTION_STRINGLENGTH); } 631 632 | INT '(' expr ')' 633 { $$ = $3; 634 bufferWriteU8($$, SWFACTION_INT); } 635 636 | ORD '(' expr ')' 637 { $$ = $3; 638 bufferWriteU8($$, SWFACTION_ORD); } 639 640 | CHR '(' expr ')' 641 { $$ = $3; 642 bufferWriteU8($$, SWFACTION_CHR); } 643 644 | CONCAT '(' expr ',' expr ')' 645 { $$ = $3; 646 bufferConcat($$, $5); 647 bufferWriteU8($$, SWFACTION_STRINGCONCAT); } 648 649 | SUBSTR '(' expr ',' expr ',' expr ')' 650 { $$ = $3; 651 bufferConcat($$, $5); 652 bufferConcat($$, $7); 653 bufferWriteU8($$, SWFACTION_SUBSTRING); } 654 655 | GETPROPERTY '(' expr ',' STRING ')' 656 { $$ = newBuffer(); 657 bufferConcat($$, $3); 658 bufferWriteProperty($$, $5); 659 bufferWriteU8($$, SWFACTION_GETPROPERTY); 660 free($5); } 661 ; 662 663 pf_expr 664 : lhs_expr "++" %prec POSTFIX 665 { $$ = newBuffer(); 666 bufferWriteBuffer($$, $1); 667 bufferWriteU8($$, SWFACTION_GETVARIABLE); 668 bufferWriteBuffer($$, $1); 669 bufferConcat($$, $1); 670 bufferWriteU8($$, SWFACTION_GETVARIABLE); 671 bufferWriteString($$, "1", 2); 672 bufferWriteU8($$, SWFACTION_ADD); 673 bufferWriteU8($$, SWFACTION_SETVARIABLE); } 674 675 | lhs_expr "--" %prec POSTFIX 676 { $$ = newBuffer(); 677 bufferWriteBuffer($$, $1); 678 bufferWriteU8($$, SWFACTION_GETVARIABLE); 679 bufferWriteBuffer($$, $1); 680 bufferConcat($$, $1); 681 bufferWriteU8($$, SWFACTION_GETVARIABLE); 682 bufferWriteString($$, "1", 2); 683 bufferWriteU8($$, SWFACTION_SUBTRACT); 684 bufferWriteU8($$, SWFACTION_SETVARIABLE); } 685 ; 686 687 /* these leave a value on the stack */ 688 rhs_expr 689 : function_call 690 691 | '(' rhs_expr ')' 692 { $$ = $2; } 693 694 | NUMBER 695 { $$ = newBuffer(); 696 bufferWriteString($$, $1, strlen($1)+1); 697 free($1); } 698 699 | '-' NUMBER %prec NEGATE 700 { $$ = newBuffer(); 701 bufferWriteString($$, "-", 2); 702 bufferWriteString($$, $2, strlen($2)+1); 703 free($2); } 704 705 | STRING 706 { $$ = newBuffer(); 707 bufferWriteString($$, $1, strlen($1)+1); 708 free($1); } 709 710 | variable 711 { $$ = newBuffer(); 712 bufferWriteString($$, $1, strlen($1)+1); 713 bufferWriteU8($$, SWFACTION_GETVARIABLE); 714 free($1); } 715 716 | sprite 717 { $$ = newBuffer(); 718 bufferWriteString($$, $1, strlen($1)+1); 719 free($1); } 720 721 | sprite '.' IDENTIFIER 722 { $$ = newBuffer(); 723 bufferWriteString($$, $1, strlen($1)+1); 724 bufferWriteProperty($$, $3); 725 bufferWriteU8($$, SWFACTION_GETPROPERTY); 726 free($3); 727 free($1); } 728 729 | "++" sprite '.' IDENTIFIER 730 { $$ = newBuffer(); 731 bufferWriteString($$, $2, strlen($2)+1); 732 bufferWriteProperty($$, $4); 733 bufferWriteString($$, $2, strlen($2)+1); 734 bufferWriteProperty($$, $4); 735 bufferWriteString($$, $2, strlen($2)+1); 736 bufferWriteProperty($$, $4); 737 bufferWriteString($$, "1", 2); 738 bufferWriteU8($$, SWFACTION_ADD); 739 bufferWriteU8($$, SWFACTION_SETPROPERTY); 740 bufferWriteU8($$, SWFACTION_GETPROPERTY); 741 free($2); 742 free($4); } 743 744 | "++" lhs_expr 745 { $$ = $2; 746 bufferWriteU8($$, SWFACTION_PUSHDUP); 747 bufferWriteU8($$, SWFACTION_PUSHDUP); 748 bufferWriteU8($$, SWFACTION_GETVARIABLE); 749 bufferWriteString($$, "1", 2); 750 bufferWriteU8($$, SWFACTION_ADD); 751 bufferWriteU8($$, SWFACTION_SETVARIABLE); 752 bufferWriteU8($$, SWFACTION_GETVARIABLE); } 753 754 | "--" sprite '.' IDENTIFIER 755 { $$ = newBuffer(); 756 bufferWriteString($$, $2, strlen($2)+1); 757 bufferWriteProperty($$, $4); 758 bufferWriteString($$, $2, strlen($2)+1); 759 bufferWriteProperty($$, $4); 760 bufferWriteString($$, $2, strlen($2)+1); 761 bufferWriteProperty($$, $4); 762 bufferWriteString($$, "1", 2); 763 bufferWriteU8($$, SWFACTION_ADD); 764 bufferWriteU8($$, SWFACTION_SETPROPERTY); 765 bufferWriteU8($$, SWFACTION_GETPROPERTY); 766 free($2); 767 free($4); } 768 769 | "--" lhs_expr 770 { $$ = $2; 771 bufferWriteU8($$, SWFACTION_PUSHDUP); 772 bufferWriteU8($$, SWFACTION_PUSHDUP); 773 bufferWriteU8($$, SWFACTION_GETVARIABLE); 774 bufferWriteString($$, "1", 2); 775 bufferWriteU8($$, SWFACTION_SUBTRACT); 776 bufferWriteU8($$, SWFACTION_SETVARIABLE); 777 bufferWriteU8($$, SWFACTION_GETVARIABLE); } 778 779 | '-' rhs_expr %prec UMINUS 780 { $$ = $2; 781 bufferWriteString($2, "-1", 3); 782 bufferWriteU8($2, SWFACTION_MULTIPLY); } 783 784 | '!' rhs_expr 785 { $$ = $2; 786 bufferWriteU8($2, SWFACTION_LOGICALNOT); } 787 788 | lhs_expr '=' rhs_expr /* assign and leave copy on stack */ 789 { $$ = $1; 790 bufferConcat($$, $3); 791 bufferWriteU8($$, SWFACTION_PUSHDUP); 792 bufferWriteU8($$, SWFACTION_SETVARIABLE); } 793 794 | rhs_expr '*' rhs_expr 795 { $$ = $1; 796 bufferConcat($$, $3); 797 bufferWriteU8($$, SWFACTION_MULTIPLY); } 798 799 | rhs_expr '/' rhs_expr 800 { $$ = $1; 801 bufferConcat($$, $3); 802 bufferWriteU8($$, SWFACTION_DIVIDE); } 803 804 | rhs_expr '+' rhs_expr 805 { $$ = $1; 806 bufferConcat($$, $3); 807 bufferWriteU8($$, SWFACTION_ADD); } 808 809 | rhs_expr '-' rhs_expr 810 { $$ = $1; 811 bufferConcat($$, $3); 812 bufferWriteU8($$, SWFACTION_SUBTRACT); } 813 814 | rhs_expr '&' rhs_expr 815 { $$ = $1; 816 bufferConcat($$, $3); 817 bufferWriteU8($$, SWFACTION_STRINGCONCAT); } 818 819 | rhs_expr '<' rhs_expr 820 { $$ = $1; 821 bufferConcat($$, $3); 822 bufferWriteU8($$, SWFACTION_LESSTHAN); } 823 824 | rhs_expr '>' rhs_expr 825 { $$ = $3; 826 bufferConcat($$, $1); 827 bufferWriteU8($$, SWFACTION_LESSTHAN); } 828 829 | rhs_expr "<=" rhs_expr 830 { $$ = $3; 831 bufferConcat($$, $1); 832 bufferWriteU8($$, SWFACTION_LESSTHAN); 833 bufferWriteU8($$, SWFACTION_LOGICALNOT); } 834 835 | rhs_expr ">=" rhs_expr 836 { bufferConcat($1, $3); 837 bufferWriteU8($1, SWFACTION_LESSTHAN); 838 bufferWriteU8($1, SWFACTION_LOGICALNOT); } 839 840 | rhs_expr "!==" rhs_expr 841 { bufferConcat($1, $3); 842 bufferWriteU8($1, SWFACTION_STRINGEQ); 843 bufferWriteU8($1, SWFACTION_LOGICALNOT); } 844 845 | rhs_expr "===" rhs_expr 846 { bufferConcat($1, $3); 847 bufferWriteU8($1, SWFACTION_STRINGEQ); } 848 849 | rhs_expr "<=>" rhs_expr 850 { bufferConcat($1, $3); 851 bufferWriteU8($1, SWFACTION_STRINGCOMPARE); } 852 853 | rhs_expr "==" rhs_expr 854 { bufferConcat($1, $3); 855 bufferWriteU8($1, SWFACTION_EQUAL); } 856 857 | rhs_expr "!=" rhs_expr 858 { bufferConcat($1, $3); 859 bufferWriteU8($1, SWFACTION_EQUAL); 860 bufferWriteU8($1, SWFACTION_LOGICALNOT); } 861 862 | rhs_expr "&&" rhs_expr 863 { bufferConcat($1, $3); 864 bufferWriteU8($1, SWFACTION_LOGICALAND); } 865 866 | rhs_expr "||" rhs_expr 867 { bufferConcat($1, $3); 868 bufferWriteU8($1, SWFACTION_LOGICALOR); } 869 870 | rhs_expr '?' rhs_expr ':' rhs_expr 871 { bufferWriteU8($1, SWFACTION_IF); 872 bufferWriteS16($1, 2); 873 bufferWriteS16($1, bufferLength($5)+5); 874 bufferConcat($1, $5); 875 bufferWriteU8($1, SWFACTION_JUMP); 876 bufferWriteS16($1, 2); 877 bufferWriteS16($1, bufferLength($3)); 878 bufferConcat($1, $3); } 879 ; 880 881 variable 882 : IDENTIFIER 883 884 | sprite ':' IDENTIFIER 885 { $$ = $1; 886 $$ = stringConcat($$, strdup(":")); 887 $$ = stringConcat($$, $3); } 888 ; 889 890 sprite 891 : THIS 892 { $$ = strdup(""); } 893 894 | '.' 895 { $$ = strdup(""); } 896 897 | '/' 898 { $$ = strdup("/"); } 899 900 | PARENT 901 { $$ = strdup(".."); } 902 903 | IDENTIFIER 904 { $$ = $1; } 905 906 | PATH 907 { $$ = $1; } 908 ; 909 910 lhs_expr 911 : variable 912 { $$ = newBuffer(); 913 bufferWriteString($$, $1, strlen($1)+1); 914 free($1); } 915 916 | STRING 917 { $$ = newBuffer(); 918 bufferWriteString($$, $1, strlen($1)+1); 919 free($1); } 920 921 | '(' rhs_expr ')' { $$ = $2; } 922 ; 923 924 assign_stmt 925 : pf_expr 926 927 | ASM '{' 928 { asmBuffer = newBuffer(); } 929 opcode_list '}' 930 { $$ = asmBuffer; } 931 932 | void_function_call 933 934 | "++" lhs_expr 935 { $$ = $2; 936 bufferWriteBuffer($$, $2); 937 bufferWriteU8($$, SWFACTION_GETVARIABLE); 938 bufferWriteString($$, "1", 2); 939 bufferWriteU8($$, SWFACTION_ADD); 940 bufferWriteU8($$, SWFACTION_SETVARIABLE); } 941 942 | "--" lhs_expr 943 { $$ = $2; 944 bufferWriteBuffer($$, $2); 945 bufferWriteU8($$, SWFACTION_GETVARIABLE); 946 bufferWriteString($$, "1", 2); 947 bufferWriteU8($$, SWFACTION_SUBTRACT); 948 bufferWriteU8($$, SWFACTION_SETVARIABLE); } 949 950 | "++" sprite '.' IDENTIFIER 951 { $$ = newBuffer(); 952 bufferWriteString($$, $2, strlen($2)+1); 953 bufferWriteProperty($$, $4); 954 bufferWriteU8($$, SWFACTION_GETPROPERTY); 955 bufferWriteString($$, "1", 2); 956 bufferWriteU8($$, SWFACTION_ADD); 957 bufferWriteString($$, $2, strlen($2)+1); 958 bufferWriteProperty($$, $4); 959 bufferWriteU8($$, SWFACTION_SETPROPERTY); 960 free($2); 961 free($4); } 962 963 | "--" sprite '.' IDENTIFIER 964 { $$ = newBuffer(); 965 bufferWriteString($$, $2, strlen($2)+1); 966 bufferWriteProperty($$, $4); 967 bufferWriteU8($$, SWFACTION_GETPROPERTY); 968 bufferWriteString($$, "1", 2); 969 bufferWriteU8($$, SWFACTION_SUBTRACT); 970 bufferWriteString($$, $2, strlen($2)+1); 971 bufferWriteProperty($$, $4); 972 bufferWriteU8($$, SWFACTION_SETPROPERTY); 973 free($2); 974 free($4); } 975 976 | lhs_expr '=' rhs_expr 977 { bufferConcat($1, $3); 978 bufferWriteU8($1, SWFACTION_SETVARIABLE); } 979 980 | lhs_expr "*=" rhs_expr 981 { bufferWriteBuffer($1, $1); 982 bufferWriteU8($1, SWFACTION_GETVARIABLE); 983 bufferConcat($1, $3); 984 bufferWriteU8($1, SWFACTION_MULTIPLY); 985 bufferWriteU8($1, SWFACTION_SETVARIABLE); } 986 987 | lhs_expr "/=" rhs_expr 988 { bufferWriteBuffer($1, $1); 989 bufferWriteU8($1, SWFACTION_GETVARIABLE); 990 bufferConcat($1, $3); 991 bufferWriteU8($1, SWFACTION_DIVIDE); 992 bufferWriteU8($1, SWFACTION_SETVARIABLE); } 993 994 | lhs_expr "+=" rhs_expr 995 { bufferWriteBuffer($1, $1); 996 bufferWriteU8($1, SWFACTION_GETVARIABLE); 997 bufferConcat($1, $3); 998 bufferWriteU8($1, SWFACTION_ADD); 999 bufferWriteU8($1, SWFACTION_SETVARIABLE); } 1000 1001 | lhs_expr "-=" rhs_expr 1002 { bufferWriteBuffer($1, $1); 1003 bufferWriteU8($1, SWFACTION_GETVARIABLE); 1004 bufferConcat($1, $3); 1005 bufferWriteU8($1, SWFACTION_SUBTRACT); 1006 bufferWriteU8($1, SWFACTION_SETVARIABLE); } 1007 1008 | sprite '.' IDENTIFIER '=' rhs_expr 1009 { $$ = newBuffer(); 1010 bufferWriteString($$, $1, strlen($1)+1); 1011 bufferWriteProperty($$, $3); 1012 bufferConcat($$,$5); 1013 bufferWriteU8($$, SWFACTION_SETPROPERTY); 1014 free($1); 1015 free($3); } 1016 1017 | sprite '.' IDENTIFIER "*=" rhs_expr 1018 { $$ = newBuffer(); 1019 bufferWriteString($$, $1, strlen($1)+1); 1020 bufferWriteProperty($$, $3); 1021 bufferWriteString($$, $1, strlen($1)+1); 1022 bufferWriteProperty($$, $3); 1023 bufferWriteU8($$, SWFACTION_GETPROPERTY); 1024 bufferConcat($$, $5); 1025 bufferWriteU8($$, SWFACTION_MULTIPLY); 1026 bufferWriteU8($$, SWFACTION_SETPROPERTY); 1027 free($1); 1028 free($3); } 1029 1030 | sprite '.' IDENTIFIER "/=" rhs_expr 1031 { $$ = newBuffer(); 1032 bufferWriteString($$, $1, strlen($1)+1); 1033 bufferWriteProperty($$, $3); 1034 bufferWriteString($$, $1, strlen($1)+1); 1035 bufferWriteProperty($$, $3); 1036 bufferWriteU8($$, SWFACTION_GETPROPERTY); 1037 bufferConcat($$, $5); 1038 bufferWriteU8($$, SWFACTION_DIVIDE); 1039 bufferWriteU8($$, SWFACTION_SETPROPERTY); 1040 free($1); 1041 free($3); } 1042 1043 | sprite '.' IDENTIFIER "+=" rhs_expr 1044 { $$ = newBuffer(); 1045 bufferWriteString($$, $1, strlen($1)+1); 1046 bufferWriteProperty($$, $3); 1047 bufferWriteString($$, $1, strlen($1)+1); 1048 bufferWriteProperty($$, $3); 1049 bufferWriteU8($$, SWFACTION_GETPROPERTY); 1050 bufferConcat($$, $5); 1051 bufferWriteU8($$, SWFACTION_ADD); 1052 bufferWriteU8($$, SWFACTION_SETPROPERTY); 1053 free($1); 1054 free($3); } 1055 1056 | sprite '.' IDENTIFIER "-=" rhs_expr 1057 { $$ = newBuffer(); 1058 bufferWriteString($$, $1, strlen($1)+1); 1059 bufferWriteProperty($$, $3); 1060 bufferWriteString($$, $1, strlen($1)+1); 1061 bufferWriteProperty($$, $3); 1062 bufferWriteU8($$, SWFACTION_GETPROPERTY); 1063 bufferConcat($$, $5); 1064 bufferWriteU8($$, SWFACTION_SUBTRACT); 1065 bufferWriteU8($$, SWFACTION_SETPROPERTY); 1066 free($1); 1067 free($3); } 1068 ; 1069 1070 expr 1071 : rhs_expr 1072 ; 1073 1074 push_item 1075 : STRING { $$ = bufferWriteU8(asmBuffer, PUSH_STRING); 1076 $$ += bufferWriteHardString(asmBuffer, $1, strlen($1) + 1); } 1077 1078 push_list 1079 : push_item { $$ = $1; } 1080 | push_list ',' push_item { $$ = $1 + $3; } 1081 1082 1083 opcode_list 1084 : opcode 1085 | opcode_list opcode { $$ = $1 + $2; } 1086 ; 1087 1088 opcode 1089 : ASMPUSH { $<len>$ = bufferWritePushOp(asmBuffer); 1090 $<len>$ += bufferWriteS16(asmBuffer, 0); } 1091 push_list { $$ = $<len>2 + $3; 1092 1093 bufferPatchLength(asmBuffer, $3); } 1094 1095 | ASMADD { $$ = bufferWriteOp(asmBuffer, SWFACTION_ADD); } 1096 | ASMSUBSTRACT { $$ = bufferWriteOp(asmBuffer, SWFACTION_SUBTRACT); } 1097 | ASMMULTIPLY { $$ = bufferWriteOp(asmBuffer, SWFACTION_MULTIPLY); } 1098 | ASMDIVIDE { $$ = bufferWriteOp(asmBuffer, SWFACTION_DIVIDE); } 1099 | ASMEQUALS { $$ = bufferWriteOp(asmBuffer, SWFACTION_EQUAL); } 1100 | ASMLESS { $$ = bufferWriteOp(asmBuffer, SWFACTION_LESSTHAN); } 1101 | ASMLOGICALAND { $$ = bufferWriteOp(asmBuffer, SWFACTION_LOGICALAND); } 1102 | ASMLOGICALOR { $$ = bufferWriteOp(asmBuffer, SWFACTION_LOGICALOR); } 1103 | ASMLOGICALNOT { $$ = bufferWriteOp(asmBuffer, SWFACTION_LOGICALNOT); } 1104 | ASMSTRINGAND { $$ = bufferWriteOp(asmBuffer, SWFACTION_STRINGCONCAT); } 1105 | ASMSTRINGEQUALS { $$ = bufferWriteOp(asmBuffer, SWFACTION_STRINGEQ); } 1106 | ASMSTRINGLENGTH { $$ = bufferWriteOp(asmBuffer, SWFACTION_STRINGLENGTH); } 1107 | ASMSTRINGEXTRACT { $$ = bufferWriteOp(asmBuffer, SWFACTION_SUBSTRING); } 1108 | ASMMBSTRINGEXTRACT { $$ = bufferWriteOp(asmBuffer, SWFACTION_MBSUBSTRING); } 1109 | ASMMBSTRINGLENGTH { $$ = bufferWriteOp(asmBuffer, SWFACTION_MBLENGTH); } 1110 | ASMSTRINGLESS { $$ = bufferWriteOp(asmBuffer, SWFACTION_STRINGCOMPARE); } 1111 | ASMPOP { $$ = bufferWriteOp(asmBuffer, SWFACTION_POP); } 1112 | ASMASCIITOCHAR { $$ = bufferWriteOp(asmBuffer, SWFACTION_CHR); } 1113 | ASMCHARTOASCII { $$ = bufferWriteOp(asmBuffer, SWFACTION_ORD); } 1114 | ASMTOINTEGER { $$ = bufferWriteOp(asmBuffer, SWFACTION_INT); } 1115 | ASMMBASCIITOCHAR { $$ = bufferWriteOp(asmBuffer, SWFACTION_MBCHR); } 1116 | ASMMBCHARTOASCII { $$ = bufferWriteOp(asmBuffer, SWFACTION_MBORD); } 1117 | ASMCALL { $$ = bufferWriteOp(asmBuffer, SWFACTION_CALLFRAME); } 1118 | ASMGETVARIABLE { $$ = bufferWriteOp(asmBuffer, SWFACTION_GETVARIABLE); } 1119 | ASMSETVARIABLE { $$ = bufferWriteOp(asmBuffer, SWFACTION_SETVARIABLE); } 1120 | ASMGETPROPERTY { $$ = bufferWriteOp(asmBuffer, SWFACTION_GETPROPERTY); } 1121 | ASMSETPROPERTY { $$ = bufferWriteOp(asmBuffer, SWFACTION_SETPROPERTY); } 1122 | ASMREMOVESPRITE { $$ = bufferWriteOp(asmBuffer, SWFACTION_REMOVECLIP); } 1123 | ASMSETTARGET2 { $$ = bufferWriteOp(asmBuffer, SWFACTION_SETTARGET2); } 1124 | ASMSTARTDRAG { $$ = bufferWriteOp(asmBuffer, SWFACTION_STARTDRAG); } 1125 | ASMENDDRAG { $$ = bufferWriteOp(asmBuffer, SWFACTION_ENDDRAG); } 1126 | ASMCLONESPRITE { $$ = bufferWriteOp(asmBuffer, SWFACTION_DUPLICATECLIP); } 1127 | ASMGETTIME { $$ = bufferWriteOp(asmBuffer, SWFACTION_GETTIME); } 1128 | ASMRANDOMNUMBER { $$ = bufferWriteOp(asmBuffer, SWFACTION_RANDOMNUMBER); } 1129 | ASMTRACE { $$ = bufferWriteOp(asmBuffer, SWFACTION_TRACE); } 1130 1131 | ASMIF NUMBER { $$ = ( 1132 bufferWriteOp(asmBuffer, SWFACTION_IF) 1133 + bufferWriteS16(asmBuffer, 2) 1134 + bufferWriteS16(asmBuffer, atoi($2))); } 1135 | ASMJUMP NUMBER { $$ = ( 1136 bufferWriteOp(asmBuffer, SWFACTION_JUMP) 1137 + bufferWriteS16(asmBuffer, 2) 1138 + bufferWriteS16(asmBuffer, atoi($2))); } 1139 | ASMGETURL2 NUMBER { $$ = (bufferWriteOp(asmBuffer, SWFACTION_GETURL2) 1140 + bufferWriteS16(asmBuffer, 1) 1141 + bufferWriteU8(asmBuffer, atoi($2))); } 1142 | ASMGOTOFRAME2 NUMBER { $$ = (bufferWriteOp(asmBuffer, SWFACTION_GOTOFRAME2) 1143 + bufferWriteS16(asmBuffer, 1) 1144 + bufferWriteU8(asmBuffer, atoi($2))); 1145 /* SceneBias missing */ } 1146 | ASMWAITFORFRAME2 NUMBER { $$ = (bufferWriteOp(asmBuffer, SWFACTION_WAITFORFRAME2) 1147 + bufferWriteS16(asmBuffer, 1) 1148 + bufferWriteU8(asmBuffer, atoi($2))); } 1149 1150 ; 1151 1152 %% 1153