X-Git-Url: http://git.asbjorn.it/?a=blobdiff_plain;f=lib%2Fas3%2Fparser.y;h=8c99eca25f0350f1e0e858b478c8ba21f797e772;hb=d9fc7aab1efc946d04f0e8cde52c88ffd4598943;hp=a0e58ddb8a6f08cac2d9fa587077370fa128268b;hpb=94b8b908c3a7c2143b45122060d5a646de218c73;p=swftools.git diff --git a/lib/as3/parser.y b/lib/as3/parser.y index a0e58dd..8c99eca 100644 --- a/lib/as3/parser.y +++ b/lib/as3/parser.y @@ -69,6 +69,11 @@ %token T_SHORT %token T_FLOAT +%token T_FOR "for" +%token T_WHILE "while" +%token T_DO "do" +%token T_SWITCH "switch" + %token KW_IMPLEMENTS %token KW_NAMESPACE "namespace" %token KW_PACKAGE "package" @@ -82,9 +87,10 @@ %token KW_FUNCTION "function" %token KW_UNDEFINED "undefined" %token KW_CONTINUE "continue" -%token KW_FOR "for" %token KW_CLASS "class" %token KW_CONST "const" +%token KW_CATCH "catch" +%token KW_CASE "case" %token KW_SET "set" %token KW_VOID "void" %token KW_STATIC @@ -99,6 +105,7 @@ %token KW_OVERRIDE %token KW_FINAL %token KW_GET "get" +%token KW_TRY "try" %token KW_SUPER "super" %token KW_EXTENDS %token KW_FALSE "false" @@ -106,16 +113,15 @@ %token KW_BOOLEAN "Boolean" %token KW_UINT "uint" %token KW_INT "int" -%token KW_WHILE "while" %token KW_NUMBER "Number" %token KW_STRING "String" +%token KW_DEFAULT "default" %token KW_DELETE "delete" %token KW_IF "if" %token KW_ELSE "else" %token KW_BREAK "break" %token KW_IS "is" %token KW_AS "as" -%token KW_DO "do" %token T_EQEQ "==" %token T_EQEQEQ "===" @@ -142,11 +148,11 @@ %token T_USHR ">>>" %token T_SHR ">>" -%type X_IDENTIFIER PACKAGE MAYBELABEL +%type X_IDENTIFIER PACKAGE %type VARCONST %type CODE %type CODEPIECE -%type CODEBLOCK MAYBECODE +%type CODEBLOCK MAYBECODE MAYBE_CASE_LIST CASE_LIST DEFAULT CASE SWITCH %type PACKAGE_DECLARATION %type FUNCTION_DECLARATION %type VARIABLE_DECLARATION ONE_VARIABLE VARIABLE_LIST @@ -183,7 +189,7 @@ //%type T_IDENTIFIER %type MODIFIER %type FUNCTIONCALL -%type MAYBE_EXPRESSION_LIST EXPRESSION_LIST MAYBE_PARAM_VALUES +%type MAYBE_EXPRESSION_LIST EXPRESSION_LIST MAYBE_PARAM_VALUES MAYBE_EXPRPAIR_LIST EXPRPAIR_LIST // precedence: from low to high @@ -209,6 +215,7 @@ %left '/' '*' '%' %left plusplus_prefix minusminus_prefix '~' '!' "void" "delete" "typeof" //FIXME: *unary* + - should be here, too %left "--" "++" +%nonassoc below_curly %left '[' ']' '{' "new" '.' ".." "::" %nonassoc T_IDENTIFIER %left below_else @@ -220,6 +227,7 @@ %nonassoc T_INT T_UINT T_BYTE T_SHORT T_FLOAT %nonassoc "false" "true" "null" "undefined" "super" + %{ @@ -944,19 +952,13 @@ code_t*converttype(code_t*c, classinfo_t*from, classinfo_t*to) return abc_coerce2(c, &m); } - if(TYPE_IS_NUMBER(from) && TYPE_IS_UINT(to)) { - return abc_coerce2(c, &m); - } - if(TYPE_IS_NUMBER(from) && TYPE_IS_INT(to)) { - return abc_coerce2(c, &m); - } - /* these are subject to overflow */ - if(TYPE_IS_INT(from) && TYPE_IS_UINT(to)) { - return abc_coerce2(c, &m); - } - if(TYPE_IS_UINT(from) && TYPE_IS_INT(to)) { + if((TYPE_IS_NUMBER(from) || TYPE_IS_UINT(from) || TYPE_IS_INT(from)) && + (TYPE_IS_NUMBER(to) || TYPE_IS_UINT(to) || TYPE_IS_INT(to))) { + // allow conversion between number types return abc_coerce2(c, &m); } + //printf("%s.%s\n", from.package, from.name); + //printf("%s.%s\n", to.package, to.name); classinfo_t*supertype = from; while(supertype) { @@ -967,7 +969,7 @@ code_t*converttype(code_t*c, classinfo_t*from, classinfo_t*to) int t=0; while(supertype->interfaces[t]) { if(supertype->interfaces[t]==to) { - // to type is one of from's interfaces + // target type is one of from's interfaces return abc_coerce2(c, &m); } t++; @@ -1195,10 +1197,14 @@ static code_t* toreadwrite(code_t*in, code_t*middlepart, char justassign, char r /* ------------ code blocks / statements ---------------- */ -PROGRAM: MAYBECODE +PROGRAM: MAYBECODE { + /* todo: do something with this code if we're outside a function */ + if($1) + warning("ignored code"); +} -MAYBECODE: CODE {$$=$1;/*TODO: do something with this code if we're not in a function*/} -MAYBECODE: {$$=code_new();} +MAYBECODE: CODE {$$=$1;} +MAYBECODE: {$$=code_new();} CODE: CODE CODEPIECE { $$=code_append($1,$2); @@ -1218,6 +1224,7 @@ CODEPIECE: VOIDEXPRESSION {$$=$1} CODEPIECE: FOR {$$=$1} CODEPIECE: WHILE {$$=$1} CODEPIECE: DO_WHILE {$$=$1} +CODEPIECE: SWITCH {$$=$1} CODEPIECE: BREAK {$$=$1} CODEPIECE: CONTINUE {$$=$1} CODEPIECE: RETURN {$$=$1} @@ -1225,7 +1232,8 @@ CODEPIECE: IF {$$=$1} CODEPIECE: NAMESPACE_DECLARATION {/*TODO*/$$=code_new();} CODEPIECE: USE_NAMESPACE {/*TODO*/$$=code_new();} -CODEBLOCK : '{' MAYBECODE '}' {$$=$2;} +CODEBLOCK : '{' CODE '}' {$$=$2;} +CODEBLOCK : '{' '}' {$$=0;} CODEBLOCK : CODEPIECE ';' {$$=$1;} CODEBLOCK : CODEPIECE %prec below_semicolon {$$=$1;} @@ -1294,7 +1302,7 @@ MAYBEELSE: %prec below_else {$$ = code_new();} MAYBEELSE: "else" CODEBLOCK {$$=$2;} //MAYBEELSE: ';' "else" CODEBLOCK {$$=$3;} -IF : "if" '(' {new_state();} EXPRESSION ')' CODEBLOCK MAYBEELSE { +IF : "if" '(' {new_state();} EXPRESSION ')' CODEBLOCK MAYBEELSE { $$ = code_new(); $$ = code_append($$, $4.c); code_t*myjmp,*myif = $$ = abc_iffalse($$, 0); @@ -1312,22 +1320,19 @@ IF : "if" '(' {new_state();} EXPRESSION ')' CODEBLOCK MAYBEELSE { $$ = killvars($$);old_state(); } -MAYBELABEL : T_IDENTIFIER ':' {$$=$1;} -MAYBELABEL : {$$="";} - FOR_INIT : {$$=code_new();} FOR_INIT : VARIABLE_DECLARATION FOR_INIT : VOIDEXPRESSION -FOR : MAYBELABEL "for" '(' {new_state();} FOR_INIT ';' EXPRESSION ';' VOIDEXPRESSION ')' CODEBLOCK { +FOR : T_FOR '(' {new_state();} FOR_INIT ';' EXPRESSION ';' VOIDEXPRESSION ')' CODEBLOCK { $$ = code_new(); - $$ = code_append($$, $5); + $$ = code_append($$, $4); code_t*loopstart = $$ = abc_label($$); - $$ = code_append($$, $7.c); + $$ = code_append($$, $6.c); code_t*myif = $$ = abc_iffalse($$, 0); - $$ = code_append($$, $11); + $$ = code_append($$, $10); code_t*cont = $$ = abc_nop($$); - $$ = code_append($$, $9); + $$ = code_append($$, $8); $$ = abc_jump($$, loopstart); code_t*out = $$ = abc_nop($$); breakjumpsto($$, $1, out); @@ -1337,15 +1342,15 @@ FOR : MAYBELABEL "for" '(' {new_state();} FOR_INIT ';' EXPRESSION ';' VOIDEXPRES $$ = killvars($$);old_state(); } -WHILE : MAYBELABEL "while" '(' {new_state();} EXPRESSION ')' CODEBLOCK { +WHILE : T_WHILE '(' {new_state();} EXPRESSION ')' CODEBLOCK { $$ = code_new(); code_t*myjmp = $$ = abc_jump($$, 0); code_t*loopstart = $$ = abc_label($$); - $$ = code_append($$, $7); + $$ = code_append($$, $6); code_t*cont = $$ = abc_nop($$); myjmp->branch = cont; - $$ = code_append($$, $5.c); + $$ = code_append($$, $4.c); $$ = abc_iftrue($$, loopstart); code_t*out = $$ = abc_nop($$); breakjumpsto($$, $1, out); @@ -1355,12 +1360,12 @@ WHILE : MAYBELABEL "while" '(' {new_state();} EXPRESSION ')' CODEBLOCK { old_state(); } -DO_WHILE : MAYBELABEL "do" {new_state();} CODEBLOCK "while" '(' EXPRESSION ')' { +DO_WHILE : T_DO {new_state();} CODEBLOCK "while" '(' EXPRESSION ')' { $$ = code_new(); code_t*loopstart = $$ = abc_label($$); - $$ = code_append($$, $4); + $$ = code_append($$, $3); code_t*cont = $$ = abc_nop($$); - $$ = code_append($$, $7.c); + $$ = code_append($$, $6.c); $$ = abc_iftrue($$, loopstart); code_t*out = $$ = abc_nop($$); breakjumpsto($$, $1, out); @@ -1382,6 +1387,49 @@ CONTINUE : "continue" T_IDENTIFIER { $$ = abc___continue__(0, $2); } +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_LIST CASE {$$=code_append($$,$2);} + +CASE: "case" CONSTANT ':' MAYBECODE { + $$ = abc_dup(0); + $$ = code_append($$, $2.c); + code_t*j = $$ = abc_ifne($$, 0); + $$ = code_append($$, $4); + $$ = abc___continue__($$, ""); + code_t*e = $$ = abc_nop($$); + j->branch = e; +} +DEFAULT: "default" ':' MAYBECODE { + $$ = $3; +} +SWITCH : T_SWITCH '(' {new_state();} E ')' '{' MAYBE_CASE_LIST '}' { + $$=$4.c; + $$ = code_append($$, $7); + code_t*out = $$ = abc_pop($$); + breakjumpsto($$, $1, out); + + code_t*c = $$,*lastblock=0; + while(c) { + if(c->opcode == OPCODE_IFNE) { + lastblock=c->next; + } else if(c->opcode == OPCODE___CONTINUE__) { + if(lastblock) { + c->opcode = OPCODE_JUMP; + c->branch = lastblock; + } else { + /* fall through end of switch */ + c->opcode = OPCODE_NOP; + } + } + c=c->prev; + } + old_state(); +} + /* ------------ packages and imports ---------------- */ X_IDENTIFIER: T_IDENTIFIER @@ -1623,6 +1671,7 @@ QNAME_LIST : QNAME_LIST ',' QNAME {$$=$1;list_append($$,$3);} TYPE : QNAME {$$=$1;} | '*' {$$=registry_getanytype();} + | "void" {$$=registry_getanytype();} /* | "String" {$$=registry_getstringclass();} | "int" {$$=registry_getintclass();} @@ -2037,6 +2086,37 @@ E : '[' MAYBE_EXPRESSION_LIST ']' { $$.t = registry_getarrayclass(); } +MAYBE_EXPRPAIR_LIST : {$$=0;} +MAYBE_EXPRPAIR_LIST : EXPRPAIR_LIST {$$=$1}; + +EXPRPAIR_LIST : NONCOMMAEXPRESSION ':' NONCOMMAEXPRESSION { + typedcode_t*t1 = malloc(sizeof(typedcode_t));*t1 = $1; + typedcode_t*t2 = malloc(sizeof(typedcode_t));*t2 = $3; + $$ = 0; + list_append($$, t1); + list_append($$, t2); +} +EXPRPAIR_LIST : EXPRPAIR_LIST ',' NONCOMMAEXPRESSION ':' NONCOMMAEXPRESSION { + $$=$1; + typedcode_t*t1 = malloc(sizeof(typedcode_t));*t1 = $3; + typedcode_t*t2 = malloc(sizeof(typedcode_t));*t2 = $5; + list_append($$, t1); + list_append($$, t2); +} +//MAYBECOMMA: ',' +//MAYBECOMMA: + +E : '{' MAYBE_EXPRPAIR_LIST '}' { + $$.c = code_new(); + typedcode_list_t*l = 0; + int len = 0; + for(l=$2;l;l=l->next) { + $$.c = code_append($$.c, l->typedcode->c);len++; + } + $$.c = abc_newobject($$.c, len/2); + $$.t = registry_getobjectclass(); +} + E : E "*=" E { code_t*c = $3.c; if(BOTH_INT($1,$3)) {