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