#include "registry.h"
#include "code.h"
#include "opcodes.h"
+#include "compiler.h"
extern int a3_lex();
%type <classinfo_list> IMPLEMENTS_LIST
%type <classinfo> EXTENDS
%type <classinfo_list> EXTENDS_LIST
-%type <classinfo> CLASS PACKAGEANDCLASS QNAME
-%type <classinfo_list> QNAME_LIST
+%type <classinfo> CLASS PACKAGEANDCLASS CLASS_SPEC
+%type <classinfo_list> CLASS_SPEC_LIST
%type <classinfo> TYPE
//%type <token> VARIABLE
%type <value> VAR_READ
void initialize_file(char*filename)
{
+ if(state) {
+ syntaxerror("invalid call to initialize_file during parsing of another file");
+ }
new_state();
state->package = strdup(filename);
if(!state || state->level!=1) {
syntaxerror("unexpected end of file in pass %d", as3_pass);
}
- free(state->package);state->package=0;
+ free(state->method);state->method=0;
+
+ //free(state->package);state->package=0; // used in registry
+
state_destroy(state);state=0;
}
}
new_state();
state->cls = rfx_calloc(sizeof(classstate_t));
- state->method = rfx_calloc(sizeof(methodstate_t)); // method state, for static constructor
- state->method->variable_count = 1;
token_list_t*t=0;
classinfo_list_t*mlist=0;
char*package=0;
if(!(flags&FLAG_PUBLIC) && !state->package) {
- access = ACCESS_PRIVATE; package = current_filename;
+ access = ACCESS_PRIVATE; package = strdup(current_filename_short);
} else if(!(flags&FLAG_PUBLIC) && state->package) {
access = ACCESS_PACKAGEINTERNAL; package = state->package;
} else if(state->package) {
}
if(as3_pass==1) {
+ state->method = rfx_calloc(sizeof(methodstate_t)); // method state, for static constructor
+ state->method->variable_count = 1;
+ dict_put(global->token2info, (void*)(ptroff_t)as3_tokencount, state->method);
+
if(registry_findclass(package, classname)) {
syntaxerror("Package \"%s\" already contains a class called \"%s\"", package, classname);
}
}
if(as3_pass == 2) {
+ state->method = dict_lookup(global->token2info, (void*)(ptroff_t)as3_tokencount);
+
state->cls->info = registry_findclass(package, classname);
parserassert((int)state->cls->info);
/* try global package */
c = registry_findclass("", name);
if(c) return c;
-
+
/* try local "filename" package */
c = registry_findclass(current_filename_short, name);
if(c) return c;
[prefix code] ([dup]) [read instruction] [middlepart] [setvar] [write instruction] [getvar]
*/
-
if(in && in->opcode == OPCODE_COERCE_A) {
in = code_cutlast(in);
}
c = code_append(c, write);
c = code_append(c, r);
} else {
+ code_free(r);r=0;
temp = gettempvar();
if(prefix) {
c = code_append(c, prefix);
| FUNCTION_DECLARATION
| SLOT_DECLARATION
| PACKAGE_INITCODE
+ | T_IDENTIFIER "::" T_IDENTIFIER '{' PROGRAM_CODE_LIST '}' // conditional compilation
| ';'
MAYBE_INPACKAGE_CODE_LIST: | INPACKAGE_CODE_LIST
| FUNCTION_DECLARATION
| SLOT_DECLARATION
| PACKAGE_INITCODE
+ | T_IDENTIFIER "::" T_IDENTIFIER '{' INPACKAGE_CODE_LIST '}' // conditional compilation
| ';'
MAYBECODE: CODE {$$=$1;}
$$ = converttype($$, $3.t, $2);
$$ = abc_setlocal($$, index);
} else {
+ code_free($3.c);
$$ = defaultvalue(0, $2);
$$ = abc_setlocal($$, index);
}
$$ = abc_coerce_a($$);
$$ = abc_setlocal($$, index);
} else {
+ code_free($3.c);
$$ = code_new();
}
}
PACKAGE_DECLARATION : "package" '{' {PASS12 startpackage("");}
MAYBE_INPACKAGE_CODE_LIST '}' {PASS12 endpackage();$$=0;}
-IMPORT : "import" QNAME {
+IMPORT : "import" PACKAGEANDCLASS {
+ PASS1
+ if(!registry_findclass($2->package, $2->name)) {
+ as3_schedule_class($2->package, $2->name);
+ }
+
+ PASS2
classinfo_t*c = $2;
if(!c)
syntaxerror("Couldn't import class\n");
$$=0;
}
IMPORT : "import" PACKAGE '.' '*' {
+ PASS1
+ if(strncmp("flash.", $2, 6)) {
+ as3_schedule_package($2);
+ }
+
+ PASS2
NEW(import_t,i);
i->package = $2;
state_has_imports();
| KW_INTERNAL {PASS12 $$=FLAG_PACKAGEINTERNAL;}
EXTENDS : {$$=registry_getobjectclass();}
-EXTENDS : KW_EXTENDS QNAME {$$=$2;}
+EXTENDS : KW_EXTENDS CLASS_SPEC {$$=$2;}
EXTENDS_LIST : {PASS12 $$=list_new();}
-EXTENDS_LIST : KW_EXTENDS QNAME_LIST {PASS12 $$=$2;}
+EXTENDS_LIST : KW_EXTENDS CLASS_SPEC_LIST {PASS12 $$=$2;}
IMPLEMENTS_LIST : {PASS12 $$=list_new();}
-IMPLEMENTS_LIST : KW_IMPLEMENTS QNAME_LIST {PASS12 $$=$2;}
+IMPLEMENTS_LIST : KW_IMPLEMENTS CLASS_SPEC_LIST {PASS12 $$=$2;}
CLASS_DECLARATION : MAYBE_MODIFIERS "class" T_IDENTIFIER
EXTENDS IMPLEMENTS_LIST
STATICCONSTANT : T_INT {$$ = constant_new_int($1);}
STATICCONSTANT : T_UINT {$$ = constant_new_uint($1);}
STATICCONSTANT : T_FLOAT {$$ = constant_new_float($1);}
-STATICCONSTANT : T_STRING {$$ = constant_new_string2($1.str,$1.len);}
+STATICCONSTANT : T_STRING {$$ = constant_new_string2($1.str,$1.len);free((char*)$1.str);}
//STATICCONSTANT : T_NAMESPACE {$$ = constant_new_namespace($1);}
STATICCONSTANT : "true" {$$ = constant_new_true($1);}
STATICCONSTANT : "false" {$$ = constant_new_false($1);}
}
PACKAGEANDCLASS : PACKAGE '.' T_IDENTIFIER {
- PASS1 $$=0;
+ PASS1 static classinfo_t c;
+ memset(&c, 0, sizeof(c));
+ c.package = $1;
+ c.name = $3;
+ $$=&c;
PASS2
$$ = registry_findclass($1, $3);
if(!$$) syntaxerror("Couldn't find class %s.%s\n", $1, $3);
free($1);$1=0;
}
-QNAME: PACKAGEANDCLASS
- | CLASS
+CLASS_SPEC: PACKAGEANDCLASS
+ | CLASS
-QNAME_LIST : QNAME {PASS12 $$=list_new();list_append($$, $1);}
-QNAME_LIST : QNAME_LIST ',' QNAME {PASS12 $$=$1;list_append($$,$3);}
+CLASS_SPEC_LIST : CLASS_SPEC {PASS12 $$=list_new();list_append($$, $1);}
+CLASS_SPEC_LIST : CLASS_SPEC_LIST ',' CLASS_SPEC {PASS12 $$=$1;list_append($$,$3);}
-TYPE : QNAME {$$=$1;}
+TYPE : CLASS_SPEC {$$=$1;}
| '*' {$$=registry_getanytype();}
| "void" {$$=registry_getanytype();}
/*
CONSTANT : T_FLOAT {$$.c = abc_pushdouble(0, $1);
$$.t = TYPE_FLOAT;
}
-CONSTANT : T_STRING {$$.c = abc_pushstring2(0, &$1);
+CONSTANT : T_STRING {$$.c = abc_pushstring2(0, &$1);free((char*)$1.str);
$$.t = TYPE_STRING;
}
CONSTANT : "undefined" {$$.c = abc_pushundefined(0);