gave up the idea of constants.
enhanced namespace handling with selfns and self uniformified identifier handling related to namespacing
This commit is contained in:
parent
36c48a8daf
commit
34a5e0cab8
@ -6,7 +6,7 @@ class(#pointer,#limited) Class(Apex)
|
||||
{
|
||||
var spec, selfspec, superclass, subclasses, name, modname.
|
||||
var instvars, classinstvars, classvars, pooldics.
|
||||
var instmthdic, classmthdic, nsup, nsdic, cdic.
|
||||
var instmthdic, classmthdic, nsup, nsdic.
|
||||
var trsize, initv, initv_ci.
|
||||
|
||||
method(#class) initialize { ^self }
|
||||
|
@ -217,13 +217,13 @@ extend MethodContext
|
||||
method isExceptionContext
|
||||
{
|
||||
## 12 - MOO_METHOD_PREAMBLE_EXCEPTION in VM.
|
||||
^self.method preambleCode == 12.
|
||||
^self.method preambleCode == 13.
|
||||
}
|
||||
|
||||
method isEnsureContext
|
||||
{
|
||||
## 13 - MOO_METHOD_PREAMBLE_ENSURE in VM.
|
||||
^self.method preambleCode == 13
|
||||
^self.method preambleCode == 14
|
||||
}
|
||||
|
||||
method ensureBlock
|
||||
@ -236,7 +236,7 @@ extend MethodContext
|
||||
* instance variables of the method context. As MethodContex has
|
||||
* 8 instance variables, the ensure block must be at the 9th position
|
||||
* which translates to index 8 *)
|
||||
^if (self.method preambleCode == 13) { self basicAt: 8 } else { nil }
|
||||
^if (self.method preambleCode == 14) { self basicAt: 8 } else { nil }
|
||||
}
|
||||
|
||||
|
||||
|
655
moo/lib/comp.c
655
moo/lib/comp.c
@ -67,7 +67,9 @@ enum var_type_t
|
||||
|
||||
VAR_GLOBAL,
|
||||
VAR_ARGUMENT,
|
||||
VAR_TEMPORARY
|
||||
VAR_TEMPORARY,
|
||||
|
||||
VAR_LITERAL /* used when compiling pooldic elements only */
|
||||
};
|
||||
typedef enum var_type_t var_type_t;
|
||||
|
||||
@ -75,8 +77,12 @@ struct var_info_t
|
||||
{
|
||||
var_type_t type;
|
||||
moo_ooi_t pos; /* not used for VAR_GLOBAL */
|
||||
moo_oop_class_t cls; /* useful if type is VAR_CLASS. note MOO_NULL indicates the self class. */
|
||||
moo_oop_class_t cls; /* useful if type is VAR_CLASS(class variable). note MOO_NULL indicates the self class. */
|
||||
union
|
||||
{
|
||||
moo_oop_association_t gbl; /* used for VAR_GLOBAL only */
|
||||
moo_oop_t lit; /* used for VAR_LITERAL only */
|
||||
} u;
|
||||
};
|
||||
typedef struct var_info_t var_info_t;
|
||||
|
||||
@ -91,8 +97,6 @@ static struct voca_t
|
||||
{ 5, { 'c','l','a','s','s' } },
|
||||
{ 6, { '#','c','l','a','s','s' } },
|
||||
{ 10, { '#','c','l','a','s','s','i','n','s','t' } },
|
||||
{ 5, { 'c','o','n','s','t' } },
|
||||
{ 8, { 'c','o','n','s','t','a','n','t' } },
|
||||
{ 8, { 'c','o','n','t','i','n','u','e' } },
|
||||
{ 3, { 'd','c','l' } },
|
||||
{ 2, { 'd','o' } },
|
||||
@ -123,6 +127,7 @@ static struct voca_t
|
||||
{ 10, { 'p','r','i','m','i','t','i','v','e',':' } },
|
||||
{ 10, { '#','p','r','i','m','i','t','i','v','e' } },
|
||||
{ 4, { 's','e','l','f' } },
|
||||
{ 6, { 's','e','l','f','n','s' } },
|
||||
{ 5, { 's','u','p','e','r' } },
|
||||
{ 11, { 't','h','i','s','C','o','n','t','e','x','t' } },
|
||||
{ 11, { 't','h','i','s','P','r','o','c','e','s','s' } },
|
||||
@ -151,8 +156,6 @@ enum voca_id_t
|
||||
VOCA_CLASS,
|
||||
VOCA_CLASS_S,
|
||||
VOCA_CLASSINST_S,
|
||||
VOCA_CONST,
|
||||
VOCA_CONSTANT,
|
||||
VOCA_CONTINUE,
|
||||
VOCA_DCL,
|
||||
VOCA_DO,
|
||||
@ -183,6 +186,7 @@ enum voca_id_t
|
||||
VOCA_PRIMITIVE_COLON,
|
||||
VOCA_PRIMITIVE_S,
|
||||
VOCA_SELF,
|
||||
VOCA_SELFNS,
|
||||
VOCA_SUPER,
|
||||
VOCA_THIS_CONTEXT,
|
||||
VOCA_THIS_PROCESS,
|
||||
@ -210,6 +214,7 @@ 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_oop_t token_to_literal (moo_t* moo, int rdonly);
|
||||
static moo_oop_t find_element_in_compiling_pooldic (moo_t* moo, const moo_oocs_t* name);
|
||||
|
||||
static MOO_INLINE int is_spacechar (moo_ooci_t c)
|
||||
{
|
||||
@ -328,6 +333,7 @@ static int is_reserved_word (const moo_oocs_t* ucs)
|
||||
VOCA_ERROR,
|
||||
VOCA_THIS_CONTEXT,
|
||||
VOCA_THIS_PROCESS,
|
||||
VOCA_SELFNS,
|
||||
VOCA_IF,
|
||||
VOCA_ELSE,
|
||||
VOCA_ELSIF,
|
||||
@ -1128,6 +1134,10 @@ static int get_ident (moo_t* moo, moo_ooci_t char_read_ahead)
|
||||
{
|
||||
SET_TOKEN_TYPE (moo, MOO_IOTOK_THIS_PROCESS);
|
||||
}
|
||||
else if (is_token_word(moo, VOCA_SELFNS))
|
||||
{
|
||||
SET_TOKEN_TYPE (moo, MOO_IOTOK_SELFNS);
|
||||
}
|
||||
else if (is_token_word(moo, VOCA_IF))
|
||||
{
|
||||
SET_TOKEN_TYPE (moo, MOO_IOTOK_IF);
|
||||
@ -2594,11 +2604,11 @@ static int set_class_level_variable_initv (moo_t* moo, var_type_t var_type, moo_
|
||||
{
|
||||
moo_oow_t newcapa, oldcapa;
|
||||
/*moo_oow_t i;*/
|
||||
moo_oop_t* tmp;
|
||||
moo_initv_t* tmp;
|
||||
|
||||
oldcapa = moo->c->cls.var[var_type].initv_capa;
|
||||
newcapa = MOO_ALIGN_POW2 ((var_index + 1), 32);
|
||||
tmp = moo_reallocmem (moo, moo->c->cls.var[var_type].initv, newcapa * MOO_SIZEOF(moo_oop_t));
|
||||
tmp = moo_reallocmem (moo, moo->c->cls.var[var_type].initv, newcapa * MOO_SIZEOF(*tmp));
|
||||
if (!tmp) return -1;
|
||||
|
||||
/*for (i = moo->c->cls.var[var_type].initv_capa; i < newcapa; i++) tmp[i] = MOO_NULL;*/
|
||||
@ -2613,12 +2623,16 @@ static int set_class_level_variable_initv (moo_t* moo, var_type_t var_type, moo_
|
||||
moo_oow_t i;
|
||||
|
||||
for (i = moo->c->cls.var[var_type].initv_count; i < var_index; i++)
|
||||
moo->c->cls.var[var_type].initv[i] = MOO_NULL;
|
||||
{
|
||||
moo->c->cls.var[var_type].initv[i].v = MOO_NULL;
|
||||
moo->c->cls.var[var_type].initv[i].flags = 0;
|
||||
}
|
||||
|
||||
moo->c->cls.var[var_type].initv_count = var_index + 1;
|
||||
}
|
||||
|
||||
moo->c->cls.var[var_type].initv[var_index] = initv;
|
||||
moo->c->cls.var[var_type].initv[var_index].v = initv;
|
||||
moo->c->cls.var[var_type].initv[var_index].flags = 0; /* TODO: set flags properly */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2674,6 +2688,7 @@ static moo_ooi_t find_class_level_variable (moo_t* moo, moo_oop_class_t self, co
|
||||
if (find_word_in_string(&hs, name, &pos) >= 0)
|
||||
{
|
||||
super = self->superclass;
|
||||
MOO_ASSERT (moo, super == moo->c->cls.super_oop);
|
||||
|
||||
/* 'self' may be MOO_NULL if MOO_NULL has been given for it.
|
||||
* the caller must take good care when interpreting the meaning of
|
||||
@ -2684,6 +2699,7 @@ static moo_ooi_t find_class_level_variable (moo_t* moo, moo_oop_class_t self, co
|
||||
}
|
||||
|
||||
super = self->superclass;
|
||||
MOO_ASSERT (moo, super == moo->c->cls.super_oop);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2694,7 +2710,7 @@ static moo_ooi_t find_class_level_variable (moo_t* moo, moo_oop_class_t self, co
|
||||
if (find_word_in_string(&moo->c->cls.var[index].str, name, &pos) >= 0)
|
||||
{
|
||||
super = moo->c->cls.super_oop;
|
||||
var->cls = self;
|
||||
var->cls = MOO_NULL; /* the current class being compiled */
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
@ -3276,11 +3292,11 @@ if super is variable-nonpointer, no instance variable is allowed.
|
||||
|
||||
GET_TOKEN (moo);
|
||||
|
||||
/* [NOTE] default value assignment. only a literal is allowed
|
||||
/* [NOTE] default value assignment. only a literal is allowed.
|
||||
* the initial values for instance variables and
|
||||
* class instance variables are set to read-only.
|
||||
* this is likely to change if the actual initial
|
||||
* value assignment upon instantiation employes
|
||||
* I may change this if i get the actual initial
|
||||
* value assignment upon instantiation to employ
|
||||
* deep-copying in moo_instantiate() and in the compiler. */
|
||||
lit = token_to_literal (moo, dcl_type != VAR_CLASS);
|
||||
if (!lit) return -1;
|
||||
@ -3433,139 +3449,6 @@ static int compile_class_level_imports (moo_t* moo)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int compile_class_level_constants (moo_t* moo)
|
||||
{
|
||||
#if 0
|
||||
if (moo->c->cls.self_oop)
|
||||
{
|
||||
/* the current class has been created already */
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
#endif
|
||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_LPAREN)
|
||||
{
|
||||
/* process variable declaration modifiers */
|
||||
GET_TOKEN (moo);
|
||||
|
||||
if (TOKEN_TYPE(moo) != MOO_IOTOK_RPAREN)
|
||||
{
|
||||
do
|
||||
{
|
||||
/* [NOTE] no modifier is supported for constant declarations.
|
||||
* the following code is for consistency sake only */
|
||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_COMMA || TOKEN_TYPE(moo) == MOO_IOTOK_EOF || TOKEN_TYPE(moo) == MOO_IOTOK_RPAREN)
|
||||
{
|
||||
/* no modifier is present */
|
||||
set_syntax_error (moo, MOO_SYNERR_MODIFIER, TOKEN_LOC(moo), TOKEN_NAME(moo));
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* invalid modifier */
|
||||
set_syntax_error (moo, MOO_SYNERR_MODIFIERINVAL, TOKEN_LOC(moo), TOKEN_NAME(moo));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (TOKEN_TYPE(moo) != MOO_IOTOK_COMMA) break; /* hopefully ) */
|
||||
GET_TOKEN (moo); /* get the token after , */
|
||||
}
|
||||
while (1);
|
||||
}
|
||||
|
||||
if (TOKEN_TYPE(moo) != MOO_IOTOK_RPAREN)
|
||||
{
|
||||
/* ) expected */
|
||||
set_syntax_error (moo, MOO_SYNERR_RPAREN, TOKEN_LOC(moo), TOKEN_NAME(moo));
|
||||
return -1;
|
||||
}
|
||||
|
||||
GET_TOKEN (moo);
|
||||
}
|
||||
|
||||
/* variable declaration */
|
||||
do
|
||||
{
|
||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT)
|
||||
{
|
||||
var_info_t var;
|
||||
|
||||
#if 0
|
||||
if (dcl_type == VAR_INSTANCE && (moo->c->cls.flags & CLASS_INDEXED) && (moo->c->cls.indexed_type != MOO_OBJ_TYPE_OOP))
|
||||
{
|
||||
set_syntax_error (moo, MOO_SYNERR_VARNAMEDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (find_class_level_variable(moo, MOO_NULL, TOKEN_NAME(moo), &var) >= 0 ||
|
||||
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;
|
||||
}
|
||||
|
||||
if (add_class_level_variable(moo, dcl_type, TOKEN_NAME(moo)) <= -1) return -1;
|
||||
#endif
|
||||
|
||||
GET_TOKEN (moo);
|
||||
|
||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_ASSIGN)
|
||||
{
|
||||
moo_oop_t lit;
|
||||
|
||||
GET_TOKEN (moo); /* skip := and go on the the value token */
|
||||
|
||||
/* [NOTE] default value assignment. only a literal is allowed
|
||||
* the initial values for instance variables and
|
||||
* class instance variables are set to read-only.
|
||||
* this is likely to change if the actual initial
|
||||
* value assignment upon instantiation employes
|
||||
* deep-copying in moo_instantiate() and in the compiler. */
|
||||
lit = token_to_literal (moo, 1);
|
||||
if (!lit) return -1;
|
||||
|
||||
/* TODO: store the constannt value... */
|
||||
|
||||
GET_TOKEN (moo);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_syntax_error (moo, MOO_SYNERR_ASSIGN, TOKEN_LOC(moo), TOKEN_NAME(moo));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (TOKEN_TYPE(moo) == MOO_IOTOK_COMMA || TOKEN_TYPE(moo) == MOO_IOTOK_EOF || TOKEN_TYPE(moo) == MOO_IOTOK_PERIOD)
|
||||
{
|
||||
/* no variable name is present */
|
||||
set_syntax_error (moo, MOO_SYNERR_VARNAMEDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo));
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT)
|
||||
{
|
||||
set_syntax_error (moo, MOO_SYNERR_COMMA, TOKEN_LOC(moo), TOKEN_NAME(moo));
|
||||
return -1;
|
||||
}
|
||||
else if (TOKEN_TYPE(moo) != MOO_IOTOK_COMMA) break; /* hopefully . */
|
||||
GET_TOKEN (moo);
|
||||
}
|
||||
while (1);
|
||||
|
||||
if (TOKEN_TYPE(moo) != MOO_IOTOK_PERIOD)
|
||||
{
|
||||
set_syntax_error (moo, MOO_SYNERR_PERIOD, TOKEN_LOC(moo), TOKEN_NAME(moo));
|
||||
return -1;
|
||||
}
|
||||
|
||||
GET_TOKEN (moo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int compile_unary_method_name (moo_t* moo)
|
||||
{
|
||||
@ -3951,144 +3834,8 @@ static int compile_method_pragma (moo_t* moo)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int find_dotted_ident (moo_t* moo, const moo_oocs_t* name, const moo_ioloc_t* name_loc, var_info_t* var)
|
||||
static int validate_class_level_variable (moo_t* moo, var_info_t* var, const moo_oocs_t* name, const moo_ioloc_t* name_loc)
|
||||
{
|
||||
/* if a name is dotted,
|
||||
*
|
||||
* self.XXX - instance variable
|
||||
* A.B.C - namespace or pool dictionary related reference.
|
||||
* self.B.C - B.C under the current class where B is not an instance variable
|
||||
*/
|
||||
|
||||
moo_oocs_t last;
|
||||
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.
|
||||
* 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.
|
||||
* a proper variable name is expected. */
|
||||
set_syntax_error (moo, MOO_SYNERR_VARNAME, name_loc, name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (moo->c->cls.self_oop)
|
||||
{
|
||||
/* 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_not_class_level;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto self_inacc;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (moo->c->cls.self_oop)
|
||||
{
|
||||
self_not_class_level:
|
||||
top_dic = moo->c->cls.ns_oop;
|
||||
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, 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, (moo_oop_dic_t)ns_oop, &last);
|
||||
if (!ass)
|
||||
{
|
||||
/* undeclared identifier */
|
||||
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;
|
||||
|
||||
MOO_MEMSET (var, 0, MOO_SIZEOF(*var));
|
||||
|
||||
if (name_dotted)
|
||||
{
|
||||
int n;
|
||||
if ((n = find_dotted_ident (moo, name, name_loc, var)) <= -1) return -1;
|
||||
if (n >= 1) goto class_level_variable; /* prefixed with self. */
|
||||
return 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;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (find_class_level_variable(moo, moo->c->cls.self_oop, name, var) >= 0)
|
||||
{
|
||||
class_level_variable:
|
||||
switch (var->type)
|
||||
{
|
||||
case VAR_INSTANCE:
|
||||
@ -4131,14 +3878,216 @@ static int get_variable_info (moo_t* moo, const moo_oocs_t* name, const moo_iolo
|
||||
moo_seterrnum (moo, MOO_EINTERN);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static moo_oow_t is_dotted_ident_prefixed (const moo_oocs_t* name, int voca_id)
|
||||
{
|
||||
if (name->len > vocas[voca_id].len &&
|
||||
moo_equaloochars(name->ptr, vocas[voca_id].str, vocas[voca_id].len) &&
|
||||
name->ptr[vocas[voca_id].len] == '.') return vocas[voca_id].len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static MOO_INLINE int find_dotted_ident (moo_t* moo, const moo_oocs_t* name, const moo_ioloc_t* name_loc, var_info_t* var)
|
||||
{
|
||||
/* if a name is dotted,
|
||||
*
|
||||
* self.XXX - instance variable
|
||||
* A.B.C - namespace or pool dictionary related reference.
|
||||
* self.B.C - B.C under the current class where B is not an instance variable
|
||||
*/
|
||||
|
||||
moo_oocs_t last;
|
||||
moo_oop_nsdic_t top_dic, ns_oop;
|
||||
moo_oop_association_t ass;
|
||||
|
||||
moo_oow_t pxlen;
|
||||
|
||||
moo_oocs_t xname;
|
||||
moo_ioloc_t xname_loc;
|
||||
|
||||
top_dic = MOO_NULL;
|
||||
xname = *name;
|
||||
xname_loc = *name_loc;
|
||||
|
||||
if ((pxlen = is_dotted_ident_prefixed (name, VOCA_SELF)) > 0)
|
||||
{
|
||||
/* the first word in the dotted notation is self */
|
||||
|
||||
if (!moo_findoochar (name->ptr + pxlen + 1, name->len - pxlen - 1, '.'))
|
||||
{
|
||||
/* the dotted name is composed of 2 segments only */
|
||||
last.ptr = name->ptr + pxlen + 1;
|
||||
last.len = name->len - pxlen - 1;
|
||||
|
||||
if (is_reserved_word(&last))
|
||||
{
|
||||
/* self. is followed by a reserved word.
|
||||
* a proper variable name is expected. */
|
||||
set_syntax_error (moo, MOO_SYNERR_VARNAME, name_loc, name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (moo->c->cls.super_oop)
|
||||
{
|
||||
/* called inside a class definition */
|
||||
|
||||
/* [NOTE]
|
||||
* cls.ns_oop is set when the class name is enountered.
|
||||
* cls.super_oop is set when the parent class name is enountered.
|
||||
* cls.super_oop may still be MOO_NULL even if cls.ns_oop is not.
|
||||
* on the other hand, cls.ns_oop is not MOO_NULL as long as
|
||||
* cls.super_oop is not MOO_NULL.
|
||||
*/
|
||||
|
||||
MOO_ASSERT (moo, moo->c->cls.ns_oop != MOO_NULL);
|
||||
MOO_ASSERT (moo, moo->c->pooldic.ns_oop == MOO_NULL);
|
||||
/* moo->c->cls.self_oop may still be MOO_NULL if the class has not been instantiated */
|
||||
|
||||
if (find_class_level_variable(moo, moo->c->cls.self_oop, &last, var) >= 0)
|
||||
{
|
||||
/* if the current class has not been instantiated,
|
||||
* no validation nor adjustment of the var->pos field is performed */
|
||||
if (moo->c->cls.self_oop && validate_class_level_variable (moo, var, name, name_loc) <= -1) return -1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (moo->c->pooldic.ns_oop)
|
||||
{
|
||||
moo_oop_t v;
|
||||
|
||||
/* called inside a pooldic definition */
|
||||
MOO_ASSERT (moo, moo->c->cls.ns_oop == MOO_NULL);
|
||||
MOO_ASSERT (moo, moo->c->cls.super_oop == MOO_NULL);
|
||||
MOO_ASSERT (moo, moo->c->cls.self_oop == MOO_NULL);
|
||||
MOO_ASSERT (moo, moo->c->pooldic.pd_oop == MOO_NULL);
|
||||
|
||||
v = find_element_in_compiling_pooldic (moo, &last);
|
||||
if (!v)
|
||||
{
|
||||
set_syntax_error (moo, MOO_SYNERR_VARUNDCL, name_loc, name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
var->type = VAR_LITERAL;
|
||||
var->u.lit = v; /* TODO: change this */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!moo->c->cls.self_oop)
|
||||
{
|
||||
/* self is not usable when it's not compiling in a class.
|
||||
* a pooldic definition cannot contain subdictionaries.
|
||||
* the pooldic is a terminal point and the items inside
|
||||
* are final nodes. if self is followed by more than 1
|
||||
* subsegments, it's */
|
||||
set_syntax_error (moo, MOO_SYNERR_VARINACC, name_loc, name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* namespace that the current class starts */
|
||||
top_dic = moo->c->cls.self_oop->nsdic;
|
||||
pxlen++; /* include . into the length */
|
||||
}
|
||||
else if ((pxlen = is_dotted_ident_prefixed (name, VOCA_SELFNS)) > 0)
|
||||
{
|
||||
/* the first segment is selfns which indicates a namespace that
|
||||
* the current class belongs to */
|
||||
if (moo->c->cls.ns_oop)
|
||||
{
|
||||
/* compiling in a class definition */
|
||||
top_dic = moo->c->cls.ns_oop;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* compiling in a pooldic definition */
|
||||
MOO_ASSERT (moo, moo->c->pooldic.ns_oop != MOO_NULL);
|
||||
top_dic = moo->c->pooldic.ns_oop;
|
||||
}
|
||||
pxlen++; /* include . into the length */
|
||||
}
|
||||
|
||||
if ((moo_oop_t)top_dic == moo->_nil) top_dic = MOO_NULL;
|
||||
xname.ptr += pxlen;
|
||||
xname.len -= pxlen;
|
||||
xname_loc.colm += pxlen;
|
||||
|
||||
/*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, (moo_oop_dic_t)ns_oop, &last);
|
||||
if (!ass)
|
||||
{
|
||||
/* undeclared identifier */
|
||||
set_syntax_error (moo, MOO_SYNERR_VARUNDCL, name_loc, name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
var->type = VAR_GLOBAL;
|
||||
var->u.gbl = ass;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static MOO_INLINE int find_undotted_ident (moo_t* moo, const moo_oocs_t* name, const moo_ioloc_t* name_loc, var_info_t* var)
|
||||
{
|
||||
moo_oow_t index;
|
||||
moo_oop_association_t ass;
|
||||
|
||||
lookup_in_dics:
|
||||
/* find an undotted identifier in dictionaries */
|
||||
if (moo->c->cls.self_oop)
|
||||
{
|
||||
/* the current class being compiled has been instantiated.
|
||||
* look up in the temporary variable list if compiling in a method */
|
||||
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;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (moo->c->cls.super_oop)
|
||||
{
|
||||
/* called inside a class definition */
|
||||
/* read a comment in find_dotted_ident() for the reason behind
|
||||
* the if condition above. */
|
||||
|
||||
MOO_ASSERT (moo, moo->c->cls.ns_oop != MOO_NULL);
|
||||
MOO_ASSERT (moo, moo->c->pooldic.ns_oop == MOO_NULL);
|
||||
|
||||
if (find_class_level_variable(moo, moo->c->cls.self_oop, name, var) >= 0)
|
||||
{
|
||||
/* if the current class being compiled has not been instantiated,
|
||||
* no validation nor adjustment of the var->pos field is performed */
|
||||
return moo->c->cls.self_oop? validate_class_level_variable (moo, var, name, name_loc): 0;
|
||||
}
|
||||
}
|
||||
else if (moo->c->pooldic.ns_oop)
|
||||
{
|
||||
moo_oop_t v;
|
||||
|
||||
/* called inside a pooldic definition */
|
||||
MOO_ASSERT (moo, moo->c->cls.ns_oop == MOO_NULL);
|
||||
MOO_ASSERT (moo, moo->c->cls.super_oop == MOO_NULL);
|
||||
MOO_ASSERT (moo, moo->c->cls.self_oop == MOO_NULL);
|
||||
MOO_ASSERT (moo, moo->c->pooldic.pd_oop == MOO_NULL);
|
||||
|
||||
v = find_element_in_compiling_pooldic (moo, name);
|
||||
if (!v)
|
||||
{
|
||||
set_syntax_error (moo, MOO_SYNERR_VARUNDCL, name_loc, name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
var->type = VAR_LITERAL;
|
||||
var->u.lit = v; /* TODO: change this */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
@ -4180,10 +4129,22 @@ static int get_variable_info (moo_t* moo, const moo_oocs_t* name, const moo_iolo
|
||||
}
|
||||
|
||||
var->type = VAR_GLOBAL;
|
||||
var->gbl = ass;
|
||||
}
|
||||
}
|
||||
var->u.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)
|
||||
{
|
||||
int x;
|
||||
|
||||
MOO_MEMSET (var, 0, MOO_SIZEOF(*var));
|
||||
|
||||
x = name_dotted? find_dotted_ident (moo, name, name_loc, var): find_undotted_ident (moo, name, name_loc, var);
|
||||
if (x <= -1) return -1;
|
||||
|
||||
/* final validation on the range of pos field. just check regardless of var->type.
|
||||
* i assume the functions above don't taint the var-type field when it's meaningless. */
|
||||
if (var->pos > MAX_CODE_INDEX)
|
||||
{
|
||||
/* the assignee is not usable because its index is too large
|
||||
@ -4710,6 +4671,7 @@ static int compile_expression_primary (moo_t* moo, const moo_oocs_t* ident, cons
|
||||
{
|
||||
/* the caller has read the identifier and the next word */
|
||||
handle_ident:
|
||||
MOO_ASSERT (moo, moo->c->cls.super_oop != MOO_NULL && moo->c->cls.self_oop != MOO_NULL);
|
||||
if (get_variable_info(moo, ident, ident_loc, ident_dotted, &var) <= -1) return -1;
|
||||
|
||||
switch (var.type)
|
||||
@ -4761,7 +4723,7 @@ static int compile_expression_primary (moo_t* moo, const moo_oocs_t* ident, cons
|
||||
* the code compiled before the deletion will still access
|
||||
* the deleted association
|
||||
*/
|
||||
if (add_literal(moo, (moo_oop_t)var.gbl, &index) <= -1 ||
|
||||
if (add_literal(moo, (moo_oop_t)var.u.gbl, &index) <= -1 ||
|
||||
emit_single_param_instruction(moo, BCODE_PUSH_OBJECT_0, index) <= -1) return -1;
|
||||
break;
|
||||
|
||||
@ -4840,6 +4802,11 @@ static int compile_expression_primary (moo_t* moo, const moo_oocs_t* ident, cons
|
||||
GET_TOKEN (moo);
|
||||
break;
|
||||
|
||||
case MOO_IOTOK_SELFNS:
|
||||
if (emit_byte_instruction(moo, BCODE_PUSH_RECEIVER_NS) <= -1) return -1;
|
||||
GET_TOKEN (moo);
|
||||
break;
|
||||
|
||||
case MOO_IOTOK_CHARLIT:
|
||||
MOO_ASSERT (moo, TOKEN_NAME_LEN(moo) == 1);
|
||||
if (emit_push_character_literal(moo, TOKEN_NAME_PTR(moo)[0]) <= -1) return -1;
|
||||
@ -5725,6 +5692,7 @@ static int compile_method_expression (moo_t* moo, int pop)
|
||||
* assignee to update the actual pointer after the recursive
|
||||
* compile_method_expression() call */
|
||||
assignee.ptr = &moo->c->mth.assignees.ptr[assignee_offset];
|
||||
MOO_ASSERT (moo, moo->c->cls.super_oop != MOO_NULL && moo->c->cls.self_oop != MOO_NULL);
|
||||
if (get_variable_info(moo, &assignee, &assignee_loc, assignee_dotted, &var) <= -1) goto oops;
|
||||
|
||||
switch (var.type)
|
||||
@ -5771,7 +5739,7 @@ static int compile_method_expression (moo_t* moo, int pop)
|
||||
break;
|
||||
|
||||
case VAR_GLOBAL:
|
||||
if (add_literal(moo, (moo_oop_t)var.gbl, &index) <= -1 ||
|
||||
if (add_literal(moo, (moo_oop_t)var.u.gbl, &index) <= -1 ||
|
||||
emit_single_param_instruction(moo, (pop? BCODE_POP_INTO_OBJECT_0: BCODE_STORE_INTO_OBJECT_0), index) <= -1) return -1;
|
||||
ret = pop;
|
||||
break;
|
||||
@ -6051,6 +6019,10 @@ static int add_compiled_method (moo_t* moo)
|
||||
preamble_code = MOO_METHOD_PREAMBLE_RETURN_PROCESS;
|
||||
break;
|
||||
|
||||
case BCODE_PUSH_RECEIVER_NS:
|
||||
preamble_code = MOO_METHOD_PREAMBLE_RETURN_RECEIVER_NS;
|
||||
break;
|
||||
|
||||
case BCODE_PUSH_NIL:
|
||||
preamble_code = MOO_METHOD_PREAMBLE_RETURN_NIL;
|
||||
break;
|
||||
@ -6548,8 +6520,8 @@ static int make_default_initial_values (moo_t* moo, var_type_t var_type)
|
||||
|
||||
for (i = 0; i < moo->c->cls.var[var_type].initv_count; i++)
|
||||
{
|
||||
if (moo->c->cls.var[var_type].initv[i])
|
||||
((moo_oop_oop_t)tmp)->slot[j] = moo->c->cls.var[var_type].initv[i];
|
||||
if (moo->c->cls.var[var_type].initv[i].v)
|
||||
((moo_oop_oop_t)tmp)->slot[j] = moo->c->cls.var[var_type].initv[i].v;
|
||||
j++;
|
||||
}
|
||||
|
||||
@ -6698,8 +6670,7 @@ static int make_defined_class (moo_t* moo)
|
||||
MOO_ASSERT (moo, MOO_CLASS_NAMED_INSTVARS + j + initv_count <= MOO_OBJ_GET_SIZE(moo->c->cls.self_oop));
|
||||
for (i = 0; i < initv_count; i++)
|
||||
{
|
||||
/* ((moo_oop_oop_t)moo->c->cls.self_oop)->slot[MOO_CLASS_NAMED_INSTVARS + j] = moo->c->cls.var[VAR_CLASS].initv[i]; */
|
||||
moo->c->cls.self_oop->slot[j] = moo->c->cls.var[VAR_CLASS].initv[i];
|
||||
moo->c->cls.self_oop->slot[j] = moo->c->cls.var[VAR_CLASS].initv[i].v;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
@ -6929,6 +6900,7 @@ static int __compile_class_definition (moo_t* moo, int extend)
|
||||
else
|
||||
{
|
||||
int super_is_nil = 0;
|
||||
int superfqn_is_dotted;
|
||||
|
||||
MOO_INFO2 (moo, "Defining a class %.*js\n", moo->c->cls.fqn.len, moo->c->cls.fqn.ptr);
|
||||
|
||||
@ -6959,17 +6931,7 @@ static int __compile_class_definition (moo_t* moo, int extend)
|
||||
if (set_superclass_fqn(moo, TOKEN_NAME(moo)) <= -1) return -1;
|
||||
moo->c->cls.superfqn_loc = moo->c->tok.loc;
|
||||
|
||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED)
|
||||
{
|
||||
if (preprocess_dotted_name(moo, PDN_DONT_ADD_NS, MOO_NULL, &moo->c->cls.superfqn, &moo->c->cls.superfqn_loc, &moo->c->cls.supername, &moo->c->cls.superns_oop) <= -1) return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if no fully qualified name is specified for the super class name,
|
||||
* the name is searched in the name space that the class being defined
|
||||
* belongs to first and in the 'moo->sysdic'. */
|
||||
moo->c->cls.superns_oop = moo->c->cls.ns_oop;
|
||||
}
|
||||
superfqn_is_dotted = (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED);
|
||||
|
||||
GET_TOKEN (moo);
|
||||
if (TOKEN_TYPE(moo) != MOO_IOTOK_RPAREN)
|
||||
@ -6980,7 +6942,6 @@ 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_oop_dic_t)moo->c->cls.ns_oop, &moo->c->cls.name);
|
||||
if (ass)
|
||||
{
|
||||
@ -7009,19 +6970,21 @@ static int __compile_class_definition (moo_t* moo, int extend)
|
||||
}
|
||||
else
|
||||
{
|
||||
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_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)
|
||||
var_info_t var;
|
||||
|
||||
if (get_variable_info (moo, &moo->c->cls.superfqn, &moo->c->cls.superfqn_loc, superfqn_is_dotted, &var) <= -1) return -1;
|
||||
|
||||
|
||||
if (var.type != VAR_GLOBAL) goto unknown_superclass;
|
||||
if (MOO_CLASSOF(moo, var.u.gbl->value) == moo->_class && MOO_OBJ_GET_FLAGS_KERNEL(var.u.gbl->value) != 1)
|
||||
{
|
||||
/* the value found must be a class and it must not be
|
||||
* an incomplete internal class object.
|
||||
* 0(non-kernel object)
|
||||
* 1(incomplete kernel object),
|
||||
* 2(complete kernel object) */
|
||||
moo->c->cls.super_oop = ass->value;
|
||||
|
||||
moo->c->cls.super_oop = var.u.gbl->value;
|
||||
|
||||
/* the superclass became known. */
|
||||
if (((moo_oop_class_t)moo->c->cls.super_oop)->trsize != moo->_nil &&
|
||||
@ -7042,6 +7005,7 @@ static int __compile_class_definition (moo_t* moo, int extend)
|
||||
}
|
||||
else
|
||||
{
|
||||
unknown_superclass:
|
||||
/* there is no object with such a name. or,
|
||||
* the object found with the name is not a class object. or,
|
||||
* the class object found is a internally defined kernel
|
||||
@ -7204,12 +7168,6 @@ static int __compile_class_definition (moo_t* moo, int extend)
|
||||
GET_TOKEN (moo);
|
||||
if (compile_class_level_imports(moo) <= -1) return -1;
|
||||
}
|
||||
else if (is_token_word(moo, VOCA_CONST) || is_token_word(moo, VOCA_CONSTANT))
|
||||
{
|
||||
/* constant declaration */
|
||||
GET_TOKEN (moo);
|
||||
if (compile_class_level_constants(moo) <= -1) return -1;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
while (1);
|
||||
@ -7247,12 +7205,6 @@ static int __compile_class_definition (moo_t* moo, int extend)
|
||||
GET_TOKEN (moo);
|
||||
if (compile_method_definition(moo) <= -1) return -1;
|
||||
}
|
||||
else if (is_token_word(moo, VOCA_CONST) || is_token_word(moo, VOCA_CONSTANT))
|
||||
{
|
||||
/* constant declaration */
|
||||
GET_TOKEN (moo);
|
||||
if (compile_class_level_constants(moo) <= -1) return -1;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
while (1);
|
||||
@ -7385,14 +7337,22 @@ static moo_oop_t token_to_literal (moo_t* moo, int rdonly)
|
||||
{
|
||||
var_info_t var;
|
||||
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)
|
||||
if (var.type == VAR_GLOBAL)
|
||||
{
|
||||
return var.u.gbl->value;
|
||||
}
|
||||
else if (var.type == VAR_LITERAL)
|
||||
{
|
||||
return var.u.lit;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_syntax_error (moo, MOO_SYNERR_VARINACC, TOKEN_LOC(moo), TOKEN_NAME(moo));
|
||||
return MOO_NULL;
|
||||
}
|
||||
|
||||
/* [NOTE] i don't mark RDONLY on a value resolved via an identifier */
|
||||
return var.gbl->value;
|
||||
|
||||
}
|
||||
|
||||
case MOO_IOTOK_BABRACK: /* #[ - byte array literal parenthesis */
|
||||
@ -7425,6 +7385,26 @@ static moo_oop_t token_to_literal (moo_t* moo, int rdonly)
|
||||
}
|
||||
}
|
||||
|
||||
static moo_oop_t find_element_in_compiling_pooldic (moo_t* moo, const moo_oocs_t* name)
|
||||
{
|
||||
moo_oow_t i;
|
||||
moo_oop_char_t s;
|
||||
|
||||
for (i = moo->c->pooldic.start; i < moo->c->pooldic.end; i += 2)
|
||||
{
|
||||
s = (moo_oop_char_t)moo->c->arlit.ptr[i];
|
||||
MOO_ASSERT (moo, MOO_CLASSOF(moo,s) == moo->_symbol);
|
||||
if (MOO_OBJ_GET_SIZE(s) == name->len &&
|
||||
moo_equaloochars (name->ptr, MOO_OBJ_GET_CHAR_SLOT(s), name->len))
|
||||
{
|
||||
return moo->c->arlit.ptr[i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
moo_seterrnum (moo, MOO_ENOENT);
|
||||
return MOO_NULL;
|
||||
}
|
||||
|
||||
static int __compile_pooldic_definition (moo_t* moo, moo_pooldic_t* pd)
|
||||
{
|
||||
moo_oop_t lit;
|
||||
@ -7441,14 +7421,9 @@ static int __compile_pooldic_definition (moo_t* moo, moo_pooldic_t* pd)
|
||||
goto oops;
|
||||
}
|
||||
|
||||
if (moo->c->cls.self_oop && TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED)
|
||||
{
|
||||
/* 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 */
|
||||
MOO_ASSERT (moo, moo->c->cls.ns_oop == MOO_NULL);
|
||||
MOO_ASSERT (moo, moo->c->cls.super_oop == MOO_NULL);
|
||||
MOO_ASSERT (moo, moo->c->cls.self_oop == MOO_NULL);
|
||||
|
||||
if (set_pooldic_fqn(moo, pd, TOKEN_NAME(moo)) <= -1) goto oops;
|
||||
pd->fqn_loc = moo->c->tok.loc;
|
||||
@ -7480,6 +7455,8 @@ static int __compile_pooldic_definition (moo_t* moo, moo_pooldic_t* pd)
|
||||
|
||||
GET_TOKEN (moo);
|
||||
|
||||
pd->start = moo->c->arlit.count;
|
||||
pd->end = moo->c->arlit.count;
|
||||
while (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT)
|
||||
{
|
||||
lit = moo_makesymbol (moo, TOKEN_NAME_PTR(moo), TOKEN_NAME_LEN(moo));
|
||||
@ -7504,6 +7481,8 @@ static int __compile_pooldic_definition (moo_t* moo, moo_pooldic_t* pd)
|
||||
/* 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;
|
||||
pd->end = moo->c->arlit.count;
|
||||
|
||||
GET_TOKEN (moo);
|
||||
|
||||
/*if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACE) goto done;
|
||||
@ -7648,8 +7627,8 @@ static void gc_compiler (moo_t* moo)
|
||||
{
|
||||
for (j = 0; j < moo->c->cls.var[i].initv_count; j++)
|
||||
{
|
||||
register moo_oop_t x = moo->c->cls.var[i].initv[j];
|
||||
if (x) moo->c->cls.var[i].initv[j] = moo_moveoop (moo, x);
|
||||
register moo_oop_t x = moo->c->cls.var[i].initv[j].v;
|
||||
if (x) moo->c->cls.var[i].initv[j].v = moo_moveoop (moo, x);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -463,6 +463,10 @@ int moo_decode (moo_t* moo, moo_oop_method_t mth, const moo_oocs_t* classfqn)
|
||||
LOG_INST_0 (moo, "push_process");
|
||||
break;
|
||||
|
||||
case BCODE_PUSH_RECEIVER_NS:
|
||||
LOG_INST_0 (moo, "push_receiver_ns");
|
||||
break;
|
||||
|
||||
case BCODE_PUSH_NEGONE:
|
||||
LOG_INST_0 (moo, "push_negone");
|
||||
break;
|
||||
@ -479,6 +483,7 @@ int moo_decode (moo_t* moo, moo_oop_method_t mth, const moo_oocs_t* classfqn)
|
||||
LOG_INST_0 (moo, "push_two");
|
||||
break;
|
||||
|
||||
|
||||
case BCODE_PUSH_INTLIT:
|
||||
FETCH_PARAM_CODE_TO (moo, b1);
|
||||
LOG_INST_1 (moo, "push_intlit %zu", b1);
|
||||
|
@ -3944,6 +3944,18 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
|
||||
MOO_STACK_SETTOP (moo, (moo_oop_t)moo->processor->active);
|
||||
break;
|
||||
|
||||
case MOO_METHOD_PREAMBLE_RETURN_RECEIVER_NS:
|
||||
{
|
||||
moo_oop_t c;
|
||||
LOG_INST_0 (moo, "preamble_return_receiver_ns");
|
||||
MOO_STACK_POPS (moo, nargs); /* pop arguments only*/
|
||||
c = MOO_STACK_GETTOP (moo); /* get receiver */
|
||||
c = (moo_oop_t)MOO_CLASSOF(moo, c);
|
||||
if (c == (moo_oop_t)moo->_class) c = MOO_STACK_GETTOP (moo);
|
||||
MOO_STACK_SETTOP (moo, (moo_oop_t)((moo_oop_class_t)c)->nsup);
|
||||
break;
|
||||
}
|
||||
|
||||
case MOO_METHOD_PREAMBLE_RETURN_NIL:
|
||||
LOG_INST_0 (moo, "preamble_return_nil");
|
||||
MOO_STACK_POPS (moo, nargs);
|
||||
@ -5030,6 +5042,16 @@ int moo_execute (moo_t* moo)
|
||||
MOO_STACK_PUSH (moo, (moo_oop_t)moo->processor->active);
|
||||
break;
|
||||
|
||||
case BCODE_PUSH_RECEIVER_NS:
|
||||
{
|
||||
register moo_oop_t c;
|
||||
LOG_INST_0 (moo, "push_receiver_ns");
|
||||
c = (moo_oop_t)MOO_CLASSOF(moo, moo->active_context->origin->receiver_or_source);
|
||||
if (c == (moo_oop_t)moo->_class) c = moo->active_context->origin->receiver_or_source;
|
||||
MOO_STACK_PUSH (moo, (moo_oop_t)((moo_oop_class_t)c)->nsup);
|
||||
break;
|
||||
}
|
||||
|
||||
case BCODE_PUSH_NEGONE:
|
||||
LOG_INST_0 (moo, "push_negone");
|
||||
MOO_STACK_PUSH (moo, MOO_SMOOI_TO_OOP(-1));
|
||||
|
@ -320,6 +320,7 @@ struct moo_iotok_t
|
||||
MOO_IOTOK_NUMLIT,
|
||||
MOO_IOTOK_RADNUMLIT,
|
||||
MOO_IOTOK_ERRLIT, /* error(NN) */
|
||||
|
||||
MOO_IOTOK_ERROR, /* error */
|
||||
MOO_IOTOK_NIL,
|
||||
MOO_IOTOK_SELF,
|
||||
@ -328,6 +329,18 @@ struct moo_iotok_t
|
||||
MOO_IOTOK_FALSE,
|
||||
MOO_IOTOK_THIS_CONTEXT,
|
||||
MOO_IOTOK_THIS_PROCESS,
|
||||
MOO_IOTOK_SELFNS,
|
||||
|
||||
MOO_IOTOK_IF,
|
||||
MOO_IOTOK_ELSE,
|
||||
MOO_IOTOK_ELSIF,
|
||||
|
||||
MOO_IOTOK_WHILE,
|
||||
MOO_IOTOK_UNTIL,
|
||||
MOO_IOTOK_DO,
|
||||
MOO_IOTOK_BREAK,
|
||||
MOO_IOTOK_CONTINUE,
|
||||
|
||||
MOO_IOTOK_IDENT,
|
||||
MOO_IOTOK_IDENT_DOTTED,
|
||||
MOO_IOTOK_BINSEL,
|
||||
@ -348,17 +361,7 @@ struct moo_iotok_t
|
||||
MOO_IOTOK_DICBRACE, /* :{ - dictionary expression */
|
||||
MOO_IOTOK_PERIOD,
|
||||
MOO_IOTOK_COMMA,
|
||||
MOO_IOTOK_SEMICOLON,
|
||||
|
||||
MOO_IOTOK_IF,
|
||||
MOO_IOTOK_ELSE,
|
||||
MOO_IOTOK_ELSIF,
|
||||
|
||||
MOO_IOTOK_WHILE,
|
||||
MOO_IOTOK_UNTIL,
|
||||
MOO_IOTOK_DO,
|
||||
MOO_IOTOK_BREAK,
|
||||
MOO_IOTOK_CONTINUE
|
||||
MOO_IOTOK_SEMICOLON
|
||||
} type;
|
||||
|
||||
moo_oocs_t name;
|
||||
@ -425,6 +428,9 @@ struct moo_pooldic_t
|
||||
|
||||
moo_oop_dic_t pd_oop;
|
||||
moo_oop_nsdic_t ns_oop;
|
||||
|
||||
moo_oow_t start;
|
||||
moo_oow_t end;
|
||||
};
|
||||
|
||||
typedef struct moo_oopbuf_t moo_oopbuf_t;
|
||||
@ -443,6 +449,13 @@ struct moo_oobbuf_t
|
||||
moo_oow_t capa;
|
||||
};
|
||||
|
||||
typedef struct moo_initv_t moo_initv_t;
|
||||
struct moo_initv_t
|
||||
{
|
||||
moo_oop_t v;
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct moo_compiler_t
|
||||
{
|
||||
/* input handler */
|
||||
@ -490,9 +503,6 @@ 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 */
|
||||
#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;
|
||||
@ -508,10 +518,11 @@ struct moo_compiler_t
|
||||
moo_oocs_t modname; /* module name after 'from' */
|
||||
moo_oow_t modname_capa;
|
||||
|
||||
/* instance variable, class variable, class instance variable
|
||||
/* instance variable, class variable, class instance variable, constant
|
||||
* var[0] - named instance variables
|
||||
* var[1] - class instance variables
|
||||
* var[2] - class variables */
|
||||
* var[2] - class variables
|
||||
*/
|
||||
struct
|
||||
{
|
||||
moo_oocs_t str; /* long string containing all variables declared delimited by a space */
|
||||
@ -520,7 +531,7 @@ struct moo_compiler_t
|
||||
moo_oow_t count; /* the number of variables declared in this class only */
|
||||
moo_oow_t total_count; /* the number of variables declared in this class and superclasses */
|
||||
|
||||
moo_oop_t* initv;
|
||||
moo_initv_t* initv;
|
||||
moo_oow_t initv_capa;
|
||||
/* initv_count holds the index to the last variable with a
|
||||
* default initial value defined in this class only plus one.
|
||||
@ -545,7 +556,6 @@ struct moo_compiler_t
|
||||
moo_oop_dic_t* oops;
|
||||
moo_oow_t oops_capa;
|
||||
} pooldic_imp;
|
||||
|
||||
} cls;
|
||||
|
||||
/* pooldic declaration */
|
||||
@ -611,27 +621,6 @@ struct moo_compiler_t
|
||||
moo_oow_t code_capa;
|
||||
} mth;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
typedef struct moo_bchbuf_t moo_bchbuf_t;
|
||||
struct moo_bchbuf_t
|
||||
{
|
||||
moo_bch_t buf[128];
|
||||
moo_bch_t* ptr;
|
||||
moo_oow_t capa;
|
||||
};
|
||||
|
||||
typedef struct moo_oochbuf_t moo_oochbuf_t;
|
||||
struct moo_oochbuf_t
|
||||
{
|
||||
moo_ooch_t buf[128];
|
||||
moo_ooch_t* ptr;
|
||||
moo_oow_t capa;
|
||||
};
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(MOO_USE_METHOD_TRAILER)
|
||||
@ -891,13 +880,14 @@ enum moo_bcode_t
|
||||
BCODE_PUSH_FALSE = 0x84, /* 132 */
|
||||
BCODE_PUSH_CONTEXT = 0x85, /* 133 */
|
||||
BCODE_PUSH_PROCESS = 0x86, /* 134 */
|
||||
BCODE_PUSH_NEGONE = 0x87, /* 135 */
|
||||
BCODE_PUSH_RECEIVER_NS = 0x87, /* 135 */
|
||||
|
||||
BCODE_POP_INTO_INSTVAR_X = 0x88, /* 136 ## */
|
||||
|
||||
BCODE_PUSH_ZERO = 0x89, /* 137 */
|
||||
BCODE_PUSH_ONE = 0x8A, /* 138 */
|
||||
BCODE_PUSH_TWO = 0x8B, /* 139 */
|
||||
BCODE_PUSH_NEGONE = 0x89, /* 137 */
|
||||
BCODE_PUSH_ZERO = 0x8A, /* 138 */
|
||||
BCODE_PUSH_ONE = 0x8B, /* 139 */
|
||||
BCODE_PUSH_TWO = 0x8C, /* 140 */
|
||||
|
||||
BCODE_PUSH_INSTVAR_X = 0x90, /* 144 ## */
|
||||
BCODE_PUSH_TEMPVAR_X = 0x98, /* 152 ## */
|
||||
|
@ -494,7 +494,7 @@ struct moo_dic_t
|
||||
typedef struct moo_nsdic_t moo_nsdic_t;
|
||||
typedef struct moo_nsdic_t* moo_oop_nsdic_t;
|
||||
|
||||
#define MOO_CLASS_NAMED_INSTVARS 18
|
||||
#define MOO_CLASS_NAMED_INSTVARS 17
|
||||
typedef struct moo_class_t moo_class_t;
|
||||
typedef struct moo_class_t* moo_oop_class_t;
|
||||
|
||||
@ -537,8 +537,6 @@ struct moo_class_t
|
||||
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_t trsize; /* trailer size for new instances */
|
||||
|
||||
/* [0] - initial values for instance variables of new instances
|
||||
@ -619,7 +617,7 @@ struct moo_method_t
|
||||
*
|
||||
* The code can be one of the following values:
|
||||
* 0 - no special action
|
||||
* 1 - return self
|
||||
* 1 - return self (receiver)
|
||||
* 2 - return thisContext (not used)
|
||||
* 3 - return thisProcess
|
||||
* 4 - return nil
|
||||
@ -627,11 +625,12 @@ struct moo_method_t
|
||||
* 6 - return false
|
||||
* 7 - return index.
|
||||
* 8 - return -index.
|
||||
* 9 - return instvar[index]
|
||||
* 10 - do primitive[index]
|
||||
* 11 - do named primitive[index]
|
||||
* 12 - exception handler
|
||||
* 13 - ensure block
|
||||
* 9 - return selfns
|
||||
* 10 - return instvar[index]
|
||||
* 11 - do primitive[index]
|
||||
* 12 - do named primitive[index]
|
||||
* 13 - exception handler
|
||||
* 14 - ensure block
|
||||
*/
|
||||
|
||||
/* [NOTE] changing preamble code bit structure requires changes to CompiledMethod>>preambleCode */
|
||||
@ -645,17 +644,17 @@ struct moo_method_t
|
||||
#define MOO_METHOD_PREAMBLE_RETURN_RECEIVER 1
|
||||
#define MOO_METHOD_PREAMBLE_RETURN_CONTEXT 2
|
||||
#define MOO_METHOD_PREAMBLE_RETURN_PROCESS 3
|
||||
#define MOO_METHOD_PREAMBLE_RETURN_NIL 4
|
||||
#define MOO_METHOD_PREAMBLE_RETURN_TRUE 5
|
||||
#define MOO_METHOD_PREAMBLE_RETURN_FALSE 6
|
||||
#define MOO_METHOD_PREAMBLE_RETURN_INDEX 7
|
||||
#define MOO_METHOD_PREAMBLE_RETURN_NEGINDEX 8
|
||||
#define MOO_METHOD_PREAMBLE_RETURN_INSTVAR 9
|
||||
#define MOO_METHOD_PREAMBLE_PRIMITIVE 10
|
||||
#define MOO_METHOD_PREAMBLE_NAMED_PRIMITIVE 11 /* index is an index to the symbol table */
|
||||
|
||||
#define MOO_METHOD_PREAMBLE_EXCEPTION 12 /* NOTE changing this requires changes in Except.st */
|
||||
#define MOO_METHOD_PREAMBLE_ENSURE 13 /* NOTE changing this requires changes in Except.st */
|
||||
#define MOO_METHOD_PREAMBLE_RETURN_RECEIVER_NS 4
|
||||
#define MOO_METHOD_PREAMBLE_RETURN_NIL 5
|
||||
#define MOO_METHOD_PREAMBLE_RETURN_TRUE 6
|
||||
#define MOO_METHOD_PREAMBLE_RETURN_FALSE 7
|
||||
#define MOO_METHOD_PREAMBLE_RETURN_INDEX 8
|
||||
#define MOO_METHOD_PREAMBLE_RETURN_NEGINDEX 9
|
||||
#define MOO_METHOD_PREAMBLE_RETURN_INSTVAR 10
|
||||
#define MOO_METHOD_PREAMBLE_PRIMITIVE 11
|
||||
#define MOO_METHOD_PREAMBLE_NAMED_PRIMITIVE 12 /* index is an index to the symbol table */
|
||||
#define MOO_METHOD_PREAMBLE_EXCEPTION 13 /* NOTE changing this requires changes in Except.st */
|
||||
#define MOO_METHOD_PREAMBLE_ENSURE 14 /* NOTE changing this requires changes in Except.st */
|
||||
|
||||
/* the index is an 16-bit unsigned integer. */
|
||||
#define MOO_METHOD_PREAMBLE_INDEX_MIN 0x0000
|
||||
|
Loading…
Reference in New Issue
Block a user