code_t*code;
typedcode_t value;
typedcode_list_t*value_list;
+ param_t* param;
+ param_list_t* param_list;
writeable_t writeable;
char*string;
}
%type <token> IMPORT
%type <class_signature> MAYBETYPE
%type <token> GETSET
-%type <token> PARAM
-%type <token> PARAMS
-%type <token> PARAM_LIST
+%type <param> PARAM
+%type <param_list> PARAM_LIST
+%type <param_list> MAYBE_PARAM_LIST
%type <token> MODIFIERS
%type <token> MODIFIER_LIST
%type <class_signature_list> IMPLEMENTS_LIST
%type <token> MODIFIER
%type <token> PACKAGE
%type <value> FUNCTIONCALL
-%type <value_list> MAYBE_EXPRESSION_LIST EXPRESSION_LIST
+%type <value_list> MAYBE_EXPRESSION_LIST EXPRESSION_LIST MAYBE_PARAM_VALUES
// precendence: from low to high
// http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000012.html
%left ';'
%nonassoc "else"
%left '('
-%left prec_highest
%{
old_state();
}
static void startfunction(token_t*ns, token_t*mod, token_t*getset, token_t*name,
- token_t*params, class_signature_t*type)
+ param_list_t*params, class_signature_t*type)
{
token_list_t*t;
new_state();
} else {
state->m = abc_class_method(state->cls, type2, name->text, 0);
}
+ param_list_t*p;
+ for(p=params;p;p=p->next) {
+ multiname_t*m = sig2mname(p->param->type);
+ list_append(state->m->method->parameters, m);
+ }
+
/* state->vars is initialized by state_new */
array_append(state->vars, "this", 0);
+ for(p=params;p;p=p->next) {
+ array_append(state->vars, p->param->name, 0);
+ }
__ getlocal_0(state->m);
__ pushscope(state->m);
/* ------------ functions --------------------------- */
-FUNCTION_DECLARATION: MODIFIERS "function" GETSET T_IDENTIFIER '(' PARAMS ')'
+FUNCTION_DECLARATION: MODIFIERS "function" GETSET T_IDENTIFIER '(' MAYBE_PARAM_LIST ')'
MAYBETYPE '{' {startfunction(0,$1,$3,$4,$6,$8)} MAYBECODE '}' {
if(!state->m) syntaxerror("internal error: undefined function");
state->initcode = abc_nop(state->initcode);
MAYBETYPE: {$$=0;}
//FUNCTION_HEADER: NAMESPACE MODIFIERS T_FUNCTION GETSET T_IDENTIFIER '(' PARAMS ')'
-FUNCTION_HEADER: MODIFIERS "function" GETSET T_IDENTIFIER '(' PARAMS ')'
+FUNCTION_HEADER: MODIFIERS "function" GETSET T_IDENTIFIER '(' MAYBE_PARAM_LIST ')'
MAYBETYPE
NAMESPACE_DECLARATION : MODIFIERS KW_NAMESPACE T_IDENTIFIER
E : CONSTANT
E : VAR_READ %prec T_IDENTIFIER {$$ = $1;}
-E : NEW {$$.c = abc_pushundefined(0); /* FIXME */
- $$.t = TYPE_ANY;
- }
+E : NEW {$$ = $1;}
E : T_REGEXP {$$.c = abc_pushundefined(0); /* FIXME */
$$.t = TYPE_ANY;
}
$$.t = TYPE_BOOLEAN;
}
+E : E "||" E {$$.c = $1.c;
+ $$.c=abc_dup($$.c);
+ code_t*jmp = $$.c = abc_iftrue($$.c, 0);
+ $$.c=abc_pop($$.c);
+ $$.c = code_append($$.c,$3.c);
+ code_t*label = $$.c = abc_label($$.c);
+ jmp->branch = label;
+ $$.t = join_types($1.t, $3.t, 'O');
+ }
+E : E "&&" E {$$.c = $1.c;
+ $$.c=abc_dup($$.c);
+ code_t*jmp = $$.c = abc_iffalse($$.c, 0);
+ $$.c=abc_pop($$.c);
+ $$.c = code_append($$.c,$3.c);
+ code_t*label = $$.c = abc_label($$.c);
+ jmp->branch = label;
+ $$.t = join_types($1.t, $3.t, 'A');
+ }
+
+E : '!' E {$$.c=$2.c;
+ $$.c = abc_not($$.c);
+ $$.t = TYPE_BOOLEAN;
+ }
+
E : E '-' E
E : E '/' E
E : E '+' E {$$.c = code_append($1.c,$3.c);$$.c = abc_add($$.c);$$.c=abc_coerce_a($$.c);
$$.write = abc_setlocal(0, i);
}
-NEW : "new" T_IDENTIFIER {$$.c=0;$$.t=0;/*FIXME*/}
- | "new" T_IDENTIFIER '(' ')' {$$.c=0;$$.t=0;/*FIXME*/}
- | "new" T_IDENTIFIER '(' EXPRESSION_LIST ')' {$$.c=0;$$.t=0;/*FIXME*/}
+MAYBE_PARAM_VALUES : %prec prec_none {$$=0;}
+MAYBE_PARAM_VALUES : '(' MAYBE_EXPRESSION_LIST ')' {$$=$2}
+
+NEW : "new" PACKAGEANDCLASS MAYBE_PARAM_VALUES {
+ MULTINAME(m, $2);
+ $$.c = code_new();
+ $$.c = abc_findpropstrict2($$.c, &m);
+ typedcode_list_t*l = $3;
+ int len = 0;
+ while(l) {
+ $$.c = code_append($$.c, l->typedcode->c); // push parameters on stack
+ l = l->next;
+ len ++;
+ }
+ $$.c = abc_constructprop2($$.c, &m, len);
+ $$.t = $2;
+}
FUNCTIONCALL : T_IDENTIFIER '(' MAYBE_EXPRESSION_LIST ')' {
- /* TODO: use abc_call (for calling local variables),
- abc_callstatic (for calling own methods) */
- $$.c = code_new();
- $$.c = abc_findpropstrict($$.c, $1->text);
- typedcode_list_t*l = $3;
- // push parameters on stack
- int len = 0;
- while(l) {
- $$.c = code_append($$.c, l->typedcode.c);
- l = l->nxt;
- len ++;
- }
- $$.c = abc_callproperty($$.c, $1->text, len);
+ /* TODO: use abc_call (for calling local variables),
+ abc_callstatic (for calling own methods) */
+ $$.c = code_new();
+ $$.c = abc_findpropstrict($$.c, $1->text);
+ typedcode_list_t*l = $3;
+ int len = 0;
+ while(l) {
+ $$.c = code_append($$.c, l->typedcode->c); // push parameters on stack
+ l = l->next;
+ len ++;
+ }
+ $$.c = abc_callproperty($$.c, $1->text, len);
+ /* TODO: look up the functions's return value */
+ $$.t = TYPE_ANY;
}
MAYBE_EXPRESSION_LIST : {$$=0;}
MAYBE_EXPRESSION_LIST : EXPRESSION_LIST
-EXPRESSION_LIST : EXPRESSION {$$=malloc(sizeof(typedcode_list_t));
- $$->nxt = 0;
- $$->typedcode = $1;}
-EXPRESSION_LIST : EXPRESSION_LIST ',' EXPRESSION {$$=malloc(sizeof(typedcode_list_t));
- $$->nxt = $1;
- $$->typedcode = $3;
- }
+EXPRESSION_LIST : EXPRESSION {$$=list_new();
+ typedcode_t*t = malloc(sizeof(typedcode_t));
+ *t = $1;
+ list_append($$, t);}
+EXPRESSION_LIST : EXPRESSION_LIST ',' EXPRESSION {$$=$1;
+ typedcode_t*t = malloc(sizeof(typedcode_t));
+ *t = $3;
+ list_append($$, t);}
VAR_READ : T_IDENTIFIER {
- int i = find_variable($1->text, &$$.t);
- $$.c = abc_getlocal(0, i);
+ int i = find_variable($1->text, &$$.t);
+ $$.c = abc_getlocal(0, i);
}
//VARIABLE : T_IDENTIFIER
| "set" {$$=$1;}
| {$$=empty_token();}
-PARAMS: {$$=empty_token();}
-PARAMS: PARAM_LIST {$$=$1;}
-PARAM_LIST: PARAM_LIST ',' PARAM {extend($1,$3);$$=$1;}
-PARAM_LIST: PARAM {$$=empty_token();extend($$,$1);}
-PARAM: T_IDENTIFIER ':' TYPE {$$=$1;}
+MAYBE_PARAM_LIST: {$$=list_new();}
+MAYBE_PARAM_LIST: PARAM_LIST {$$=$1;}
+PARAM_LIST: PARAM_LIST ',' PARAM {$$ =$1; list_append($$, $3);}
+PARAM_LIST: PARAM {$$ = list_new();list_append($$, $1);}
+PARAM: T_IDENTIFIER ':' TYPE {$$ = malloc(sizeof(param_t));
+ $$->name=$1->text;$$->type = $3;}
+PARAM: T_IDENTIFIER {$$ = malloc(sizeof(param_t));
+ $$->name=$1->text;$$->type = TYPE_ANY;}
DECLARATION : VARIABLE_DECLARATION
DECLARATION : FUNCTION_DECLARATION
//IDENTIFIER_LIST : T_IDENTIFIER {$$=empty_token();extend($$,$1);}
PACKAGEANDCLASS : T_IDENTIFIER {
+
+ /* try current package */
$$ = registry_findclass(state->package, $1->text);
- import_list_t*l = state->wildcard_imports;
- while(l) {
- if($$)
- break;
- //printf("does package %s contain a class %s?\n", l->import->package, $1->text);
- $$ = registry_findclass(l->import->package, $1->text);
- l = l->next;
- }
+
+ /* try explicit imports */
dictentry_t* e = dict_get_slot(state->imports, $1->text);
while(e) {
if($$)
}
e = e->next;
}
+
+ /* try package.* imports */
+ import_list_t*l = state->wildcard_imports;
+ while(l) {
+ if($$)
+ break;
+ //printf("does package %s contain a class %s?\n", l->import->package, $1->text);
+ $$ = registry_findclass(l->import->package, $1->text);
+ l = l->next;
+ }
+
+ /* try global package */
+ if(!$$) {
+ $$ = registry_findclass("", $1->text);
+ }
+
if(!$$) syntaxerror("Could not find class %s\n", $1->text);
}
PACKAGEANDCLASS : PACKAGE '.' T_IDENTIFIER {