implemented new()
authorkramm <kramm>
Tue, 23 Dec 2008 18:45:45 +0000 (18:45 +0000)
committerkramm <kramm>
Tue, 23 Dec 2008 18:45:45 +0000 (18:45 +0000)
lib/as3/parser.y

index 2837116..152a001 100644 (file)
@@ -50,6 +50,8 @@
     code_t*code;
     typedcode_t value;
     typedcode_list_t*value_list;
+    param_t* param;
+    param_list_t* param_list;
     writeable_t writeable;
     char*string;
 }
 %type <token> IMPORT
 %type <class_signature> MAYBETYPE
 %type <token> GETSET
-%type <token> PARAM
-%type <token> PARAMS
-%type <token> PARAM_LIST
+%type <param> PARAM
+%type <param_list> PARAM_LIST
+%type <param_list> MAYBE_PARAM_LIST
 %type <token> MODIFIERS
 %type <token> MODIFIER_LIST
 %type <class_signature_list> IMPLEMENTS_LIST
 %type <token> MODIFIER
 %type <token> PACKAGE
 %type <value> FUNCTIONCALL
-%type <value_list> MAYBE_EXPRESSION_LIST EXPRESSION_LIST
+%type <value_list> MAYBE_EXPRESSION_LIST EXPRESSION_LIST MAYBE_PARAM_VALUES
 
 // precendence: from low to high
 // http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000012.html
 %left ';'
 %nonassoc "else"
 %left '('
