X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fas3%2Fparser.y;h=d2188ef3adca462869ab324366483baa6c335e20;hb=21e0e9dfeec2455715d31b5ed3994209c5ac48a8;hp=e643572fbdbd40d3f97181b597f8fa3ced02a63a;hpb=8b2821e0ab6177c6de89865ba00c319ba40fc6c0;p=swftools.git diff --git a/lib/as3/parser.y b/lib/as3/parser.y index e643572..d2188ef 100644 --- a/lib/as3/parser.y +++ b/lib/as3/parser.y @@ -58,6 +58,8 @@ char*id; constant_t*constant; for_start_t for_start; + abc_exception_t *exception; + abc_exception_list_t *exception_list; } @@ -76,16 +78,16 @@ %token T_DO "do" %token T_SWITCH "switch" -%token KW_IMPLEMENTS +%token KW_IMPLEMENTS "implements" %token KW_NAMESPACE "namespace" %token KW_PACKAGE "package" -%token KW_PROTECTED -%token KW_PUBLIC -%token KW_PRIVATE +%token KW_PROTECTED "protected" +%token KW_PUBLIC "public" +%token KW_PRIVATE "private" %token KW_USE "use" -%token KW_INTERNAL +%token KW_INTERNAL "internal" %token KW_NEW "new" -%token KW_NATIVE +%token KW_NATIVE "native" %token KW_FUNCTION "function" %token KW_UNDEFINED "undefined" %token KW_CONTINUE "continue" @@ -95,7 +97,9 @@ %token KW_CASE "case" %token KW_SET "set" %token KW_VOID "void" -%token KW_STATIC +%token KW_THROW "throw" +%token KW_STATIC "static" +%token KW_WITH "with" %token KW_INSTANCEOF "instanceof" %token KW_IMPORT "import" %token KW_RETURN "return" @@ -104,13 +108,13 @@ %token KW_NULL "null" %token KW_VAR "var" %token KW_DYNAMIC "dynamic" -%token KW_OVERRIDE -%token KW_FINAL +%token KW_OVERRIDE "override" +%token KW_FINAL "final" %token KW_EACH "each" %token KW_GET "get" %token KW_TRY "try" %token KW_SUPER "super" -%token KW_EXTENDS +%token KW_EXTENDS "extends" %token KW_FALSE "false" %token KW_TRUE "true" %token KW_BOOLEAN "Boolean" @@ -157,10 +161,12 @@ %type VARCONST %type CODE %type CODEPIECE CODE_STATEMENT -%type CODEBLOCK MAYBECODE MAYBE_CASE_LIST CASE_LIST DEFAULT CASE SWITCH +%type CODEBLOCK MAYBECODE MAYBE_CASE_LIST CASE_LIST DEFAULT CASE SWITCH WITH %type PACKAGE_DECLARATION SLOT_DECLARATION %type FUNCTION_DECLARATION PACKAGE_INITCODE -%type VARIABLE_DECLARATION ONE_VARIABLE VARIABLE_LIST +%type VARIABLE_DECLARATION ONE_VARIABLE VARIABLE_LIST THROW +%type CATCH +%type CATCH_LIST %type CLASS_DECLARATION %type NAMESPACE_DECLARATION %type INTERFACE_DECLARATION @@ -169,7 +175,7 @@ %type MAYBEEXPRESSION %type E DELETE %type CONSTANT -%type FOR FOR_IN IF WHILE DO_WHILE MAYBEELSE BREAK RETURN CONTINUE +%type FOR FOR_IN IF WHILE DO_WHILE MAYBEELSE BREAK RETURN CONTINUE TRY %type USE_NAMESPACE %type FOR_INIT %type IMPORT @@ -289,6 +295,7 @@ typedef struct _methodstate { char is_constructor; char has_super; char is_global; + abc_exception_list_t*exceptions; } methodstate_t; typedef struct _state { @@ -302,6 +309,8 @@ typedef struct _state { classstate_t*cls; methodstate_t*method; + + char*exception_name; dict_t*vars; } state_t; @@ -957,11 +966,13 @@ static void endfunction(token_t*ns, int flags, enum yytokentype getset, char*nam } check_code_for_break(body); - if(f->body) + if(f->body) { f->body->code = body; - else //interface + f->body->exceptions = state->method->exceptions; + } else { //interface if(body) syntaxerror("interface methods can't have a method body"); + } free(state->method);state->method=0; old_state(); @@ -1316,18 +1327,17 @@ CODE_STATEMENT: WHILE CODE_STATEMENT: DO_WHILE CODE_STATEMENT: SWITCH CODE_STATEMENT: IF +CODE_STATEMENT: WITH +CODE_STATEMENT: TRY // code which may appear anywhere -//CODEPIECE: PACKAGE_DECLARATION -//CODEPIECE: CLASS_DECLARATION -//CODEPIECE: FUNCTION_DECLARATION -//CODEPIECE: INTERFACE_DECLARATION CODEPIECE: ';' {$$=0;} CODEPIECE: VARIABLE_DECLARATION CODEPIECE: CODE_STATEMENT CODEPIECE: BREAK CODEPIECE: CONTINUE CODEPIECE: RETURN +CODEPIECE: THROW CODEPIECE: NAMESPACE_DECLARATION {/*TODO*/$$=0;} CODEPIECE: USE_NAMESPACE {/*TODO*/$$=0;} @@ -1585,6 +1595,79 @@ SWITCH : T_SWITCH '(' {new_state();} E ')' '{' MAYBE_CASE_LIST '}' { old_state(); } +/* ------------ try / catch /finally ---------------- */ + +FINALLY: "finally" '{' CODE '}' +MAYBE_FINALLY: | FINALLY + +CATCH: "catch" '(' T_IDENTIFIER MAYBETYPE ')' {new_state();state->exception_name=$3;new_variable($3, $4, 0);} + '{' CODE '}' { + code_t*c = 0; + int i = find_variable_safe($3)->index; + c = abc_setlocal(c, i); + c = code_append(c, $8); + c = abc_kill(c, i); + + namespace_t name_ns = {ACCESS_PACKAGE, ""}; + multiname_t name = {QNAME, &name_ns, 0, $3}; + + NEW(abc_exception_t, e) + e->exc_type = sig2mname($4); + e->var_name = multiname_clone(&name); + e->target = code_start(c); + $$ = e; + old_state(); +} + +CATCH_LIST: CATCH {$$=list_new();list_append($$,$1);} +CATCH_LIST: CATCH_LIST CATCH {$$=$1;list_append($$,$2);} + +TRY : "try" '{' CODE '}' CATCH_LIST MAYBE_FINALLY { + code_t*start = code_start($3); + $$=$3; + + code_t*out = abc_nop(0); + code_t*jmp = $$ = abc_jump($$, out); + + abc_exception_list_t*l = $5; + while(l) { + abc_exception_t*e = l->abc_exception; + e->from = start; + e->to = jmp; + $$ = code_append($$, e->target); + $$ = abc_jump($$, out); + l = l->next; + } + $$ = code_append($$, out); + jmp->branch = out; + + list_concat(state->method->exceptions, $5); +} + +/* ------------ throw ------------------------------- */ + +THROW : "throw" EXPRESSION { + $$=$2.c; + $$=abc_throw($$); +} +THROW : "throw" %prec prec_none { + if(!state->exception_name) + syntaxerror("re-throw only possible within a catch block"); + variable_t*v = find_variable(state->exception_name); + $$=code_new(); + $$=abc_getlocal($$, v->index); + $$=abc_throw($$); +} + +/* ------------ with -------------------------------- */ + +WITH : "with" '(' EXPRESSION ')' CODEBLOCK { + $$ = $3.c; + $$ = abc_pushscope($$); + $$ = code_append($$, $5); + $$ = abc_popscope($$); +} + /* ------------ packages and imports ---------------- */ X_IDENTIFIER: T_IDENTIFIER