From: kramm Date: Tue, 9 Dec 2008 13:40:09 +0000 (+0000) Subject: implemented if and else X-Git-Tag: release-0-9-0~716 X-Git-Url: http://git.asbjorn.it/?a=commitdiff_plain;h=0dcc87936907b5f1a80e74f9483e43f763e0cdc2;p=swftools.git implemented if and else --- diff --git a/lib/as3/parser.y b/lib/as3/parser.y index 6055295..353f12e 100644 --- a/lib/as3/parser.y +++ b/lib/as3/parser.y @@ -1,3 +1,25 @@ +/* parser.lex + + Routines for compiling Flash2 AVM2 ABC Actionscript + + Extension module for the rfxswf library. + Part of the swftools package. + + Copyright (c) 2008 Matthias Kramm + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ %{ #include #include @@ -24,11 +46,13 @@ double number_float; struct _code*code; struct _code_list*code_list; + struct _writeable writeable; + char*string; } %token T_IDENTIFIER -%token T_STRING +%token T_STRING %token T_REGEXP %token T_EMPTY %token T_INT @@ -62,17 +86,20 @@ %token KW_FINAL %token KW_GET "get" %token KW_EXTENDS -%token KW_FALSE "False" -%token KW_TRUE "True" +%token KW_FALSE "false" +%token KW_TRUE "true" %token KW_BOOLEAN "Boolean" %token KW_UINT "uint" %token KW_INT "int" %token KW_NUMBER "Number" %token KW_STRING "String" +%token KW_IF "if" +%token KW_ELSE "else" %token KW_IS "is" %token KW_AS "as" %token T_EQEQ "==" +%token T_NE "!=" %token T_LE "<=" %token T_GE ">=" %token T_DIVBY "/=" @@ -95,8 +122,9 @@ %token T_STAR '*' %token T_DOT '.' -%type CODE +%type CODE %type CODEPIECE CODEPIECE2 +%type CODEBLOCK MAYBECODE %type PACKAGE_DECLARATION %type FUNCTION_DECLARATION %type VARIABLE_DECLARATION @@ -106,10 +134,11 @@ %type EXPRESSION %type MAYBEEXPRESSION %type E +%type LH %type CONSTANT -%type FOR +%type FOR IF MAYBEELSE %type USE -%type ASSIGNMENT +%type ASSIGNMENT NEW_ASSIGNMENT SOME_ASSIGNMENT %type IMPORT %type MAYBETYPE %type PACKAGESPEC @@ -127,7 +156,7 @@ %type MULTILEVELIDENTIFIER %type TYPE %type VAR -%type VARIABLE +//%type VARIABLE %type VAR_READ %type NEW %type X_IDENTIFIER @@ -169,7 +198,10 @@ %nonassoc "as" %left '.' ".." "::" %nonassoc T_IDENTIFIER +%left ';' +%nonassoc "else" %left '(' +%left prec_highest %{ @@ -479,8 +511,12 @@ static int newvariable(token_t*mod, token_t*varconst, token_t*name, multiname_t* { token_list_t*t; printf("defining new variable %s\n", name->text); - printf(" mod: ");for(t=mod->tokens;t;t=t->next) printf("%s ", t->token->text);printf("\n"); - printf(" access: ");printf("%s\n", varconst->text); + if(mod) { + printf(" mod: ");for(t=mod->tokens;t;t=t->next) printf("%s ", t->token->text);printf("\n"); + } + if(varconst) { + printf(" access: ");printf("%s\n", varconst->text); + } printf(" type: ");printf("%s\n", multiname_tostring(type)); if(!state->vars) @@ -528,11 +564,11 @@ void extend_s(token_t*list, char*seperator, token_t*add) { PROGRAM: MAYBECODE -MAYBECODE: CODE -MAYBECODE: +MAYBECODE: CODE {$$=$1;} +MAYBECODE: {$$=code_new();} CODE: CODE CODEPIECE2 {$$=$1;} -CODE: CODEPIECE2 {$$=empty_token();} +CODE: CODEPIECE2 {$$=code_new();} CODEPIECE2: CODEPIECE { if(state->m) { @@ -540,7 +576,7 @@ CODEPIECE2: CODEPIECE { } } -CODEPIECE: ';' {/*TODO*/$$=code_new();} +CODEPIECE: ';' {$$=code_new();} CODEPIECE: VARIABLE_DECLARATION {$$=$1} CODEPIECE: PACKAGE_DECLARATION {/*TODO*/$$=code_new();} CODEPIECE: IMPORT {/*TODO*/$$=code_new();} @@ -549,10 +585,14 @@ CODEPIECE: CLASS_DECLARATION {/*TODO*/$$=code_new();} CODEPIECE: INTERFACE_DECLARATION {/*TODO*/$$=code_new();} CODEPIECE: FUNCTION_DECLARATION {/*TODO*/$$=code_new();} CODEPIECE: EXPRESSION {/*calculate and discard*/$$=$1;$$=abc_pop($$);} -CODEPIECE: FOR {/*TODO*/$$=code_new();} +CODEPIECE: FOR {$$=$1} +CODEPIECE: IF {$$=$1} CODEPIECE: USE {/*TODO*/$$=code_new();} CODEPIECE: ASSIGNMENT {/*TODO*/$$=code_new();} +CODEBLOCK : '{' MAYBECODE '}' {$$=$2;} +CODEBLOCK : CODEPIECE {$$=$1;} + PACKAGE_DECLARATION : "package" MULTILEVELIDENTIFIER '{' {startpackage($2)} MAYBECODE '}' {endpackage()} PACKAGE_DECLARATION : "package" '{' {startpackage(0)} MAYBECODE '}' {endpackage()} @@ -582,12 +622,12 @@ NAMESPACE_DECLARATION : MODIFIERS KW_NAMESPACE T_IDENTIFIER '=' T_STRING //NAMESPACE : {$$=empty_token();} //NAMESPACE : T_IDENTIFIER {$$=$1}; -CONSTANT : T_BYTE {$$ = abc_pushbyte(0, $1);} +CONSTANT : T_BYTE {$$ = abc_pushbyte(0, $1);$$=abc_coerce2($$,registry_getnumberclass());} CONSTANT : T_SHORT {$$ = abc_pushshort(0, $1);} CONSTANT : T_INT {$$ = abc_pushint(0, $1);} CONSTANT : T_UINT {$$ = abc_pushuint(0, $1);} CONSTANT : T_FLOAT {$$ = abc_pushdouble(0, $1);} -CONSTANT : T_STRING {$$ = abc_pushstring(0, $1->text);} +CONSTANT : T_STRING {$$ = abc_pushstring(0, $1);} CONSTANT : KW_TRUE {$$ = abc_pushtrue(0);} CONSTANT : KW_FALSE {$$ = abc_pushfalse(0);} CONSTANT : KW_NULL {$$ = abc_pushnull(0);} @@ -599,11 +639,57 @@ VAR : "const" | "var" VARIABLE_DECLARATION : MODIFIERS VAR T_IDENTIFIER MAYBETYPE MAYBEEXPRESSION { int i = newvariable($1,$2,$3,$4); - $$=code_new(); $$ = $5; $$ = abc_setlocal($$, i); } +NEW_ASSIGNMENT : "var" T_IDENTIFIER MAYBETYPE '=' EXPRESSION { + int i = newvariable(0,0,$2,$3); + $$ = $5; + $$ = abc_setlocal($$, i); +} +ASSIGNMENT : T_IDENTIFIER '=' EXPRESSION { + int i = array_find(state->vars, $1->text); + if(i<0) { + syntaxerror("Unknown variable '%s'", $1->text); + } + $$ = $3; + $$ = abc_setlocal($$, i); +} +SOME_ASSIGNMENT : ASSIGNMENT | NEW_ASSIGNMENT + +FOR : "for" '(' SOME_ASSIGNMENT ';' EXPRESSION ';' EXPRESSION ')' '{' MAYBECODE '}' { + $$ = $3; + code_t*loopstart = $$ = abc_label($$); + $$ = code_append($$, $5); + code_t*myif = $$ = abc_iffalse($$, 0); + $$ = code_append($$, $10); + $$ = code_append($$, $7);$$=abc_pop($$); + $$ = abc_jump($$, loopstart); + $$ = abc_label($$); + myif->branch = $$; +} +MAYBEELSE: %prec prec_none {$$ = code_new();} +MAYBEELSE: "else" CODEBLOCK {$$=$2;} +MAYBEELSE: ';' "else" CODEBLOCK {$$=$3;} + +IF : "if" '(' EXPRESSION ')' CODEBLOCK MAYBEELSE { + $$=$3; + code_t*myjmp,*myif = $$ = abc_iffalse($$, 0); + $$ = code_append($$, $5); + if($6) { + myjmp = $$ = abc_jump($$, 0); + } + myif->branch = $$ = abc_label($$); + if($6) { + $$ = code_append($$, $6); + myjmp->branch = $$ = abc_label($$); + } +} + +USE : "use" KW_NAMESPACE T_IDENTIFIER + + MAYBEEXPRESSION : '=' EXPRESSION {$$=$2;} | {$$=code_new();} @@ -614,23 +700,33 @@ E : VAR_READ %prec T_IDENTIFIER {$$ = $1;} E : NEW {$$ = abc_pushundefined(0); /* FIXME */} E : T_REGEXP {$$ = abc_pushundefined(0); /* FIXME */} E : FUNCTIONCALL -E : E '<' E -E : E '>' E -E : E "<=" E -E : E ">=" E -E : E "==" E -E : E '+' E +E : E '<' E {$$ = code_append($1,$3);$$ = abc_greaterequals($$);$$=abc_not($$);} +E : E '>' E {$$ = code_append($1,$3);$$ = abc_greaterthan($$);} +E : E "<=" E {$$ = code_append($1,$3);$$ = abc_greaterthan($$);$$=abc_not($$);} +E : E ">=" E {$$ = code_append($1,$3);$$ = abc_greaterequals($$);} +E : E "==" E {$$ = code_append($1,$3);$$ = abc_equals($$);} +E : E "!=" E {$$ = code_append($1,$3);$$ = abc_equals($$);$$ = abc_not($$);} +E : E '+' E {$$ = code_append($1,$3);$$ = abc_add($$);} E : E '-' E E : E '/' E E : E '%' E E : E '*' E -E : E "++" -E : E "--" E : E "as" TYPE E : E "is" TYPE E : '(' E ')' {$$=$2;} E : '-' E {$$=$2;} +// TODO: use inclocal where appropriate +E : LH "++" {$$ = $1.read;$$=abc_increment($$);$$=abc_dup($$);$$=code_append($$,$1.write);} +E : LH "--" {$$ = $1.read;$$=abc_decrement($$);$$=abc_dup($$);$$=code_append($$,$1.write);} + +LH: T_IDENTIFIER { + int i = array_find(state->vars, $1->text); + if(i<0) syntaxerror("unknown variable '%s'", $1->text); + $$.read = abc_getlocal(0, i); + $$.write = abc_setlocal(0, i); +} + NEW : "new" T_IDENTIFIER | "new" T_IDENTIFIER '(' ')' | "new" T_IDENTIFIER '(' EXPRESSION_LIST ')' @@ -657,23 +753,16 @@ EXPRESSION_LIST : EXPRESSION_LIST ',' EXPRESSION {list_append($$,$3);} VAR_READ : T_IDENTIFIER { int i = array_find(state->vars, $1->text); if(i<0) - syntaxerror("unknown variable"); + syntaxerror("unknown variable '%s'", $1->text); $$ = abc_getlocal(0, i); } -VARIABLE : T_IDENTIFIER -VARIABLE : VARIABLE '.' T_IDENTIFIER -VARIABLE : VARIABLE ".." T_IDENTIFIER // descendants -VARIABLE : VARIABLE "::" VARIABLE // namespace declaration -VARIABLE : VARIABLE "::" '[' EXPRESSION ']' // qualified expression -VARIABLE : VARIABLE '[' EXPRESSION ']' // unqualified expression -ASSIGNMENT : VARIABLE '=' EXPRESSION -NEW_ASSIGNMENT : "var" VARIABLE MAYBETYPE '=' EXPRESSION - -FOR : "for" '(' NEW_ASSIGNMENT ';' EXPRESSION ';' EXPRESSION ')' '{' MAYBECODE '}' -FOR : "for" '(' ASSIGNMENT ';' EXPRESSION ';' EXPRESSION ')' '{' MAYBECODE '}' - -USE : "use" KW_NAMESPACE T_IDENTIFIER +//VARIABLE : T_IDENTIFIER +//VARIABLE : VARIABLE '.' T_IDENTIFIER +//VARIABLE : VARIABLE ".." T_IDENTIFIER // descendants +//VARIABLE : VARIABLE "::" VARIABLE // namespace declaration +//VARIABLE : VARIABLE "::" '[' EXPRESSION ']' // qualified expression +//VARIABLE : VARIABLE '[' EXPRESSION ']' // unqualified expression // keywords which also may be identifiers X_IDENTIFIER : T_IDENTIFIER | KW_PACKAGE