From de60bed06d2292c1f0c8616ab76b1983970e6982 Mon Sep 17 00:00:00 2001 From: kramm Date: Fri, 2 Jan 2009 19:50:33 +0000 Subject: [PATCH] added do-while, break label, continue (label) --- lib/as3/parser.y | 80 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 61 insertions(+), 19 deletions(-) diff --git a/lib/as3/parser.y b/lib/as3/parser.y index 5a3ad79..c74b519 100644 --- a/lib/as3/parser.y +++ b/lib/as3/parser.y @@ -81,6 +81,7 @@ %token KW_NATIVE %token KW_FUNCTION "function" %token KW_UNDEFINED "undefined" +%token KW_CONTINUE "continue" %token KW_FOR "for" %token KW_CLASS "class" %token KW_CONST "const" @@ -114,6 +115,7 @@ %token KW_BREAK "break" %token KW_IS "is" %token KW_AS "as" +%token KW_DO "do" %token T_EQEQ "==" %token T_EQEQEQ "===" @@ -140,7 +142,7 @@ %token T_USHR ">>>" %token T_SHR ">>" -%type X_IDENTIFIER PACKAGE +%type X_IDENTIFIER PACKAGE MAYBELABEL %type VARCONST %type CODE %type CODEPIECE @@ -156,7 +158,7 @@ %type MAYBEEXPRESSION %type E DELETE %type CONSTANT -%type FOR IF WHILE MAYBEELSE BREAK RETURN +%type FOR IF WHILE DO_WHILE MAYBEELSE BREAK RETURN CONTINUE %type USE_NAMESPACE %type FOR_INIT %type IMPORT @@ -870,16 +872,24 @@ char is_subtype_of(classinfo_t*type, classinfo_t*supertype) return 1; // FIXME } -void breakjumpsto(code_t*c, code_t*jump) +void breakjumpsto(code_t*c, char*name, code_t*jump) { - while(c->prev) - c=c->prev; while(c) { if(c->opcode == OPCODE___BREAK__) { c->opcode = OPCODE_JUMP; c->branch = jump; } - c = c->next; + c=c->prev; + } +} +void continuejumpsto(code_t*c, char*name, code_t*jump) +{ + while(c) { + if(c->opcode == OPCODE___CONTINUE__) { + c->opcode = OPCODE_JUMP; + c->branch = jump; + } + c = c->prev; } } @@ -1176,7 +1186,9 @@ CODEPIECE: VARIABLE_DECLARATION {$$=$1} CODEPIECE: VOIDEXPRESSION {$$=$1} CODEPIECE: FOR {$$=$1} CODEPIECE: WHILE {$$=$1} +CODEPIECE: DO_WHILE {$$=$1} CODEPIECE: BREAK {$$=$1} +CODEPIECE: CONTINUE {$$=$1} CODEPIECE: RETURN {$$=$1} CODEPIECE: IF {$$=$1} CODEPIECE: NAMESPACE_DECLARATION {/*TODO*/$$=code_new();} @@ -1269,43 +1281,73 @@ 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 : "for" '(' {new_state();} FOR_INIT ';' EXPRESSION ';' VOIDEXPRESSION ')' CODEBLOCK { +FOR : MAYBELABEL "for" '(' {new_state();} FOR_INIT ';' EXPRESSION ';' VOIDEXPRESSION ')' CODEBLOCK { $$ = code_new(); - $$ = code_append($$, $4); + $$ = code_append($$, $5); code_t*loopstart = $$ = abc_label($$); - $$ = code_append($$, $6.c); + $$ = code_append($$, $7.c); code_t*myif = $$ = abc_iffalse($$, 0); - $$ = code_append($$, $10); - $$ = code_append($$, $8); + $$ = code_append($$, $11); + code_t*cont = $$ = abc_nop($$); + $$ = code_append($$, $9); $$ = abc_jump($$, loopstart); code_t*out = $$ = abc_nop($$); - breakjumpsto($$, out); + breakjumpsto($$, $1, out); + continuejumpsto($$, $1, cont); myif->branch = out; $$ = killvars($$);old_state(); } -WHILE : "while" '(' {new_state();} EXPRESSION ')' CODEBLOCK { +WHILE : MAYBELABEL "while" '(' {new_state();} EXPRESSION ')' CODEBLOCK { $$ = code_new(); code_t*myjmp = $$ = abc_jump($$, 0); code_t*loopstart = $$ = abc_label($$); - $$ = code_append($$, $6); + $$ = code_append($$, $7); myjmp->branch = $$ = abc_nop($$); - $$ = code_append($$, $4.c); + $$ = code_append($$, $5.c); $$ = abc_iftrue($$, loopstart); code_t*out = $$ = abc_nop($$); - breakjumpsto($$, out); + breakjumpsto($$, $1, out); + continuejumpsto($$, $1, loopstart); - $$ = killvars($$);old_state(); + $$ = killvars($$); + old_state(); } -BREAK : "break" { - $$ = abc___break__(0); +DO_WHILE : MAYBELABEL "do" {new_state();} CODEBLOCK "while" '(' EXPRESSION ')' { + $$ = code_new(); + code_t*loopstart = $$ = abc_label($$); + $$ = code_append($$, $4); + code_t*cont = $$ = abc_nop($$); + $$ = code_append($$, $7.c); + $$ = abc_iftrue($$, loopstart); + code_t*out = $$ = abc_nop($$); + breakjumpsto($$, $1, out); + continuejumpsto($$, $1, cont); + $$ = killvars($$); + old_state(); +} + +BREAK : "break" %prec prec_none { + $$ = abc___break__(0, ""); +} +BREAK : "break" T_IDENTIFIER { + $$ = abc___break__(0, $2); +} +CONTINUE : "continue" %prec prec_none { + $$ = abc___continue__(0, ""); +} +CONTINUE : "continue" T_IDENTIFIER { + $$ = abc___continue__(0, $2); } /* ------------ packages and imports ---------------- */ -- 1.7.10.4