X-Git-Url: http://git.asbjorn.it/?a=blobdiff_plain;f=lib%2Fas3%2Fparser.y;h=19c878b54a8c9cb336312c49b1b9129c7fe506bc;hb=d76b64d25bf7801e86f3ba1d21209abb3b219cb9;hp=318a6d544a603addcb043ef9abad97327e2f324d;hpb=1a4045db483c3f39b4b840090dd0efabfa9f72e9;p=swftools.git diff --git a/lib/as3/parser.y b/lib/as3/parser.y index 318a6d5..19c878b 100644 --- a/lib/as3/parser.y +++ b/lib/as3/parser.y @@ -767,6 +767,7 @@ static void startfunction(token_t*ns, int flags, enum yytokentype getset, char*n int slot = 0; if(!strcmp(state->clsinfo->name,name)) { state->m = abc_class_constructor(state->cls, type2); + name = "__as3_constructor__"; } else { if(flags&FLAG_STATIC) state->m = abc_class_staticmethod(state->cls, type2, &mname); @@ -902,6 +903,8 @@ code_t*converttype(code_t*c, classinfo_t*from, classinfo_t*to) } if(TYPE_IS_FUNCTION(from) && TYPE_IS_FUNCTION(to)) return c; + if(TYPE_IS_CLASS(from) && TYPE_IS_CLASS(to)) + return c; syntaxerror("can't convert type %s to %s", from->name, to->name); } @@ -927,6 +930,40 @@ void parserassert(int b) if(!b) syntaxerror("internal error: assertion failed"); } +static classinfo_t* find_class(char*name) +{ + classinfo_t*c=0; + + c = registry_findclass(state->package, name); + + /* try explicit imports */ + dictentry_t* e = dict_get_slot(state->imports, name); + while(e) { + if(c) + break; + if(!strcmp(e->key, name)) { + c = (classinfo_t*)e->data; + } + e = e->next; + } + + /* try package.* imports */ + import_list_t*l = state->wildcard_imports; + while(l) { + if(c) + break; + //printf("does package %s contain a class %s?\n", l->import->package, name); + c = registry_findclass(l->import->package, name); + l = l->next; + } + + /* try global package */ + if(!c) { + c = registry_findclass("", name); + } + return c; +} + static code_t* toreadwrite(code_t*in, code_t*middlepart, char justassign, char readbefore) { /* converts this: @@ -1431,34 +1468,7 @@ FUNCTION_DECLARATION: MAYBE_MODIFIERS "function" GETSET T_IDENTIFIER '(' MAYBE_P CLASS: T_IDENTIFIER { /* try current package */ - $$ = registry_findclass(state->package, $1); - - /* try explicit imports */ - dictentry_t* e = dict_get_slot(state->imports, $1); - while(e) { - if($$) - break; - if(!strcmp(e->key, $1)) { - $$ = (classinfo_t*)e->data; - } - e = e->next; - } - - /* try package.* imports */ - import_list_t*l = state->wildcard_imports; - while(l) { - if($$) - break; - //printf("does package %s contain a class %s?\n", l->import->package, $1); - $$ = registry_findclass(l->import->package, $1); - l = l->next; - } - - /* try global package */ - if(!$$) { - $$ = registry_findclass("", $1); - } - + $$ = find_class($1); if(!$$) syntaxerror("Could not find class %s\n", $1); } @@ -1504,8 +1514,12 @@ NEW : "new" CLASS MAYBE_PARAM_VALUES { MULTINAME(m, $2); $$.c = code_new(); - /* TODO: why do we have to *find* our own classes? */ - $$.c = abc_findpropstrict2($$.c, &m); + if($2->slot) { + $$.c = abc_getglobalscope($$.c); + $$.c = abc_getslot($$.c, $2->slot); + } else { + $$.c = abc_findpropstrict2($$.c, &m); + } typedcode_list_t*l = $3; int len = 0; @@ -1514,7 +1528,10 @@ NEW : "new" CLASS MAYBE_PARAM_VALUES { l = l->next; len ++; } - $$.c = abc_constructprop2($$.c, &m, len); + if($2->slot) + $$.c = abc_construct($$.c, len); + else + $$.c = abc_constructprop2($$.c, &m, len); $$.t = $2; } @@ -1842,10 +1859,21 @@ E : "--" E { code_t*c = 0; E : E '.' T_IDENTIFIER {$$.c = $1.c; - if($$.t) { - memberinfo_t*f = registry_findmember($$.t, $3); + classinfo_t*t = $1.t; + char is_static = 0; + if(TYPE_IS_CLASS(t)) { + memberinfo_t*m = registry_findmember($1.t, "prototype"); + if(!m) syntaxerror("identifier '%s' not found in anonymous class", $3); + t = m->type; + is_static = 1; + } + if(t) { + memberinfo_t*f = registry_findmember(t, $3); + char noslot = 0; + if(f && !is_static != !(f->flags&FLAG_STATIC)) + noslot=1; - if(f && f->slot) { + if(f && f->slot && !noslot) { $$.c = abc_getslot($$.c, f->slot); } else { if(f) { @@ -1883,11 +1911,16 @@ VAR_READ : T_IDENTIFIER { $$.t = 0; $$.c = 0; int i; + classinfo_t*a = 0; memberinfo_t*f = 0; + + /* look at variables */ if((i = find_variable($1, &$$.t)) >= 0) { // $1 is a local variable $$.c = abc_getlocal($$.c, i); - } else if(f = registry_findmember(state->clsinfo, $1)) { + + /* look at current class' members */ + } else if((f = registry_findmember(state->clsinfo, $1))) { // $1 is a function in this class int var_is_static = (f->flags&FLAG_STATIC); int i_am_static = (state->minfo?(state->minfo->flags&FLAG_STATIC):FLAG_STATIC); @@ -1916,8 +1949,20 @@ VAR_READ : T_IDENTIFIER { } else { $$.t = f->type; } + + /* look at classes in the current package and imported classes */ + } else if((a = find_class($1))) { + if(a->slot) { + $$.c = abc_getglobalscope($$.c); + $$.c = abc_getslot($$.c, a->slot); + } else { + MULTINAME(m, a); + $$.c = abc_getlex2($$.c, &m); + } + $$.t = TYPE_CLASS(a); + + /* unknown object, let the avm2 resolve it */ } else { - // let the avm2 resolve $1 if(strcmp($1,"trace")) warning("Couldn't resolve %s, doing late binding", $1); state->late_binding = 1;