diff --git a/moo/kernel/Class.moo b/moo/kernel/Class.moo index 3c5bde8..adbac7b 100644 --- a/moo/kernel/Class.moo +++ b/moo/kernel/Class.moo @@ -6,26 +6,15 @@ class(#pointer,#limited) Class(Apex) { var spec, selfspec, superclass, subclasses, name, modname. var instvars, classinstvars, classvars, pooldics. - var instmthdic, classmthdic, nsdic, cdic. + var instmthdic, classmthdic, nsup, nsdic, cdic. var trsize, initv, initv_ci. - method(#class) initialize - { - ^self. - } + method(#class) initialize { ^self } (* most of the following methods can actually become class methods of Apex. * if the instance varibles can be made accessible from the Apex class. *) - - method name - { - ^self.name - } - - method superclass - { - ^self.superclass - } + method name { ^self.name } + method superclass { ^self.superclass } method specNumInstVars { @@ -45,8 +34,6 @@ class(#pointer,#limited) Class(Apex) ^false }*) - method nsdic - { - ^self.nsdic - } + method nsup { ^self.nsup } + method nsdic { ^self.nsdic } } diff --git a/moo/kernel/Collect.moo b/moo/kernel/Collect.moo index 75a910c..fded7df 100644 --- a/moo/kernel/Collect.moo +++ b/moo/kernel/Collect.moo @@ -513,8 +513,23 @@ class Dictionary(Set) } } -class SystemDictionary(Set) +(* Namespace is marked with #limited. If a compiler is writeen in moo itself, it must + * call a primitive to instantiate a new namespace rather than sending the new message + * to Namespace *) +class(#limited) Namespace(Set) { + var name, nsup. + + method name { ^self.name } + ## method name: name { self.name := name } + + (* nsup points to either the class associated with this namespace or directly + * the upper namespace placed above this namespace. when it points to a class, + * you should inspect the nsup field of the class to reach the actual upper + * namespace *) + method nsup { ^self.nsup } + ## method nsup: nsup { self.nsup := nsup } + method at: key { if (key class ~= Symbol) { InvalidArgumentException signal: 'key is not a symbol' }. @@ -528,17 +543,12 @@ class SystemDictionary(Set) } } -class Namespace(Set) -{ -} - class PoolDictionary(Set) { } class MethodDictionary(Dictionary) { - } extend Apex diff --git a/moo/kernel/generr.moo b/moo/kernel/generr.moo index 9eb4990..e026137 100644 --- a/moo/kernel/generr.moo +++ b/moo/kernel/generr.moo @@ -94,6 +94,7 @@ class MyObject(Object) 'unusable variable in compiled code' 'inaccessible variable' 'ambiguous variable' + 'inaccessible self' 'wrong expression primary' 'too many temporaries' 'too many arguments' diff --git a/moo/lib/comp.c b/moo/lib/comp.c index ec7bee9..8c29e20 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -37,7 +37,7 @@ /* initial method dictionary size */ #define INSTANCE_METHOD_DICTIONARY_SIZE 256 /* TODO: choose the right size */ #define CLASS_METHOD_DICTIONARY_SIZE 128 /* TODO: choose the right size */ -#define NAMESPACE_SIZE 128 /* TODO: choose the right size */ +#define NAMESPACE_SIZE 128 /* TODO: choose the right size - moo->option.dfl_sysdic_size may be too big for non-toplevel namespaces */ #define POOL_DICTIONARY_SIZE_ALIGN 128 #define INVALID_IP MOO_TYPE_MAX(moo_oow_t) @@ -204,11 +204,12 @@ enum voca_id_t }; typedef enum voca_id_t voca_id_t; +static int compile_pooldic_definition (moo_t* moo, moo_pooldic_t* pd); static int compile_block_statement (moo_t* moo); static int compile_method_statement (moo_t* moo); static int compile_method_expression (moo_t* moo, int pop); static int add_literal (moo_t* moo, moo_oop_t lit, moo_oow_t* index); -static MOO_INLINE moo_oop_t token_to_literal (moo_t* moo, int rdonly); +static moo_oop_t token_to_literal (moo_t* moo, int rdonly); static MOO_INLINE int is_spacechar (moo_ooci_t c) { @@ -2621,15 +2622,15 @@ static int set_class_level_variable_initv (moo_t* moo, var_type_t var_type, moo_ return 0; } -static MOO_INLINE int add_pooldic_import (moo_t* moo, const moo_oocs_t* name, moo_oop_set_t pooldic_oop) +static MOO_INLINE int add_pooldic_import (moo_t* moo, const moo_oocs_t* name, moo_oop_dic_t pooldic_oop) { if (moo->c->cls.pooldic_imp.dcl_count >= moo->c->cls.pooldic_imp.oops_capa) { moo_oow_t new_capa; - moo_oop_set_t* tmp; + moo_oop_dic_t* tmp; new_capa = MOO_ALIGN(moo->c->cls.pooldic_imp.oops_capa + 1, POOLDIC_OOP_BUFFER_ALIGN); - tmp = moo_reallocmem (moo, moo->c->cls.pooldic_imp.oops, new_capa * MOO_SIZEOF(moo_oop_set_t)); + tmp = moo_reallocmem (moo, moo->c->cls.pooldic_imp.oops, new_capa * MOO_SIZEOF(moo_oop_dic_t)); if (!tmp) return -1; moo->c->cls.pooldic_imp.oops_capa = new_capa; @@ -2857,58 +2858,66 @@ static MOO_INLINE int find_temporary_variable (moo_t* moo, const moo_oocs_t* nam return find_word_in_string (&moo->c->mth.tmprs, name, xindex); } -static moo_oop_set_t add_namespace (moo_t* moo, moo_oop_set_t dic, const moo_oocs_t* name) +static moo_oop_nsdic_t add_namespace (moo_t* moo, moo_oop_nsdic_t dic, const moo_oocs_t* name) { + /* add a stand-alone namespace that doesn't belong to a class */ + moo_oow_t tmp_count = 0; - moo_oop_t sym; - moo_oop_set_t ns; + moo_oop_char_t sym; + moo_oop_nsdic_t nsdic; moo_oop_association_t ass; moo_pushtmp (moo, (moo_oop_t*)&dic); tmp_count++; - sym = moo_makesymbol (moo, name->ptr, name->len); + sym = (moo_oop_char_t)moo_makesymbol (moo, name->ptr, name->len); if (!sym) goto oops; - moo_pushtmp (moo, &sym); tmp_count++; + moo_pushtmp (moo, (moo_oop_t*)&sym); tmp_count++; - ns = moo_makedic (moo, moo->_namespace, NAMESPACE_SIZE); - if (!ns) goto oops; + nsdic = moo_makensdic (moo, moo->_namespace, NAMESPACE_SIZE); + if (!nsdic) goto oops; /*moo_pushtmp (moo, &ns); tmp_count++;*/ - - ass = moo_putatdic (moo, dic, sym, (moo_oop_t)ns); + ass = moo_putatdic (moo, (moo_oop_dic_t)dic, (moo_oop_t)sym, (moo_oop_t)nsdic); if (!ass) goto oops; + nsdic = (moo_oop_nsdic_t)ass->value; + nsdic->nsup = (moo_oop_t)dic; + nsdic->name = sym; + moo_poptmps (moo, tmp_count); - return (moo_oop_set_t)ass->value; + return nsdic; oops: moo_poptmps (moo, tmp_count); return MOO_NULL; } -static moo_oop_set_t add_nsdic_to_class (moo_t* moo, moo_oop_class_t c, const moo_oocs_t* name) +static moo_oop_nsdic_t attach_nsdic_to_class (moo_t* moo, moo_oop_class_t c, moo_oop_nsdic_t up/*, const moo_oocs_t* name*/) { moo_oow_t tmp_count = 0; - moo_oop_t sym; - moo_oop_set_t ns; + /*moo_oop_t sym;*/ + moo_oop_nsdic_t nsdic; moo_pushtmp (moo, (moo_oop_t*)&c); tmp_count++; + moo_pushtmp (moo, (moo_oop_t*)&up); tmp_count++; - sym = moo_makesymbol (moo, name->ptr, name->len); + /*sym = moo_makesymbol (moo, name->ptr, name->len); if (!sym) goto oops; - moo_pushtmp (moo, &sym); tmp_count++; + moo_pushtmp (moo, &sym); tmp_count++;*/ - ns = moo_makedic (moo, moo->_namespace, NAMESPACE_SIZE); - if (!ns) goto oops; + nsdic = moo_makensdic (moo, moo->_namespace, NAMESPACE_SIZE); + if (!nsdic) goto oops; /*moo_pushtmp (moo, &ns); tmp_count++;*/ - c->nsdic = ns; + nsdic->nsup = (moo_oop_t)c; /* it points to the owning class as it belongs to a class */ + nsdic->name = c->name; /* for convenience only */ + c->nsdic = nsdic; moo_poptmps (moo, tmp_count); - return ns; + return nsdic; oops: moo_poptmps (moo, tmp_count); @@ -2918,12 +2927,12 @@ oops: #define PDN_DONT_ADD_NS (1 << 0) #define PDN_ACCEPT_POOLDIC_AS_NS (1 << 1) -static int preprocess_dotted_name (moo_t* moo, int flags, moo_oop_set_t topdic, const moo_oocs_t* fqn, const moo_ioloc_t* fqn_loc, moo_oocs_t* name, moo_oop_set_t* ns_oop) +static int preprocess_dotted_name (moo_t* moo, int flags, moo_oop_nsdic_t topdic, const moo_oocs_t* fqn, const moo_ioloc_t* fqn_loc, moo_oocs_t* name, moo_oop_nsdic_t* ns_oop) { const moo_ooch_t* ptr, * dot; moo_oow_t len; moo_oocs_t seg; - moo_oop_set_t dic; + moo_oop_nsdic_t dic; moo_oop_association_t ass; int pooldic_gotten = 0; @@ -2944,15 +2953,13 @@ static int preprocess_dotted_name (moo_t* moo, int flags, moo_oop_set_t topdic, if (is_reserved_word(&seg)) goto wrong_name; - ass = moo_lookupdic (moo, dic, &seg); + ass = moo_lookupdic (moo, (moo_oop_dic_t)dic, &seg); if (ass) { - if (MOO_CLASSOF(moo, ass->value) == moo->_namespace || - (seg.ptr == fqn->ptr && ass->value == (moo_oop_t)moo->sysdic)) + if (MOO_CLASSOF(moo, ass->value) == moo->_namespace) { - /* ok - the current segment is a namespace name or - * it is the first segment and is System */ - dic = (moo_oop_set_t)ass->value; + /* ok - the current segment is a namespace name */ + dic = (moo_oop_nsdic_t)ass->value; } else if (MOO_CLASSOF(moo, ass->value) == moo->_class) { @@ -2960,42 +2967,39 @@ static int preprocess_dotted_name (moo_t* moo, int flags, moo_oop_set_t topdic, * class X {} * class X.Y {} * when processing X in X.Y, this part is reached. */ - dic = ((moo_oop_class_t)ass->value)->nsdic; - if ((moo_oop_t)dic == moo->_nil) - { - /* the nsdic field is still nil. no namespace dictionary - * has been attached to the class */ - moo_oop_set_t t; + moo_oop_nsdic_t t; + t = ((moo_oop_class_t)ass->value)->nsdic; + if ((moo_oop_t)t == moo->_nil) + { if (flags & PDN_DONT_ADD_NS) goto wrong_name; /* attach a new namespace dictionary to the nsdic field * of the class */ - t = add_nsdic_to_class (moo, (moo_oop_class_t)ass->value, &seg); + t = attach_nsdic_to_class (moo, (moo_oop_class_t)ass->value, dic); if (!t) return -1; dic = t; } + else dic = t; + } + else if ((flags & PDN_ACCEPT_POOLDIC_AS_NS) && MOO_CLASSOF(moo, ass->value) == moo->_pool_dictionary) + { + /* A pool dictionary is treated as if it's a name space. + * However, the pool dictionary can only act as a name space + * if it's the second last segment. A pool dictionary + * cannot be nested in another pool dictionary */ + dic = (moo_oop_nsdic_t)ass->value; + pooldic_gotten = 1; } else { - if ((flags & PDN_ACCEPT_POOLDIC_AS_NS) && MOO_CLASSOF(moo, ass->value) == moo->_pool_dictionary) - { - /* A pool dictionary is treated as if it's a name space. - * However, the pool dictionary can only act as a name space - * if it's the second last segment. */ - dic = (moo_oop_set_t)ass->value; - pooldic_gotten = 1; - } - else - { - goto wrong_name; - } + goto wrong_name; } } else { - moo_oop_set_t t; + moo_oop_nsdic_t t; /* the segment does not exist. add it */ if (flags & PDN_DONT_ADD_NS) @@ -3014,7 +3018,7 @@ static int preprocess_dotted_name (moo_t* moo, int flags, moo_oop_set_t topdic, } else { - /* this is the last segment. it should be a class name */ + /* this is the last segment. it should be a class name or an item name */ seg.len = len; if (is_reserved_word(&seg)) goto wrong_name; @@ -3038,10 +3042,11 @@ wrong_name: return -1; } +#if 0 static int resolve_pooldic (moo_t* moo, int dotted, const moo_oocs_t* name) { moo_oocs_t last; /* the last segment */ - moo_oop_set_t ns_oop; /* name space */ + moo_oop_nsdic_t ns_oop; /* name space */ moo_oop_association_t ass; moo_oow_t i; @@ -3057,7 +3062,7 @@ static int resolve_pooldic (moo_t* moo, int dotted, const moo_oocs_t* name) } /* check if the name refers to a pool dictionary */ - ass = moo_lookupdic (moo, ns_oop, &last); + ass = moo_lookupdic (moo, (moo_oop_dic_t)ns_oop, &last); if (!ass || MOO_CLASSOF(moo, ass->value) != moo->_pool_dictionary) { set_syntax_error (moo, MOO_SYNERR_POOLDICINVAL, TOKEN_LOC(moo), name); @@ -3067,7 +3072,7 @@ static int resolve_pooldic (moo_t* moo, int dotted, const moo_oocs_t* name) /* check if the same dictionary pool has been declared for import */ for (i = 0; i < moo->c->cls.pooldic_imp.dcl_count; i++) { - if ((moo_oop_set_t)ass->value == moo->c->cls.pooldic_imp.oops[i]) + if ((moo_oop_dic_t)ass->value == moo->c->cls.pooldic_imp.oops[i]) { set_syntax_error (moo, MOO_SYNERR_POOLDICDUPL, TOKEN_LOC(moo), name); return -1; @@ -3076,14 +3081,15 @@ static int resolve_pooldic (moo_t* moo, int dotted, const moo_oocs_t* name) return 0; } +#endif -static int import_pool_dictionary (moo_t* moo, moo_oop_set_t ns_oop, const moo_oocs_t* tok_lastseg, const moo_oocs_t* tok_name, const moo_ioloc_t* tok_loc) +static int import_pool_dictionary (moo_t* moo, moo_oop_nsdic_t ns_oop, const moo_oocs_t* tok_lastseg, const moo_oocs_t* tok_name, const moo_ioloc_t* tok_loc) { moo_oop_association_t ass; moo_oow_t i; /* check if the name refers to a pool dictionary */ - ass = moo_lookupdic (moo, ns_oop, tok_lastseg); + ass = moo_lookupdic (moo, (moo_oop_dic_t)ns_oop, tok_lastseg); if (!ass || MOO_CLASSOF(moo, ass->value) != moo->_pool_dictionary) { set_syntax_error (moo, MOO_SYNERR_POOLDICINVAL, tok_loc, tok_name); @@ -3093,14 +3099,14 @@ static int import_pool_dictionary (moo_t* moo, moo_oop_set_t ns_oop, const moo_o /* check if the same dictionary pool has been declared for import */ for (i = 0; i < moo->c->cls.pooldic_imp.dcl_count; i++) { - if ((moo_oop_set_t)ass->value == moo->c->cls.pooldic_imp.oops[i]) + if ((moo_oop_dic_t)ass->value == moo->c->cls.pooldic_imp.oops[i]) { set_syntax_error (moo, MOO_SYNERR_POOLDICDUPL, tok_loc, tok_name); return -1; } } - if (add_pooldic_import(moo, tok_name, (moo_oop_set_t)ass->value) <= -1) return -1; + if (add_pooldic_import(moo, tok_name, (moo_oop_dic_t)ass->value) <= -1) return -1; if (copy_string_to (moo, tok_name, &moo->c->cls.pooldic_imp.dcl, &moo->c->cls.pooldic_imp.dcl_capa, 1, ' ') <= -1) { moo->c->cls.pooldic_imp.dcl_count--; /* roll back add_pool_dictionary() */ @@ -3136,8 +3142,8 @@ if super is variable-nonpointer, no instance variable is allowed. } if (find_class_level_variable(moo, MOO_NULL, TOKEN_NAME(moo), &var) >= 0 || - moo_lookupdic (moo, moo->sysdic, TOKEN_NAME(moo)) || /* conflicts with a top global name */ - moo_lookupdic (moo, moo->c->cls.ns_oop, TOKEN_NAME(moo))) /* conflicts with a global name in the class'es name space */ + moo_lookupdic (moo, (moo_oop_dic_t)moo->sysdic, TOKEN_NAME(moo)) || /* conflicts with a top global name */ + moo_lookupdic (moo, (moo_oop_dic_t)moo->c->cls.ns_oop, TOKEN_NAME(moo))) /* conflicts with a global name in the class'es name space */ { set_syntax_error (moo, MOO_SYNERR_VARNAMEDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); return -1; @@ -3253,8 +3259,8 @@ if super is variable-nonpointer, no instance variable is allowed. } if (find_class_level_variable(moo, MOO_NULL, TOKEN_NAME(moo), &var) >= 0 || - moo_lookupdic (moo, moo->sysdic, TOKEN_NAME(moo)) || /* conflicts with a top global name */ - moo_lookupdic (moo, moo->c->cls.ns_oop, TOKEN_NAME(moo))) /* conflicts with a global name in the class'es name space */ + moo_lookupdic (moo, (moo_oop_dic_t)moo->sysdic, TOKEN_NAME(moo)) || /* conflicts with a top global name */ + moo_lookupdic (moo, (moo_oop_dic_t)moo->c->cls.ns_oop, TOKEN_NAME(moo))) /* conflicts with a global name in the class'es name space */ { set_syntax_error (moo, MOO_SYNERR_VARNAMEDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); return -1; @@ -3322,7 +3328,7 @@ static int compile_class_level_imports (moo_t* moo) * import ... */ moo_oocs_t last; - moo_oop_set_t ns_oop; + moo_oop_nsdic_t ns_oop; if (TOKEN_TYPE(moo) == MOO_IOTOK_LPAREN) { @@ -3627,6 +3633,10 @@ static int compile_method_temporaries (moo_t* moo) GET_TOKEN (moo); while (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT) { + /* a temporary variable name may get the same as a class level variable name + * or even a class name in such as case, it shadows the class level variable + * name or the class name. however, it can't be the same as another temporary + * variable */ if (find_temporary_variable(moo, TOKEN_NAME(moo), MOO_NULL) >= 0) { set_syntax_error (moo, MOO_SYNERR_TMPRNAMEDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); @@ -3817,22 +3827,32 @@ static int find_dotted_ident (moo_t* moo, const moo_oocs_t* name, const moo_iolo */ moo_oocs_t last; - moo_oop_set_t ns_oop; + moo_oop_nsdic_t top_dic, ns_oop; moo_oop_association_t ass; const moo_ooch_t* dot; + moo_oocs_t xname; + moo_ioloc_t xname_loc; + + top_dic = MOO_NULL; + xname = *name; + xname_loc = *name_loc; + dot = moo_findoochar (name->ptr, name->len, '.'); MOO_ASSERT (moo, dot != MOO_NULL); if (dot - (const moo_ooch_t*)name->ptr == 4 && moo_equaloochars(name->ptr, vocas[VOCA_SELF].str, 4)) { - /* special case. the dotted name begins with self. */ + /* special case. the dotted name begins with self. + * the special prefix 'self' is used to refer to the data + * contained in a class or in its instance. */ dot = moo_findoochar (dot + 1, name->len - 5, '.'); if (!dot) { /* the dotted name is composed of 2 segments only */ last.ptr = name->ptr + 5; last.len = name->len - 5; + if (is_reserved_word(&last)) { /* self. is followed by a reserved word. @@ -3841,23 +3861,57 @@ static int find_dotted_ident (moo_t* moo, const moo_oocs_t* name, const moo_iolo return -1; } - if (find_class_level_variable(moo, moo->c->cls.self_oop, &last, var) >= 0) + if (moo->c->cls.self_oop) { - /* indicate that it's not a global variable */ - return 1; + /* it's probably called from a method or + * a nested pooldic definition inside a class */ + if (find_class_level_variable(moo, moo->c->cls.self_oop, &last, var) >= 0) + { + /* indicate that it's not a global variable */ + return 1; + } + goto self_no_class_level; } else { - /* undeclared identifier */ - set_syntax_error (moo, MOO_SYNERR_VARUNDCL, name_loc, name); + goto self_inacc; + + } + } + else + { + if (moo->c->cls.self_oop) + { + self_no_class_level: + top_dic = moo->c->cls.self_oop->nsdic; + if ((moo_oop_t)top_dic == moo->_nil) top_dic = MOO_NULL; + xname.ptr += 5; + xname.len -= 5; + xname_loc.colm += 5; + } + else + { + self_inacc: + top_dic = moo->c->cls.self_oop->nsdic; + if ((moo_oop_t)top_dic == moo->_nil) top_dic = MOO_NULL; + xname.ptr += 5; + xname.len -= 5; + xname_loc.colm += 5; +#if 0 + /* called without a class defined. possibly the following cases: + * used as a value for a pooldic item + * used as an initial value for a class-level variables */ + set_syntax_error (moo, MOO_SYNERR_SELFINACC, name_loc, name); return -1; +#endif } } } - if (preprocess_dotted_name (moo, PDN_DONT_ADD_NS | PDN_ACCEPT_POOLDIC_AS_NS, MOO_NULL, name, name_loc, &last, &ns_oop) <= -1) return -1; + /*if (preprocess_dotted_name (moo, PDN_DONT_ADD_NS | PDN_ACCEPT_POOLDIC_AS_NS, top_dic, name, name_loc, &last, &ns_oop) <= -1) return -1;*/ + if (preprocess_dotted_name (moo, PDN_DONT_ADD_NS | PDN_ACCEPT_POOLDIC_AS_NS, top_dic, &xname, &xname_loc, &last, &ns_oop) <= -1) return -1; - ass = moo_lookupdic (moo, ns_oop, &last); + ass = moo_lookupdic (moo, (moo_oop_dic_t)ns_oop, &last); if (!ass) { /* undeclared identifier */ @@ -3870,50 +3924,6 @@ static int find_dotted_ident (moo_t* moo, const moo_oocs_t* name, const moo_iolo return 0; } -static int find_ident_in_nsdic_and_sysdic (moo_t* moo, const moo_oocs_t* name, const moo_ioloc_t* name_loc, var_info_t* var) -{ - moo_oop_association_t ass; - - /* find an undotted identifier in dictionaries */ - - ass = moo_lookupdic (moo, moo->c->cls.ns_oop, name); /* in the current name space */ - if (!ass && moo->c->cls.ns_oop != moo->sysdic) - ass = moo_lookupdic (moo, moo->sysdic, name); /* in the top-level system dictionary */ - - if (!ass) - { - moo_oow_t i; - moo_oop_association_t ass2 = MOO_NULL; - - /* attempt to find the variable in pool dictionaries */ - for (i = 0; i < moo->c->cls.pooldic_imp.dcl_count; i++) - { - ass = moo_lookupdic (moo, moo->c->cls.pooldic_imp.oops[i], name); - if (ass) - { - if (ass2) - { - /* the variable name has been found at least in 2 dictionaries - ambiguous */ - set_syntax_error (moo, MOO_SYNERR_VARAMBIG, name_loc, name); - return -1; - } - ass2 = ass; - } - } - - ass = ass2; - if (!ass) - { - set_syntax_error (moo, MOO_SYNERR_VARUNDCL, name_loc, name); - return -1; - } - } - - var->type = VAR_GLOBAL; - var->gbl = ass; - return 0; -} - static int get_variable_info (moo_t* moo, const moo_oocs_t* name, const moo_ioloc_t* name_loc, int name_dotted, var_info_t* var) { moo_oow_t index; @@ -3924,11 +3934,18 @@ static int get_variable_info (moo_t* moo, const moo_oocs_t* name, const moo_iolo { int n; if ((n = find_dotted_ident (moo, name, name_loc, var)) <= -1) return -1; - if (n >= 1) goto class_level_variable; + if (n >= 1) goto class_level_variable; /* prefixed with self. */ return 0; } - if (find_temporary_variable (moo, name, &index) >= 0) + if (!moo->c->cls.self_oop) + { + /* it's called before a class is made available. commonly, outside a class. + * no need to check class level variables and temporary variables */ + goto lookup_in_dics; + } + + if (moo->c->mth.active && find_temporary_variable (moo, name, &index) >= 0) { var->type = (index < moo->c->mth.tmpr_nargs)? VAR_ARGUMENT: VAR_TEMPORARY; var->pos = index; @@ -3983,7 +4000,53 @@ static int get_variable_info (moo_t* moo, const moo_oocs_t* name, const moo_iolo } else { - if (find_ident_in_nsdic_and_sysdic (moo, name, name_loc, var) <= -1) return -1; + moo_oop_association_t ass; + + lookup_in_dics: + /* find an undotted identifier in dictionaries */ + + if (moo->c->cls.ns_oop) + { + ass = moo_lookupdic (moo, (moo_oop_dic_t)moo->c->cls.ns_oop, name); /* in the current name space */ + if (!ass && moo->c->cls.ns_oop != moo->sysdic) + ass = moo_lookupdic (moo, (moo_oop_dic_t)moo->sysdic, name); /* in the top-level system dictionary */ + } + else + { + ass = moo_lookupdic (moo, (moo_oop_dic_t)moo->sysdic, name); /* in the top-level system dictionary */ + } + + if (!ass) + { + moo_oow_t i; + moo_oop_association_t ass2 = MOO_NULL; + + /* attempt to find the variable in pool dictionaries */ + for (i = 0; i < moo->c->cls.pooldic_imp.dcl_count; i++) + { + ass = moo_lookupdic (moo, moo->c->cls.pooldic_imp.oops[i], name); + if (ass) + { + if (ass2) + { + /* the variable name has been found at least in 2 dictionaries - ambiguous */ + set_syntax_error (moo, MOO_SYNERR_VARAMBIG, name_loc, name); + return -1; + } + ass2 = ass; + } + } + + ass = ass2; + if (!ass) + { + set_syntax_error (moo, MOO_SYNERR_VARUNDCL, name_loc, name); + return -1; + } + } + + var->type = VAR_GLOBAL; + var->gbl = ass; } } @@ -4269,10 +4332,11 @@ static int read_byte_array_literal (moo_t* moo, moo_oop_t* xlit) { moo_ooi_t tmp; moo_oop_t ba; + moo_oow_t saved_balit_count; - moo->c->balit.count = 0; + saved_balit_count = moo->c->balit.count; - GET_TOKEN (moo); /* skip #[ and read the next token */ + GET_TOKEN_GOTO (moo, oops); /* skip #[ and read the next token */ while (TOKEN_TYPE(moo) == MOO_IOTOK_NUMLIT || TOKEN_TYPE(moo) == MOO_IOTOK_RADNUMLIT) { @@ -4287,29 +4351,35 @@ static int read_byte_array_literal (moo_t* moo, moo_oop_t* xlit) /* if the token is out of the SMOOI range, it's too big or * to small to be a byte */ set_syntax_error (moo, MOO_SYNERR_BYTERANGE, TOKEN_LOC(moo), TOKEN_NAME(moo)); - return -1; + goto oops; } else if (tmp < 0 || tmp > 255) { set_syntax_error (moo, MOO_SYNERR_BYTERANGE, TOKEN_LOC(moo), TOKEN_NAME(moo)); - return -1; + goto oops; } - if (add_to_byte_array_literal_buffer(moo, tmp) <= -1) return -1; - GET_TOKEN (moo); + if (add_to_byte_array_literal_buffer(moo, tmp) <= -1) goto oops; + GET_TOKEN_GOTO (moo, oops); } if (TOKEN_TYPE(moo) != MOO_IOTOK_RBRACK) { set_syntax_error (moo, MOO_SYNERR_RBRACK, TOKEN_LOC(moo), TOKEN_NAME(moo)); - return -1; + goto oops; } - ba = moo_instantiate (moo, moo->_byte_array, moo->c->balit.ptr, moo->c->balit.count); - if (!ba) return -1; + ba = moo_instantiate (moo, moo->_byte_array, &moo->c->balit.ptr[saved_balit_count], moo->c->balit.count - saved_balit_count); + if (!ba) goto oops; *xlit = ba; + + moo->c->balit.count = saved_balit_count; return 0; + +oops: + moo->c->balit.count = saved_balit_count; + return -1; } @@ -4361,6 +4431,7 @@ static int compile_byte_array_literal (moo_t* moo) moo_oop_t lit; moo_oow_t index; + MOO_ASSERT (moo, moo->c->balit.count == 0); MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_BABRACK); if (read_byte_array_literal(moo, &lit) <= -1 || @@ -6003,31 +6074,8 @@ oops: return -1; } -static int compile_method_definition (moo_t* moo) +static int __compile_method_definition (moo_t* moo) { - /* clear data required to compile a method */ - MOO_ASSERT (moo, moo->c->arlit.count == 0); - - moo->c->mth.type = MOO_METHOD_INSTANCE; - moo->c->mth.primitive = 0; - moo->c->mth.lenient = 0; - moo->c->mth.text.len = 0; - moo->c->mth.assignees.len = 0; - moo->c->mth.binsels.len = 0; - moo->c->mth.kwsels.len = 0; - moo->c->mth.name.len = 0; - MOO_MEMSET (&moo->c->mth.name_loc, 0, MOO_SIZEOF(moo->c->mth.name_loc)); - moo->c->mth.variadic = 0; - moo->c->mth.tmprs.len = 0; - moo->c->mth.tmpr_count = 0; - moo->c->mth.tmpr_nargs = 0; - moo->c->mth.literals.count = 0; - moo->c->balit.count = 0; - moo->c->mth.pftype = PFTYPE_NONE; - moo->c->mth.pfnum = 0; - moo->c->mth.blk_depth = 0; - moo->c->mth.code.len = 0; - if (TOKEN_TYPE(moo) == MOO_IOTOK_LPAREN) { /* process method modifiers */ @@ -6279,6 +6327,42 @@ static int compile_method_definition (moo_t* moo) return 0; } + +static int compile_method_definition (moo_t* moo) +{ + int n; + + /* clear data required to compile a method */ + MOO_ASSERT (moo, moo->c->balit.count == 0); + MOO_ASSERT (moo, moo->c->arlit.count == 0); + + moo->c->mth.active = 1; + moo->c->mth.type = MOO_METHOD_INSTANCE; + moo->c->mth.primitive = 0; + moo->c->mth.lenient = 0; + moo->c->mth.text.len = 0; + moo->c->mth.assignees.len = 0; + moo->c->mth.binsels.len = 0; + moo->c->mth.kwsels.len = 0; + moo->c->mth.name.len = 0; + MOO_MEMSET (&moo->c->mth.name_loc, 0, MOO_SIZEOF(moo->c->mth.name_loc)); + moo->c->mth.variadic = 0; + moo->c->mth.tmprs.len = 0; + moo->c->mth.tmpr_count = 0; + moo->c->mth.tmpr_nargs = 0; + moo->c->mth.literals.count = 0; + moo->c->mth.pftype = PFTYPE_NONE; + moo->c->mth.pfnum = 0; + moo->c->mth.blk_depth = 0; + moo->c->mth.code.len = 0; + + n = __compile_method_definition (moo); + + moo->c->mth.active = 0; + + return n; +} + static int make_default_initial_values (moo_t* moo, var_type_t var_type) { moo_oow_t initv_count; @@ -6400,9 +6484,17 @@ static int make_defined_class (moo_t* moo) moo->c->cls.self_oop->superclass = moo->c->cls.super_oop; - tmp = moo_makesymbol (moo, moo->c->cls.name.ptr, moo->c->cls.name.len); - if (!tmp) return -1; - moo->c->cls.self_oop->name = (moo_oop_char_t)tmp; + if (just_made) + { + /* set the name of a class if it's not set. at this point, + * only kernel classes must have a name which has been set + * during ignition phase. See ignite_3() */ + tmp = moo_makesymbol (moo, moo->c->cls.name.ptr, moo->c->cls.name.len); + if (!tmp) return -1; + moo->c->cls.self_oop->name = (moo_oop_char_t)tmp; + } + + MOO_ASSERT (moo, (moo_oop_t)moo->c->cls.self_oop->name != moo->_nil); if (moo->c->cls.modname.len > 0) { @@ -6430,12 +6522,12 @@ static int make_defined_class (moo_t* moo) /* TOOD: good dictionary size */ tmp = (moo_oop_t)moo_makedic (moo, moo->_method_dictionary, INSTANCE_METHOD_DICTIONARY_SIZE); if (!tmp) return -1; - moo->c->cls.self_oop->mthdic[MOO_METHOD_INSTANCE] = (moo_oop_set_t)tmp; + moo->c->cls.self_oop->mthdic[MOO_METHOD_INSTANCE] = (moo_oop_dic_t)tmp; /* TOOD: good dictionary size */ tmp = (moo_oop_t)moo_makedic (moo, moo->_method_dictionary, CLASS_METHOD_DICTIONARY_SIZE); if (!tmp) return -1; - moo->c->cls.self_oop->mthdic[MOO_METHOD_CLASS] = (moo_oop_set_t)tmp; + moo->c->cls.self_oop->mthdic[MOO_METHOD_CLASS] = (moo_oop_dic_t)tmp; /* store the default intial values for instance variables */ if (make_default_initial_values (moo, VAR_INSTANCE) <= -1) return -1; @@ -6489,9 +6581,10 @@ static int make_defined_class (moo_t* moo) if (just_made) { - /* register the class to the system dictionary */ - /*if (!moo_putatsysdic(moo, (moo_oop_t)moo->c->cls.self_oop->name, (moo_oop_t)moo->c->cls.self_oop)) return -1;*/ - if (!moo_putatdic(moo, moo->c->cls.ns_oop, (moo_oop_t)moo->c->cls.self_oop->name, (moo_oop_t)moo->c->cls.self_oop)) return -1; + /* register the class to the system dictionary. kernel classes have + * been registered at the ignition phase. */ + if (!moo_putatdic(moo, (moo_oop_dic_t)moo->c->cls.ns_oop, (moo_oop_t)moo->c->cls.self_oop->name, (moo_oop_t)moo->c->cls.self_oop)) return -1; + moo->c->cls.self_oop->nsup = moo->c->cls.ns_oop; } return 0; @@ -6675,7 +6768,7 @@ static int __compile_class_definition (moo_t* moo, int extend) MOO_INFO2 (moo, "Extending a class %.*js\n", moo->c->cls.fqn.len, moo->c->cls.fqn.ptr); /*ass = moo_lookupsysdic(moo, &moo->c->cls.name);*/ - ass = moo_lookupdic(moo, moo->c->cls.ns_oop, &moo->c->cls.name); + ass = moo_lookupdic(moo, (moo_oop_dic_t)moo->c->cls.ns_oop, &moo->c->cls.name); if (ass && MOO_CLASSOF(moo, ass->value) == moo->_class && MOO_OBJ_GET_FLAGS_KERNEL(ass->value) != 1) @@ -6754,7 +6847,7 @@ static int __compile_class_definition (moo_t* moo, int extend) GET_TOKEN (moo); /*ass = moo_lookupsysdic(moo, &moo->c->cls.name);*/ - ass = moo_lookupdic (moo, moo->c->cls.ns_oop, &moo->c->cls.name); + ass = moo_lookupdic (moo, (moo_oop_dic_t)moo->c->cls.ns_oop, &moo->c->cls.name); if (ass) { if (MOO_CLASSOF(moo, ass->value) != moo->_class || @@ -6782,9 +6875,9 @@ static int __compile_class_definition (moo_t* moo, int extend) } else { - ass = moo_lookupdic (moo, moo->c->cls.superns_oop, &moo->c->cls.supername); + ass = moo_lookupdic (moo, (moo_oop_dic_t)moo->c->cls.superns_oop, &moo->c->cls.supername); if (!ass && moo->c->cls.superns_oop != moo->sysdic) - ass = moo_lookupdic (moo, moo->sysdic, &moo->c->cls.supername); + ass = moo_lookupdic (moo, (moo_oop_dic_t)moo->sysdic, &moo->c->cls.supername); if (ass && MOO_CLASSOF(moo, ass->value) == moo->_class && MOO_OBJ_GET_FLAGS_KERNEL(ass->value) != 1) @@ -6909,7 +7002,7 @@ static int __compile_class_definition (moo_t* moo, int extend) moo_oocs_t last, tok; moo_ioloc_t loc; int dotted = 0; - moo_oop_set_t ns_oop; + moo_oop_nsdic_t ns_oop; while (ptr < end && is_spacechar(*ptr)) ptr++; if (ptr >= end) break; @@ -7006,12 +7099,17 @@ static int __compile_class_definition (moo_t* moo, int extend) } } - while (is_token_word(moo, VOCA_METHOD)) + do { /* method definition. method */ - GET_TOKEN (moo); - if (compile_method_definition(moo) <= -1) return -1; + if (is_token_word(moo, VOCA_METHOD)) + { + GET_TOKEN (moo); + if (compile_method_definition(moo) <= -1) return -1; + } + else break; } + while (1); if (TOKEN_TYPE(moo) != MOO_IOTOK_RBRACE) { @@ -7057,9 +7155,9 @@ static int compile_class_definition (moo_t* moo, int extend) moo->c->cls.ns_oop = MOO_NULL; moo->c->cls.superns_oop = MOO_NULL; moo->c->mth.literals.count = 0; - moo->c->balit.count = 0; - moo->c->arlit.count = 0; + MOO_ASSERT (moo, moo->c->balit.count == 0); + MOO_ASSERT (moo, moo->c->arlit.count == 0); /* do main compilation work */ n = __compile_class_definition (moo, extend); @@ -7071,22 +7169,24 @@ static int compile_class_definition (moo_t* moo, int extend) moo->c->cls.ns_oop = MOO_NULL; moo->c->cls.superns_oop = MOO_NULL; moo->c->mth.literals.count = 0; - moo->c->balit.count = 0; for (i = 0; i < MOO_COUNTOF(moo->c->cls.var); i++) { + moo->c->cls.var[i].str.len = 0; + moo->c->cls.var[i].count = 0; + moo->c->cls.var[i].total_count = 0; moo->c->cls.var[i].initv_count = 0; } moo->c->cls.pooldic_imp.dcl_count = 0; moo->c->cls.pooldic_imp.dcl.len = 0; - MOO_ASSERT (moo, n <= -1 || (n >= 0 && moo->c->arlit.count == 0)); - moo->c->arlit.count = 0; + MOO_ASSERT (moo, moo->c->balit.count == 0); + MOO_ASSERT (moo, moo->c->arlit.count == 0); return n; } -static MOO_INLINE moo_oop_t token_to_literal (moo_t* moo, int rdonly) +static moo_oop_t token_to_literal (moo_t* moo, int rdonly) { switch (TOKEN_TYPE(moo)) { @@ -7134,30 +7234,13 @@ static MOO_INLINE moo_oop_t token_to_literal (moo_t* moo, int rdonly) return lit; } -#if 0 -/* TODO: if a constant name is specified (constant defined in a class) or - * another variable with the default initialization value - * class { var x := 20, y := x. } */ case MOO_IOTOK_IDENT: case MOO_IOTOK_IDENT_DOTTED: -#endif - - case MOO_IOTOK_IDENT: - { - var_info_t var; - if (find_ident_in_nsdic_and_sysdic (moo, TOKEN_NAME(moo), TOKEN_LOC(moo), &var) <= -1) return MOO_NULL; - MOO_ASSERT (moo, var.type == VAR_GLOBAL); - /* [NOTE] i don't mark RDONLY on a value resolved via an identifier */ - return var.gbl->value; - } - - case MOO_IOTOK_IDENT_DOTTED: { var_info_t var; - if (find_dotted_ident (moo, TOKEN_NAME(moo), TOKEN_LOC(moo), &var) <= -1) return MOO_NULL; + if (get_variable_info (moo, TOKEN_NAME(moo), TOKEN_LOC(moo), TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED, &var) <= -1) return MOO_NULL; if (var.type != VAR_GLOBAL) { -/* TODO: XXXXXXXXXXXXXXXXXXXXXXXXxx */ set_syntax_error (moo, MOO_SYNERR_VARINACC, TOKEN_LOC(moo), TOKEN_NAME(moo)); return MOO_NULL; } @@ -7196,7 +7279,7 @@ static MOO_INLINE moo_oop_t token_to_literal (moo_t* moo, int rdonly) } } -static int __compile_pooldic_definition (moo_t* moo) +static int __compile_pooldic_definition (moo_t* moo, moo_pooldic_t* pd) { moo_oop_t lit; moo_ooi_t tally; @@ -7212,168 +7295,14 @@ static int __compile_pooldic_definition (moo_t* moo) goto oops; } - /* [NOTE] - * reuse moo->c->cls.fqn and related fields are reused - * to store the pool dictionary name */ - if (set_class_fqn(moo, TOKEN_NAME(moo)) <= -1) goto oops; - moo->c->cls.fqn_loc = moo->c->tok.loc; - - if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED) + if (moo->c->cls.self_oop && TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED) { - if (preprocess_dotted_name(moo, 0, MOO_NULL, &moo->c->cls.fqn, &moo->c->cls.fqn_loc, &moo->c->cls.name, &moo->c->cls.ns_oop) <= -1) goto oops; - } - else - { - moo->c->cls.ns_oop = moo->sysdic; - } - - if (moo_lookupdic (moo, moo->c->cls.ns_oop, &moo->c->cls.name)) - { - /* a conflicting entry has been found */ - set_syntax_error (moo, MOO_SYNERR_POOLDICDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); - goto oops; - } - - GET_TOKEN_GOTO (moo, oops); - if (TOKEN_TYPE(moo) != MOO_IOTOK_LBRACE) - { - set_syntax_error (moo, MOO_SYNERR_LBRACE, TOKEN_LOC(moo), TOKEN_NAME(moo)); - goto oops; - } - - MOO_INFO2 (moo, "Defining a pool dictionary %.*js\n", moo->c->cls.fqn.len, moo->c->cls.fqn.ptr); - - GET_TOKEN_GOTO (moo, oops); - - while (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT) - { - lit = moo_makesymbol (moo, TOKEN_NAME_PTR(moo), TOKEN_NAME_LEN(moo)); - if (!lit || add_to_array_literal_buffer (moo, lit) <= -1) goto oops; - - GET_TOKEN_GOTO (moo, oops); - - if (TOKEN_TYPE(moo) != MOO_IOTOK_ASSIGN) - { - set_syntax_error (moo, MOO_SYNERR_ASSIGN, TOKEN_LOC(moo), TOKEN_NAME(moo)); - goto oops; - } - - GET_TOKEN_GOTO (moo, oops); - - /* [NOTE] - * values assigned to a pool dictinary member are not read-only - * unlike the default initial values defined in a class */ - lit = token_to_literal (moo, 0); - if (!lit) goto oops; - - /* for this definition, #pooldic MyPoolDic { a := 10. b := 20 }, - * arlit_buffer contains (#a 10 #b 20) when the 'while' loop is over. */ - if (add_to_array_literal_buffer(moo, lit) <= -1) goto oops; - GET_TOKEN_GOTO (moo, oops); - - /*if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACE) goto done; - else*/ if (TOKEN_TYPE(moo) != MOO_IOTOK_PERIOD) - { - set_syntax_error (moo, MOO_SYNERR_PERIOD, TOKEN_LOC(moo), TOKEN_NAME(moo)); - goto oops; - } - - GET_TOKEN_GOTO (moo, oops); - } - - - if (TOKEN_TYPE(moo) != MOO_IOTOK_RBRACE) - { - set_syntax_error (moo, MOO_SYNERR_RBRACE, TOKEN_LOC(moo), TOKEN_NAME(moo)); - goto oops; - } - -/*done:*/ - GET_TOKEN_GOTO (moo, oops); - - tally = (moo->c->arlit.count - saved_arlit_count) / 2; -/*TODO: tally and arlit_count range check */ - /*if (!MOO_IN_SMOOI_RANGE(tally)) ERROR??*/ - - moo->c->cls.pooldic_oop = moo_makedic (moo, moo->_pool_dictionary, MOO_ALIGN(tally + 10, POOL_DICTIONARY_SIZE_ALIGN)); - if (!moo->c->cls.pooldic_oop) goto oops; - - for (i = saved_arlit_count; i < moo->c->arlit.count; i += 2) - { - /* TODO: handle duplicate keys? */ - if (!moo_putatdic(moo, moo->c->cls.pooldic_oop, moo->c->arlit.ptr[i], moo->c->arlit.ptr[i + 1])) goto oops; - } - - /* eveything seems ok. register the pool dictionary to the main - * system dictionary or to the name space it belongs to */ - lit = moo_makesymbol (moo, moo->c->cls.name.ptr, moo->c->cls.name.len); - if (!lit || !moo_putatdic (moo, moo->c->cls.ns_oop, lit, (moo_oop_t)moo->c->cls.pooldic_oop)) goto oops; - - moo->c->arlit.count = saved_arlit_count; - return 0; - -oops: - moo->c->arlit.count = saved_arlit_count; - return -1; -} - -static int compile_pooldic_definition (moo_t* moo) -{ - int n; - - /* reset the structure to hold information about a pool dictionary to be compiled. - * i'll be reusing some fields reserved for compling a class */ - moo->c->cls.name.len = 0; - MOO_MEMSET (&moo->c->cls.fqn_loc, 0, MOO_SIZEOF(moo->c->cls.fqn_loc)); - moo->c->cls.pooldic_oop = MOO_NULL; - moo->c->cls.ns_oop = MOO_NULL; - moo->c->balit.count = 0; - moo->c->arlit.count = 0; - -#if 0 - /* these 2 are pooldic import information. pooldic definition doesn't - * have another pooldic import in it */ - moo->c->cls.pooldic_imp.dcl_count = 0; - moo->c->cls.pooldic_imp.dcl.len = 0; -#endif - - n = __compile_pooldic_definition (moo); - - /* reset these oops plus literal pointers not to confuse gc_compiler() */ - moo->c->cls.pooldic_oop = MOO_NULL; - moo->c->cls.ns_oop = MOO_NULL; - - MOO_ASSERT (moo, n <= -1 || (n >= 0 && moo->c->balit.count == 0)); - moo->c->balit.count = 0; - -MOO_DEBUG2 (moo, "XXXXXXXXXXXXXXX %d %d\n", (int)n, (int)moo->c->arlit.count); - MOO_ASSERT (moo, n <= -1 || (n >= 0 && moo->c->arlit.count == 0)); - moo->c->arlit.count = 0; - -#if 0 - MOO_ASSERT (moo, moo->c->cls.pooldic_imp.dcl_count == 0); - MOO_ASSERT (moo, moo->c->cls.pooldic_imp.dcl.len == 0); -#endif - - return n; -} - -static int __compile_pooldic_definition_in_class (moo_t* moo, moo_pooldic_t* pd) -{ - moo_oop_t lit; - moo_ooi_t tally; - moo_oow_t i; - moo_oow_t saved_arlit_count; - - saved_arlit_count = moo->c->arlit.count; - -/* TODO: if calling from within a class, MOO_IOTOK_IDENT_DOTTED must be disallowed */ - if (TOKEN_TYPE(moo) != MOO_IOTOK_IDENT && - TOKEN_TYPE(moo) != MOO_IOTOK_IDENT_DOTTED) - { - set_syntax_error (moo, MOO_SYNERR_IDENT, TOKEN_LOC(moo), TOKEN_NAME(moo)); + /* nested pooldic definition in a class definition */ + set_syntax_error (moo, MOO_SYNERR_IDENT, TOKEN_LOC(moo), TOKEN_NAME(moo)); /* TODO: change error code - plain ident or undotted ident */ goto oops; } +/* TODO: if defined in a class, it also should be imported automatically to the containing class + * or import K.X */ if (set_pooldic_fqn(moo, pd, TOKEN_NAME(moo)) <= -1) goto oops; pd->fqn_loc = moo->c->tok.loc; @@ -7387,7 +7316,7 @@ static int __compile_pooldic_definition_in_class (moo_t* moo, moo_pooldic_t* pd) pd->ns_oop = moo->sysdic; } - if (moo_lookupdic (moo, pd->ns_oop, &pd->name)) + if (moo_lookupdic (moo, (moo_oop_dic_t)pd->ns_oop, &pd->name)) { /* a conflicting entry has been found */ set_syntax_error (moo, MOO_SYNERR_POOLDICDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); @@ -7455,19 +7384,19 @@ static int __compile_pooldic_definition_in_class (moo_t* moo, moo_pooldic_t* pd) /*TODO: tally and arlit_count range check */ /*if (!MOO_IN_SMOOI_RANGE(tally)) ERROR??*/ - moo->c->cls.pooldic_oop = moo_makedic (moo, moo->_pool_dictionary, MOO_ALIGN(tally + 10, POOL_DICTIONARY_SIZE_ALIGN)); - if (!moo->c->cls.pooldic_oop) goto oops; + pd->pd_oop = moo_makedic (moo, moo->_pool_dictionary, MOO_ALIGN(tally + 10, POOL_DICTIONARY_SIZE_ALIGN)); + if (!pd->pd_oop) goto oops; for (i = saved_arlit_count; i < moo->c->arlit.count; i += 2) { /* TODO: handle duplicate keys? */ - if (!moo_putatdic(moo, moo->c->cls.pooldic_oop, moo->c->arlit.ptr[i], moo->c->arlit.ptr[i + 1])) goto oops; + if (!moo_putatdic(moo, pd->pd_oop, moo->c->arlit.ptr[i], moo->c->arlit.ptr[i + 1])) goto oops; } /* eveything seems ok. register the pool dictionary to the main * system dictionary or to the name space it belongs to */ lit = moo_makesymbol (moo, pd->name.ptr, pd->name.len); - if (!lit || !moo_putatdic (moo, pd->ns_oop, lit, (moo_oop_t)pd->pd_oop)) goto oops; + if (!lit || !moo_putatdic (moo, (moo_oop_dic_t)pd->ns_oop, lit, (moo_oop_t)pd->pd_oop)) goto oops; moo->c->arlit.count = saved_arlit_count; return 0; @@ -7477,7 +7406,7 @@ oops: return -1; } -static int compile_pooldic_definition_in_class (moo_t* moo, moo_pooldic_t* pd) +static int compile_pooldic_definition (moo_t* moo, moo_pooldic_t* pd) { int n; @@ -7488,20 +7417,17 @@ static int compile_pooldic_definition_in_class (moo_t* moo, moo_pooldic_t* pd) pd->pd_oop = MOO_NULL; pd->ns_oop = MOO_NULL; - moo->c->balit.count = 0; - moo->c->arlit.count = 0; + MOO_ASSERT (moo, moo->c->balit.count == 0); + MOO_ASSERT (moo, moo->c->arlit.count == 0); - n = __compile_pooldic_definition_in_class (moo, pd); + n = __compile_pooldic_definition (moo, pd); /* reset these oops plus literal pointers not to confuse gc_compiler() */ pd->pd_oop = MOO_NULL; pd->ns_oop = MOO_NULL; - MOO_ASSERT (moo, n <= -1 || (n >= 0 && moo->c->balit.count == 0)); - moo->c->balit.count = 0; - - MOO_ASSERT (moo, n <= -1 || (n >= 0 && moo->c->arlit.count == 0)); - moo->c->arlit.count = 0; + MOO_ASSERT (moo, moo->c->balit.count == 0); + MOO_ASSERT (moo, moo->c->arlit.count == 0); return n; } @@ -7539,7 +7465,7 @@ static int compile_stream (moo_t* moo) { /* pooldic SharedPoolDic { ABC := 20. DEFG := 'ayz' } */ GET_TOKEN (moo); - if (compile_pooldic_definition(moo) <= -1) return -1; + if (compile_pooldic_definition(moo, &moo->c->pooldic) <= -1) return -1; } #if 0 else if (is_token_symbol(moo, VOCA_MAIN)) @@ -7581,38 +7507,46 @@ static void gc_compiler (moo_t* moo) } } - if (moo->c->cls.pooldic_oop) - { - register moo_oop_t x = moo_moveoop (moo, (moo_oop_t)moo->c->cls.pooldic_oop); - moo->c->cls.pooldic_oop = (moo_oop_set_t)x; - } - if (moo->c->cls.ns_oop) { register moo_oop_t x = moo_moveoop (moo, (moo_oop_t)moo->c->cls.ns_oop); - moo->c->cls.ns_oop = (moo_oop_set_t)x; + moo->c->cls.ns_oop = (moo_oop_nsdic_t)x; } if (moo->c->cls.superns_oop) { register moo_oop_t x = moo_moveoop (moo, (moo_oop_t)moo->c->cls.superns_oop); - moo->c->cls.superns_oop = (moo_oop_set_t)x; + moo->c->cls.superns_oop = (moo_oop_nsdic_t)x; } for (i = 0; i < moo->c->cls.pooldic_imp.dcl_count; i++) { register moo_oop_t x = moo_moveoop (moo, (moo_oop_t)moo->c->cls.pooldic_imp.oops[i]); - moo->c->cls.pooldic_imp.oops[i] = (moo_oop_set_t)x; + moo->c->cls.pooldic_imp.oops[i] = (moo_oop_dic_t)x; } for (i = 0; i < moo->c->mth.literals.count; i++) { - moo->c->mth.literals.ptr[i] = moo_moveoop (moo, moo->c->mth.literals.ptr[i]); + register moo_oop_t x = moo_moveoop (moo, moo->c->mth.literals.ptr[i]); + moo->c->mth.literals.ptr[i] = x; } for (i = 0; i < moo->c->arlit.count; i++) { - moo->c->arlit.ptr[i] = moo_moveoop (moo, moo->c->arlit.ptr[i]); + register moo_oop_t x = moo_moveoop (moo, moo->c->arlit.ptr[i]); + moo->c->arlit.ptr[i] = x; + } + + if (moo->c->pooldic.pd_oop) + { + register moo_oop_t x = moo_moveoop (moo, (moo_oop_t)moo->c->pooldic.pd_oop); + moo->c->pooldic.pd_oop = (moo_oop_dic_t)x; + } + + if (moo->c->pooldic.ns_oop) + { + register moo_oop_t x = moo_moveoop (moo, (moo_oop_t)moo->c->pooldic.ns_oop); + moo->c->pooldic.ns_oop = (moo_oop_nsdic_t)x; } } } @@ -7627,6 +7561,7 @@ static void fini_compiler (moo_t* moo) clear_io_names (moo); if (moo->c->tok.name.ptr) moo_freemem (moo, moo->c->tok.name.ptr); + if (moo->c->cls.fqn.ptr) moo_freemem (moo, moo->c->cls.fqn.ptr); if (moo->c->cls.superfqn.ptr) moo_freemem (moo, moo->c->cls.superfqn.ptr); if (moo->c->cls.modname.ptr) moo_freemem (moo, moo->c->cls.modname.ptr); @@ -7650,6 +7585,8 @@ static void fini_compiler (moo_t* moo) if (moo->c->mth.literals.ptr) moo_freemem (moo, moo->c->mth.literals.ptr); if (moo->c->mth.blk_tmprcnt) moo_freemem (moo, moo->c->mth.blk_tmprcnt); + if (moo->c->pooldic.fqn.ptr) moo_freemem (moo, moo->c->pooldic.fqn.ptr); + if (moo->c->balit.ptr) moo_freemem (moo, moo->c->balit.ptr); if (moo->c->arlit.ptr) moo_freemem (moo, moo->c->arlit.ptr); diff --git a/moo/lib/debug.c b/moo/lib/debug.c index 52ef1d4..697d33f 100644 --- a/moo/lib/debug.c +++ b/moo/lib/debug.c @@ -47,7 +47,7 @@ void moo_dumpsymtab (moo_t* moo) MOO_DEBUG0 (moo, "--------------------------------------------\n"); } -void moo_dumpdic (moo_t* moo, moo_oop_set_t dic, const moo_bch_t* title) +void moo_dumpdic (moo_t* moo, moo_oop_dic_t dic, const moo_bch_t* title) { moo_oow_t i; moo_oop_association_t ass; diff --git a/moo/lib/dic.c b/moo/lib/dic.c index b8cf66f..f5d1e73 100644 --- a/moo/lib/dic.c +++ b/moo/lib/dic.c @@ -85,7 +85,7 @@ static moo_oop_oop_t expand_bucket (moo_t* moo, moo_oop_oop_t oldbuc) return newbuc; } -static moo_oop_association_t find_or_upsert (moo_t* moo, moo_oop_set_t dic, moo_oop_char_t key, moo_oop_t value) +static moo_oop_association_t find_or_upsert (moo_t* moo, moo_oop_dic_t dic, moo_oop_char_t key, moo_oop_t value) { moo_ooi_t tally; moo_oow_t hv, index; @@ -196,7 +196,7 @@ oops: return MOO_NULL; } -static moo_oop_association_t lookup (moo_t* moo, moo_oop_set_t dic, const moo_oocs_t* name) +static moo_oop_association_t lookup (moo_t* moo, moo_oop_dic_t dic, const moo_oocs_t* name) { /* this is special version of moo_getatsysdic() that performs * lookup using a plain string specified */ @@ -234,40 +234,40 @@ static moo_oop_association_t lookup (moo_t* moo, moo_oop_set_t dic, const moo_oo moo_oop_association_t moo_putatsysdic (moo_t* moo, moo_oop_t key, moo_oop_t value) { MOO_ASSERT (moo, MOO_CLASSOF(moo,key) == moo->_symbol); - return find_or_upsert (moo, moo->sysdic, (moo_oop_char_t)key, value); + return find_or_upsert (moo, (moo_oop_dic_t)moo->sysdic, (moo_oop_char_t)key, value); } moo_oop_association_t moo_getatsysdic (moo_t* moo, moo_oop_t key) { MOO_ASSERT (moo, MOO_CLASSOF(moo,key) == moo->_symbol); - return find_or_upsert (moo, moo->sysdic, (moo_oop_char_t)key, MOO_NULL); + return find_or_upsert (moo, (moo_oop_dic_t)moo->sysdic, (moo_oop_char_t)key, MOO_NULL); } moo_oop_association_t moo_lookupsysdic (moo_t* moo, const moo_oocs_t* name) { - return lookup (moo, moo->sysdic, name); + return lookup (moo, (moo_oop_dic_t)moo->sysdic, name); } -moo_oop_association_t moo_putatdic (moo_t* moo, moo_oop_set_t dic, moo_oop_t key, moo_oop_t value) +moo_oop_association_t moo_putatdic (moo_t* moo, moo_oop_dic_t dic, moo_oop_t key, moo_oop_t value) { /*MOO_ASSERT (moo, MOO_CLASSOF(moo,key) == moo->_symbol);*/ MOO_ASSERT (moo, MOO_OBJ_IS_CHAR_POINTER(key)); return find_or_upsert (moo, dic, (moo_oop_char_t)key, value); } -moo_oop_association_t moo_getatdic (moo_t* moo, moo_oop_set_t dic, moo_oop_t key) +moo_oop_association_t moo_getatdic (moo_t* moo, moo_oop_dic_t dic, moo_oop_t key) { /*MOO_ASSERT (moo, MOO_CLASSOF(moo,key) == moo->_symbol); */ MOO_ASSERT (moo, MOO_OBJ_IS_CHAR_POINTER(key)); return find_or_upsert (moo, dic, (moo_oop_char_t)key, MOO_NULL); } -moo_oop_association_t moo_lookupdic (moo_t* moo, moo_oop_set_t dic, const moo_oocs_t* name) +moo_oop_association_t moo_lookupdic (moo_t* moo, moo_oop_dic_t dic, const moo_oocs_t* name) { return lookup (moo, dic, name); } -int moo_deletedic (moo_t* moo, moo_oop_set_t dic, const moo_oocs_t* name) +int moo_deletedic (moo_t* moo, moo_oop_dic_t dic, const moo_oocs_t* name) { moo_ooi_t tally; moo_oow_t hv, index, bs, i, x, y, z; @@ -334,18 +334,17 @@ found: return 0; } -moo_oop_set_t moo_makedic (moo_t* moo, moo_oop_class_t _class, moo_oow_t size) +moo_oop_dic_t moo_makedic (moo_t* moo, moo_oop_class_t _class, moo_oow_t size) { - moo_oop_set_t dic; + moo_oop_dic_t dic; moo_oop_t tmp; MOO_ASSERT (moo, MOO_CLASSOF(moo,_class) == moo->_class); + MOO_ASSERT (moo, MOO_CLASS_SPEC_NAMED_INSTVARS(MOO_OOP_TO_SMOOI(_class->spec)) >= MOO_DIC_NAMED_INSTVARS); - dic = (moo_oop_set_t)moo_instantiate (moo, _class, MOO_NULL, 0); + dic = (moo_oop_dic_t)moo_instantiate (moo, _class, MOO_NULL, 0); if (!dic) return MOO_NULL; - MOO_ASSERT (moo, MOO_OBJ_GET_SIZE(dic) == MOO_SET_NAMED_INSTVARS); - moo_pushtmp (moo, (moo_oop_t*)&dic); tmp = moo_instantiate (moo, moo->_array, MOO_NULL, size); moo_poptmp (moo); @@ -354,8 +353,16 @@ moo_oop_set_t moo_makedic (moo_t* moo, moo_oop_class_t _class, moo_oow_t size) dic->tally = MOO_SMOOI_TO_OOP(0); dic->bucket = (moo_oop_oop_t)tmp; - MOO_ASSERT (moo, MOO_OBJ_GET_SIZE(dic) == MOO_SET_NAMED_INSTVARS); + MOO_ASSERT (moo, MOO_OBJ_GET_SIZE(dic) == MOO_CLASS_SPEC_NAMED_INSTVARS(MOO_OOP_TO_SMOOI(_class->spec))); MOO_ASSERT (moo, MOO_OBJ_GET_SIZE(dic->bucket) == size); return dic; } + +moo_oop_nsdic_t moo_makensdic (moo_t* moo, moo_oop_class_t _class, moo_oow_t size) +{ + MOO_ASSERT (moo, MOO_CLASSOF(moo,_class) == moo->_class); + MOO_ASSERT (moo, MOO_CLASS_SPEC_NAMED_INSTVARS(MOO_OOP_TO_SMOOI(_class->spec)) >= MOO_NSDIC_NAMED_INSTVARS); + + return (moo_oop_nsdic_t)moo_makedic (moo, _class, size); +} diff --git a/moo/lib/err.c b/moo/lib/err.c index d63acf9..27cc08d 100644 --- a/moo/lib/err.c +++ b/moo/lib/err.c @@ -120,25 +120,26 @@ static moo_ooch_t synerrstr_46[] = {'u','n','d','e','c','l','a','r','e','d',' ', static moo_ooch_t synerrstr_47[] = {'u','n','u','s','a','b','l','e',' ','v','a','r','i','a','b','l','e',' ','i','n',' ','c','o','m','p','i','l','e','d',' ','c','o','d','e','\0'}; static moo_ooch_t synerrstr_48[] = {'i','n','a','c','c','e','s','s','i','b','l','e',' ','v','a','r','i','a','b','l','e','\0'}; static moo_ooch_t synerrstr_49[] = {'a','m','b','i','g','u','o','u','s',' ','v','a','r','i','a','b','l','e','\0'}; -static moo_ooch_t synerrstr_50[] = {'w','r','o','n','g',' ','e','x','p','r','e','s','s','i','o','n',' ','p','r','i','m','a','r','y','\0'}; -static moo_ooch_t synerrstr_51[] = {'t','o','o',' ','m','a','n','y',' ','t','e','m','p','o','r','a','r','i','e','s','\0'}; -static moo_ooch_t synerrstr_52[] = {'t','o','o',' ','m','a','n','y',' ','a','r','g','u','m','e','n','t','s','\0'}; -static moo_ooch_t synerrstr_53[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','t','e','m','p','o','r','a','r','i','e','s','\0'}; -static moo_ooch_t synerrstr_54[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','a','r','g','u','m','e','n','t','s','\0'}; -static moo_ooch_t synerrstr_55[] = {'t','o','o',' ','l','a','r','g','e',' ','b','l','o','c','k','\0'}; -static moo_ooch_t synerrstr_56[] = {'t','o','o',' ','l','a','r','g','e',' ','a','r','r','a','y',' ','e','x','p','r','e','s','s','i','o','n','\0'}; -static moo_ooch_t synerrstr_57[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','n','u','m','b','e','r','\0'}; -static moo_ooch_t synerrstr_58[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','i','d','e','n','t','i','f','i','e','r','\0'}; -static moo_ooch_t synerrstr_59[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','a','r','g','u','m','e','n','t',' ','d','e','f','i','n','i','t','i','o','n','\0'}; -static moo_ooch_t synerrstr_60[] = {'w','r','o','n','g',' ','m','o','d','u','l','e',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_61[] = {'#','i','n','c','l','u','d','e',' ','e','r','r','o','r','\0'}; -static moo_ooch_t synerrstr_62[] = {'w','r','o','n','g',' ','n','a','m','e','s','p','a','c','e',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_63[] = {'w','r','o','n','g',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_64[] = {'d','u','p','l','i','c','a','t','e',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_65[] = {'l','i','t','e','r','a','l',' ','e','x','p','e','c','t','e','d','\0'}; -static moo_ooch_t synerrstr_66[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','n','o','t',' ','w','i','t','h','i','n',' ','a',' ','l','o','o','p','\0'}; -static moo_ooch_t synerrstr_67[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','w','i','t','h','i','n',' ','a',' ','b','l','o','c','k','\0'}; -static moo_ooch_t synerrstr_68[] = {'w','h','i','l','e',' ','e','x','p','e','c','t','e','d','\0'}; +static moo_ooch_t synerrstr_50[] = {'i','n','a','c','c','e','s','s','i','b','l','e',' ','s','e','l','f','\0'}; +static moo_ooch_t synerrstr_51[] = {'w','r','o','n','g',' ','e','x','p','r','e','s','s','i','o','n',' ','p','r','i','m','a','r','y','\0'}; +static moo_ooch_t synerrstr_52[] = {'t','o','o',' ','m','a','n','y',' ','t','e','m','p','o','r','a','r','i','e','s','\0'}; +static moo_ooch_t synerrstr_53[] = {'t','o','o',' ','m','a','n','y',' ','a','r','g','u','m','e','n','t','s','\0'}; +static moo_ooch_t synerrstr_54[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','t','e','m','p','o','r','a','r','i','e','s','\0'}; +static moo_ooch_t synerrstr_55[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','a','r','g','u','m','e','n','t','s','\0'}; +static moo_ooch_t synerrstr_56[] = {'t','o','o',' ','l','a','r','g','e',' ','b','l','o','c','k','\0'}; +static moo_ooch_t synerrstr_57[] = {'t','o','o',' ','l','a','r','g','e',' ','a','r','r','a','y',' ','e','x','p','r','e','s','s','i','o','n','\0'}; +static moo_ooch_t synerrstr_58[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','n','u','m','b','e','r','\0'}; +static moo_ooch_t synerrstr_59[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','i','d','e','n','t','i','f','i','e','r','\0'}; +static moo_ooch_t synerrstr_60[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','a','r','g','u','m','e','n','t',' ','d','e','f','i','n','i','t','i','o','n','\0'}; +static moo_ooch_t synerrstr_61[] = {'w','r','o','n','g',' ','m','o','d','u','l','e',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_62[] = {'#','i','n','c','l','u','d','e',' ','e','r','r','o','r','\0'}; +static moo_ooch_t synerrstr_63[] = {'w','r','o','n','g',' ','n','a','m','e','s','p','a','c','e',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_64[] = {'w','r','o','n','g',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_65[] = {'d','u','p','l','i','c','a','t','e',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_66[] = {'l','i','t','e','r','a','l',' ','e','x','p','e','c','t','e','d','\0'}; +static moo_ooch_t synerrstr_67[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','n','o','t',' ','w','i','t','h','i','n',' ','a',' ','l','o','o','p','\0'}; +static moo_ooch_t synerrstr_68[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','w','i','t','h','i','n',' ','a',' ','b','l','o','c','k','\0'}; +static moo_ooch_t synerrstr_69[] = {'w','h','i','l','e',' ','e','x','p','e','c','t','e','d','\0'}; static moo_ooch_t* synerrstr[] = { synerrstr_0, synerrstr_1, synerrstr_2, synerrstr_3, synerrstr_4, synerrstr_5, synerrstr_6, synerrstr_7, @@ -149,7 +150,7 @@ static moo_ooch_t* synerrstr[] = synerrstr_40, synerrstr_41, synerrstr_42, synerrstr_43, synerrstr_44, synerrstr_45, synerrstr_46, synerrstr_47, synerrstr_48, synerrstr_49, synerrstr_50, synerrstr_51, synerrstr_52, synerrstr_53, synerrstr_54, synerrstr_55, synerrstr_56, synerrstr_57, synerrstr_58, synerrstr_59, synerrstr_60, synerrstr_61, synerrstr_62, synerrstr_63, - synerrstr_64, synerrstr_65, synerrstr_66, synerrstr_67, synerrstr_68 + synerrstr_64, synerrstr_65, synerrstr_66, synerrstr_67, synerrstr_68, synerrstr_69 }; #endif /* END: GENERATED WITH generr.moo */ diff --git a/moo/lib/exec.c b/moo/lib/exec.c index ff0874f..64e335e 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -1042,7 +1042,7 @@ static moo_oop_method_t find_method (moo_t* moo, moo_oop_t receiver, const moo_o moo_oop_class_t cls; moo_oop_association_t ass; moo_oop_t c; - moo_oop_set_t mthdic; + moo_oop_dic_t mthdic; int dic_no; /* TODO: implement method lookup cache */ @@ -5094,7 +5094,7 @@ int moo_execute (moo_t* moo) t1 = MOO_STACK_GETTOP(moo); MOO_STACK_POP (moo); t2 = MOO_STACK_GETTOP(moo); - moo_putatdic (moo, (moo_oop_set_t)t2, ((moo_oop_association_t)t1)->key, ((moo_oop_association_t)t1)->value); + moo_putatdic (moo, (moo_oop_dic_t)t2, ((moo_oop_association_t)t1)->key, ((moo_oop_association_t)t1)->value); */ if (send_message (moo, moo->dicputassocsym, 0, 1) <= -1) goto oops; break; diff --git a/moo/lib/gc.c b/moo/lib/gc.c index 642c029..8994c34 100644 --- a/moo/lib/gc.c +++ b/moo/lib/gc.c @@ -92,8 +92,6 @@ static kernel_class_info_t kernel_classes[] = { 9, { 'B','y','t','e','A','r','r','a','y' }, MOO_OFFSETOF(moo_t, _byte_array) }, { 9, { 'S','y','m','b','o','l','S','e','t' }, MOO_OFFSETOF(moo_t, _symbol_set) }, { 10, { 'D','i','c','t','i','o','n','a','r','y' }, MOO_OFFSETOF(moo_t, _dictionary) }, - { 16, { 'S','y','s','t','e','m','D','i','c','t','i','o','n','a','r','y' }, MOO_OFFSETOF(moo_t, _system_dictionary) }, - { 9, { 'N','a','m','e','s','p','a','c','e' }, MOO_OFFSETOF(moo_t, _namespace) }, { 14, { 'P','o','o','l','D','i','c','t','i','o','n','a','r','y' }, MOO_OFFSETOF(moo_t, _pool_dictionary) }, { 16, { 'M','e','t','h','o','d','D','i','c','t','i','o','n','a','r','y' }, MOO_OFFSETOF(moo_t, _method_dictionary) }, @@ -182,13 +180,11 @@ static int ignite_1 (moo_t* moo) moo->_array = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, MOO_CLASS_SPEC_FLAG_INDEXED, MOO_OBJ_TYPE_OOP)); moo->_byte_array = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, MOO_CLASS_SPEC_FLAG_INDEXED, MOO_OBJ_TYPE_BYTE)); - moo->_symbol_set = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(MOO_SET_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); - moo->_dictionary = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(MOO_SET_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); - moo->_system_dictionary = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(MOO_SET_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); - - moo->_namespace = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(MOO_SET_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); - moo->_pool_dictionary = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(MOO_SET_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); - moo->_method_dictionary = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(MOO_SET_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); + moo->_symbol_set = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(MOO_DIC_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); + moo->_dictionary = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(MOO_DIC_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); + moo->_namespace = alloc_kernel_class (moo, MOO_CLASS_SELFSPEC_FLAG_LIMITED, 0, MOO_CLASS_SPEC_MAKE(MOO_NSDIC_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); + moo->_pool_dictionary = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(MOO_DIC_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); + moo->_method_dictionary = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(MOO_DIC_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); moo->_method = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(MOO_METHOD_NAMED_INSTVARS, MOO_CLASS_SPEC_FLAG_INDEXED, MOO_OBJ_TYPE_OOP)); moo->_association = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(MOO_ASSOCIATION_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); @@ -222,8 +218,7 @@ static int ignite_1 (moo_t* moo) !moo->_object || !moo->_string || !moo->_symbol || !moo->_array || - !moo->_byte_array || !moo->_symbol_set || - !moo->_dictionary || !moo->_system_dictionary || + !moo->_byte_array || !moo->_symbol_set || !moo->_dictionary || !moo->_namespace || !moo->_pool_dictionary || !moo->_method_dictionary || !moo->_method || !moo->_association || @@ -252,7 +247,7 @@ static int ignite_2 (moo_t* moo) /* Create the symbol table */ tmp = moo_instantiate (moo, moo->_symbol_set, MOO_NULL, 0); if (!tmp) return -1; - moo->symtab = (moo_oop_set_t)tmp; + moo->symtab = (moo_oop_dic_t)tmp; moo->symtab->tally = MOO_SMOOI_TO_OOP(0); /* It's important to assign the result of moo_instantiate() to a temporary @@ -265,9 +260,9 @@ static int ignite_2 (moo_t* moo) moo->symtab->bucket = (moo_oop_oop_t)tmp; /* Create the system dictionary */ - tmp = (moo_oop_t)moo_makedic (moo, moo->_system_dictionary, moo->option.dfl_sysdic_size); + tmp = (moo_oop_t)moo_makensdic (moo, moo->_namespace, moo->option.dfl_sysdic_size); if (!tmp) return -1; - moo->sysdic = (moo_oop_set_t)tmp; + moo->sysdic = (moo_oop_nsdic_t)tmp; /* Create a nil process used to simplify nil check in GC. * only accessible by VM. not exported via the global dictionary. */ @@ -283,9 +278,6 @@ static int ignite_2 (moo_t* moo) moo->processor->tally = MOO_SMOOI_TO_OOP(0); moo->processor->active = moo->nil_process; - /* Attach the system dictionary to the nsdic field of the System class */ - moo->_system->nsdic = moo->sysdic; - return 0; } @@ -297,7 +289,8 @@ static int ignite_3 (moo_t* moo) static moo_ooch_t str_dicputassoc[] = { 'p', 'u', 't', '_', 'a', 's', 's', 'o', 'c', ':' }; moo_oow_t i; - moo_oop_t sym, cls; + moo_oop_t sym; + moo_oop_class_t cls; moo_oop_t* moo_ptr; for (i = 0; i < MOO_COUNTOF(kernel_classes); i++) @@ -305,12 +298,21 @@ static int ignite_3 (moo_t* moo) sym = moo_makesymbol (moo, kernel_classes[i].name, kernel_classes[i].len); if (!sym) return -1; - cls = *(moo_oop_t*)((moo_uint8_t*)moo + kernel_classes[i].offset); + cls = *(moo_oop_class_t*)((moo_uint8_t*)moo + kernel_classes[i].offset); + cls->name = (moo_oop_char_t)sym; + cls->nsup = moo->sysdic; - if (!moo_putatsysdic(moo, sym, cls)) return -1; + if (!moo_putatsysdic(moo, sym, (moo_oop_t)cls)) return -1; moo_ptr++; } + /* Attach the system dictionary to the nsdic field of the System class */ + moo->_system->nsdic = moo->sysdic; + /* Set the name field of the system dictionary */ + moo->sysdic->name = moo->_system->name; + /* Set the owning class field of the system dictionary, it's circular here */ + moo->sysdic->nsup = (moo_oop_t)moo->_system; + /* Make the process scheduler avaialble as the global name 'Processor' */ sym = moo_makesymbol (moo, str_processor, MOO_COUNTOF(str_processor)); if (!sym) return -1; @@ -632,7 +634,7 @@ void moo_gc (moo_t* moo) *(moo_oop_t*)((moo_uint8_t*)moo + kernel_classes[i].offset) = tmp; } - moo->sysdic = (moo_oop_set_t)moo_moveoop (moo, (moo_oop_t)moo->sysdic); + moo->sysdic = (moo_oop_nsdic_t)moo_moveoop (moo, (moo_oop_t)moo->sysdic); moo->processor = (moo_oop_process_scheduler_t)moo_moveoop (moo, (moo_oop_t)moo->processor); moo->nil_process = (moo_oop_process_t)moo_moveoop (moo, (moo_oop_t)moo->nil_process); moo->dicnewsym = (moo_oop_char_t)moo_moveoop (moo, (moo_oop_t)moo->dicnewsym); @@ -683,7 +685,7 @@ void moo_gc (moo_t* moo) compact_symbol_table (moo, old_nil); /* move the symbol table itself */ - moo->symtab = (moo_oop_set_t)moo_moveoop (moo, (moo_oop_t)moo->symtab); + moo->symtab = (moo_oop_dic_t)moo_moveoop (moo, (moo_oop_t)moo->symtab); /* scan the new heap again from the end position of * the previous scan to move referenced objects by diff --git a/moo/lib/moo-prv.h b/moo/lib/moo-prv.h index bf29cf5..5384546 100644 --- a/moo/lib/moo-prv.h +++ b/moo/lib/moo-prv.h @@ -423,8 +423,8 @@ struct moo_pooldic_t moo_oow_t fqn_capa; moo_ioloc_t fqn_loc; - moo_oop_set_t pd_oop; - moo_oop_set_t ns_oop; + moo_oop_dic_t pd_oop; + moo_oop_nsdic_t ns_oop; }; typedef struct moo_oopbuf_t moo_oopbuf_t; @@ -468,10 +468,8 @@ struct moo_compiler_t /* the last token read */ moo_iotok_t tok; moo_iolink_t* io_names; -#if 0 - int in_array; -#endif + /* syntax error information */ moo_synerr_t synerr; /* temporary space used when dealing with an illegal character */ @@ -492,14 +490,16 @@ struct moo_compiler_t moo_oop_class_t self_oop; moo_oop_t super_oop; /* this may be nil. so the type is moo_oop_t */ - moo_oop_set_t pooldic_oop; /* used when compiling a pooldic definition */ - moo_oop_set_t ns_oop; +#if 0 + moo_oop_dic_t pooldic_oop; /* used when compiling a pooldic definition */ +#endif + moo_oop_nsdic_t ns_oop; moo_oocs_t fqn; moo_oocs_t name; moo_oow_t fqn_capa; moo_ioloc_t fqn_loc; - moo_oop_set_t superns_oop; + moo_oop_nsdic_t superns_oop; moo_oocs_t superfqn; moo_oocs_t supername; moo_oow_t superfqn_capa; @@ -542,21 +542,23 @@ struct moo_compiler_t moo_oow_t dcl_count; /* used to hold imported pool dictionarie objects */ - moo_oop_set_t* oops; + moo_oop_dic_t* oops; moo_oow_t oops_capa; } pooldic_imp; - - /* pooldic declaration inside class */ - moo_pooldic_t pooldic; } cls; + /* pooldic declaration */ + moo_pooldic_t pooldic; + /* information about a method being comipled */ struct { + int active; + moo_method_type_t type; int primitive; /* true if method(#primitive) */ - int lenient; + int lenient; /* true if method(#lenient) */ /* method source text */ moo_oocs_t text; @@ -591,7 +593,6 @@ struct moo_compiler_t /* literals */ moo_oopbuf_t literals; - /* 0 for no primitive, 1 for a normal primitive, 2 for a named primitive */ int pftype; /* primitive function number */ @@ -1080,30 +1081,36 @@ moo_oop_association_t moo_lookupsysdic ( moo_oop_association_t moo_putatdic ( moo_t* moo, - moo_oop_set_t dic, + moo_oop_dic_t dic, moo_oop_t key, moo_oop_t value ); moo_oop_association_t moo_getatdic ( moo_t* moo, - moo_oop_set_t dic, + moo_oop_dic_t dic, moo_oop_t key ); moo_oop_association_t moo_lookupdic ( moo_t* moo, - moo_oop_set_t dic, + moo_oop_dic_t dic, const moo_oocs_t* name ); int moo_deletedic ( moo_t* moo, - moo_oop_set_t dic, + moo_oop_dic_t dic, const moo_oocs_t* name ); -moo_oop_set_t moo_makedic ( +moo_oop_dic_t moo_makedic ( + moo_t* moo, + moo_oop_class_t _class, + moo_oow_t size +); + +moo_oop_nsdic_t moo_makensdic ( moo_t* moo, moo_oop_class_t _class, moo_oow_t size @@ -1290,7 +1297,7 @@ moo_pfbase_t* moo_querymod ( /* debug.c */ /* ========================================================================= */ void moo_dumpsymtab (moo_t* moo); -void moo_dumpdic (moo_t* moo, moo_oop_set_t dic, const moo_bch_t* title); +void moo_dumpdic (moo_t* moo, moo_oop_dic_t dic, const moo_bch_t* title); #if defined(__cplusplus) diff --git a/moo/lib/moo.c b/moo/lib/moo.c index 12c6908..1c7beab 100644 --- a/moo/lib/moo.c +++ b/moo/lib/moo.c @@ -925,7 +925,7 @@ void* moo_getobjtrailer (moo_t* moo, moo_oop_t obj, moo_oow_t* size) return MOO_OBJ_GET_TRAILER_BYTE(obj); } -moo_oop_t moo_findclass (moo_t* moo, moo_oop_set_t nsdic, const moo_ooch_t* name) +moo_oop_t moo_findclass (moo_t* moo, moo_oop_nsdic_t nsdic, const moo_ooch_t* name) { moo_oop_association_t ass; moo_oocs_t n; @@ -933,7 +933,7 @@ moo_oop_t moo_findclass (moo_t* moo, moo_oop_set_t nsdic, const moo_ooch_t* name n.ptr = (moo_ooch_t*)name; n.len = moo_countoocstr(name); - ass = moo_lookupdic (moo, nsdic, &n); + ass = moo_lookupdic (moo, (moo_oop_dic_t)nsdic, &n); if (!ass || MOO_CLASSOF(moo,ass->value) != moo->_class) { moo_seterrnum (moo, MOO_ENOENT); diff --git a/moo/lib/moo.h b/moo/lib/moo.h index 00302f5..b39adcb 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -478,19 +478,37 @@ struct moo_trailer_t #define MOO_OBJ_GET_TRAILER_BYTE(oop) ((moo_oob_t*)&((moo_oop_oop_t)oop)->slot[MOO_OBJ_GET_SIZE(oop) + 1]) #define MOO_OBJ_GET_TRAILER_SIZE(oop) ((moo_oow_t)((moo_oop_oop_t)oop)->slot[MOO_OBJ_GET_SIZE(oop)]) -#define MOO_SET_NAMED_INSTVARS 2 -typedef struct moo_set_t moo_set_t; -typedef struct moo_set_t* moo_oop_set_t; -struct moo_set_t +#define MOO_DIC_NAMED_INSTVARS 2 +typedef struct moo_dic_t moo_dic_t; +typedef struct moo_dic_t* moo_oop_dic_t; +struct moo_dic_t { MOO_OBJ_HEADER; moo_oop_t tally; /* SmallInteger */ moo_oop_oop_t bucket; /* Array */ }; -#define MOO_CLASS_NAMED_INSTVARS 17 +/* [NOTE] the beginning of the moo_nsdic_t structure + * must be identical to the moo_dic_t streucture */ +#define MOO_NSDIC_NAMED_INSTVARS 4 +typedef struct moo_nsdic_t moo_nsdic_t; +typedef struct moo_nsdic_t* moo_oop_nsdic_t; + +#define MOO_CLASS_NAMED_INSTVARS 18 typedef struct moo_class_t moo_class_t; typedef struct moo_class_t* moo_oop_class_t; + +struct moo_nsdic_t +{ + MOO_OBJ_HEADER; + moo_oop_t tally; + moo_oop_t bucket; + /* same as moo_dic_t so far */ + + moo_oop_char_t name; /* a symbol. if it belongs to a class, it will be the same as the name of the class */ + moo_oop_t nsup; /* a class if it belongs to the class. another nsdic if it doesn't */ +}; + struct moo_class_t { MOO_OBJ_HEADER; @@ -514,10 +532,13 @@ struct moo_class_t /* [0] - instance methods, MethodDictionary * [1] - class methods, MethodDictionary */ - moo_oop_set_t mthdic[2]; + moo_oop_dic_t mthdic[2]; + + moo_oop_nsdic_t nsup; /* pointer to the upper namespace */ + moo_oop_nsdic_t nsdic; /* dictionary used for namespacing - may be nil when there are no subitems underneath */ + + moo_oop_dic_t cdic; /* constant dictionary */ - moo_oop_set_t nsdic; /* dictionary used for namespacing */ - moo_oop_set_t cdic; /* constant dictionary */ moo_oop_t trsize; /* trailer size for new instances */ /* [0] - initial values for instance variables of new instances @@ -1041,7 +1062,6 @@ struct moo_t moo_oop_class_t _byte_array; /* ByteArray */ moo_oop_class_t _symbol_set; /* SymbolSet */ moo_oop_class_t _dictionary; - moo_oop_class_t _system_dictionary; /* SystemDictionary */ moo_oop_class_t _namespace; /* Namespace */ moo_oop_class_t _pool_dictionary; /* PoolDictionary */ @@ -1078,8 +1098,8 @@ struct moo_t * are 3 */ moo_oop_class_t* tagged_classes[16]; - moo_oop_set_t symtab; /* system-wide symbol table. instance of SymbolSet */ - moo_oop_set_t sysdic; /* system dictionary. instance of SystemDictionary */ + moo_oop_dic_t symtab; /* system-wide symbol table. instance of SymbolSet */ + moo_oop_nsdic_t sysdic; /* system dictionary. instance of Namespace */ moo_oop_process_scheduler_t processor; /* instance of ProcessScheduler */ moo_oop_process_t nil_process; /* instance of Process */ moo_oop_char_t dicnewsym; /* symbol new: for dictionary */ @@ -1319,6 +1339,7 @@ enum moo_synerrnum_t MOO_SYNERR_VARUNUSE, /* unsuable variable in compiled code */ MOO_SYNERR_VARINACC, /* inaccessible variable - e.g. accessing an instance variable from a class method is not allowed. */ MOO_SYNERR_VARAMBIG, /* ambiguious variable - e.g. the variable is found in multiple pool dictionaries imported */ + MOO_SYNERR_SELFINACC, /* inaccessible self */ MOO_SYNERR_PRIMARYINVAL, /* wrong expression primary */ MOO_SYNERR_TMPRFLOOD, /* too many temporaries */ MOO_SYNERR_ARGFLOOD, /* too many arguments */ @@ -1591,7 +1612,7 @@ MOO_EXPORT int moo_inttoooi ( MOO_EXPORT moo_oop_t moo_findclass ( moo_t* moo, - moo_oop_set_t nsdic, + moo_oop_nsdic_t nsdic, const moo_ooch_t* name );