X-Git-Url: http://git.asbjorn.it/?a=blobdiff_plain;f=lib%2Fas3%2Fparser.y;h=9643008f3a5f23846cd33f9377650a586d582c79;hb=21728c8b376f4f21d67b33207887e04ef90645ca;hp=46ed6d2e8d47dbd999a31fb7a1349bf7c3e0dd6e;hpb=26d27dff034cba4973ce545af4474fbe7e0e1866;p=swftools.git diff --git a/lib/as3/parser.y b/lib/as3/parser.y index 46ed6d2..9643008 100644 --- a/lib/as3/parser.y +++ b/lib/as3/parser.y @@ -159,7 +159,7 @@ %token T_SHR ">>" %type FOR_START -%type X_IDENTIFIER PACKAGE FOR_IN_INIT +%type X_IDENTIFIER PACKAGE FOR_IN_INIT MAYBE_IDENTIFIER %type VARCONST %type CODE %type CODEPIECE CODE_STATEMENT @@ -177,7 +177,8 @@ %type MAYBEEXPRESSION %type E DELETE %type CONSTANT -%type FOR FOR_IN IF WHILE DO_WHILE MAYBEELSE BREAK RETURN CONTINUE TRY +%type FOR FOR_IN IF WHILE DO_WHILE MAYBEELSE BREAK RETURN CONTINUE TRY +%type INNERFUNCTION %type USE_NAMESPACE %type FOR_INIT %type IMPORT @@ -238,7 +239,8 @@ // needed for "return" precedence: %nonassoc T_STRING T_REGEXP %nonassoc T_INT T_UINT T_BYTE T_SHORT T_FLOAT -%nonassoc "false" "true" "null" "undefined" "super" +%nonassoc "false" "true" "null" "undefined" "super" "function" +%nonassoc above_function @@ -422,23 +424,50 @@ static void old_state() state = state->old; state_destroy(leaving); } -void initialize_state() + +void initialize_parser() { global = rfx_calloc(sizeof(global_t)); - new_state(); - - state->package = current_filename; - global->file = abc_file_new(); global->file->flags &= ~ABCFILE_LAZY; global->variable_count = 1; - - global->init = abc_initscript(global->file, 0); + global->init = abc_initscript(global->file); code_t*c = global->init->method->body->code; - c = abc_getlocal_0(c); c = abc_pushscope(c); - + /*c = abc_findpropstrict(c, "[package]::trace"); + c = abc_pushstring(c, "[entering global init function]"); + c = abc_callpropvoid(c, "[package]::trace", 1);*/ + global->init->method->body->code = c; +} + +void initialize_file(char*filename) +{ + new_state(); + state->package = filename; +} +void finish_file() +{ + if(!state || state->level!=1) { + syntaxerror("unexpected end of file"); + } + state_destroy(state);state=0; +} + +void* finish_parser() +{ + code_t*c = global->init->method->body->code; + /*c = abc_findpropstrict(c, "[package]::trace"); + c = abc_pushstring(c, "[leaving global init function]"); + c = abc_callpropvoid(c, "[package]::trace", 1);*/ + c = abc_returnvoid(c); + global->init->method->body->code = c; + return global->file; +} + + +static void xx_scopetest() +{ /* findpropstrict doesn't just return a scope object- it also makes it "active" somehow. Push local_0 on the scope stack and read it back with findpropstrict, it'll @@ -464,29 +493,6 @@ void initialize_state() c = abc_getlocal_3(c); c = abc_kill(c, 3); c = abc_iftrue(c,xx);*/ - - c = abc_findpropstrict(c, "[package]::trace"); - c = abc_pushstring(c, "[entering global init function]"); - c = abc_callpropvoid(c, "[package]::trace", 1); - - global->init->method->body->code = c; -} -void* finalize_state() -{ - if(state->level!=1) { - syntaxerror("unexpected end of file"); - } - abc_method_body_t*m = global->init->method->body; - //__ popscope(m); - - __ findpropstrict(m, "[package]::trace"); - __ pushstring(m, "[leaving global init function]"); - __ callpropvoid(m, "[package]::trace", 1); - __ returnvoid(m); - - state_destroy(state);state=0; - - return global->file; } @@ -616,7 +622,7 @@ static void endpackage() old_state(); } -char*globalclass=0; +char*as3_globalclass=0; static void startclass(int flags, char*classname, classinfo_t*extends, classinfo_list_t*implements, char interface) { if(state->cls) { @@ -738,11 +744,11 @@ static void startclass(int flags, char*classname, classinfo_t*extends, classinfo __ setslot(m, slotindex); /* flash.display.MovieClip handling */ - if(!globalclass && (flags&FLAG_PUBLIC) && classinfo_equals(registry_getMovieClip(),extends)) { + if(!as3_globalclass && (flags&FLAG_PUBLIC) && classinfo_equals(registry_getMovieClip(),extends)) { if(state->package && state->package[0]) { - globalclass = concat3(state->package, ".", classname); + as3_globalclass = concat3(state->package, ".", classname); } else { - globalclass = strdup(classname); + as3_globalclass = strdup(classname); } } multiname_destroy(extends2); @@ -1370,7 +1376,6 @@ CODE: CODEPIECE {$$=$1;} // code which also may appear outside a method CODE_STATEMENT: IMPORT -CODE_STATEMENT: VOIDEXPRESSION CODE_STATEMENT: FOR CODE_STATEMENT: FOR_IN CODE_STATEMENT: WHILE @@ -1379,11 +1384,12 @@ CODE_STATEMENT: SWITCH CODE_STATEMENT: IF CODE_STATEMENT: WITH CODE_STATEMENT: TRY +CODE_STATEMENT: VOIDEXPRESSION // code which may appear anywhere CODEPIECE: ';' {$$=0;} -CODEPIECE: VARIABLE_DECLARATION CODEPIECE: CODE_STATEMENT +CODEPIECE: VARIABLE_DECLARATION CODEPIECE: BREAK CODEPIECE: CONTINUE CODEPIECE: RETURN @@ -1400,7 +1406,7 @@ CODEBLOCK : CODEPIECE %prec below_semicolon {$$=$1;} /* ------------ package init code ------------------- */ PACKAGE_INITCODE: CODE_STATEMENT { - if($1) warning("code ignored"); + if($1) as3_warning("code ignored"); } /* ------------ variables --------------------------- */ @@ -1483,6 +1489,8 @@ IF : "if" '(' {new_state();} EXPRESSION ')' CODEBLOCK MAYBEELSE { FOR_INIT : {$$=code_new();} FOR_INIT : VARIABLE_DECLARATION FOR_INIT : VOIDEXPRESSION + +// TODO: why doesn't an %prec above_identifier resolve the r-r conflict here? FOR_IN_INIT : "var" T_IDENTIFIER MAYBETYPE { $$=$2;new_variable($2,$3,1); } @@ -1758,7 +1766,7 @@ IMPORT : "import" PACKAGE '.' '*' { /* ------------ classes and interfaces (header) -------------- */ -MAYBE_MODIFIERS : {$$=0;} +MAYBE_MODIFIERS : %prec above_function {$$=0;} MAYBE_MODIFIERS : MODIFIER_LIST {$$=$1} MODIFIER_LIST : MODIFIER {$$=$1;} MODIFIER_LIST : MODIFIER_LIST MODIFIER {$$=$1|$2;} @@ -1968,6 +1976,14 @@ FUNCTION_DECLARATION: MAYBE_MODIFIERS "function" GETSET T_IDENTIFIER '(' MAYBE_P $$=0; } +MAYBE_IDENTIFIER: T_IDENTIFIER +MAYBE_IDENTIFIER: {$$=0;} +INNERFUNCTION: "function" MAYBE_IDENTIFIER '(' MAYBE_PARAM_LIST ')' MAYBETYPE '{' MAYBECODE '}' +{ + syntaxerror("nested functions not supported yet"); +} + + /* ------------- package + class ids --------------- */ CLASS: T_IDENTIFIER { @@ -2155,6 +2171,7 @@ VOIDEXPRESSION : EXPRESSION %prec below_minus { // ----------------------- expression evaluation ------------------------------------- +E : INNERFUNCTION %prec prec_none {$$ = $1;} //V : CONSTANT {$$ = 0;} E : CONSTANT //V : VAR_READ %prec T_IDENTIFIER {$$ = 0;} @@ -2720,7 +2737,7 @@ VAR_READ : T_IDENTIFIER { /* unknown object, let the avm2 resolve it */ } else { if(strcmp($1,"trace")) - warning("Couldn't resolve '%s', doing late binding", $1); + as3_softwarning("Couldn't resolve '%s', doing late binding", $1); state->method->late_binding = 1; multiname_t m = {MULTINAME, 0, &nopackage_namespace_set, $1};