X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fas3%2Fparser.y;h=a8cb4a74098c249ba394db4718cc344e42b311e1;hb=749bee41b380e032eb3c6713dc5b6630e6cd3d15;hp=6aa84e44cea07c2c6802b5db3fa2fb4854f095a7;hpb=1adc9bdd04d6c40fadf2211a4af8c281b46ca5ec;p=swftools.git diff --git a/lib/as3/parser.y b/lib/as3/parser.y index 6aa84e4..a8cb4a7 100644 --- a/lib/as3/parser.y +++ b/lib/as3/parser.y @@ -301,6 +301,7 @@ typedef struct _methodstate { char is_constructor; char has_super; char is_global; + char inner; abc_exception_list_t*exceptions; } methodstate_t; @@ -929,6 +930,32 @@ static memberinfo_t*registerfunction(enum yytokentype getset, int flags, char*na return minfo; } +static void innerfunction(char*name, params_t*params, classinfo_t*return_type) +{ + parserassert(state->method && state->method->info); + memberinfo_t*parent_method = state->method->info; + + if(as3_pass==1) { + // not valid yet + params = 0; + return_type = 0; + } + + new_state(); + state->method = rfx_calloc(sizeof(methodstate_t)); + state->method->inner = 1; + + NEW(memberinfo_t,minfo); + minfo->return_type = return_type; + minfo->name = name; + + if(!parent_method->subfunctions) + parent_method->subfunctions = dict_new(); + + dict_put(parent_method->subfunctions, name, minfo); + state->method->info = minfo; +} + static void startfunction(token_t*ns, int flags, enum yytokentype getset, char*name, params_t*params, classinfo_t*return_type) { @@ -950,6 +977,7 @@ static void startfunction(token_t*ns, int flags, enum yytokentype getset, char*n name = "__as3_constructor__"; if(as3_pass == 1) { + return_type = 0; state->method->info = registerfunction(getset, flags, name, params, return_type, 0); } @@ -958,6 +986,7 @@ static void startfunction(token_t*ns, int flags, enum yytokentype getset, char*n TODO: better getter/setter support? */ if(!state->cls) state->method->info = registry_findclass(state->package, name)->function; else state->method->info = registry_findmember(state->cls->info, name, 0); + state->method->info->return_type = return_type; global->variable_count = 0; /* state->vars is initialized by state_new */ @@ -972,19 +1001,21 @@ static void startfunction(token_t*ns, int flags, enum yytokentype getset, char*n } } -static void endfunction(token_t*ns, int flags, enum yytokentype getset, char*name, +static abc_method_t* endfunction(token_t*ns, int flags, enum yytokentype getset, char*name, params_t*params, classinfo_t*return_type, code_t*body) { if(as3_pass==1) { old_state(); - return; + return 0; } abc_method_t*f = 0; multiname_t*type2 = sig2mname(return_type); int slot = 0; - if(state->method->is_constructor) { + if(state->method->inner) { + f = abc_method_new(global->file, type2, 1); + } else if(state->method->is_constructor) { f = abc_class_getconstructor(state->cls->abc, type2); } else if(!state->method->is_global) { namespace_t mname_ns = flags2namespace(flags, ""); @@ -1037,10 +1068,9 @@ static void endfunction(token_t*ns, int flags, enum yytokentype getset, char*nam } old_state(); + return f; } - - char is_subtype_of(classinfo_t*type, classinfo_t*supertype) { return 1; // FIXME @@ -2006,8 +2036,8 @@ MODIFIER : KW_PUBLIC {PASS12 $$=FLAG_PUBLIC;} EXTENDS : {$$=registry_getobjectclass();} EXTENDS : KW_EXTENDS QNAME {$$=$2;} -EXTENDS_LIST : {$$=list_new();} -EXTENDS_LIST : KW_EXTENDS QNAME_LIST {$$=$2;} +EXTENDS_LIST : {PASS12 $$=list_new();} +EXTENDS_LIST : KW_EXTENDS QNAME_LIST {PASS12 $$=$2;} IMPLEMENTS_LIST : {PASS12 $$=list_new();} IMPLEMENTS_LIST : KW_IMPLEMENTS QNAME_LIST {PASS12 $$=$2;} @@ -2079,6 +2109,7 @@ SLOT_DECLARATION: MAYBE_MODIFIERS VARCONST T_IDENTIFIER MAYBETYPE MAYBEEXPRESSIO code_t**code; if(!state->cls) { // global variable + mname_ns.name = state->package; traits = &global->init->traits; code = &global->init->method->body->code; } else if(flags&FLAG_STATIC) { @@ -2186,6 +2217,7 @@ FUNCTION_DECLARATION: MAYBE_MODIFIERS "function" GETSET T_IDENTIFIER '(' MAYBE_P { PASS1 old_state(); PASS2 + if(!state->method->info) syntaxerror("internal error"); code_t*c = 0; if(state->method->late_binding) { c = abc_getlocal_0(c); @@ -2204,9 +2236,21 @@ FUNCTION_DECLARATION: MAYBE_MODIFIERS "function" GETSET T_IDENTIFIER '(' MAYBE_P MAYBE_IDENTIFIER: T_IDENTIFIER MAYBE_IDENTIFIER: {$$=0;} -INNERFUNCTION: "function" MAYBE_IDENTIFIER '(' MAYBE_PARAM_LIST ')' MAYBETYPE '{' MAYBECODE '}' +INNERFUNCTION: "function" MAYBE_IDENTIFIER '(' MAYBE_PARAM_LIST ')' MAYBETYPE + '{' {PASS12 innerfunction($2,&$4,$6);} MAYBECODE '}' { - syntaxerror("nested functions not supported yet"); + PASS1 old_state(); + PASS2 + memberinfo_t*f = state->method->info; + if(!f) syntaxerror("internal error"); + + code_t*c = 0; + c = wrap_function(c, 0, $9); + + abc_method_t*abc = endfunction(0,0,0,$2,&$4,$6,c); + + $$.c = abc_newfunction(0, abc); + $$.t = TYPE_FUNCTION(f); } @@ -2649,7 +2693,7 @@ E : '-' E { E : E '[' E ']' { $$.c = $1.c; $$.c = code_append($$.c, $3.c); - + MULTINAME_LATE(m, $1.t?$1.t->access:ACCESS_PACKAGE, ""); $$.c = abc_getproperty2($$.c, &m); $$.t = 0; // array elements have unknown type