-%left prec_highest
 
      
 %{
@@ -524,7 +525,7 @@ static void endclass()
     old_state();
 }
 static void startfunction(token_t*ns, token_t*mod, token_t*getset, token_t*name,
-                          token_t*params, class_signature_t*type)
+                          param_list_t*params, class_signature_t*type)
 {
     token_list_t*t;
     new_state();
@@ -551,8 +552,17 @@ static void startfunction(token_t*ns, token_t*mod, token_t*getset, token_t*name,
     } else {
         state->m = abc_class_method(state->cls, type2, name->text, 0);
     }
+    param_list_t*p;
+    for(p=params;p;p=p->next) {
+        multiname_t*m = sig2mname(p->param->type);
+       list_append(state->m->method->parameters, m);
+    }
+
     /* state->vars is initialized by state_new */
     array_append(state->vars, "this", 0);
+    for(p=params;p;p=p->next) {
+        array_append(state->vars, p->param->name, 0);
+    }
 
     __ getlocal_0(state->m);
     __ pushscope(state->m);
@@ -720,7 +730,7 @@ CODEBLOCK :  CODEPIECE %prec below_semicolon {$$=$1;}
 
 /* ------------ functions --------------------------- */
 
-FUNCTION_DECLARATION: MODIFIERS "function" GETSET T_IDENTIFIER '(' PARAMS ')' 
+FUNCTION_DECLARATION: MODIFIERS "function" GETSET T_IDENTIFIER '(' MAYBE_PARAM_LIST ')' 
                       MAYBETYPE '{' {startfunction(0,$1,$3,$4,$6,$8)} MAYBECODE '}' {
     if(!state->m) syntaxerror("internal error: undefined function");
     state->initcode = abc_nop(state->initcode);
@@ -925,7 +935,7 @@ MAYBETYPE: ':' TYPE {$$=$2;}
 MAYBETYPE:          {$$=0;}
 
 //FUNCTION_HEADER:      NAMESPACE MODIFIERS T_FUNCTION GETSET T_IDENTIFIER '(' PARAMS ')' 
-FUNCTION_HEADER:      MODIFIERS "function" GETSET T_IDENTIFIER '(' PARAMS ')' 
+FUNCTION_HEADER:      MODIFIERS "function" GETSET T_IDENTIFIER '(' MAYBE_PARAM_LIST ')' 
                       MAYBETYPE
 
 NAMESPACE_DECLARATION : MODIFIERS KW_NAMESPACE T_IDENTIFIER
@@ -973,9 +983,7 @@ VOIDEXPRESSION : E %prec prec_none {$$=$1.c;/*calculate and discard*/$$=abc_pop(
 
 E : CONSTANT
 E : VAR_READ %prec T_IDENTIFIER {$$ = $1;}
-E : NEW                         {$$.c = abc_pushundefined(0); /* FIXME */
-                                 $$.t = TYPE_ANY;
-                                }
+E : NEW                         {$$ = $1;}
 E : T_REGEXP                    {$$.c = abc_pushundefined(0); /* FIXME */
                                  $$.t = TYPE_ANY;
                                 }
@@ -1002,6 +1010,30 @@ E : E "!=" E {$$.c = code_append($1.c,$3.c);$$.c = abc_equals($$.c);$$.c = abc_n
               $$.t = TYPE_BOOLEAN;
              }
 
+E : E "||" E {$$.c = $1.c;
+              $$.c=abc_dup($$.c);
+              code_t*jmp = $$.c = abc_iftrue($$.c, 0);
+              $$.c=abc_pop($$.c);
+              $$.c = code_append($$.c,$3.c);
+              code_t*label = $$.c = abc_label($$.c);
+              jmp->branch = label;
+              $$.t = join_types($1.t, $3.t, 'O');
+             }
+E : E "&&" E {$$.c = $1.c;
+              $$.c=abc_dup($$.c);
+              code_t*jmp = $$.c = abc_iffalse($$.c, 0);
+              $$.c=abc_pop($$.c);
+              $$.c = code_append($$.c,$3.c);
+              code_t*label = $$.c = abc_label($$.c);
+              jmp->branch = label;
+              $$.t = join_types($1.t, $3.t, 'A');
+             }
+
+E : '!' E    {$$.c=$2.c;
+              $$.c = abc_not($$.c);
+              $$.t = TYPE_BOOLEAN;
+             }
+
 E : E '-' E
 E : E '/' E
 E : E '+' E {$$.c = code_append($1.c,$3.c);$$.c = abc_add($$.c);$$.c=abc_coerce_a($$.c);
@@ -1054,39 +1086,55 @@ LH: T_IDENTIFIER {
   $$.write = abc_setlocal(0, i);
 }
 
-NEW : "new" T_IDENTIFIER                         {$$.c=0;$$.t=0;/*FIXME*/}
-    | "new" T_IDENTIFIER '(' ')'                 {$$.c=0;$$.t=0;/*FIXME*/}
-    | "new" T_IDENTIFIER '(' EXPRESSION_LIST ')' {$$.c=0;$$.t=0;/*FIXME*/}
+MAYBE_PARAM_VALUES :  %prec prec_none {$$=0;}
+MAYBE_PARAM_VALUES : '(' MAYBE_EXPRESSION_LIST ')' {$$=$2}
+
+NEW : "new" PACKAGEANDCLASS MAYBE_PARAM_VALUES {
+    MULTINAME(m, $2);
+    $$.c = code_new();
+    $$.c = abc_findpropstrict2($$.c, &m);
+    typedcode_list_t*l = $3;
+    int len = 0;
+    while(l) {
+        $$.c = code_append($$.c, l->typedcode->c); // push parameters on stack
+        l = l->next;
+        len ++;
+    }
+    $$.c = abc_constructprop2($$.c, &m, len);
+    $$.t = $2;
+}
 
 FUNCTIONCALL : T_IDENTIFIER '(' MAYBE_EXPRESSION_LIST ')' {
-        /* TODO: use abc_call (for calling local variables),
-                 abc_callstatic (for calling own methods) */
-        $$.c = code_new();
-        $$.c = abc_findpropstrict($$.c, $1->text);
-        typedcode_list_t*l = $3;
-        // push parameters on stack
-        int len = 0;
-        while(l) {
-            $$.c = code_append($$.c, l->typedcode.c);
-            l = l->nxt;
-            len ++;
-        }
-        $$.c = abc_callproperty($$.c, $1->text, len);
+    /* TODO: use abc_call (for calling local variables),
+             abc_callstatic (for calling own methods) */
+    $$.c = code_new();
+    $$.c = abc_findpropstrict($$.c, $1->text);
+    typedcode_list_t*l = $3;
+    int len = 0;
+    while(l) {
+        $$.c = code_append($$.c, l->typedcode->c); // push parameters on stack
+        l = l->next;
+        len ++;
+    }
+    $$.c = abc_callproperty($$.c, $1->text, len);
+    /* TODO: look up the functions's return value */
+    $$.t = TYPE_ANY;
 }
 
 MAYBE_EXPRESSION_LIST : {$$=0;}
 MAYBE_EXPRESSION_LIST : EXPRESSION_LIST
-EXPRESSION_LIST : EXPRESSION                     {$$=malloc(sizeof(typedcode_list_t));
-                                                  $$->nxt = 0;
-                                                  $$->typedcode = $1;}
-EXPRESSION_LIST : EXPRESSION_LIST ',' EXPRESSION {$$=malloc(sizeof(typedcode_list_t));
-                                                  $$->nxt = $1;
-                                                  $$->typedcode = $3;
-                                                 }
+EXPRESSION_LIST : EXPRESSION                     {$$=list_new();
+                                                  typedcode_t*t = malloc(sizeof(typedcode_t));
+                                                  *t = $1;
+                                                  list_append($$, t);}
+EXPRESSION_LIST : EXPRESSION_LIST ',' EXPRESSION {$$=$1;
+                                                  typedcode_t*t = malloc(sizeof(typedcode_t));
+                                                  *t = $3;
+                                                  list_append($$, t);}
 
 VAR_READ : T_IDENTIFIER {
-        int i = find_variable($1->text, &$$.t);
-        $$.c = abc_getlocal(0, i);
+    int i = find_variable($1->text, &$$.t);
+    $$.c = abc_getlocal(0, i);
 }
 
 //VARIABLE : T_IDENTIFIER
@@ -1103,11 +1151,14 @@ GETSET : "get" {$$=$1;}
        | "set" {$$=$1;}
        |       {$$=empty_token();}
 
-PARAMS: {$$=empty_token();}
-PARAMS: PARAM_LIST {$$=$1;}
-PARAM_LIST: PARAM_LIST ',' PARAM {extend($1,$3);$$=$1;}
-PARAM_LIST: PARAM                {$$=empty_token();extend($$,$1);}
-PARAM:  T_IDENTIFIER ':' TYPE {$$=$1;}
+MAYBE_PARAM_LIST: {$$=list_new();}
+MAYBE_PARAM_LIST: PARAM_LIST {$$=$1;}
+PARAM_LIST: PARAM_LIST ',' PARAM {$$ =$1;         list_append($$, $3);}
+PARAM_LIST: PARAM                {$$ = list_new();list_append($$, $1);}
+PARAM:  T_IDENTIFIER ':' TYPE {$$ = malloc(sizeof(param_t));
+                               $$->name=$1->text;$$->type = $3;}
+PARAM:  T_IDENTIFIER          {$$ = malloc(sizeof(param_t));
+                               $$->name=$1->text;$$->type = TYPE_ANY;}
 
 DECLARATION : VARIABLE_DECLARATION
 DECLARATION : FUNCTION_DECLARATION
@@ -1119,15 +1170,11 @@ IDECLARATION : FUNCTION_DECLARATION
 //IDENTIFIER_LIST : T_IDENTIFIER                     {$$=empty_token();extend($$,$1);}
 
 PACKAGEANDCLASS : T_IDENTIFIER {
+
+    /* try current package */
     $$ = registry_findclass(state->package, $1->text);
-    import_list_t*l = state->wildcard_imports;
-    while(l) {
-        if($$)
-            break;
-        //printf("does package %s contain a class %s?\n", l->import->package, $1->text);
-        $$ = registry_findclass(l->import->package, $1->text);
-        l = l->next;
-    }
+
+    /* try explicit imports */
     dictentry_t* e = dict_get_slot(state->imports, $1->text);
     while(e) {
         if($$)
@@ -1137,6 +1184,22 @@ PACKAGEANDCLASS : T_IDENTIFIER {
         }
         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->text);
+        $$ = registry_findclass(l->import->package, $1->text);
+        l = l->next;
+    }
+
+    /* try global package */
+    if(!$$) {
+        $$ = registry_findclass("", $1->text);
+    }
+
     if(!$$) syntaxerror("Could not find class %s\n", $1->text);
 }
 PACKAGEANDCLASS : PACKAGE '.' T_IDENTIFIER {