import_list_t*wildcard_imports;
dict_t*import_toplevel_packages;
dict_t*imports;
- namespace_list_t*active_namespaces;
- namespace_decl_list_t*new_namespaces;
+
char has_own_imports;
char new_vars; // e.g. transition between two functions
state = s;
state->level++;
state->has_own_imports = 0;
- state->new_namespaces = 0;
state->vars = dict_new();
state->old = oldstate;
state->new_vars = 0;
+
+ trie_remember(active_namespaces);
}
static void state_has_imports()
{
static void old_state()
{
+ trie_rollback(active_namespaces);
+
if(!state || !state->old)
syntaxerror("invalid nesting");
state_t*leaving = state;
state = state->old;
- namespace_decl_list_t*nl=leaving->new_namespaces;
- while(nl) {
- tokenizer_unregister_namespace(nl->namespace_decl->name);
- nl = nl->next;
- }
-
if(as3_pass>1 && leaving->method && leaving->method != state->method && !leaving->method->inner) {
free(leaving->method);
leaving->method=0;
if(state) {
syntaxerror("invalid call to initialize_file during parsing of another file");
}
+
+ active_namespaces = trie_new();
+
new_state();
state->package = internal_filename_package = strdup(filename);
if(mod->flags&(FLAG_PRIVATE|FLAG_PROTECTED|FLAG_PACKAGEINTERNAL))
syntaxerror("invalid combination of access levels and namespaces");
ns.access = ACCESS_NAMESPACE;
- ns.name = mod->ns;
+ state_t*s = state;
+ const char*url = (const char*)trie_lookup(active_namespaces, mod->ns);
+ if(!url) {
+ /* shouldn't happen- the tokenizer only reports something as a namespace
+ if it was already registered */
+ syntaxerror("unknown namespace: %s", mod->ns);
+ }
+ ns.name = url;
} else if(mod->flags&FLAG_PUBLIC) {
if(mod->flags&(FLAG_PRIVATE|FLAG_PROTECTED|FLAG_PACKAGEINTERNAL))
syntaxerror("invalid combination of access levels");
}
static slotinfo_t* find_class(const char*name);
+memberinfo_t* findmember_nsset(classinfo_t*cls, const char*name, char recurse)
+{
+ /* FIXME- we need to loop through namespaces here */
+ return registry_findmember(cls, "", name, recurse);
+}
+
static void function_initvars(methodstate_t*m, params_t*params, int flags, char var0)
{
if(var0) {
static void check_constant_against_type(classinfo_t*t, constant_t*c)
{
+ return;
#define xassert(b) if(!(b)) syntaxerror("Invalid default value %s for type '%s'", constant_tostring(c), t->name)
if(TYPE_IS_NUMBER(t)) {
xassert(c->type == CONSTANT_FLOAT
static abc_method_t* endfunction(modifiers_t*mod, enum yytokentype getset, char*name,
params_t*params, classinfo_t*return_type, code_t*body)
{
- int flags = mod?mod->flags:0;
-
if(as3_pass==1) {
// store inner methods in variables
function_initvars(state->method, 0, 0, 0);
} else if(state->method->is_constructor) {
f = abc_class_getconstructor(state->cls->abc, type2);
} else if(!state->method->is_global) {
- namespace_t mname_ns = {state->method->info->access, ""};
+ namespace_t mname_ns = modifiers2access(mod);
multiname_t mname = {QNAME, &mname_ns, 0, name};
- if(flags&FLAG_STATIC)
+ if(mod->flags&FLAG_STATIC)
f = abc_class_staticmethod(state->cls->abc, type2, &mname);
else
f = abc_class_method(state->cls->abc, type2, &mname);
//flash doesn't seem to allow us to access function slots
//state->method->info->slot = slot;
- if(flags&FLAG_OVERRIDE) f->trait->attributes |= TRAIT_ATTR_OVERRIDE;
+ if(mod && mod->flags&FLAG_OVERRIDE) f->trait->attributes |= TRAIT_ATTR_OVERRIDE;
if(getset == KW_GET) f->trait->kind = TRAIT_GETTER;
if(getset == KW_SET) f->trait->kind = TRAIT_SETTER;
if(params->varargs) f->flags |= METHOD_NEED_REST;
return 0;
}
-
#define IS_FINALLY_TARGET(op) \
((op) == OPCODE___CONTINUE__ || \
(op) == OPCODE___BREAK__ || \
X_IDENTIFIER: T_IDENTIFIER
| "package" {PASS12 $$="package";}
+ | T_NAMESPACE {PASS12 $$=$1;}
PACKAGE: PACKAGE '.' X_IDENTIFIER {PASS12 $$ = concat3($1,".",$3);free($1);$1=0;}
PACKAGE: X_IDENTIFIER {PASS12 $$=strdup($1);}
$$.ns=$1.ns?$1.ns:$2.ns;
}
-
MODIFIER : KW_PUBLIC {PASS12 $$.flags=FLAG_PUBLIC;$$.ns=0;}
| KW_PRIVATE {PASS12 $$.flags=FLAG_PRIVATE;$$.ns=0;}
| KW_PROTECTED {PASS12 $$.flags=FLAG_PROTECTED;$$.ns=0;}
/* ------------- package + class ids --------------- */
-CLASS: T_IDENTIFIER {
+CLASS: X_IDENTIFIER {
PASS1 NEW(unresolvedinfo_t,c);
memset(c, 0, sizeof(*c));
c->kind = INFOTYPE_UNRESOLVED;
$$ = (classinfo_t*)s;
}
-PACKAGEANDCLASS : PACKAGE '.' T_IDENTIFIER {
+PACKAGEANDCLASS : PACKAGE '.' X_IDENTIFIER {
PASS1 NEW(unresolvedinfo_t,c);
memset(c, 0, sizeof(*c));
c->kind = INFOTYPE_UNRESOLVED;
classinfo_t*t = state->cls->info->superclass;
if(!t) t = TYPE_OBJECT;
- memberinfo_t*f = registry_findmember_nsset(t, state->active_namespaces, $3, 1);
+ memberinfo_t*f = findmember_nsset(t, $3, 1);
MEMBER_MULTINAME(m, f, $3);
$$.c = 0;
if(t->subtype==INFOTYPE_UNRESOLVED) {
syntaxerror("syntaxerror: trying to resolve property '%s' on incomplete object '%s'", $3, t->name);
}
- memberinfo_t*f = registry_findmember_nsset(t, state->active_namespaces, $3, 1);
+ memberinfo_t*f = findmember_nsset(t, $3, 1);
char noslot = 0;
if(f && !is_static != !(f->flags&FLAG_STATIC))
noslot=1;
int i_am_static = (state->method && state->method->info)?(state->method->info->flags&FLAG_STATIC):FLAG_STATIC;
/* look at current class' members */
- if(state->cls && (f = registry_findmember_nsset(state->cls->info, state->active_namespaces, $1, 1)) &&
+ if(state->cls && (f = findmember_nsset(state->cls->info, $1, 1)) &&
(f->flags&FLAG_STATIC) >= i_am_static) {
// $1 is a function in this class
int var_is_static = (f->flags&FLAG_STATIC);
PASS12
NEW(namespace_decl_t,n);
n->name = $2;
- n->url = 0;
+ n->url = $2;
$$=n;
}
NAMESPACE_ID : "namespace" T_IDENTIFIER '=' T_IDENTIFIER {
}
NAMESPACE_DECLARATION : MAYBE_MODIFIERS NAMESPACE_ID {
PASS12
- list_append(state->new_namespaces, $2);
- tokenizer_register_namespace($2->name);
+ trie_put(active_namespaces, $2->name, (void*)$2->url);
+
+ namespace_t access = modifiers2access(&$1);
+ varinfo_t* var = varinfo_register_global(access.access, state->package, $2->name);
+ var->type = TYPE_NAMESPACE;
+ namespace_t ns;
+ ns.access = ACCESS_NAMESPACE;
+ ns.name = $2->url;
+ var->value = constant_new_namespace(&ns);
+
$$=0;
}
USE_NAMESPACE : "use" "namespace" CLASS_SPEC {
PASS12
- NEW(namespace_decl_t,n);
- n->name = $3->name;
- n->url = 0;
- /* FIXME: for pass2, we should now try to figure out what the URL of
- this thing is */
- list_append(state->new_namespaces, n);
- tokenizer_register_namespace($3->name);
+ char*url = 0;
+ trie_put(active_namespaces, $3->name, url);
$$=0;
}