added -I option
[swftools.git] / lib / as3 / parser.y
index f26a444..3783b29 100644 (file)
@@ -31,6 +31,9 @@
 #include "registry.h"
 #include "code.h"
 #include "opcodes.h"
+#include "compiler.h"
+
+extern int a3_lex();
 
 %}
 
 %type <classinfo_list> IMPLEMENTS_LIST
 %type <classinfo> EXTENDS
 %type <classinfo_list> EXTENDS_LIST
-%type <classinfo> CLASS PACKAGEANDCLASS QNAME
-%type <classinfo_list> QNAME_LIST
+%type <classinfo> CLASS PACKAGEANDCLASS CLASS_SPEC
+%type <classinfo_list> CLASS_SPEC_LIST
 %type <classinfo> TYPE
 //%type <token> VARIABLE
 %type <value> VAR_READ
 %left plusplus_prefix minusminus_prefix '~' '!' "void" "delete" "typeof" //FIXME: *unary* + - should be here, too
 %left "--" "++" 
 %nonassoc below_curly
-%left '[' ']' '{' "new" '.' ".." "::"
+
+%left '('
+%left new2
+%left '[' ']' "new" '{' '.' ".." "::"
+
 %nonassoc T_IDENTIFIER
 %left above_identifier
 %left below_else
 %nonassoc "else"
-%left '('
 
 // 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" "function"
-%nonassoc above_function
+%left above_function
 
 
      
 %{
 
-static int yyerror(char*s)
+static int a3_error(char*s)
 {
    syntaxerror("%s", s); 
    return 0; //make gcc happy
 }
 
+
 static char* concat2(const char* t1, const char* t2)
 {
     int l1 = strlen(t1);
@@ -294,6 +301,8 @@ typedef struct _classstate {
     char has_constructor;
 } classstate_t;
 
+DECLARE_LIST(methodstate);
+
 typedef struct _methodstate {
     /* method data */
     memberinfo_t*info;
@@ -301,7 +310,15 @@ typedef struct _methodstate {
     char is_constructor;
     char has_super;
     char is_global;
+    int variable_count;
+
+    char inner;
+    abc_method_t*abc;
+    int var_index; // for inner methods
+
     abc_exception_list_t*exceptions;
+    
+    methodstate_list_t*innerfunctions;
 } methodstate_t;
 
 typedef struct _state {
@@ -312,6 +329,7 @@ typedef struct _state {
     import_list_t*wildcard_imports;
     dict_t*imports;
     char has_own_imports;
+    char new_vars; // e.g. transition between two functions
   
     classstate_t*cls;   
     methodstate_t*method;
@@ -324,8 +342,7 @@ typedef struct _state {
 typedef struct _global {
     abc_file_t*file;
     abc_script_t*init;
-
-    int variable_count;
+    dict_t*token2info;
 } global_t;
 
 static global_t*global = 0;
@@ -427,40 +444,57 @@ static void old_state()
     state_t*leaving = state;
     
     state = state->old;
+    
+    if(as3_pass>1 && leaving->method && leaving->method != state->method && !leaving->method->inner) {
+        free(leaving->method);
+        leaving->method=0;
+    }
+    if(leaving->cls && leaving->cls != state->cls) {
+        free(leaving->cls);
+        leaving->cls=0;
+    }
+    
     state_destroy(leaving);
 }
 
-void initialize_parser()
-{
-    global = rfx_calloc(sizeof(global_t));
-    global->file = abc_file_new();
-    global->file->flags &= ~ABCFILE_LAZY;
-    global->variable_count = 1;
-    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)
 {
+    if(state) {
+        syntaxerror("invalid call to initialize_file during parsing of another file");
+    }
     new_state();
-    state->package = filename;
-    // needed for state->method->late_binding:
+    state->package = strdup(filename);
+    
     state->method = rfx_calloc(sizeof(methodstate_t));
+    state->method->variable_count = 1;
 }
+
 void finish_file()
 {
     if(!state || state->level!=1) {
-        syntaxerror("unexpected end of file");
+        syntaxerror("unexpected end of file in pass %d", as3_pass);
     }
+    free(state->method);state->method=0;
+
+    //free(state->package);state->package=0; // used in registry
+
     state_destroy(state);state=0;
 }
 
+void initialize_parser()
+{
+    global = rfx_calloc(sizeof(global_t));
+    global->file = abc_file_new();
+    global->file->flags &= ~ABCFILE_LAZY;
+    global->token2info = dict_new2(&ptr_type);
+    
+    global->init = abc_initscript(global->file);
+    code_t*c = global->init->method->body->code;
+    c = abc_getlocal_0(c);
+    c = abc_pushscope(c);
+    global->init->method->body->code = c;
+}
+
 void* finish_parser()
 {
     code_t*c = global->init->method->body->code;
@@ -469,6 +503,7 @@ void* finish_parser()
       c = abc_callpropvoid(c, "[package]::trace", 1);*/
     c = abc_returnvoid(c);
     global->init->method->body->code = c;
+    dict_destroy(global->token2info);global->token2info=0;
     return global->file;
 }
 
@@ -519,6 +554,8 @@ static variable_t* find_variable(char*name)
         if(v) {
             return v;
         }
+        if(s->new_vars)
+            break;
         s = s->old;
     }
     return 0;
@@ -535,16 +572,16 @@ static char variable_exists(char*name)
     return dict_lookup(state->vars, name)!=0;
 }
 code_t*defaultvalue(code_t*c, classinfo_t*type);
-static int new_variable(char*name, classinfo_t*type, char init)
+static int new_variable(const char*name, classinfo_t*type, char init)
 {
     NEW(variable_t, v);
-    v->index = global->variable_count;
+    v->index = state->method->variable_count;
     v->type = type;
     v->init = init;
     
     dict_put(state->vars, name, v);
 
-    return global->variable_count++;
+    return state->method->variable_count++;
 }
 #define TEMPVARNAME "__as3_temp__"
 static int gettempvar()
@@ -599,6 +636,44 @@ code_t* var_block(code_t*body)
     return c;
 }
 
+#define parserassert(b) {if(!(b)) parsererror(__FILE__, __LINE__,__func__);}
+
+static void parsererror(const char*file, int line, const char*f)
+{
+    syntaxerror("internal error in %s, %s:%d", f, file, line);
+}
+
+   
+code_t* method_header()
+{
+    code_t*c = 0;
+    if(state->method->late_binding && !state->method->inner) {
+        c = abc_getlocal_0(c);
+        c = abc_pushscope(c);
+    }
+    /*if(state->method->innerfunctions) {
+        c = abc_newactivation(c);
+        c = abc_pushscope(c);
+    }*/
+    if(state->method->is_constructor && !state->method->has_super) {
+        // call default constructor
+        c = abc_getlocal_0(c);
+        c = abc_constructsuper(c, 0);
+    }
+    methodstate_list_t*l = state->method->innerfunctions;
+    while(l) {
+        parserassert(l->methodstate->abc);
+        c = abc_newfunction(c, l->methodstate->abc);
+        c = abc_setlocal(c, l->methodstate->var_index);
+        free(l->methodstate);l->methodstate=0;
+        l = l->next;
+    }
+    list_free(state->method->innerfunctions);
+    state->method->innerfunctions = 0;
+    return c;
+}
+    
+
 static code_t* wrap_function(code_t*c,code_t*header, code_t*body)
 {
     c = code_append(c, header);
@@ -617,7 +692,6 @@ static void startpackage(char*name)
     new_state();
     /*printf("entering package \"%s\"\n", name);*/
     state->package = strdup(name);
-    global->variable_count = 1;
 }
 static void endpackage()
 {
@@ -629,6 +703,7 @@ static void endpackage()
     old_state();
 }
 
+
 char*as3_globalclass=0;
 static void startclass(int flags, char*classname, classinfo_t*extends, classinfo_list_t*implements, char interface)
 {
@@ -636,9 +711,7 @@ static void startclass(int flags, char*classname, classinfo_t*extends, classinfo
         syntaxerror("inner classes now allowed"); 
     }
     new_state();
-    global->variable_count = 1;
     state->cls = rfx_calloc(sizeof(classstate_t));
-    state->method = rfx_calloc(sizeof(methodstate_t)); // method state, for static constructor
 
     token_list_t*t=0;
     classinfo_list_t*mlist=0;
@@ -654,7 +727,7 @@ static void startclass(int flags, char*classname, classinfo_t*extends, classinfo
     char*package=0;
 
     if(!(flags&FLAG_PUBLIC) && !state->package) {
-        access = ACCESS_PRIVATE; package = current_filename;
+        access = ACCESS_PRIVATE; package = strdup(current_filename_short);
     } else if(!(flags&FLAG_PUBLIC) && state->package) {
         access = ACCESS_PACKAGEINTERNAL; package = state->package;
     } else if(state->package) {
@@ -663,131 +736,141 @@ static void startclass(int flags, char*classname, classinfo_t*extends, classinfo
         syntaxerror("public classes only allowed inside a package");
     }
 
-    if(registry_findclass(package, classname)) {
-        syntaxerror("Package \"%s\" already contains a class called \"%s\"", package, classname);
-    }
-   
+    if(as3_pass==1) {
+        state->method = rfx_calloc(sizeof(methodstate_t)); // method state, for static constructor
+        state->method->variable_count = 1;
+        dict_put(global->token2info, (void*)(ptroff_t)as3_tokencount, state->method);
 
-    /* build info struct */
-    int num_interfaces = (list_length(implements));
-    state->cls->info = classinfo_register(access, package, classname, num_interfaces);
-    state->cls->info->superclass = extends?extends:TYPE_OBJECT;
-    int pos = 0;
-    classinfo_list_t*l = implements;
-    for(l=implements;l;l=l->next) {
-        state->cls->info->interfaces[pos++] = l->classinfo;
+        if(registry_findclass(package, classname)) {
+            syntaxerror("Package \"%s\" already contains a class called \"%s\"", package, classname);
+        }
+        /* build info struct */
+        int num_interfaces = (list_length(implements));
+        state->cls->info = classinfo_register(access, package, classname, num_interfaces);
     }
     
-    multiname_t*extends2 = sig2mname(extends);
+    if(as3_pass == 2) {
+        state->method = dict_lookup(global->token2info, (void*)(ptroff_t)as3_tokencount);
+
+        state->cls->info = registry_findclass(package, classname);
+        parserassert((int)state->cls->info);
+
+        /* fill out interfaces and extends (we couldn't resolve those during the first pass) */
+        state->cls->info->superclass = extends?extends:TYPE_OBJECT;
+        int pos = 0;
+        classinfo_list_t*l = implements;
+        for(l=implements;l;l=l->next) {
+            state->cls->info->interfaces[pos++] = l->classinfo;
+        }
 
-    MULTINAME(classname2,state->cls->info);
+        /* generate the abc code for this class */
+        MULTINAME(classname2,state->cls->info);
+        multiname_t*extends2 = sig2mname(extends);
 
-    /*if(extends) {
-        state->cls_init = abc_getlocal_0(state->cls_init);
-        state->cls_init = abc_constructsuper(state->cls_init, 0);
-    }*/
+        state->cls->abc = abc_class_new(global->file, &classname2, extends2);
+        if(flags&FLAG_FINAL) abc_class_final(state->cls->abc);
+        if(!(flags&FLAG_DYNAMIC)) abc_class_sealed(state->cls->abc);
+        if(interface) {
+            state->cls->info->flags |= CLASS_INTERFACE;
+            abc_class_interface(state->cls->abc);
+        }
 
-    state->cls->abc = abc_class_new(global->file, &classname2, extends2);
-    if(flags&FLAG_FINAL) abc_class_final(state->cls->abc);
-    if(!(flags&FLAG_DYNAMIC)) abc_class_sealed(state->cls->abc);
-    if(interface) {
-        state->cls->info->flags |= CLASS_INTERFACE;
-        abc_class_interface(state->cls->abc);
-    }
+        abc_class_protectedNS(state->cls->abc, classname);
 
-    abc_class_protectedNS(state->cls->abc, classname);
+        for(mlist=implements;mlist;mlist=mlist->next) {
+            MULTINAME(m, mlist->classinfo);
+            abc_class_add_interface(state->cls->abc, &m);
+        }
 
-    for(mlist=implements;mlist;mlist=mlist->next) {
-        MULTINAME(m, mlist->classinfo);
-        abc_class_add_interface(state->cls->abc, &m);
-    }
+        /* write the construction code for this class to the global init
+           function */
+        int slotindex = abc_initscript_addClassTrait(global->init, &classname2, state->cls->abc);
 
-    /* now write the construction code for this class */
-    int slotindex = abc_initscript_addClassTrait(global->init, &classname2, state->cls->abc);
+        abc_method_body_t*m = global->init->method->body;
+        __ getglobalscope(m);
+        classinfo_t*s = extends;
 
-    abc_method_body_t*m = global->init->method->body;
-    __ getglobalscope(m);
-    classinfo_t*s = extends;
+        int count=0;
+        
+        while(s) {
+            //TODO: take a look at the current scope stack, maybe 
+            //      we can re-use something
+            s = s->superclass;
+            if(!s) 
+            break;
+           
+            multiname_t*s2 = sig2mname(s);
+            __ getlex2(m, s2);
+            multiname_destroy(s2);
 
-    int count=0;
-    
-    while(s) {
-        //TODO: take a look at the current scope stack, maybe 
-        //      we can re-use something
-        s = s->superclass;
-        if(!s) 
-        break;
-       
-        multiname_t*s2 = sig2mname(s);
-        __ getlex2(m, s2);
-        multiname_destroy(s2);
-
-        __ pushscope(m); count++;
-        m->code = m->code->prev->prev; // invert
-    }
-    /* continue appending after last op end */
-    while(m->code && m->code->next) m->code = m->code->next; 
-
-    /* TODO: if this is one of *our* classes, we can also 
-             do a getglobalscope/getslot <nr> (which references
-             the init function's slots) */
-    if(extends2) {
-        __ getlex2(m, extends2);
-        __ dup(m);
-        /* notice: we get a Verify Error #1107 if the top elemnt on the scope
-           stack is not the superclass */
-        __ pushscope(m);count++;
-    } else {
-        __ pushnull(m);
-        /* notice: we get a verify error #1107 if the top element on the scope 
-           stack is not the global object */
-        __ getlocal_0(m);
-        __ pushscope(m);count++;
-    }
-    __ newclass(m,state->cls->abc);
-    while(count--) {
-        __ popscope(m);
-    }
-    __ setslot(m, slotindex);
-
-    /* flash.display.MovieClip handling */
-    if(!as3_globalclass && (flags&FLAG_PUBLIC) && classinfo_equals(registry_getMovieClip(),extends)) {
-        if(state->package && state->package[0]) {
-            as3_globalclass = concat3(state->package, ".", classname);
+            __ pushscope(m); count++;
+            m->code = m->code->prev->prev; // invert
+        }
+        /* continue appending after last op end */
+        while(m->code && m->code->next) m->code = m->code->next; 
+
+        /* TODO: if this is one of *our* classes, we can also 
+                 do a getglobalscope/getslot <nr> (which references
+                 the init function's slots) */
+        if(extends2) {
+            __ getlex2(m, extends2);
+            __ dup(m);
+            /* notice: we get a Verify Error #1107 if the top elemnt on the scope
+               stack is not the superclass */
+            __ pushscope(m);count++;
         } else {
-            as3_globalclass = strdup(classname);
+            __ pushnull(m);
+            /* notice: we get a verify error #1107 if the top element on the scope 
+               stack is not the global object */
+            __ getlocal_0(m);
+            __ pushscope(m);count++;
+        }
+        __ newclass(m,state->cls->abc);
+        while(count--) {
+            __ popscope(m);
+        }
+        __ setslot(m, slotindex);
+        multiname_destroy(extends2);
+
+        /* flash.display.MovieClip handling */
+
+        if(!as3_globalclass && (flags&FLAG_PUBLIC) && classinfo_equals(registry_getMovieClip(),extends)) {
+            if(state->package && state->package[0]) {
+                as3_globalclass = concat3(state->package, ".", classname);
+            } else {
+                as3_globalclass = strdup(classname);
+            }
         }
     }
-    multiname_destroy(extends2);
 }
 
 static void endclass()
 {
-    if(!state->cls->has_constructor && !(state->cls->info->flags&CLASS_INTERFACE)) {
-        code_t*c = 0;
-        c = abc_getlocal_0(c);
-        c = abc_constructsuper(c, 0);
-        state->cls->init = code_append(state->cls->init, c);
-    }
-    if(!state->method->late_binding) {
-        // class initialization code uses late binding
-        code_t*c = 0;
-        c = abc_getlocal_0(c);
-        c = abc_pushscope(c);
-        state->cls->static_init = code_append(c, state->cls->static_init);
-    }
+    if(as3_pass == 2) {
+        if(!state->cls->has_constructor && !(state->cls->info->flags&CLASS_INTERFACE)) {
+            code_t*c = 0;
+            c = abc_getlocal_0(c);
+            c = abc_constructsuper(c, 0);
+            state->cls->init = code_append(state->cls->init, c);
+        }
+        if(!state->method->late_binding) {
+            // class initialization code uses late binding
+            code_t*c = 0;
+            c = abc_getlocal_0(c);
+            c = abc_pushscope(c);
+            state->cls->static_init = code_append(c, state->cls->static_init);
+        }
 
-    if(state->cls->init) {
-        abc_method_t*m = abc_class_getconstructor(state->cls->abc, 0);
-        m->body->code = wrap_function(0, state->cls->init, m->body->code);
-    }
-    if(state->cls->static_init) {
-        abc_method_t*m = abc_class_getstaticconstructor(state->cls->abc, 0);
-        m->body->code = wrap_function(0, state->cls->static_init, m->body->code);
+        if(state->cls->init) {
+            abc_method_t*m = abc_class_getconstructor(state->cls->abc, 0);
+            m->body->code = wrap_function(0, state->cls->init, m->body->code);
+        }
+        if(state->cls->static_init) {
+            abc_method_t*m = abc_class_getstaticconstructor(state->cls->abc, 0);
+            m->body->code = wrap_function(0, state->cls->static_init, m->body->code);
+        }
     }
 
-    free(state->cls);state->cls=0;
-    free(state->method);state->method=0;
     old_state();
 }
 
@@ -878,7 +961,7 @@ static memberinfo_t*registerfunction(enum yytokentype getset, int flags, char*na
         classinfo_t*type=0;
         if(getset == KW_GET)
             type = return_type;
-        else if(params->list)
+        else if(params->list && params->list->param)
             type = params->list->param->type;
         // not sure wether to look into superclasses here, too
         if((minfo=registry_findmember(state->cls->info, name, 0))) {
@@ -909,6 +992,67 @@ static memberinfo_t*registerfunction(enum yytokentype getset, int flags, char*na
     return minfo;
 }
 
+static void function_initvars(params_t*params, int flags)
+{
+    if(state->method->inner)
+        new_variable("this", 0, 0);
+    else if(!state->method->is_global)
+        new_variable((flags&FLAG_STATIC)?"class":"this", state->cls->info, 0);
+    else
+        new_variable("globalscope", 0, 0);
+
+    param_list_t*p=0;
+    for(p=params->list;p;p=p->next) {
+        new_variable(p->param->name, p->param->type, 0);
+    }
+    
+    methodstate_list_t*l = state->method->innerfunctions;
+    while(l) {
+        methodstate_t*m = l->methodstate;
+        m->var_index = new_variable(m->info->name, TYPE_FUNCTION(m->info), 0);
+        l = l->next;
+    }
+}
+
+static void innerfunction(char*name, params_t*params, classinfo_t*return_type)
+{
+    parserassert(state->method && state->method->info);
+
+    methodstate_t*parent_method = state->method;
+
+    if(as3_pass==1) {
+        // not valid yet
+        params = 0;
+        return_type = 0;
+    }
+
+    new_state();
+    state->new_vars = 1;
+   
+    if(as3_pass == 1) {
+        state->method = rfx_calloc(sizeof(methodstate_t));
+        state->method->inner = 1;
+        state->method->variable_count = 0;
+        state->method->abc = rfx_calloc(sizeof(abc_method_t));
+
+        NEW(memberinfo_t,minfo);
+        minfo->name = name;
+        state->method->info = minfo;
+
+        list_append(parent_method->innerfunctions, state->method);
+
+        dict_put(global->token2info, (void*)(ptroff_t)as3_tokencount, state->method);
+    }
+
+    if(as3_pass == 2) {
+        state->method = dict_lookup(global->token2info, (void*)(ptroff_t)as3_tokencount);
+        parserassert(state->method);
+
+        state->method->info->return_type = return_type;
+        function_initvars(params, 0);
+    }
+}
+
 static void startfunction(token_t*ns, int flags, enum yytokentype getset, char*name,
                           params_t*params, classinfo_t*return_type)
 {
@@ -916,41 +1060,56 @@ static void startfunction(token_t*ns, int flags, enum yytokentype getset, char*n
         syntaxerror("not able to start another method scope");
     }
     new_state();
-    global->variable_count = 0;
-    state->method = rfx_calloc(sizeof(methodstate_t));
-    state->method->has_super = 0;
+    
+    if(as3_pass == 1) {
+        state->method = rfx_calloc(sizeof(methodstate_t));
+        state->method->has_super = 0;
+        state->method->variable_count = 0;
 
-    if(state->cls) {
-        state->method->is_constructor = !strcmp(state->cls->info->name,name);
-        state->cls->has_constructor |= state->method->is_constructor;
-        
-        new_variable((flags&FLAG_STATIC)?"class":"this", state->cls->info, 0);
-    } else {
-        state->method->is_global = 1;
-        state->method->late_binding = 1; // for global methods, always push local_0 on the scope stack
+        if(state->cls) {
+            state->method->is_constructor = !strcmp(state->cls->info->name,name);
+        } else {
+            state->method->is_global = 1;
+            state->method->late_binding = 1; // for global methods, always push local_0 on the scope stack
+        }
+        if(state->method->is_constructor)
+            name = "__as3_constructor__";
 
-        new_variable("globalscope", 0, 0);
+        return_type = 0;
+        state->method->info = registerfunction(getset, flags, name, params, return_type, 0);
+        
+        dict_put(global->token2info, (void*)(ptroff_t)as3_tokencount, state->method);
     }
 
-    /* state->vars is initialized by state_new */
-
-    param_list_t*p=0;
-    for(p=params->list;p;p=p->next) {
-        new_variable(p->param->name, p->param->type, 0);
-    }
-    if(state->method->is_constructor)
-        name = "__as3_constructor__";
-    state->method->info = registerfunction(getset, flags, name, params, return_type, 0);
+    if(as3_pass == 2) {
+        state->method = dict_lookup(global->token2info, (void*)(ptroff_t)as3_tokencount);
+        parserassert(state->method);
+            
+        if(state->cls) { 
+            state->cls->has_constructor |= state->method->is_constructor;
+        }
+        
+        state->method->info->return_type = return_type;
+        function_initvars(params, flags);
+    } 
 }
 
-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 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 = state->method->abc;
+        abc_method_init(f, 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, "");
@@ -1002,12 +1161,10 @@ static void endfunction(token_t*ns, int flags, enum yytokentype getset, char*nam
             syntaxerror("interface methods can't have a method body");
     }
        
-    free(state->method);state->method=0;
     old_state();
+    return f;
 }
 
-
-
 char is_subtype_of(classinfo_t*type, classinfo_t*supertype)
 {
     return 1; // FIXME
@@ -1134,11 +1291,6 @@ char is_pushundefined(code_t*c)
     return (c && !c->prev && !c->next && c->opcode == OPCODE_PUSHUNDEFINED);
 }
 
-void parserassert(int b)
-{
-    if(!b) syntaxerror("internal error: assertion failed");
-}
-
 static classinfo_t* find_class(char*name)
 {
     classinfo_t*c=0;
@@ -1169,9 +1321,9 @@ static classinfo_t* find_class(char*name)
     /* try global package */
     c = registry_findclass("", name);
     if(c) return c;
-   
+  
     /* try local "filename" package */
-    c = registry_findclass(current_filename, name);
+    c = registry_findclass(current_filename_short, name);
     if(c) return c;
 
     return 0;
@@ -1208,7 +1360,6 @@ static code_t* toreadwrite(code_t*in, code_t*middlepart, char justassign, char r
 
        [prefix code] ([dup]) [read instruction] [middlepart] [setvar] [write instruction] [getvar]
     */
-    
     if(in && in->opcode == OPCODE_COERCE_A) {
         in = code_cutlast(in);
     }
@@ -1328,6 +1479,7 @@ static code_t* toreadwrite(code_t*in, code_t*middlepart, char justassign, char r
             c = code_append(c, write);
             c = code_append(c, r);
         } else {
+            code_free(r);r=0;
             temp = gettempvar();
             if(prefix) {
                 c = code_append(c, prefix);
@@ -1474,8 +1626,13 @@ code_t* insert_finally(code_t*c, code_t*finally, int tempvar)
     }
 }
 
-%}
+#define PASS1 }} if(as3_pass == 1) {{
+#define PASS1END }} if(as3_pass == 2) {{
+#define PASS2 }} if(as3_pass == 2) {{
+#define PASS12 }} {{
+#define PASS12END }} if(as3_pass == 2) {{
 
+%}
 
 %%
 
@@ -1493,6 +1650,7 @@ PROGRAM_CODE: PACKAGE_DECLARATION
             | FUNCTION_DECLARATION
             | SLOT_DECLARATION
             | PACKAGE_INITCODE
+            | T_IDENTIFIER "::" T_IDENTIFIER '{' PROGRAM_CODE_LIST '}' // conditional compilation
             | ';'
 
 MAYBE_INPACKAGE_CODE_LIST: | INPACKAGE_CODE_LIST
@@ -1504,6 +1662,7 @@ INPACKAGE_CODE: INTERFACE_DECLARATION
               | FUNCTION_DECLARATION
               | SLOT_DECLARATION
               | PACKAGE_INITCODE
+              | T_IDENTIFIER "::" T_IDENTIFIER '{' INPACKAGE_CODE_LIST '}' // conditional compilation
               | ';'
 
 MAYBECODE: CODE {$$=$1;}
@@ -1579,6 +1738,7 @@ ONE_VARIABLE: T_IDENTIFIER MAYBETYPE MAYBEEXPRESSION
             $$ = converttype($$, $3.t, $2);
             $$ = abc_setlocal($$, index);
         } else {
+            code_free($3.c);
             $$ = defaultvalue(0, $2);
             $$ = abc_setlocal($$, index);
         }
@@ -1588,6 +1748,7 @@ ONE_VARIABLE: T_IDENTIFIER MAYBETYPE MAYBEEXPRESSION
             $$ = abc_coerce_a($$);
             $$ = abc_setlocal($$, index);
         } else {
+            code_free($3.c);
             $$ = code_new();
         }
     }
@@ -1754,7 +1915,7 @@ MAYBE_CASE_LIST :           {$$=0;}
 MAYBE_CASE_LIST : CASE_LIST {$$=$1;}
 MAYBE_CASE_LIST : DEFAULT   {$$=$1;}
 MAYBE_CASE_LIST : CASE_LIST DEFAULT {$$=code_append($1,$2);}
-CASE_LIST: CASE             {$$=$1}
+CASE_LIST: CASE             {$$=$1;}
 CASE_LIST: CASE_LIST CASE   {$$=code_append($$,$2);}
 
 CASE: "case" E ':' MAYBECODE {
@@ -1839,7 +2000,7 @@ FINALLY: "finally" '{' {new_state();state->exception_name=0;} MAYBECODE '}' {
 
 CATCH_LIST: CATCH {$$.l=list_new();$$.finally=0;list_append($$.l,$1);}
 CATCH_LIST: CATCH_LIST CATCH {$$=$1;list_append($$.l,$2);}
-CATCH_FINALLY_LIST: CATCH_LIST {$$=$1};
+CATCH_FINALLY_LIST: CATCH_LIST {$$=$1;}
 CATCH_FINALLY_LIST: CATCH_LIST FINALLY {
     $$ = $1;
     $$.finally = 0;
@@ -1927,15 +2088,23 @@ WITH : "with" '(' EXPRESSION ')' CODEBLOCK {
 /* ------------ packages and imports ---------------- */
 
 X_IDENTIFIER: T_IDENTIFIER
-            | "package" {$$="package";}
+            | "package" {PASS12 $$="package";}
+
+PACKAGE: PACKAGE '.' X_IDENTIFIER {PASS12 $$ = concat3($1,".",$3);free($1);$1=0;}
+PACKAGE: X_IDENTIFIER             {PASS12 $$=strdup($1);}
 
-PACKAGE: PACKAGE '.' X_IDENTIFIER {$$ = concat3($1,".",$3);free($1);$1=0;}
-PACKAGE: X_IDENTIFIER             {$$=strdup($1);}
+PACKAGE_DECLARATION : "package" PACKAGE '{' {PASS12 startpackage($2);free($2);$2=0;}
+                                MAYBE_INPACKAGE_CODE_LIST '}' {PASS12 endpackage();$$=0;}
+PACKAGE_DECLARATION : "package" '{' {PASS12 startpackage("");} 
+                                MAYBE_INPACKAGE_CODE_LIST '}' {PASS12 endpackage();$$=0;}
 
-PACKAGE_DECLARATION : "package" PACKAGE '{' {startpackage($2);free($2);$2=0;} MAYBE_INPACKAGE_CODE_LIST '}' {endpackage();$$=0;}
-PACKAGE_DECLARATION : "package" '{' {startpackage("")} MAYBE_INPACKAGE_CODE_LIST '}' {endpackage();$$=0;}
+IMPORT : "import" PACKAGEANDCLASS {
+       PASS1 
+       if(!registry_findclass($2->package, $2->name)) {
+           as3_schedule_class($2->package, $2->name);
+       }
 
-IMPORT : "import" QNAME {
+       PASS2
        classinfo_t*c = $2;
        if(!c) 
             syntaxerror("Couldn't import class\n");
@@ -1944,6 +2113,12 @@ IMPORT : "import" QNAME {
        $$=0;
 }
 IMPORT : "import" PACKAGE '.' '*' {
+       PASS1 
+       if(strncmp("flash.", $2, 6)) {
+           as3_schedule_package($2);
+       }
+
+       PASS2
        NEW(import_t,i);
        i->package = $2;
        state_has_imports();
@@ -1953,41 +2128,41 @@ IMPORT : "import" PACKAGE '.' '*' {
 
 /* ------------ classes and interfaces (header) -------------- */
 
-MAYBE_MODIFIERS : %prec above_function {$$=0;}
-MAYBE_MODIFIERS : MODIFIER_LIST {$$=$1}
-MODIFIER_LIST : MODIFIER               {$$=$1;}
-MODIFIER_LIST : MODIFIER_LIST MODIFIER {$$=$1|$2;}
-
-MODIFIER : KW_PUBLIC {$$=FLAG_PUBLIC;}
-         | KW_PRIVATE {$$=FLAG_PRIVATE;}
-         | KW_PROTECTED {$$=FLAG_PROTECTED;}
-         | KW_STATIC {$$=FLAG_STATIC;}
-         | KW_DYNAMIC {$$=FLAG_DYNAMIC;}
-         | KW_FINAL {$$=FLAG_FINAL;}
-         | KW_OVERRIDE {$$=FLAG_OVERRIDE;}
-         | KW_NATIVE {$$=FLAG_NATIVE;}
-         | KW_INTERNAL {$$=FLAG_PACKAGEINTERNAL;}
+MAYBE_MODIFIERS : %prec above_function {PASS12 $$=0;}
+MAYBE_MODIFIERS : MODIFIER_LIST        {PASS12 $$=$1;}
+MODIFIER_LIST : MODIFIER               {PASS12 $$=$1;}
+MODIFIER_LIST : MODIFIER_LIST MODIFIER {PASS12 $$=$1|$2;}
+
+MODIFIER : KW_PUBLIC {PASS12 $$=FLAG_PUBLIC;}
+         | KW_PRIVATE {PASS12 $$=FLAG_PRIVATE;}
+         | KW_PROTECTED {PASS12 $$=FLAG_PROTECTED;}
+         | KW_STATIC {PASS12 $$=FLAG_STATIC;}
+         | KW_DYNAMIC {PASS12 $$=FLAG_DYNAMIC;}
+         | KW_FINAL {PASS12 $$=FLAG_FINAL;}
+         | KW_OVERRIDE {PASS12 $$=FLAG_OVERRIDE;}
+         | KW_NATIVE {PASS12 $$=FLAG_NATIVE;}
+         | KW_INTERNAL {PASS12 $$=FLAG_PACKAGEINTERNAL;}
 
 EXTENDS : {$$=registry_getobjectclass();}
-EXTENDS : KW_EXTENDS QNAME {$$=$2;}
+EXTENDS : KW_EXTENDS CLASS_SPEC {$$=$2;}
 
-EXTENDS_LIST : {$$=list_new();}
-EXTENDS_LIST : KW_EXTENDS QNAME_LIST {$$=$2;}
+EXTENDS_LIST : {PASS12 $$=list_new();}
+EXTENDS_LIST : KW_EXTENDS CLASS_SPEC_LIST {PASS12 $$=$2;}
 
-IMPLEMENTS_LIST : {$$=list_new();}
-IMPLEMENTS_LIST : KW_IMPLEMENTS QNAME_LIST {$$=$2;}
+IMPLEMENTS_LIST : {PASS12 $$=list_new();}
+IMPLEMENTS_LIST : KW_IMPLEMENTS CLASS_SPEC_LIST {PASS12 $$=$2;}
 
 CLASS_DECLARATION : MAYBE_MODIFIERS "class" T_IDENTIFIER 
                               EXTENDS IMPLEMENTS_LIST 
-                              '{' {startclass($1,$3,$4,$5, 0);} 
+                              '{' {PASS12 startclass($1,$3,$4,$5, 0);} 
                               MAYBE_CLASS_BODY 
-                              '}' {endclass();$$=0;}
+                              '}' {PASS12 endclass();$$=0;}
 
 INTERFACE_DECLARATION : MAYBE_MODIFIERS "interface" T_IDENTIFIER 
                               EXTENDS_LIST 
-                              '{' {startclass($1,$3,0,$4,1);}
+                              '{' {PASS12 startclass($1,$3,0,$4,1);}
                               MAYBE_INTERFACE_BODY 
-                              '}' {endclass();$$=0;}
+                              '}' {PASS12 endclass();$$=0;}
 
 /* ------------ classes and interfaces (body) -------------- */
 
@@ -2014,12 +2189,14 @@ IDECLARATION : "var" T_IDENTIFIER {
     syntaxerror("variable declarations not allowed in interfaces");
 }
 IDECLARATION : MAYBE_MODIFIERS "function" GETSET T_IDENTIFIER '(' MAYBE_PARAM_LIST ')' MAYBETYPE {
+    PASS12
     $1 |= FLAG_PUBLIC;
     if($1&(FLAG_PRIVATE|FLAG_PACKAGEINTERNAL|FLAG_PROTECTED)) {
         syntaxerror("invalid method modifiers: interface methods always need to be public");
     }
     startfunction(0,$1,$3,$4,&$6,$8);
     endfunction(0,$1,$3,$4,&$6,$8, 0);
+    list_deep_free($6.list);
 }
 
 /* ------------ classes and interfaces (body, slots ) ------- */
@@ -2043,6 +2220,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) {
@@ -2091,7 +2269,7 @@ STATICCONSTANT : T_BYTE {$$ = constant_new_int($1);}
 STATICCONSTANT : T_INT {$$ = constant_new_int($1);}
 STATICCONSTANT : T_UINT {$$ = constant_new_uint($1);}
 STATICCONSTANT : T_FLOAT {$$ = constant_new_float($1);}
-STATICCONSTANT : T_STRING {$$ = constant_new_string2($1.str,$1.len);}
+STATICCONSTANT : T_STRING {$$ = constant_new_string2($1.str,$1.len);free((char*)$1.str);}
 //STATICCONSTANT : T_NAMESPACE {$$ = constant_new_namespace($1);}
 STATICCONSTANT : "true" {$$ = constant_new_true($1);}
 STATICCONSTANT : "false" {$$ = constant_new_false($1);}
@@ -2101,19 +2279,23 @@ STATICCONSTANT : "null" {$$ = constant_new_null($1);}
 
 // non-vararg version
 MAYBE_PARAM_LIST: {
+    PASS12
     memset(&$$,0,sizeof($$));
 }
 MAYBE_PARAM_LIST: PARAM_LIST {
+    PASS12
     $$=$1;
 }
 
 // vararg version
 MAYBE_PARAM_LIST: "..." PARAM {
+    PASS12
     memset(&$$,0,sizeof($$));
     $$.varargs=1;
     list_append($$.list, $2);
 }
 MAYBE_PARAM_LIST: PARAM_LIST ',' "..." PARAM {
+    PASS12
     $$ =$1;
     $$.varargs=1;
     list_append($$.list, $4);
@@ -2121,21 +2303,27 @@ MAYBE_PARAM_LIST: PARAM_LIST ',' "..." PARAM {
 
 // non empty
 PARAM_LIST: PARAM_LIST ',' PARAM {
+    PASS12
     $$ = $1;
     list_append($$.list, $3);
 }
 PARAM_LIST: PARAM {
+    PASS12
     memset(&$$,0,sizeof($$));
     list_append($$.list, $1);
 }
 
 PARAM:  T_IDENTIFIER ':' TYPE MAYBESTATICCONSTANT {
+     PASS1 $$=0;
+     PASS2
      $$ = malloc(sizeof(param_t));
      $$->name=$1;
      $$->type = $3;
      $$->value = $4;
 }
 PARAM:  T_IDENTIFIER MAYBESTATICCONSTANT {
+     PASS1 $$=0;
+     PASS2
      $$ = malloc(sizeof(param_t));
      $$->name=$1;
      $$->type = TYPE_ANY;
@@ -2146,53 +2334,71 @@ GETSET : "get" {$$=$1;}
        |       {$$=0;}
 
 FUNCTION_DECLARATION: MAYBE_MODIFIERS "function" GETSET T_IDENTIFIER '(' MAYBE_PARAM_LIST ')' 
-                      MAYBETYPE '{' {startfunction(0,$1,$3,$4,&$6,$8)} MAYBECODE '}' 
+                      MAYBETYPE '{' {PASS12 startfunction(0,$1,$3,$4,&$6,$8);} MAYBECODE '}' 
 {
-    code_t*c = 0;
-    if(state->method->late_binding) {
-        c = abc_getlocal_0(c);
-        c = abc_pushscope(c);
-    }
-    if(state->method->is_constructor && !state->method->has_super) {
-        // call default constructor
-        c = abc_getlocal_0(c);
-        c = abc_constructsuper(c, 0);
-    }
+    PASS1 old_state();list_deep_free($6.list);
+    PASS2
+    if(!state->method->info) syntaxerror("internal error");
+    
+    code_t*c = method_header();
     c = wrap_function(c, 0, $11);
+
     endfunction(0,$1,$3,$4,&$6,$8,c);
+    list_deep_free($6.list);
     $$=0;
 }
 
 MAYBE_IDENTIFIER: T_IDENTIFIER
-MAYBE_IDENTIFIER: {$$=0;}
-INNERFUNCTION: "function" MAYBE_IDENTIFIER '(' MAYBE_PARAM_LIST ')' MAYBETYPE '{' MAYBECODE '}'
+MAYBE_IDENTIFIER: {PASS12 $$=0;}
+INNERFUNCTION: "function" MAYBE_IDENTIFIER '(' MAYBE_PARAM_LIST ')' MAYBETYPE 
+               '{' {PASS12 innerfunction($2,&$4,$6);} MAYBECODE '}'
 {
-    syntaxerror("nested functions not supported yet");
+    PASS1 old_state();list_deep_free($4.list);
+    PASS2
+    memberinfo_t*f = state->method->info;
+    if(!f) syntaxerror("internal error");
+    
+    code_t*c = method_header();
+    c = wrap_function(c, 0, $9);
+
+    int index = state->method->var_index;
+    endfunction(0,0,0,$2,&$4,$6,c);
+    list_deep_free($4.list);
+    
+    $$.c = abc_getlocal(0, index);
+    $$.t = TYPE_FUNCTION(f);
 }
 
 
 /* ------------- package + class ids --------------- */
 
 CLASS: T_IDENTIFIER {
-
+    PASS1 $$=0;
+    PASS2
     /* try current package */
     $$ = find_class($1);
     if(!$$) syntaxerror("Could not find class %s\n", $1);
 }
 
 PACKAGEANDCLASS : PACKAGE '.' T_IDENTIFIER {
+    PASS1 static classinfo_t c;
+          memset(&c, 0, sizeof(c));
+          c.package = $1;
+          c.name = $3;
+          $$=&c;
+    PASS2
     $$ = registry_findclass($1, $3);
     if(!$$) syntaxerror("Couldn't find class %s.%s\n", $1, $3);
     free($1);$1=0;
 }
 
-QNAME: PACKAGEANDCLASS
-     | CLASS
+CLASS_SPEC: PACKAGEANDCLASS
+          | CLASS
 
-QNAME_LIST : QNAME {$$=list_new();list_append($$, $1);}
-QNAME_LIST : QNAME_LIST ',' QNAME {$$=$1;list_append($$,$3);}
+CLASS_SPEC_LIST : CLASS_SPEC {PASS12 $$=list_new();list_append($$, $1);}
+CLASS_SPEC_LIST : CLASS_SPEC_LIST ',' CLASS_SPEC {PASS12 $$=$1;list_append($$,$3);}
 
-TYPE : QNAME      {$$=$1;}
+TYPE : CLASS_SPEC {$$=$1;}
      | '*'        {$$=registry_getanytype();}
      | "void"     {$$=registry_getanytype();}
     /*
@@ -2209,7 +2415,7 @@ MAYBETYPE:          {$$=0;}
 /* ----------function calls, delete, constructor calls ------ */
 
 MAYBE_PARAM_VALUES :  %prec prec_none {$$.cc=0;$$.len=0;}
-MAYBE_PARAM_VALUES : '(' MAYBE_EXPRESSION_LIST ')' {$$=$2}
+MAYBE_PARAM_VALUES : '(' MAYBE_EXPRESSION_LIST ')' {$$=$2;}
 
 MAYBE_EXPRESSION_LIST : {$$.cc=0;$$.len=0;}
 MAYBE_EXPRESSION_LIST : EXPRESSION_LIST
@@ -2220,25 +2426,38 @@ EXPRESSION_LIST : EXPRESSION_LIST ',' NONCOMMAEXPRESSION {
                                                   $$.len= $1.len+1;
                                                   $$.cc = code_append($1.cc, $3.c);
                                                   }
-
-NEW : "new" CLASS MAYBE_PARAM_VALUES {
-    MULTINAME(m, $2);
-    $$.c = code_new();
-
-    if($2->slot) {
-        $$.c = abc_getglobalscope($$.c);
-        $$.c = abc_getslot($$.c, $2->slot);
+               
+XX : %prec new2
+NEW : "new" E XX MAYBE_PARAM_VALUES {
+    $$.c = $2.c;
+    if($$.c->opcode == OPCODE_COERCE_A) $$.c = code_cutlast($$.c);
+    
+    code_t*paramcode = $4.cc;
+    if($$.c->opcode == OPCODE_GETPROPERTY) {
+        multiname_t*name = $$.c->data[0];$$.c->data[0]=0;
+        $$.c = code_cutlast($$.c);
+        $$.c = code_append($$.c, paramcode);
+        $$.c = abc_constructprop2($$.c, name, $4.len);
+        multiname_destroy(name);
+    } else if($$.c->opcode == OPCODE_GETSLOT) {
+        int slot = (int)(ptroff_t)$$.c->data[0];
+        trait_t*t = abc_class_find_slotid(state->cls->abc,slot);//FIXME
+        multiname_t*name = t->name;
+        $$.c = code_cutlast($$.c);
+        $$.c = code_append($$.c, paramcode);
+        $$.c = abc_constructprop2($$.c, name, $4.len);
     } else {
-        $$.c = abc_findpropstrict2($$.c, &m);
+        $$.c = code_append($$.c, paramcode);
+        $$.c = abc_construct($$.c, $4.len);
+    }
+   
+    $$.t = TYPE_ANY;
+    if(TYPE_IS_CLASS($2.t) && $2.t->cls) {
+        $$.t = $2.t->cls;
+    } else {
+        $$.c = abc_coerce_a($$.c);
+        $$.t = TYPE_ANY;
     }
-
-    $$.c = code_append($$.c, $3.cc);
-
-    if($2->slot)
-        $$.c = abc_construct($$.c, $3.len);
-    else
-        $$.c = abc_constructprop2($$.c, &m, $3.len);
-    $$.t = $2;
 }
 
 /* TODO: use abc_call (for calling local variables),
@@ -2278,21 +2497,19 @@ FUNCTIONCALL : E '(' MAYBE_EXPRESSION_LIST ')' {
         $$.c = abc_callsuper2($$.c, name, $3.len);
         multiname_destroy(name);
     } else {
-        $$.c = abc_getlocal_0($$.c);
+        $$.c = abc_getglobalscope($$.c);
         $$.c = code_append($$.c, paramcode);
         $$.c = abc_call($$.c, $3.len);
     }
    
-    memberinfo_t*f = 0;
-   
     if(TYPE_IS_FUNCTION($1.t) && $1.t->function) {
         $$.t = $1.t->function->return_type;
     } else {
         $$.c = abc_coerce_a($$.c);
         $$.t = TYPE_ANY;
     }
-
 }
+
 FUNCTIONCALL : "super" '(' MAYBE_EXPRESSION_LIST ')' {
     if(!state->cls) syntaxerror("super() not allowed outside of a class");
     if(!state->method) syntaxerror("super() not allowed outside of a function");
@@ -2308,6 +2525,7 @@ FUNCTIONCALL : "super" '(' MAYBE_EXPRESSION_LIST ')' {
         syntaxerror("constructor may call super() only once");
     */
     state->method->has_super = 1;
+
     $$.c = abc_constructsuper($$.c, $3.len);
     $$.c = abc_pushundefined($$.c);
     $$.t = TYPE_ANY;
@@ -2368,6 +2586,8 @@ E : NEW                         {$$ = $1;}
 //V : DELETE                      {$$ = $1.c;}
 E : DELETE                      {$$ = $1;}
 
+E : FUNCTIONCALL
+
 E : T_REGEXP {
     $$.c = 0;
     namespace_t ns = {ACCESS_PACKAGE, ""};
@@ -2402,7 +2622,7 @@ CONSTANT : T_UINT {$$.c = abc_pushuint(0, $1);
 CONSTANT : T_FLOAT {$$.c = abc_pushdouble(0, $1);
                     $$.t = TYPE_FLOAT;
                    }
-CONSTANT : T_STRING {$$.c = abc_pushstring2(0, &$1);
+CONSTANT : T_STRING {$$.c = abc_pushstring2(0, &$1);free((char*)$1.str);
                      $$.t = TYPE_STRING;
                     }
 CONSTANT : "undefined" {$$.c = abc_pushundefined(0);
@@ -2418,7 +2638,6 @@ CONSTANT : "null" {$$.c = abc_pushnull(0);
                     $$.t = TYPE_NULL;
                    }
 
-E : FUNCTIONCALL
 E : E '<' E {$$.c = code_append($1.c,$3.c);$$.c = abc_greaterequals($$.c);$$.c=abc_not($$.c);
              $$.t = TYPE_BOOLEAN;
             }
@@ -2607,7 +2826,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
@@ -2621,7 +2840,7 @@ E : '[' MAYBE_EXPRESSION_LIST ']' {
 }
 
 MAYBE_EXPRPAIR_LIST : {$$.cc=0;$$.len=0;}
-MAYBE_EXPRPAIR_LIST : EXPRPAIR_LIST {$$=$1};
+MAYBE_EXPRPAIR_LIST : EXPRPAIR_LIST {$$=$1;}
 
 EXPRPAIR_LIST : NONCOMMAEXPRESSION ':' NONCOMMAEXPRESSION {
     $$.cc = 0;
@@ -2934,8 +3153,7 @@ VAR_READ : T_IDENTIFIER {
 
     /* unknown object, let the avm2 resolve it */
     if(1) {
-        if(strcmp($1,"trace"))
-            as3_softwarning("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};