X-Git-Url: http://git.asbjorn.it/?a=blobdiff_plain;f=lib%2Fas3%2Fparser.y;h=7415c961ea3921b317a9237edcd21d99d71b3bcf;hb=631dcf0673b8eadb969dd418613002261953a456;hp=319bd8021b5df2fc88b254cfc9380aea1068cf2b;hpb=587e0f9b99afe95e4e758960074c594a81e323b0;p=swftools.git diff --git a/lib/as3/parser.y b/lib/as3/parser.y index 319bd80..7415c96 100644 --- a/lib/as3/parser.y +++ b/lib/as3/parser.y @@ -80,13 +80,16 @@ %token KW_NEW "new" %token KW_NATIVE %token KW_FUNCTION "function" +%token KW_UNDEFINED "undefined" %token KW_FOR "for" %token KW_CLASS "class" %token KW_CONST "const" %token KW_SET "set" +%token KW_VOID "void" %token KW_STATIC %token KW_IMPORT "import" %token KW_RETURN "return" +%token KW_TYPEOF "typeof" %token KW_INTERFACE "interface" %token KW_NULL "null" %token KW_VAR "var" @@ -113,6 +116,7 @@ %token T_EQEQ "==" %token T_EQEQEQ "===" %token T_NE "!=" +%token T_NEE "!==" %token T_LE "<=" %token T_GE ">=" %token T_DIVBY "/=" @@ -184,6 +188,7 @@ %left below_semicolon %left ';' %left ',' +%nonassoc below_assignment // for ?:, contrary to spec %right '=' "*=" "/=" "%=" "+=" "-=" "<<=" ">>=" ">>>=" "&=" "^=" "|=" %right '?' ':' %left "||" @@ -192,14 +197,14 @@ %nonassoc '^' %nonassoc '&' %nonassoc "==" "!=" "===" "!==" +%nonassoc "is" "as" %nonassoc "<=" '<' ">=" '>' "instanceof" // TODO: support "a < b < c" syntax? %left "<<" ">>" ">>>" %left below_minus %left '-' '+' %left '/' '*' '%' -%left plusplus_prefix minusminus_prefix '~' '!' "delete" "typeof" //FIXME: *unary* + - should be here, too +%left plusplus_prefix minusminus_prefix '~' '!' "void" "delete" "typeof" //FIXME: *unary* + - should be here, too %left "--" "++" -%nonassoc "is" "as" %left '[' ']' '{' "new" '.' ".." "::" %nonassoc T_IDENTIFIER %left below_else @@ -209,7 +214,7 @@ // needed for "return" precedence: %nonassoc T_STRING T_REGEXP %nonassoc T_INT T_UINT T_BYTE T_SHORT T_FLOAT -%nonassoc "false" "true" "null" +%nonassoc "false" "true" "null" "undefined" %{ @@ -1411,9 +1416,9 @@ 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_NAMESPACE {$$ = constant_new_namespace($1);} -STATICCONSTANT : KW_TRUE {$$ = constant_new_true($1);} -STATICCONSTANT : KW_FALSE {$$ = constant_new_false($1);} -STATICCONSTANT : KW_NULL {$$ = constant_new_null($1);} +STATICCONSTANT : "true" {$$ = constant_new_true($1);} +STATICCONSTANT : "false" {$$ = constant_new_false($1);} +STATICCONSTANT : "null" {$$ = constant_new_null($1);} /* ------------ classes and interfaces (body, functions) ------- */ @@ -1492,11 +1497,13 @@ QNAME_LIST : QNAME_LIST ',' QNAME {$$=$1;list_append($$,$3);} TYPE : QNAME {$$=$1;} | '*' {$$=registry_getanytype();} + /* | "String" {$$=registry_getstringclass();} | "int" {$$=registry_getintclass();} | "uint" {$$=registry_getuintclass();} | "Boolean" {$$=registry_getbooleanclass();} | "Number" {$$=registry_getnumberclass();} + */ MAYBETYPE: ':' TYPE {$$=$2;} MAYBETYPE: {$$=0;} @@ -1588,9 +1595,8 @@ FUNCTIONCALL : E '(' MAYBE_EXPRESSION_LIST ')' { memberinfo_t*f = 0; - if(TYPE_IS_FUNCTION($1.t) && - (f = registry_findmember($1.t, "call"))) { - $$.t = f->return_type; + if(TYPE_IS_FUNCTION($1.t) && $1.t->function) { + $$.t = $1.t->function->return_type; } else { $$.c = abc_coerce_a($$.c); $$.t = TYPE_ANY; @@ -1668,13 +1674,16 @@ CONSTANT : T_FLOAT {$$.c = abc_pushdouble(0, $1); CONSTANT : T_STRING {$$.c = abc_pushstring2(0, &$1); $$.t = TYPE_STRING; } -CONSTANT : KW_TRUE {$$.c = abc_pushtrue(0); +CONSTANT : "undefined" {$$.c = abc_pushundefined(0); + $$.t = TYPE_ANY; + } +CONSTANT : "true" {$$.c = abc_pushtrue(0); $$.t = TYPE_BOOLEAN; } -CONSTANT : KW_FALSE {$$.c = abc_pushfalse(0); +CONSTANT : "false" {$$.c = abc_pushfalse(0); $$.t = TYPE_BOOLEAN; } -CONSTANT : KW_NULL {$$.c = abc_pushnull(0); +CONSTANT : "null" {$$.c = abc_pushnull(0); $$.t = TYPE_NULL; } @@ -1696,6 +1705,9 @@ E : E "==" E {$$.c = code_append($1.c,$3.c);$$.c = abc_equals($$.c); } E : E "===" E {$$.c = code_append($1.c,$3.c);$$.c = abc_strictequals($$.c); $$.t = TYPE_BOOLEAN; + } +E : E "!==" E {$$.c = code_append($1.c,$3.c);$$.c = abc_strictequals($$.c);$$.c = abc_not($$.c); + $$.t = TYPE_BOOLEAN; } E : E "!=" E {$$.c = code_append($1.c,$3.c);$$.c = abc_equals($$.c);$$.c = abc_not($$.c); $$.t = TYPE_BOOLEAN; @@ -1745,6 +1757,11 @@ E : E '&' E {$$.c = code_append($1.c,$3.c); $$.t = TYPE_INT; } +E : E '^' E {$$.c = code_append($1.c,$3.c); + $$.c = abc_bitxor($$.c); + $$.t = TYPE_INT; + } + E : E '|' E {$$.c = code_append($1.c,$3.c); $$.c = abc_bitor($$.c); $$.t = TYPE_INT; @@ -1759,6 +1776,19 @@ E : E '-' E {$$.c = code_append($1.c,$3.c); $$.t = TYPE_NUMBER; } } +E : E ">>" E {$$.c = code_append($1.c,$3.c); + $$.c = abc_rshift($$.c); + $$.t = TYPE_INT; + } +E : E ">>>" E {$$.c = code_append($1.c,$3.c); + $$.c = abc_urshift($$.c); + $$.t = TYPE_INT; + } +E : E "<<" E {$$.c = code_append($1.c,$3.c); + $$.c = abc_lshift($$.c); + $$.t = TYPE_INT; + } + E : E '/' E {$$.c = code_append($1.c,$3.c); $$.c = abc_divide($$.c); $$.t = TYPE_NUMBER; @@ -1781,9 +1811,41 @@ E : E '*' E {$$.c = code_append($1.c,$3.c); } } -E : E "as" E -E : E "is" E -E : '(' E ')' {$$=$2;} +E : E "as" E {char use_astype=0; // flash player's astype works differently than astypelate + if(use_astype && TYPE_IS_CLASS($3.t)) { + MULTINAME(m,$3.t->cls); + $$.c = abc_astype2($1.c, &m); + $$.t = $3.t->cls; + } else { + $$.c = code_append($1.c, $3.c); + $$.c = abc_astypelate($$.c); + $$.t = TYPE_ANY; + } + } + +E : E "is" E {$$.c = code_append($1.c, $3.c); + $$.c = abc_istypelate($$.c); + $$.t = TYPE_BOOLEAN; + } + +E : "typeof" '(' E ')' { + $$.c = $3.c; + $$.c = abc_typeof($$.c); + $$.t = TYPE_STRING; + } + +E : "void" E { + $$.c = cut_last_push($2.c); + $$.c = abc_pushundefined($$.c); + $$.t = TYPE_ANY; + } + +E : "void" { $$.c = abc_pushundefined(0); + $$.t = TYPE_ANY; + } + +E : '(' EXPRESSION ')' {$$=$2;} //allow commas in here, too + E : '-' E { $$=$2; if(IS_INT($2)) { @@ -1815,6 +1877,7 @@ E : E "*=" E { $$.c = toreadwrite($1.c, c, 0, 0); $$.t = $1.t; } + E : E "%=" E { code_t*c = abc_modulo($3.c); c=converttype(c, join_types($1.t, $3.t, '%'), $1.t); @@ -1875,6 +1938,17 @@ E : E '=' E { code_t*c = 0; $$.t = $1.t; } +E : E '?' E ':' E %prec below_assignment { + $$.c = $1.c; + code_t*j1 = $$.c = abc_iffalse($$.c, 0); + $$.c = code_append($$.c, $3.c); + code_t*j2 = $$.c = abc_jump($$.c, 0); + $$.c = j1->branch = abc_label($$.c); + $$.c = code_append($$.c, $5.c); + $$.c = j2->branch = abc_label($$.c); + $$.t = join_types($3.t,$5.t,'?'); + } + // TODO: use inclocal where appropriate E : E "++" { code_t*c = 0; classinfo_t*type = $1.t; @@ -2038,7 +2112,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); + warning("Couldn't resolve '%s', doing late binding", $1); state->late_binding = 1; multiname_t m = {MULTINAME, 0, &nopackage_namespace_set, $1};