added stub for inner functions
[swftools.git] / lib / as3 / parser.y
index ea4da6b..9643008 100644 (file)
 %token<token> T_SHR ">>"
 
 %type <for_start> FOR_START
-%type <id> X_IDENTIFIER PACKAGE FOR_IN_INIT
+%type <id> X_IDENTIFIER PACKAGE FOR_IN_INIT MAYBE_IDENTIFIER
 %type <token> VARCONST
 %type <code> CODE
 %type <code> CODEPIECE CODE_STATEMENT
 %type <value> MAYBEEXPRESSION
 %type <value> E DELETE
 %type <value> CONSTANT
-%type <code> FOR FOR_IN IF WHILE DO_WHILE MAYBEELSE BREAK RETURN CONTINUE TRY
+%type <code> FOR FOR_IN IF WHILE DO_WHILE MAYBEELSE BREAK RETURN CONTINUE TRY 
+%type <value> INNERFUNCTION
 %type <token> USE_NAMESPACE
 %type <code> FOR_INIT
 %type <code> IMPORT
 // 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;}
@@ -2701,7 +2718,11 @@ VAR_READ : T_IDENTIFIER {
             MULTINAME(m, a);
             $$.c = abc_findpropstrict2($$.c, &m);
             $$.c = abc_getproperty2($$.c, &m);
-            $$.t = TYPE_FUNCTION(a->function);
+            if(a->function->kind == MEMBER_METHOD) {
+                $$.t = TYPE_FUNCTION(a->function);
+            } else {
+                $$.t = a->function->type;
+            }
         } else {
             if(a->slot) {
                 $$.c = abc_getglobalscope($$.c);
@@ -2716,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};