📄 swf5compiler.y
字号:
| SETMEMBER { $$ = strdup("setmember"); } | SHIFTLEFT { $$ = strdup("shiftleft"); } | SHIFTRIGHT { $$ = strdup("shiftright"); } | SHIFTRIGHT2 { $$ = strdup("shiftright2"); } | VAREQUALS { $$ = strdup("varequals"); } | OLDADD { $$ = strdup("oldAdd"); } | SUBTRACT { $$ = strdup("subtract"); } | MULTIPLY { $$ = strdup("multiply"); } | DIVIDE { $$ = strdup("divide"); } | OLDEQUALS { $$ = strdup("oldequals"); } | OLDLESSTHAN { $$ = strdup("oldlessthan"); } | LOGICALAND { $$ = strdup("logicaland"); } | LOGICALOR { $$ = strdup("logicalor"); } | NOT { $$ = strdup("not"); } | STRINGEQ { $$ = strdup("stringeq"); } | STRINGLENGTH { $$ = strdup("stringlength"); } | SUBSTRING { $$ = strdup("substring"); } | GETVARIABLE { $$ = strdup("getvariable"); } | SETVARIABLE { $$ = strdup("setvariable"); } | SETTARGETEXPRESSION { $$ = strdup("settargetexpression"); } | DUPLICATEMOVIECLIP { $$ = strdup("duplicateMovieClip"); } | REMOVEMOVIECLIP { $$ = strdup("removeMovieClip"); } | STARTDRAG { $$ = strdup("startDrag"); } | STOPDRAG { $$ = strdup("stopDrag"); } | STRINGLESSTHAN { $$ = strdup("stringlessthan"); } | MBLENGTH { $$ = strdup("mblength"); } | MBSUBSTRING { $$ = strdup("mbsubstring"); } | MBORD { $$ = strdup("mbord"); } | MBCHR { $$ = strdup("mbchr"); } | BRANCHALWAYS { $$ = strdup("branchalways"); } | BRANCHIFTRUE { $$ = strdup("branchiftrue"); } | GETURL2 { $$ = strdup("getURL2"); } | POST { $$ = strdup("post"); } | GET { $$ = strdup("get"); } | LOADVARIABLES { $$ = strdup("loadVariables"); } | LOADVARIABLESNUM { $$ = strdup("loadVariablesNum"); } | LOADMOVIE { $$ = strdup("loadMovie"); } | LOADMOVIENUM { $$ = strdup("loadMovieNum"); } | GOTOANDSTOP { $$ = strdup("gotoAndStop"); } | GOTOANDPLAY { $$ = strdup("gotoAndPlay"); } | SETTARGET { $$ = strdup("setTarget"); } | CALLFRAME { $$ = strdup("call"); } | GETPROPERTY { $$ = strdup("getProperty"); } | SETPROPERTY { $$ = strdup("setProperty"); } | CAST { $$ = strdup("cast"); } /* temp hack to keep things working */ | THIS { $$ = strdup("this"); } /* property names */ | _P_X { $$ = strdup("_x"); } | _P_Y { $$ = strdup("_y"); } | _P_XSCALE { $$ = strdup("_xscale"); } | _P_YSCALE { $$ = strdup("_yscale"); } | _P_CURRENTFRAME { $$ = strdup("_currentframe"); } | _P_TOTALFRAMES { $$ = strdup("_totalframes"); } | _P_ALPHA { $$ = strdup("_alpha"); } | _P_VISIBLE { $$ = strdup("_visible"); } | _P_WIDTH { $$ = strdup("_width"); } | _P_HEIGHT { $$ = strdup("_height"); } | _P_ROTATION { $$ = strdup("_rotation"); } | _P_TARGET { $$ = strdup("_target"); } | _P_FRAMESLOADED { $$ = strdup("_framesloaded"); } | _P_NAME { $$ = strdup("_name"); } | _P_DROPTARGET { $$ = strdup("_droptarget"); } | _P_URL { $$ = strdup("_url"); } | _P_HIGHQUALITY { $$ = strdup("_highquality"); } | _P_FOCUSRECT { $$ = strdup("_focusrect"); } | _P_SOUNDBUFTIME { $$ = strdup("_soundbuftime"); } | _P_QUALITY { $$ = strdup("_quality"); } | _P_XMOUSE { $$ = strdup("_xmouse"); } | _P_YMOUSE { $$ = strdup("_ymouse"); } ;formals_list : /* empty */ { $$.buffer = newBuffer(); $$.count = 0; } | identifier type_attr { $$.buffer = newBuffer(); bufferWriteHardString($$.buffer, $1, strlen($1)+1); $$.count = 1; free($1); } | formals_list ',' identifier type_attr { $$ = $1; bufferWriteHardString($$.buffer, $3, strlen($3)+1); ++$$.count; free($3); } ;function_identifier : { addctx(CTX_FUNCTION); $$ = NULL; } | identifier { addctx(CTX_FUNCTION); $$ = $1; } ;function_decl : FUNCTION function_identifier '(' formals_list ')' type_attr stmt { $$ = newASFunction(); $$->name = $2; $$->params = $4; $$->code = $7; delctx(CTX_FUNCTION); } ;inpart : IN obj_ref { $$ = $2; } ;obj_ref : lvalue { if($1.obj) { $$ = $1.obj; $$->hasObject = 1; if($1.ident) bufferConcat($$, $1.ident); else bufferConcat($$, $1.memexpr); bufferWriteOp($$, SWFACTION_GETMEMBER); } else { $$ = $1.ident; } } | function_call | method_call ;// this is a workaround for DELETE / DELETE2 OPs. (AS is broken!!!)obj_ref_for_delete_only : lvalue { if($1.obj) { $$ = $1.obj; $$->hasObject = 1; if($1.ident) bufferConcat($$, $1.ident); else bufferConcat($$, $1.memexpr); } else { $$ = $1.ident; } } | function_call | void_function_call | method_call | '(' obj_ref_for_delete_only ')' { $$ = $2; } ;while_init : WHILE { addctx(CTX_LOOP); } ;do_init : DO { addctx(CTX_LOOP); } ;for_init : /* empty */ { addctx(CTX_LOOP); } ;for_in_init : /* empty */ { addctx(CTX_FOR_IN); } ;iter_stmt : while_init '(' expr ')' stmt { $$ = $3; bufferWriteOp($$, SWFACTION_LOGICALNOT); bufferWriteOp($$, SWFACTION_IF); bufferWriteS16($$, 2); bufferWriteS16($$, bufferLength($5)+5); bufferConcat($$, $5); bufferWriteOp($$, SWFACTION_JUMP); bufferWriteS16($$, 2); bufferWriteS16($$, -(bufferLength($$)+2)); bufferResolveJumps($$); delctx(CTX_LOOP); } | do_init stmt WHILE '(' expr ')' { if($2) { $$ = $2; bufferConcat($$, $5); } else $$ = $5; bufferWriteOp($$, SWFACTION_IF); bufferWriteS16($$, 2); bufferWriteS16($$, -(bufferLength($$)+2)); bufferResolveJumps($$); delctx(CTX_LOOP); } | FOR '(' assign_stmts_opt ';' expr_opt ';' assign_stmts_opt ')' for_init stmt { int continue_len; if($3) $$ = $3; else $$ = newBuffer(); continue_len = bufferLength ($7); if($10) bufferConcatSimple($10, $7); else if ($7) $10 = $7; else $10 = newBuffer(); if($5) { bufferWriteOp($5, SWFACTION_LOGICALNOT); bufferWriteOp($5, SWFACTION_IF); bufferWriteS16($5, 2); bufferWriteS16($5, bufferLength($10)+5); bufferConcat($5, $10); } else $5 = $10; bufferWriteOp($5, SWFACTION_JUMP); bufferWriteS16($5, 2); bufferWriteS16($5, -(bufferLength($5)+2)); /* need to jump to last part of for stmt in continue case */ if (continue_len) bufferResolveJumpsFull($5, $5->pos, $5->pos - continue_len - 5); else bufferResolveJumps($5); bufferConcat($$, $5); delctx(CTX_LOOP); } | FOR '(' identifier inpart ')' for_in_init stmt { Buffer b2, b3; int tmp; $$ = $4; if($4->hasObject) bufferWriteOp($$, SWFACTION_ENUMERATE2); else bufferWriteOp($$, SWFACTION_ENUMERATE); b2 = newBuffer(); bufferWriteSetRegister(b2, 0); bufferWriteOp(b2, SWFACTION_PUSH); bufferWriteS16(b2, 1); bufferWriteU8(b2, 2); bufferWriteOp(b2, SWFACTION_EQUALS2); bufferWriteOp(b2, SWFACTION_IF); bufferWriteS16(b2, 2); b3 = newBuffer();/* basically a lvalue could be used here rather than an ident !!! *//* probably by using reg1 for the test rather than reg0 */ bufferWriteString(b3, $3, strlen($3)+1); bufferWriteRegister(b3, 0); bufferWriteOp(b3, SWFACTION_SETVARIABLE); bufferConcat(b3, $7); bufferWriteS16(b2, bufferLength(b3) + 5); tmp = bufferLength(b2) + bufferLength(b3) + 5; bufferWriteOp(b3, SWFACTION_JUMP); bufferWriteS16(b3, 2); bufferWriteS16(b3, -tmp); bufferConcat(b2, b3); bufferResolveJumps(b2); bufferConcat($$, b2); delctx(CTX_FOR_IN); free($3); } | FOR '(' VAR identifier inpart ')' for_in_init stmt { Buffer b2, b3; int tmp; $$ = $5; if($5->hasObject) bufferWriteOp($$, SWFACTION_ENUMERATE2); else bufferWriteOp($$, SWFACTION_ENUMERATE); b2 = newBuffer(); bufferWriteSetRegister(b2, 0); bufferWriteOp(b2, SWFACTION_PUSH); bufferWriteS16(b2, 1); bufferWriteU8(b2, 2); bufferWriteOp(b2, SWFACTION_EQUALS2); bufferWriteOp(b2, SWFACTION_IF); bufferWriteS16(b2, 2); // add size later b3 = newBuffer(); bufferWriteString(b3, $4, strlen($4)+1); bufferWriteRegister(b3, 0); bufferWriteOp(b3, SWFACTION_DEFINELOCAL); bufferConcat(b3, $8); bufferWriteS16(b2, bufferLength(b3) + 5); tmp = bufferLength(b2) + bufferLength(b3) + 5; bufferWriteOp(b3, SWFACTION_JUMP); bufferWriteS16(b3, 2); bufferWriteS16(b3, -tmp); bufferConcat(b2, b3); bufferResolveJumps(b2); bufferConcat($$, b2); delctx(CTX_FOR_IN); free($4); } ;assign_stmts_opt : /* empty */ { $$ = NULL; } | assign_stmts ;// continue only makes sense if there is a CTX_LOOP or CTX_FOR_IN// on the stackcont_stmt : CONTINUE ';' { if(chkctx(CTX_CONTINUE) < 0) { swf5error("continue outside loop"); YYABORT; } $$ = newBuffer(); bufferWriteOp($$, SWFACTION_JUMP); bufferWriteS16($$, 2); bufferWriteS16($$, MAGIC_CONTINUE_NUMBER); } ;// break is possible if there is a CTX_LOOP, CTX_FOR_IN or CTX_SWITCHbreak_stmt : BREAK ';' { int context = chkctx(CTX_BREAK); $$ = newBuffer(); if(context == CTX_FOR_IN || context == CTX_LOOP) { if(CTX_FOR_IN) /* break out of a for .. in */ bufferWriteOp($$, SWFACTION_POP); bufferWriteOp($$, SWFACTION_JUMP); bufferWriteS16($$, 2); bufferWriteS16($$, MAGIC_BREAK_NUMBER); } else if(context == CTX_SWITCH) { addctx(CTX_BREAK); } else { swf5error("break outside switch / loop"); YYABORT; } } ;urlmethod : /* empty */ { $$ = GETURL_METHOD_NOSEND; } | ',' GET { $$ = GETURL_METHOD_GET; } | ',' POST { $$ = GETURL_METHOD_POST; } | ',' STRING { if(strcasecmp($2, "GET") == 0) $$ = GETURL_METHOD_GET; else if(strcasecmp($2, "POST") == 0) $$ = GETURL_METHOD_POST; else $$ = GETURL_METHOD_NOSEND; } ;level : expr { $$ = newBuffer(); bufferWriteString($$, "_level", 7); bufferConcat($$, $1); bufferWriteOp($$, SWFACTION_STRINGCONCAT); } ;void_function_call : TRACE '(' expr_or_obj ')' { $$ = $3; bufferWriteOp($$, SWFACTION_TRACE); } | GETURL '(' expr ')' {#ifdef DEBUG printf("void_function_call: GETURL '(' expr ')'\n");#endif $$ = $3; bufferWriteOp($$, SWFACTION_PUSH); bufferWriteS16($$, 2); bufferWriteS16($$, 0); // two 0 bytes bufferWriteOp($$, SWFACTION_GETURL2); bufferWriteS16($$, 1); bufferWriteU8($$, 0); } | GETURL '(' expr ',' expr urlmethod ')' {#ifdef DEBUG printf("void_function_call: GETURL '(' expr ',' expr urlmethod ')'\n");#endif $$ = $3; bufferConcat($$, $5); bufferWriteOp($$, SWFACTION_GETURL2); bufferWriteS16($$, 1); bufferWriteU8($$, $6); } | LOADVARIABLES '(' expr ',' expr urlmethod ')' { $$ = $3; bufferConcat($$, $5); bufferWriteOp($$, SWFACTION_GETURL2); bufferWriteS16($$, 1); bufferWriteU8($$, 0xc0+$6); } | LOADVARIABLESNUM '(' expr ',' level urlmethod ')' { $$ = $3; bufferConcat($$, $5); bufferWriteOp($$, SWFACTION_GETURL2); bufferWriteS16($$, 1); bufferWriteU8($$, 0x80+$6); } | LOADMOVIE '(' expr ',' expr urlmethod ')' { $$ = $3; bufferConcat($$, $5); bufferWriteOp($$, SWFACTION_GETURL2); bufferWriteS16($$, 1); bufferWriteU8($$, 0x40+$6); } | LOADMOVIENUM '(' expr ',' level urlmethod ')' { $$ = $3; bufferConcat($$, $5); bufferWriteOp($$, SWFACTION_GETURL2); bufferWriteS16($$, 1); bufferWriteU8($$, $6); } | CALLFRAME '(' expr ')' { $$ = $3; bufferWriteOp($$, SWFACTION_CALLFRAME); bufferWriteS16($$, 0); } /* startDrag(target, lock, [left, right, top, bottom]) */ | STARTDRAG '(' expr ',' expr ')' { $$ = newBuffer(); bufferWriteString($$, "0", 2); /* no constraint */ bufferConcat($$, $5); bufferConcat($$, $3); bufferWriteOp($$, SWFACTION_STARTDRAG); } | STARTDRAG '(' expr ',' expr ',' expr ',' expr ',' expr ',' expr ')' { $$ = newBuffer(); bufferConcat($$, $7); bufferConcat($$, $11); bufferConcat($$, $9); bufferConcat($$, $13); bufferWriteString($$, "1", 2); /* has constraint */ bufferConcat($$, $5); bufferConcat($$, $3); bufferWriteOp($$, SWFACTION_STARTDRAG); } | STOPDRAG '(' ')' /* no args */ { $$ = newBuffer(); bufferWriteOp($$, SWFACTION_ENDDRAG); } /* duplicateMovieClip(target, new, depth) */ | DUPLICATEMOVIECLIP '(' expr ',' expr ',' expr ')' { $$ = $3; bufferConcat($$, $5); bufferConcat($$, $7); bufferWriteInt($$, 16384); /* magic number */ bufferWriteOp($$, SWFACTION_ADD); bufferWriteOp($$, SWFACTION_DUPLICATECLIP); } | REMOVEMOVIECLIP '(' expr ')' { $$ = $3; bufferWriteOp($$, SWFACTION_REMOVECLIP); } | GETURL1 '(' STRING ',' STRING ')' { $$ = newBuffer(); bufferWriteOp($$, SWFACTION_GETURL); bufferWriteS16($$, strlen($3) + strlen($5) + 2); bufferWriteHardString($$, $3, strlen($3)); bufferWriteU8($$, 0); bufferWriteHardString($$, $5, strlen($5)); bufferWriteU8($$, 0); } /* v3 actions */ | NEXTFRAME '(' ')' { $$ = newBuffer(); bufferWriteOp($$, SWFACTION_NEXTFRAME); } | PREVFRAME '(' ')' { $$ = newBuffer(); bufferWriteOp($$, SWFACTION_PREVFRAME); } | PLAY '(' ')' { $$ = newBuffer(); bufferWriteOp($$, SWFACTION_PLAY); } | STOP '(' ')' { $$ = newBuffer(); bufferWriteOp($$, SWFACTION_STOP); } | STOPSOUNDS '(' ')' { $$ = newBuffer(); bufferWriteOp($$, SWFACTION_STOPSOUNDS); } | TOGGLEQUALITY '(' ')' { $$ = newBuffer(); bufferWriteOp($$, SWFACTION_TOGGLEQUALITY); } | GOTOANDPLAY '(' INTEGER ')' { $$ = newBuffer(); bufferWriteOp($$, SWFACTION_GOTOFRAME); bufferWriteS16($$, 2); bufferWriteS16($$, $3-1); /* GOTOFRAME target is 0-based */ bufferWriteOp($$, SWFACTION_PLAY); } | GOTOANDSTOP '(' INTEGER ')' { $$ = newBuffer(); bufferWriteOp($$, SWFACTION_GOTOFRAME); bufferWriteS16($$, 2); bufferWriteS16($$, $3-1); /* GOTOFRAME target is 0-based */ bufferWriteOp($$, SWFACTION_STOP); } | GOTOANDPLAY '(' STRING ')' { $$ = newBuffer(); bufferWriteOp($$, SWFACTION_GOTOLABEL); bufferWriteS16($$, strlen($3)+1); bufferWriteHardString($$, $3, strlen($3)+1); free($3); bufferWriteOp($$, SWFACTION_PLAY); } | GOTOANDSTOP '(' STRING ')'
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -