%token<token> T_SHR ">>"
%type <for_start> FOR_START
-%type <id> X_IDENTIFIER PACKAGE FOR_IN_INIT
+%type <id> X_IDENTIFIER PACKAGE FOR_IN_INIT MAYBE_IDENTIFIER
%type <token> VARCONST
%type <code> CODE
%type <code> CODEPIECE CODE_STATEMENT
%type <value> MAYBEEXPRESSION
%type <value> E DELETE
%type <value> CONSTANT
-%type <code> FOR FOR_IN IF WHILE DO_WHILE MAYBEELSE BREAK RETURN CONTINUE TRY
+%type <code> FOR FOR_IN IF WHILE DO_WHILE MAYBEELSE BREAK RETURN CONTINUE TRY
+%type <value> INNERFUNCTION
%type <token> USE_NAMESPACE
%type <code> FOR_INIT
%type <code> IMPORT
// needed for "return" precedence:
%nonassoc T_STRING T_REGEXP
%nonassoc T_INT T_UINT T_BYTE T_SHORT T_FLOAT
-%nonassoc "false" "true" "null" "undefined" "super"
+%nonassoc "false" "true" "null" "undefined" "super" "function"
+%nonassoc above_function
state = state->old;
state_destroy(leaving);
}
-void initialize_state()
+
+void initialize_parser()
{
global = rfx_calloc(sizeof(global_t));
- new_state();
-
- state->package = current_filename;
-
global->file = abc_file_new();
global->file->flags &= ~ABCFILE_LAZY;
global->variable_count = 1;
-
- global->init = abc_initscript(global->file, 0);
+ global->init = abc_initscript(global->file);
code_t*c = global->init->method->body->code;
-
c = abc_getlocal_0(c);
c = abc_pushscope(c);
-
+ /*c = abc_findpropstrict(c, "[package]::trace");
+ c = abc_pushstring(c, "[entering global init function]");
+ c = abc_callpropvoid(c, "[package]::trace", 1);*/
+ global->init->method->body->code = c;
+}
+
+void initialize_file(char*filename)
+{
+ new_state();
+ state->package = filename;
+}
+void finish_file()
+{
+ if(!state || state->level!=1) {
+ syntaxerror("unexpected end of file");
+ }
+ state_destroy(state);state=0;
+}
+
+void* finish_parser()
+{
+ code_t*c = global->init->method->body->code;
+ /*c = abc_findpropstrict(c, "[package]::trace");
+ c = abc_pushstring(c, "[leaving global init function]");
+ c = abc_callpropvoid(c, "[package]::trace", 1);*/
+ c = abc_returnvoid(c);
+ global->init->method->body->code = c;
+ return global->file;
+}
+
+
+static void xx_scopetest()
+{
/* findpropstrict doesn't just return a scope object- it
also makes it "active" somehow. Push local_0 on the
scope stack and read it back with findpropstrict, it'll
c = abc_getlocal_3(c);
c = abc_kill(c, 3);
c = abc_iftrue(c,xx);*/
-
- c = abc_findpropstrict(c, "[package]::trace");
- c = abc_pushstring(c, "[entering global init function]");
- c = abc_callpropvoid(c, "[package]::trace", 1);
-
- global->init->method->body->code = c;
-}
-void* finalize_state()
-{
- if(state->level!=1) {
- syntaxerror("unexpected end of file");
- }
- abc_method_body_t*m = global->init->method->body;
- //__ popscope(m);
-
- __ findpropstrict(m, "[package]::trace");
- __ pushstring(m, "[leaving global init function]");
- __ callpropvoid(m, "[package]::trace", 1);
- __ returnvoid(m);
-
- state_destroy(state);state=0;
-
- return global->file;
}
old_state();
}
-char*globalclass=0;
+char*as3_globalclass=0;
static void startclass(int flags, char*classname, classinfo_t*extends, classinfo_list_t*implements, char interface)
{
if(state->cls) {
__ setslot(m, slotindex);
/* flash.display.MovieClip handling */
- if(!globalclass && (flags&FLAG_PUBLIC) && classinfo_equals(registry_getMovieClip(),extends)) {
+ if(!as3_globalclass && (flags&FLAG_PUBLIC) && classinfo_equals(registry_getMovieClip(),extends)) {
if(state->package && state->package[0]) {
- globalclass = concat3(state->package, ".", classname);
+ as3_globalclass = concat3(state->package, ".", classname);
} else {
- globalclass = strdup(classname);
+ as3_globalclass = strdup(classname);
}
}
multiname_destroy(extends2);
// code which also may appear outside a method
CODE_STATEMENT: IMPORT
-CODE_STATEMENT: VOIDEXPRESSION
CODE_STATEMENT: FOR
CODE_STATEMENT: FOR_IN
CODE_STATEMENT: WHILE
CODE_STATEMENT: IF
CODE_STATEMENT: WITH
CODE_STATEMENT: TRY
+CODE_STATEMENT: VOIDEXPRESSION
// code which may appear anywhere
CODEPIECE: ';' {$$=0;}
-CODEPIECE: VARIABLE_DECLARATION
CODEPIECE: CODE_STATEMENT
+CODEPIECE: VARIABLE_DECLARATION
CODEPIECE: BREAK
CODEPIECE: CONTINUE
CODEPIECE: RETURN
/* ------------ package init code ------------------- */
PACKAGE_INITCODE: CODE_STATEMENT {
- if($1) warning("code ignored");
+ if($1) as3_warning("code ignored");
}
/* ------------ variables --------------------------- */
FOR_INIT : {$$=code_new();}
FOR_INIT : VARIABLE_DECLARATION
FOR_INIT : VOIDEXPRESSION
+
+// TODO: why doesn't an %prec above_identifier resolve the r-r conflict here?
FOR_IN_INIT : "var" T_IDENTIFIER MAYBETYPE {
$$=$2;new_variable($2,$3,1);
}
/* ------------ classes and interfaces (header) -------------- */
-MAYBE_MODIFIERS : {$$=0;}
+MAYBE_MODIFIERS : %prec above_function {$$=0;}
MAYBE_MODIFIERS : MODIFIER_LIST {$$=$1}
MODIFIER_LIST : MODIFIER {$$=$1;}
MODIFIER_LIST : MODIFIER_LIST MODIFIER {$$=$1|$2;}
$$=0;
}
+MAYBE_IDENTIFIER: T_IDENTIFIER
+MAYBE_IDENTIFIER: {$$=0;}
+INNERFUNCTION: "function" MAYBE_IDENTIFIER '(' MAYBE_PARAM_LIST ')' MAYBETYPE '{' MAYBECODE '}'
+{
+ syntaxerror("nested functions not supported yet");
+}
+
+
/* ------------- package + class ids --------------- */
CLASS: T_IDENTIFIER {
// ----------------------- expression evaluation -------------------------------------
+E : INNERFUNCTION %prec prec_none {$$ = $1;}
//V : CONSTANT {$$ = 0;}
E : CONSTANT
//V : VAR_READ %prec T_IDENTIFIER {$$ = 0;}
/* unknown object, let the avm2 resolve it */
} else {
if(strcmp($1,"trace"))
- warning("Couldn't resolve '%s', doing late binding", $1);
+ as3_softwarning("Couldn't resolve '%s', doing late binding", $1);
state->method->late_binding = 1;
multiname_t m = {MULTINAME, 0, &nopackage_namespace_set, $1};