📄 swf5compiler.y
字号:
| FOR '(' VAR identifier IN obj_ref ')' for_in_init stmt { Buffer b2, b3; int tmp; $$ = $6; bufferWriteOp($$, SWFACTION_ENUMERATE); b2 = newBuffer(); bufferWriteSetRegister(b2, 0); bufferWriteOp(b2, SWFACTION_PUSHDATA); bufferWriteS16(b2, 1); bufferWriteU8(b2, 2); bufferWriteOp(b2, SWFACTION_NEWEQUALS); bufferWriteOp(b2, SWFACTION_BRANCHIFTRUE); bufferWriteS16(b2, 2); // add size later b3 = newBuffer(); bufferWriteString(b3, $4, strlen($4)+1); bufferWriteRegister(b3, 0); bufferWriteOp(b3, SWFACTION_VAREQUALS); bufferConcat(b3, $9); bufferWriteS16(b2, bufferLength(b3) + 5); tmp = bufferLength(b2) + bufferLength(b3) + 5; bufferConcat($$, b2); bufferWriteOp(b3, SWFACTION_BRANCHALWAYS); bufferWriteS16(b3, 2); bufferWriteS16(b3, -tmp); bufferResolveJumps(b3); bufferConcat($$, b3); delctx(CTX_FOR_IN); } ;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"); $$ = newBuffer(); bufferWriteOp($$, SWFACTION_BRANCHALWAYS); bufferWriteS16($$, 2); bufferWriteS16($$, MAGIC_CONTINUE_NUMBER); } ;// break is possible if there is a CTX_LOOP, CTX_FOR_IN or CTX_SWITCHbreak_stmt : BREAK ';' { int tmp = chkctx(CTX_BREAK); if(tmp < 0) swf5error("break outside switch / loop"); $$ = newBuffer(); if(tmp) /* break out of a for .. in */ bufferWriteOp($$, SWFACTION_POP); bufferWriteOp($$, SWFACTION_BRANCHALWAYS); bufferWriteS16($$, 2); bufferWriteS16($$, MAGIC_BREAK_NUMBER); } ;urlmethod : /* empty */ { $$ = GETURL_METHOD_NOSEND; } | ',' GET { $$ = GETURL_METHOD_GET; } | ',' POST { $$ = GETURL_METHOD_POST; } | ',' STRING { if(strcmp($2, "GET") == 0) $$ = GETURL_METHOD_GET; else if(strcmp($2, "POST") == 0) $$ = GETURL_METHOD_POST; } ;level : INTEGER { char *lvlstring = (char*) malloc(12*sizeof(char)); sprintf(lvlstring, "_level%d", $1); $$ = newBuffer(); bufferWriteString($$, lvlstring, strlen(lvlstring)+1); free(lvlstring); } | expr { $$ = newBuffer(); bufferWriteString($$, "_level", 7); bufferConcat($$, $1); bufferWriteOp($$, SWFACTION_STRINGCONCAT); } ;void_function_call : IDENTIFIER '(' expr_list ')' { $$ = $3.buffer; bufferWriteInt($$, $3.count); bufferWriteString($$, $1, strlen($1)+1); bufferWriteOp($$, SWFACTION_CALLFUNCTION); bufferWriteOp($$, SWFACTION_POP); free($1); } | DELETE IDENTIFIER { $$ = newBuffer(); bufferWriteString($$, $2, strlen($2)+1); free($2); bufferWriteOp($$, SWFACTION_DELETE); } | DELETE lvalue_expr '.' IDENTIFIER { $$ = $2; // bufferWriteOp($$, SWFACTION_GETVARIABLE); bufferWriteString($$, $4, strlen($4)+1); free($4); bufferWriteOp($$, SWFACTION_DELETEVAR); } | DELETE lvalue_expr '[' expr ']' { $$ = $2; // bufferWriteOp($$, SWFACTION_GETVARIABLE); bufferConcat($$, $4); // bufferWriteOp($$, SWFACTION_GETVARIABLE); bufferWriteOp($$, SWFACTION_DELETEVAR); } | TRACE '(' expr_or_obj ')' { $$ = $3; bufferWriteOp($$, SWFACTION_TRACE); } | GETURL '(' expr ',' expr urlmethod ')' { $$ = $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_STARTDRAGMOVIE); } | 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_STARTDRAGMOVIE); } | STOPDRAG '(' ')' /* no args */ { $$ = newBuffer(); bufferWriteOp($$, SWFACTION_STOPDRAGMOVIE); } /* 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($$, (byte*)$3, strlen($3)); bufferWriteU8($$, 0); bufferWriteHardString($$, (byte*)$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); } | GOTOFRAME '(' INTEGER ')' { $$ = newBuffer(); bufferWriteOp($$, SWFACTION_GOTOFRAME); bufferWriteS16($$, 2); bufferWriteS16($$, $3); } | GOTOFRAME '(' STRING ')' { $$ = newBuffer(); bufferWriteOp($$, SWFACTION_GOTOLABEL); bufferWriteS16($$, strlen($3)+1); bufferWriteHardString($$, (byte*)$3, strlen($3)+1); free($3); } | GOTOFRAME '(' expr ')' { $$ = $3; bufferWriteOp($$, SWFACTION_GOTOEXPRESSION); bufferWriteS16($$, 1); bufferWriteU8($$, 0); } /* XXX - and stop */ | SETTARGET '(' STRING ')' { $$ = newBuffer(); bufferWriteOp($$, SWFACTION_SETTARGET); bufferWriteS16($$, strlen($3)+1); bufferWriteHardString($$, (byte*)$3, strlen($3)+1); free($3); } | SETTARGET '(' expr ')' { $$ = $3; bufferWriteOp($$, SWFACTION_SETTARGETEXPRESSION); } ;function_call : IDENTIFIER '(' expr_list ')' { $$ = $3.buffer; bufferWriteInt($$, $3.count); bufferWriteString($$, $1, strlen($1)+1); bufferWriteOp($$, SWFACTION_CALLFUNCTION); free($1); } | EVAL '(' expr ')' { $$ = $3; bufferWriteOp($$, SWFACTION_GETVARIABLE); } | GETTIMER '(' ')' { $$ = newBuffer(); bufferWriteOp($$, SWFACTION_GETTIMER); } | RANDOM '(' expr ')' { $$ = $3; bufferWriteOp($$, SWFACTION_RANDOM); } | LENGTH '(' expr_or_obj ')' { $$ = $3; bufferWriteOp($$, SWFACTION_STRINGLENGTH); } | INT '(' expr ')' { $$ = $3; bufferWriteOp($$, SWFACTION_INT); } | ORD '(' expr ')' { $$ = $3; bufferWriteOp($$, SWFACTION_ORD); } | CHR '(' expr ')' { $$ = $3; bufferWriteOp($$, SWFACTION_CHR); } | CONCAT '(' expr ',' expr ')' { $$ = $3; bufferConcat($$, $5); bufferWriteOp($$, SWFACTION_STRINGCONCAT); } | SUBSTRING '(' expr ',' expr ',' expr ')' { $$ = $3; bufferConcat($$, $5); bufferConcat($$, $7); bufferWriteOp($$, SWFACTION_SUBSTRING); } | TYPEOF '(' expr_or_obj ')' { $$ = $3; bufferWriteOp($$, SWFACTION_TYPEOF); } ;expr_list : /* empty */ { $$.buffer = newBuffer(); $$.count = 0; } | expr_or_obj { $$.buffer = $1; $$.count = 1; } /* goes backwards. rrgh. */ | expr_list ',' expr_or_obj { Buffer tmp = newBuffer(); bufferConcat(tmp, $3); bufferConcat(tmp, $$.buffer); $$.buffer = tmp; ++$$.count; } ;anon_function_decl : function_init '(' formals_list ')' stmt { $$ = newBuffer(); bufferWriteOp($$, SWFACTION_DEFINEFUNCTION); bufferWriteS16($$, bufferLength($3.buffer) + 5); bufferWriteU8($$, 0); /* empty function name */ bufferWriteS16($$, $3.count); bufferConcat($$, $3.buffer); bufferWriteS16($$, bufferLength($5)); bufferConcat($$, $5); delctx(CTX_FUNCTION); } ;method_call : lvalue_expr '.' identifier '(' expr_list ')' { $$ = $5.buffer; bufferWriteInt($$, $5.count); bufferConcat($$, $1); bufferWriteString($$, $3, strlen($3)+1); bufferWriteOp($$, SWFACTION_CALLMETHOD); free($3); } | lvalue_expr '[' expr ']' '(' expr_list ')' { $$ = $6.buffer; bufferWriteInt($$, $6.count); bufferConcat($$, $1); bufferConcat($$, $3); bufferWriteOp($$, SWFACTION_CALLMETHOD); } ;objexpr : identifier ':' expr_or_obj { $$ = newBuffer(); bufferWriteString($$, $1, strlen($1)+1); bufferConcat($$, $3); } ;objexpr_list : objexpr { $$.buffer = $1; $$.count = 1; } | objexpr_list ',' objexpr { bufferConcat($$.buffer, $3); ++$$.count; } ;assignop : "+=" { $$ = SWFACTION_NEWADD; } | "-=" { $$ = SWFACTION_SUBTRACT; } | "*=" { $$ = SWFACTION_MULTIPLY; } | "/=" { $$ = SWFACTION_DIVIDE; } | "%=" { $$ = SWFACTION_MODULO; } | "&=" { $$ = SWFACTION_BITWISEAND; } | "|=" { $$ = SWFACTION_BITWISEOR; } | "^=" { $$ = SWFACTION_BITWISEXOR; } | "<<=" { $$ = SWFACTION_SHIFTLEFT; } | ">>=" { $$ = SWFACTION_SHIFTRIGHT; } | ">>>=" { $$ = SWFACTION_SHIFTRIGHT2; } ;incdecop : "++" { $$ = SWFACTION_INCREMENT; } | "--" { $$ = SWFACTION_DECREMENT; } ;/*integer : '-' INTEGER %prec UMINUS { $$ = -$2; } | INTEGER { $$ = $1; } ;double : '-' DOUBLE %prec UMINUS { $$ = -$2; } | DOUBLE { $$ = $1; } ;*//* resolves an lvalue into a buffer */lvalue_expr : lvalue { if($1.obj) { $$ = $1.obj; if($1.ident) bufferConcat($$, $1.ident); else bufferConcat($$, $1.memexpr); bufferWriteOp($$, SWFACTION_GETMEMBER); } else { $$ = $1.ident; bufferWriteOp($$, SWFACTION_GETVARIABLE); } } | function_call | method_call ;/* lvalue - things you can assign to */lvalue : identifier { $$.ident = newBuffer(); bufferWriteString($$.ident, $1, strlen($1)+1); free($1); $$.obj = 0; $$.memexpr = 0; } | lvalue_expr '.' identifier %prec '.' { $$.obj = $1; $$.ident = newBuffer(); bufferWriteString($$.ident, $3, strlen($3)+1); $$.memexpr = 0; } | lvalue_expr '[' expr ']' %prec '.' { $$.obj = $1; $$.memexpr = $3; $$.ident = 0; } ;/* these leave a value on the stack */expr : primary | '-' expr %prec UMINUS { $$ = $2; bufferWriteInt($2, -1); bufferWriteOp($2, SWFACTION_MULTIPLY); } | '~' expr %prec UMINUS { $$ = $2; bufferWriteInt($2, 0xffffffff); bufferWriteOp($2, SWFACTION_BITWISEXOR); } | '!' expr { $$ = $2; bufferWriteOp($2, SWFACTION_LOGICALNOT); } | expr "||" expr { $$ = $1; bufferWriteOp($$, SWFACTION_DUP); bufferWriteOp($$, SWFACTION_BRANCHIFTRUE); bufferWriteS16($$, 2); bufferWriteS16($$, bufferLength($3)+1); bufferWriteOp($$, SWFACTION_POP); bufferConcat($$, $3); } | expr "&&" expr { $$ = $1; bufferWriteOp($$, SWFACTION_DUP); bufferWriteOp($$, SWFACTION_LOGICALNOT); bufferWriteOp($$, SWFACTION_BRANCHIFTRUE); bufferWriteS16($$, 2); bufferWriteS16($$, bufferLength($3)+1); bufferWriteOp($$, SWFACTION_POP); bufferConcat($$, $3); } | expr '*' expr { $$ = $1; bufferConcat($$, $3); bufferWriteOp($$, SWFACTION_MULTIPLY); } | expr '/' expr { $$ = $1; bufferConcat($$, $3); bufferWriteOp($$, SWFACTION_DIVIDE); } | expr '%' expr { $$ = $1; bufferConcat($$, $3); bufferWriteOp($$, SWFACTION_MODULO); } | expr '+' expr { $$ = $1; bufferConcat($$, $3); bufferWriteOp($$, SWFACTION_NEWADD); } | expr '-' expr { $$ = $1; bufferConcat($$, $3); bufferWriteOp($$, SWFACTION_SUBTRACT); } | expr '&' expr { $$ = $1; bufferConcat($$, $3); bufferWriteOp($$, SWFACTION_BITWISEAND); } | expr '|' expr { $$ = $1; bufferConcat($$, $3); bufferWriteOp($$, SWFACTION_BITWISEOR); } | expr '^' expr { $$ = $1; bufferConcat($$, $3); bufferWriteOp($$, SWFACTION_BITWISEXOR); } | expr '<' expr { $$ = $1; bufferConcat($$, $3); bufferWriteOp($$, SWFACTION_NEWLESSTHAN); } | expr '>' expr { $$ = $3; bufferConcat($$, $1); bufferWriteOp($$, SWFACTION_NEWLESSTHAN); } | expr "<=" expr { $$ = $3; bufferConcat($$, $1); bufferWriteOp($$, SWFACTION_NEWLESSTHAN); bufferWriteOp($$, SWFACTION_LOGICALNOT); } | expr ">=" expr { bufferConcat($1, $3); bufferWriteOp($1, SWFACTION_NEWLESSTHAN); bufferWriteOp($1, SWFACTION_LOGICALNOT); } | expr "==" expr { bufferConcat($1, $3);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -