added moo_findmethodinclasschain()

added MOO_SYNERR_CLASSNCIFCE
finished implementing interface conformance check primitively
This commit is contained in:
hyunghwan.chung 2018-10-12 09:09:45 +00:00
parent a6a2cb2d16
commit 18b270529c
10 changed files with 210 additions and 125 deletions

View File

@ -1,8 +1,14 @@
interface ClassInterface
{
method name.
method superclass.
}
## ##
## the Class object should be a variable-pointer object because ## the Class object should be a variable-pointer object because
## it needs to accomodate class instance variables. ## it needs to accomodate class instance variables.
## ##
class(#pointer,#limited) Class(Apex) class(#pointer,#limited) Class(Apex) [ClassInterface]
{ {
var spec, selfspec, superclass, subclasses, name, modname. var spec, selfspec, superclass, subclasses, name, modname.
var instvars, classinstvars, classvars, pooldics. var instvars, classinstvars, classvars, pooldics.

View File

@ -3,7 +3,7 @@
interface X11able interface X11able
{ {
method(#dual) abc. method(#dual) abc.
method(#dual) def. method(#dual,#liberal) def(x, y).
} }
interface X11able2 interface X11able2
{ {
@ -13,7 +13,7 @@ interface X11able2
interface X11able3 interface X11able3
{ {
method(#dual) abc3. method(#dual) class.
} }
@ -33,8 +33,8 @@ class X11(Object) [X11able,selfns.X11able3] from 'x11'
var llevent_blocks. var llevent_blocks.
method(#dual) abc { ^nil } method(#dual) abc { ^nil }
method(#dual) def { ^nil } method(#dual,#liberal) def(x, z) { ^nil }
method(#dual) abc3 { ^nil } ###method(#dual) abc3 { ^nil }
interface X11able3 interface X11able3
{ {

View File

@ -80,6 +80,7 @@ class MyObject(Object)
'duplicate name' 'duplicate name'
'undefined name' 'undefined name'
'contradictory class definition' 'contradictory class definition'
'class not conforming to interface'
'invalid non-pointer instance size' 'invalid non-pointer instance size'
'prohibited inheritance' 'prohibited inheritance'
'variable declaration not allowed' 'variable declaration not allowed'

View File

@ -4253,7 +4253,7 @@ static MOO_INLINE int find_dotted_ident (moo_t* moo, const moo_oocs_t* name, con
MOO_ASSERT (moo, moo->c->cunit->cunit_type == MOO_CUNIT_CLASS); MOO_ASSERT (moo, moo->c->cunit->cunit_type == MOO_CUNIT_CLASS);
/* called inside a class definition */ /* called inside a class definition */
if (cc->super_oop) if (cc->in_class_body)
{ {
/* [NOTE] /* [NOTE]
* cls.ns_oop is set when the class name is enountered. * cls.ns_oop is set when the class name is enountered.
@ -4262,6 +4262,7 @@ static MOO_INLINE int find_dotted_ident (moo_t* moo, const moo_oocs_t* name, con
* on the other hand, cls.ns_oop is not MOO_NULL as long as * on the other hand, cls.ns_oop is not MOO_NULL as long as
* cls.super_oop is not MOO_NULL. * cls.super_oop is not MOO_NULL.
*/ */
MOO_ASSERT (moo, cc->super_oop != MOO_NULL);
MOO_ASSERT (moo, cc->ns_oop != MOO_NULL); MOO_ASSERT (moo, cc->ns_oop != MOO_NULL);
/* cc->self_oop may still be MOO_NULL if the class has not been instantiated */ /* cc->self_oop may still be MOO_NULL if the class has not been instantiated */
@ -4371,11 +4372,11 @@ static MOO_INLINE int find_undotted_ident (moo_t* moo, const moo_oocs_t* name, c
} }
} }
if (cc->super_oop) if (cc->in_class_body)
{ {
/* called inside a class definition */ /* called inside a class definition */
/* read a comment in find_dotted_ident() for the reason behind /* read a comment in find_dotted_ident() for the reason behind
* the if condition above. */ * the 'if' condition above. */
MOO_ASSERT (moo, cc->super_oop != MOO_NULL); MOO_ASSERT (moo, cc->super_oop != MOO_NULL);
MOO_ASSERT (moo, cc->ns_oop != MOO_NULL); MOO_ASSERT (moo, cc->ns_oop != MOO_NULL);
@ -7310,7 +7311,7 @@ static int make_defined_class (moo_t* moo)
/* this is an internally created class object being defined. */ /* this is an internally created class object being defined. */
MOO_ASSERT (moo, MOO_CLASSOF(moo, cc->self_oop) == moo->_class); MOO_ASSERT (moo, MOO_CLASSOF(moo, cc->self_oop) == moo->_class);
MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_KERNEL(cc->self_oop) == 1); MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_KERNEL(cc->self_oop) == MOO_OBJ_FLAGS_KERNEL_IMMATURE);
if (spec != MOO_OOP_TO_SMOOI(cc->self_oop->spec) || if (spec != MOO_OOP_TO_SMOOI(cc->self_oop->spec) ||
self_spec != MOO_OOP_TO_SMOOI(cc->self_oop->selfspec)) self_spec != MOO_OOP_TO_SMOOI(cc->self_oop->selfspec))
@ -7341,7 +7342,7 @@ static int make_defined_class (moo_t* moo)
* if superclass is byte variable, the current class cannot be word variable or something else. * if superclass is byte variable, the current class cannot be word variable or something else.
* TODO: TODO: TODO: * TODO: TODO: TODO:
*/ */
MOO_OBJ_SET_FLAGS_KERNEL (cc->self_oop, 2); MOO_OBJ_SET_FLAGS_KERNEL (cc->self_oop, MOO_OBJ_FLAGS_KERNEL_MATURE);
cc->self_oop->superclass = cc->super_oop; cc->self_oop->superclass = cc->super_oop;
@ -7680,7 +7681,8 @@ static int process_class_superclass (moo_t* moo)
if (get_variable_info(moo, &cc->superfqn, &cc->superfqn_loc, superfqn_is_dotted, &var) <= -1) return -1; if (get_variable_info(moo, &cc->superfqn, &cc->superfqn_loc, superfqn_is_dotted, &var) <= -1) return -1;
if (var.type != VAR_GLOBAL) goto unknown_superclass; 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) if (MOO_CLASSOF(moo, var.u.gbl->value) == moo->_class &&
MOO_OBJ_GET_FLAGS_KERNEL(var.u.gbl->value) != MOO_OBJ_FLAGS_KERNEL_IMMATURE)
{ {
/* the value found must be a class and it must not be an incomplete internal class object. /* the value found must be a class and it must not be an incomplete internal class object.
* 0(non-kernel object) * 0(non-kernel object)
@ -7830,17 +7832,21 @@ struct ciim_t
}; };
typedef struct ciim_t ciim_t; typedef struct ciim_t ciim_t;
static int on_each_method (moo_t* moo, moo_oop_dic_t dic, moo_oop_association_t ass, void* ctx) static int ciim_on_each_method (moo_t* moo, moo_oop_dic_t dic, moo_oop_association_t ass, void* ctx)
{ {
ciim_t* ciim = (ciim_t*)ctx; ciim_t* ciim = (ciim_t*)ctx;
moo_oocs_t name; moo_oocs_t name;
moo_oop_method_t mth;
moo_oop_methsig_t sig;
name.ptr = MOO_OBJ_GET_CHAR_SLOT(ass->key); name.ptr = MOO_OBJ_GET_CHAR_SLOT(ass->key);
name.len = MOO_OBJ_GET_SIZE(ass->key); name.len = MOO_OBJ_GET_SIZE(ass->key);
ass = moo_lookupdic(moo, ciim->_class->mthdic[ciim->mth_type], &name);
if (!ass) /* [IMPORT] the method lookup logic should be the same as moo_findmethod() in exec.c */
{/* TODO: change error code */ mth = moo_findmethodinclasschain(moo, ciim->_class, ciim->mth_type, &name);
moo_setsynerrbfmt (moo, MOO_SYNERR_ARGFLOOD, MOO_NULL, MOO_NULL, if (!mth)
{
moo_setsynerrbfmt (moo, MOO_SYNERR_CLASSNCIFCE, MOO_NULL, MOO_NULL,
"%.*js not implementing %.*js>>%.*js", "%.*js not implementing %.*js>>%.*js",
MOO_OBJ_GET_SIZE(ciim->_class->name), MOO_OBJ_GET_CHAR_SLOT(ciim->_class->name), MOO_OBJ_GET_SIZE(ciim->_class->name), MOO_OBJ_GET_CHAR_SLOT(ciim->_class->name),
MOO_OBJ_GET_SIZE(ciim->ifce->name), MOO_OBJ_GET_CHAR_SLOT(ciim->ifce->name), MOO_OBJ_GET_SIZE(ciim->ifce->name), MOO_OBJ_GET_CHAR_SLOT(ciim->ifce->name),
@ -7849,7 +7855,31 @@ static int on_each_method (moo_t* moo, moo_oop_dic_t dic, moo_oop_association_t
return -1; return -1;
} }
/* TODO: check preamble flags in signature */ sig = (moo_oop_methsig_t)ass->value;
if (MOO_METHOD_GET_PREAMBLE_FLAGS(MOO_OOP_TO_SMOOI(mth->preamble)) != MOO_METHOD_GET_PREAMBLE_FLAGS(MOO_OOP_TO_SMOOI(sig->preamble)))
{
moo_setsynerrbfmt (moo, MOO_SYNERR_CLASSNCIFCE, MOO_NULL, MOO_NULL,
"%.*js>>%.*js modifiers conficting with %.*js>>%.*js",
MOO_OBJ_GET_SIZE(ciim->_class->name), MOO_OBJ_GET_CHAR_SLOT(ciim->_class->name),
name.len, name.ptr,
MOO_OBJ_GET_SIZE(ciim->ifce->name), MOO_OBJ_GET_CHAR_SLOT(ciim->ifce->name),
name.len, name.ptr
);
return -1;
}
if (mth->tmpr_nargs != sig->tmpr_nargs) /* don't need MOO_OOP_TO_SMOOI */
{
moo_setsynerrbfmt (moo, MOO_SYNERR_CLASSNCIFCE, MOO_NULL, MOO_NULL,
"%.*js>>%.*js parameters conflicting with %.*js>>%.*js",
MOO_OBJ_GET_SIZE(ciim->_class->name), MOO_OBJ_GET_CHAR_SLOT(ciim->_class->name),
name.len, name.ptr,
MOO_OBJ_GET_SIZE(ciim->ifce->name), MOO_OBJ_GET_CHAR_SLOT(ciim->ifce->name),
name.len, name.ptr
);
return -1;
}
return 0; return 0;
} }
@ -7860,12 +7890,12 @@ static int class_implements_interface (moo_t* moo, moo_oop_class_t _class, moo_o
ciim.ifce = ifce; ciim.ifce = ifce;
ciim._class = _class; ciim._class = _class;
ciim.mth_type = MOO_METHOD_INSTANCE; ciim.mth_type = MOO_METHOD_INSTANCE;
if (moo_walkdic(moo, ifce->mthdic[MOO_METHOD_INSTANCE], on_each_method, &ciim) <= -1) return 0; if (moo_walkdic(moo, ifce->mthdic[MOO_METHOD_INSTANCE], ciim_on_each_method, &ciim) <= -1) return 0;
ciim.ifce = ifce; ciim.ifce = ifce;
ciim._class = _class; ciim._class = _class;
ciim.mth_type = MOO_METHOD_CLASS; ciim.mth_type = MOO_METHOD_CLASS;
if (moo_walkdic(moo, ifce->mthdic[MOO_METHOD_CLASS], on_each_method, &ciim) <= -1) return 0; if (moo_walkdic(moo, ifce->mthdic[MOO_METHOD_CLASS], ciim_on_each_method, &ciim) <= -1) return 0;
return 1; return 1;
} }
@ -7975,7 +8005,7 @@ static int __compile_class_definition (moo_t* moo, int class_type)
ass = moo_lookupdic(moo, (moo_oop_dic_t)cc->ns_oop, &cc->name); ass = moo_lookupdic(moo, (moo_oop_dic_t)cc->ns_oop, &cc->name);
if (ass && MOO_CLASSOF(moo, ass->value) == moo->_class && if (ass && MOO_CLASSOF(moo, ass->value) == moo->_class &&
MOO_OBJ_GET_FLAGS_KERNEL(ass->value) != 1) MOO_OBJ_GET_FLAGS_KERNEL(ass->value) != MOO_OBJ_FLAGS_KERNEL_IMMATURE)
{ {
/* the value must be a class object. /* the value must be a class object.
* and it must be either a user-defined(0) or completed kernel built-in(2). * and it must be either a user-defined(0) or completed kernel built-in(2).
@ -7999,7 +8029,8 @@ static int __compile_class_definition (moo_t* moo, int class_type)
ass = moo_lookupdic(moo, (moo_oop_dic_t)cc->ns_oop, &cc->name); ass = moo_lookupdic(moo, (moo_oop_dic_t)cc->ns_oop, &cc->name);
if (ass) if (ass)
{ {
if (MOO_CLASSOF(moo, ass->value) != moo->_class || MOO_OBJ_GET_FLAGS_KERNEL(ass->value) > 1) if (MOO_CLASSOF(moo, ass->value) != moo->_class ||
MOO_OBJ_GET_FLAGS_KERNEL(ass->value) == MOO_OBJ_FLAGS_KERNEL_MATURE)
{ {
/* the object found with the name is not a class object /* the object found with the name is not a class object
* or the the class object found is a fully defined kernel * or the the class object found is a fully defined kernel
@ -8030,6 +8061,7 @@ static int __compile_class_definition (moo_t* moo, int class_type)
} }
} }
cc->in_class_body = 1;
if (TOKEN_TYPE(moo) != MOO_IOTOK_LBRACE) if (TOKEN_TYPE(moo) != MOO_IOTOK_LBRACE)
{ {
moo_setsynerr (moo, MOO_SYNERR_LBRACE, TOKEN_LOC(moo), TOKEN_NAME(moo)); moo_setsynerr (moo, MOO_SYNERR_LBRACE, TOKEN_LOC(moo), TOKEN_NAME(moo));

View File

@ -107,49 +107,50 @@ static moo_ooch_t synerrstr_27[] = {'p','r','i','m','i','t','i','v','e',':',' ',
static moo_ooch_t synerrstr_28[] = {'w','r','o','n','g',' ','d','i','r','e','c','t','i','v','e','\0'}; static moo_ooch_t synerrstr_28[] = {'w','r','o','n','g',' ','d','i','r','e','c','t','i','v','e','\0'};
static moo_ooch_t synerrstr_29[] = {'w','r','o','n','g',' ','n','a','m','e','\0'}; static moo_ooch_t synerrstr_29[] = {'w','r','o','n','g',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_30[] = {'d','u','p','l','i','c','a','t','e',' ','n','a','m','e','\0'}; static moo_ooch_t synerrstr_30[] = {'d','u','p','l','i','c','a','t','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_31[] = {'u','n','d','e','f','i','n','e','d',' ','n','a','a','e','\0'}; static moo_ooch_t synerrstr_31[] = {'u','n','d','e','f','i','n','e','d',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_32[] = {'c','o','n','t','r','a','d','i','c','t','o','r','y',' ','c','l','a','s','s',' ','d','e','f','i','n','i','t','i','o','n','\0'}; static moo_ooch_t synerrstr_32[] = {'c','o','n','t','r','a','d','i','c','t','o','r','y',' ','c','l','a','s','s',' ','d','e','f','i','n','i','t','i','o','n','\0'};
static moo_ooch_t synerrstr_33[] = {'i','n','v','a','l','i','d',' ','n','o','n','-','p','o','i','n','t','e','r',' ','i','n','s','t','a','n','c','e',' ','s','i','z','e','\0'}; static moo_ooch_t synerrstr_33[] = {'c','l','a','s','s',' ','n','o','t',' ','c','o','n','f','o','r','m','i','n','g',' ','t','o',' ','i','n','t','e','r','f','a','c','e','\0'};
static moo_ooch_t synerrstr_34[] = {'p','r','o','h','i','b','i','t','e','d',' ','i','n','h','e','r','i','t','a','n','c','e','\0'}; static moo_ooch_t synerrstr_34[] = {'i','n','v','a','l','i','d',' ','n','o','n','-','p','o','i','n','t','e','r',' ','i','n','s','t','a','n','c','e',' ','s','i','z','e','\0'};
static moo_ooch_t synerrstr_35[] = {'v','a','r','i','a','b','l','e',' ','d','e','c','l','a','r','a','t','i','o','n',' ','n','o','t',' ','a','l','l','o','w','e','d','\0'}; static moo_ooch_t synerrstr_35[] = {'p','r','o','h','i','b','i','t','e','d',' ','i','n','h','e','r','i','t','a','n','c','e','\0'};
static moo_ooch_t synerrstr_36[] = {'m','o','d','i','f','i','e','r',' ','e','x','p','e','c','t','e','d','\0'}; static moo_ooch_t synerrstr_36[] = {'v','a','r','i','a','b','l','e',' ','d','e','c','l','a','r','a','t','i','o','n',' ','n','o','t',' ','a','l','l','o','w','e','d','\0'};
static moo_ooch_t synerrstr_37[] = {'w','r','o','n','g',' ','m','o','d','i','f','i','e','r','\0'}; static moo_ooch_t synerrstr_37[] = {'m','o','d','i','f','i','e','r',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t synerrstr_38[] = {'d','i','s','a','l','l','o','w','e','d',' ','m','o','d','i','f','i','e','r','\0'}; static moo_ooch_t synerrstr_38[] = {'w','r','o','n','g',' ','m','o','d','i','f','i','e','r','\0'};
static moo_ooch_t synerrstr_39[] = {'d','u','p','l','i','c','a','t','e',' ','m','o','d','i','f','i','e','r','\0'}; static moo_ooch_t synerrstr_39[] = {'d','i','s','a','l','l','o','w','e','d',' ','m','o','d','i','f','i','e','r','\0'};
static moo_ooch_t synerrstr_40[] = {'m','e','t','h','o','d',' ','n','a','m','e',' ','e','x','p','e','c','t','e','d','\0'}; static moo_ooch_t synerrstr_40[] = {'d','u','p','l','i','c','a','t','e',' ','m','o','d','i','f','i','e','r','\0'};
static moo_ooch_t synerrstr_41[] = {'d','u','p','l','i','c','a','t','e',' ','m','e','t','h','o','d',' ','n','a','m','e','\0'}; static moo_ooch_t synerrstr_41[] = {'m','e','t','h','o','d',' ','n','a','m','e',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t synerrstr_42[] = {'i','n','v','a','l','i','d',' ','v','a','r','i','a','d','i','c',' ','m','e','t','h','o','d',' ','d','e','f','i','n','i','t','i','o','n','\0'}; static moo_ooch_t synerrstr_42[] = {'d','u','p','l','i','c','a','t','e',' ','m','e','t','h','o','d',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_43[] = {'v','a','r','i','a','b','l','e',' ','n','a','m','e',' ','e','x','p','e','c','t','e','d','\0'}; static moo_ooch_t synerrstr_43[] = {'i','n','v','a','l','i','d',' ','v','a','r','i','a','d','i','c',' ','m','e','t','h','o','d',' ','d','e','f','i','n','i','t','i','o','n','\0'};
static moo_ooch_t synerrstr_44[] = {'d','u','p','l','i','c','a','t','e',' ','a','r','g','u','m','e','n','t',' ','n','a','m','e','\0'}; static moo_ooch_t synerrstr_44[] = {'v','a','r','i','a','b','l','e',' ','n','a','m','e',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t synerrstr_45[] = {'d','u','p','l','i','c','a','t','e',' ','t','e','m','p','o','r','a','r','y',' ','v','a','r','i','a','b','l','e',' ','n','a','m','e','\0'}; static moo_ooch_t synerrstr_45[] = {'d','u','p','l','i','c','a','t','e',' ','a','r','g','u','m','e','n','t',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_46[] = {'d','u','p','l','i','c','a','t','e',' ','v','a','r','i','a','b','l','e',' ','n','a','m','e','\0'}; static moo_ooch_t synerrstr_46[] = {'d','u','p','l','i','c','a','t','e',' ','t','e','m','p','o','r','a','r','y',' ','v','a','r','i','a','b','l','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_47[] = {'d','u','p','l','i','c','a','t','e',' ','b','l','o','c','k',' ','a','r','g','u','m','e','n','t',' ','n','a','m','e','\0'}; static moo_ooch_t synerrstr_47[] = {'d','u','p','l','i','c','a','t','e',' ','v','a','r','i','a','b','l','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_48[] = {'u','n','d','e','c','l','a','r','e','d',' ','v','a','r','i','a','b','l','e','\0'}; static moo_ooch_t synerrstr_48[] = {'d','u','p','l','i','c','a','t','e',' ','b','l','o','c','k',' ','a','r','g','u','m','e','n','t',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_49[] = {'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_49[] = {'u','n','d','e','c','l','a','r','e','d',' ','v','a','r','i','a','b','l','e','\0'};
static moo_ooch_t synerrstr_50[] = {'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_50[] = {'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_51[] = {'a','m','b','i','g','u','o','u','s',' ','v','a','r','i','a','b','l','e','\0'}; static moo_ooch_t synerrstr_51[] = {'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_52[] = {'t','o','o',' ','m','a','n','y',' ','i','n','s','t','a','n','c','e','/','c','l','a','s','s',' ','v','a','r','i','a','b','l','e','s','\0'}; static moo_ooch_t synerrstr_52[] = {'a','m','b','i','g','u','o','u','s',' ','v','a','r','i','a','b','l','e','\0'};
static moo_ooch_t synerrstr_53[] = {'i','n','a','c','c','e','s','s','i','b','l','e',' ','s','e','l','f','\0'}; static moo_ooch_t synerrstr_53[] = {'t','o','o',' ','m','a','n','y',' ','i','n','s','t','a','n','c','e','/','c','l','a','s','s',' ','v','a','r','i','a','b','l','e','s','\0'};
static moo_ooch_t synerrstr_54[] = {'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_54[] = {'i','n','a','c','c','e','s','s','i','b','l','e',' ','s','e','l','f','\0'};
static moo_ooch_t synerrstr_55[] = {'t','o','o',' ','m','a','n','y',' ','t','e','m','p','o','r','a','r','i','e','s','\0'}; static moo_ooch_t synerrstr_55[] = {'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_56[] = {'t','o','o',' ','m','a','n','y',' ','a','r','g','u','m','e','n','t','s','\0'}; static moo_ooch_t synerrstr_56[] = {'t','o','o',' ','m','a','n','y',' ','t','e','m','p','o','r','a','r','i','e','s','\0'};
static moo_ooch_t synerrstr_57[] = {'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_57[] = {'t','o','o',' ','m','a','n','y',' ','a','r','g','u','m','e','n','t','s','\0'};
static moo_ooch_t synerrstr_58[] = {'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_58[] = {'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_59[] = {'t','o','o',' ','l','a','r','g','e',' ','b','l','o','c','k','\0'}; static moo_ooch_t synerrstr_59[] = {'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_60[] = {'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_60[] = {'t','o','o',' ','l','a','r','g','e',' ','b','l','o','c','k','\0'};
static moo_ooch_t synerrstr_61[] = {'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_61[] = {'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_62[] = {'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_62[] = {'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_63[] = {'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_63[] = {'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_64[] = {'f','a','i','l','e','d',' ','t','o',' ','i','m','p','o','r','t',' ','m','o','d','u','l','e','\0'}; static moo_ooch_t synerrstr_64[] = {'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_65[] = {'#','i','n','c','l','u','d','e',' ','e','r','r','o','r','\0'}; static moo_ooch_t synerrstr_65[] = {'f','a','i','l','e','d',' ','t','o',' ','i','m','p','o','r','t',' ','m','o','d','u','l','e','\0'};
static moo_ooch_t synerrstr_66[] = {'w','r','o','n','g',' ','p','r','a','g','m','a',' ','n','a','m','e','\0'}; static moo_ooch_t synerrstr_66[] = {'#','i','n','c','l','u','d','e',' ','e','r','r','o','r','\0'};
static moo_ooch_t synerrstr_67[] = {'w','r','o','n','g',' ','n','a','m','e','s','p','a','c','e',' ','n','a','m','e','\0'}; static moo_ooch_t synerrstr_67[] = {'w','r','o','n','g',' ','p','r','a','g','m','a',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_68[] = {'w','r','o','n','g',' ','p','o','o','l','d','i','c','i','m','p','o','r','t',' ','n','a','m','e','\0'}; static moo_ooch_t synerrstr_68[] = {'w','r','o','n','g',' ','n','a','m','e','s','p','a','c','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_69[] = {'d','u','p','l','i','c','a','t','e',' ','p','o','o','l','d','i','c','i','m','p','o','r','t',' ','n','a','m','e','\0'}; static moo_ooch_t synerrstr_69[] = {'w','r','o','n','g',' ','p','o','o','l','d','i','c','i','m','p','o','r','t',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_70[] = {'l','i','t','e','r','a','l',' ','e','x','p','e','c','t','e','d','\0'}; static moo_ooch_t synerrstr_70[] = {'d','u','p','l','i','c','a','t','e',' ','p','o','o','l','d','i','c','i','m','p','o','r','t',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_71[] = {'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_71[] = {'l','i','t','e','r','a','l',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t synerrstr_72[] = {'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_72[] = {'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_73[] = {'w','h','i','l','e',' ','e','x','p','e','c','t','e','d','\0'}; static moo_ooch_t synerrstr_73[] = {'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_74[] = {'w','h','i','l','e',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t* synerrstr[] = static moo_ooch_t* synerrstr[] =
{ {
synerrstr_0, synerrstr_1, synerrstr_2, synerrstr_3, synerrstr_4, synerrstr_5, synerrstr_6, synerrstr_7, synerrstr_0, synerrstr_1, synerrstr_2, synerrstr_3, synerrstr_4, synerrstr_5, synerrstr_6, synerrstr_7,
@ -161,7 +162,7 @@ static moo_ooch_t* synerrstr[] =
synerrstr_48, synerrstr_49, synerrstr_50, synerrstr_51, synerrstr_52, synerrstr_53, synerrstr_54, synerrstr_55, 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_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_69, synerrstr_70, synerrstr_71, synerrstr_64, synerrstr_65, synerrstr_66, synerrstr_67, synerrstr_68, synerrstr_69, synerrstr_70, synerrstr_71,
synerrstr_72, synerrstr_73 synerrstr_72, synerrstr_73, synerrstr_74
}; };
#endif #endif
/* END: GENERATED WITH generr.moo */ /* END: GENERATED WITH generr.moo */

View File

@ -1620,82 +1620,107 @@ static MOO_INLINE int activate_new_method (moo_t* moo, moo_oop_method_t mth, moo
return 0; return 0;
} }
moo_oop_method_t moo_findmethod (moo_t* moo, moo_oop_t receiver, const moo_oocs_t* message, int super) MOO_INLINE moo_oop_method_t find_method_in_class (moo_t* moo, moo_oop_class_t _class, int mth_type, const moo_oocs_t* name)
{ {
moo_oop_class_t cls;
moo_oop_association_t ass; moo_oop_association_t ass;
moo_oop_t c;
moo_oop_dic_t mthdic; moo_oop_dic_t mthdic;
int dic_no;
/* TODO: implement method lookup cache */
cls = MOO_CLASSOF(moo, receiver); mthdic = _class->mthdic[mth_type];
if (cls == moo->_class)
{
/* receiver is a class object (an instance of Class) */
c = receiver;
dic_no = MOO_METHOD_CLASS;
}
else
{
/* receiver is not a class object. so take its class */
c = (moo_oop_t)cls;
dic_no = MOO_METHOD_INSTANCE;
}
MOO_ASSERT (moo, c != moo->_nil);
if (super)
{
/*
moo_oop_method_t m;
MOO_ASSERT (moo, MOO_CLASSOF(moo, moo->active_context->origin) == moo->_method_context);
m = (moo_oop_method_t)moo->active_context->origin->method_or_nargs;
c = ((moo_oop_class_t)m->owner)->superclass;
*/
MOO_ASSERT (moo, moo->active_method);
MOO_ASSERT (moo, moo->active_method->owner);
c = ((moo_oop_class_t)moo->active_method->owner)->superclass;
if (c == moo->_nil) goto not_found; /* reached the top of the hierarchy */
}
do
{
mthdic = ((moo_oop_class_t)c)->mthdic[dic_no];
/* if a kernel class is not defined in the bootstrapping code, /* if a kernel class is not defined in the bootstrapping code,
* the method dictionary is still nil. the initial kernel classes * the method dictionary is still nil. you must define all the initial
* must all be defined properly */ * kernel classes properly before you can use this function */
MOO_ASSERT (moo, (moo_oop_t)mthdic != moo->_nil); MOO_ASSERT (moo, (moo_oop_t)mthdic != moo->_nil);
MOO_ASSERT (moo, MOO_CLASSOF(moo, mthdic) == moo->_method_dictionary); MOO_ASSERT (moo, MOO_CLASSOF(moo, mthdic) == moo->_method_dictionary);
ass = (moo_oop_association_t)moo_lookupdic (moo, mthdic, message); ass = (moo_oop_association_t)moo_lookupdic(moo, mthdic, name);
if (ass) if (ass)
{ {
/* found the method */ /* found the method */
MOO_ASSERT (moo, MOO_CLASSOF(moo, ass->value) == moo->_method); MOO_ASSERT (moo, MOO_CLASSOF(moo, ass->value) == moo->_method);
return (moo_oop_method_t)ass->value; return (moo_oop_method_t)ass->value;
} }
c = ((moo_oop_class_t)c)->superclass;
/* NOTE: moo_seterrXXX() is not called here */
return MOO_NULL;
} }
while (c != moo->_nil);
MOO_INLINE moo_oop_method_t find_method_in_class_chain (moo_t* moo, moo_oop_class_t _class, int mth_type, const moo_oocs_t* name)
{
moo_oop_method_t mth;
do
{
mth = find_method_in_class(moo, _class, mth_type, name);
if (mth) return mth;
_class = (moo_oop_class_t)_class->superclass;
}
while ((moo_oop_t)_class != moo->_nil);
/* NOTE: moo_seterrXXX() is not called here */
return MOO_NULL;
}
moo_oop_method_t moo_findmethodinclass (moo_t* moo, moo_oop_class_t _class, int mth_type, const moo_oocs_t* name)
{
moo_oop_method_t mth;
mth = find_method_in_class(moo, _class, mth_type, name);
if (!mth) moo_seterrnum (moo, MOO_ENOENT);
return mth;
}
moo_oop_method_t moo_findmethodinclasschain (moo_t* moo, moo_oop_class_t _class, int mth_type, const moo_oocs_t* name)
{
moo_oop_method_t mth;
mth = find_method_in_class_chain(moo, _class, mth_type, name);
if (!mth) moo_seterrnum (moo, MOO_ENOENT);
return mth;
}
moo_oop_method_t moo_findmethod (moo_t* moo, moo_oop_t receiver, const moo_oocs_t* message, int super)
{
moo_oop_class_t _class;
moo_oop_class_t c;
int mth_type;
moo_oop_method_t mth;
_class = MOO_CLASSOF(moo, receiver);
if (_class == moo->_class)
{
/* receiver is a class object (an instance of Class) */
c = (moo_oop_class_t)receiver;
mth_type = MOO_METHOD_CLASS;
}
else
{
/* receiver is not a class object. so take its class */
c = _class;
mth_type = MOO_METHOD_INSTANCE;
}
MOO_ASSERT (moo, (moo_oop_t)c != moo->_nil);
if (super)
{
MOO_ASSERT (moo, moo->active_method);
MOO_ASSERT (moo, moo->active_method->owner);
c = (moo_oop_class_t)((moo_oop_class_t)moo->active_method->owner)->superclass;
if ((moo_oop_t)c == moo->_nil) goto not_found;
// c is nil if it reached the top of the hierarch.
// otherwise c points to a class object
}
/* [IMPORT] the method lookup logic should be the same as ciim_on_each_method() in comp.c */
mth = find_method_in_class_chain(moo, c, mth_type, message);
if (mth) return mth;
not_found: not_found:
if (cls == moo->_class) if (_class == moo->_class)
{ {
/* the object is an instance of Class. find the method /* the object is an instance of Class. find the method
* in an instance method dictionary of Class also */ * in an instance method dictionary of Class also */
mthdic = ((moo_oop_class_t)cls)->mthdic[MOO_METHOD_INSTANCE]; mth = find_method_in_class(moo, _class, MOO_METHOD_INSTANCE, message);
MOO_ASSERT (moo, (moo_oop_t)mthdic != moo->_nil); if (mth) return mth;
MOO_ASSERT (moo, MOO_CLASSOF(moo, mthdic) == moo->_method_dictionary);
ass = (moo_oop_association_t)moo_lookupdic (moo, mthdic, message);
if (ass)
{
MOO_ASSERT (moo, MOO_CLASSOF(moo, ass->value) == moo->_method);
return (moo_oop_method_t)ass->value;
}
} }
MOO_LOG3 (moo, MOO_LOG_DEBUG, "Method '%.*js' not found in %O\n", message->len, message->ptr, receiver); MOO_LOG3 (moo, MOO_LOG_DEBUG, "Method '%.*js' not found in %O\n", message->len, message->ptr, receiver);

View File

@ -409,7 +409,7 @@ static moo_oop_class_t alloc_kernel_class (moo_t* moo, int class_flags, moo_oow_
c = (moo_oop_class_t)moo_allocoopobj (moo, MOO_CLASS_NAMED_INSTVARS + num_classvars); c = (moo_oop_class_t)moo_allocoopobj (moo, MOO_CLASS_NAMED_INSTVARS + num_classvars);
if (!c) return MOO_NULL; if (!c) return MOO_NULL;
MOO_OBJ_SET_FLAGS_KERNEL (c, 1); MOO_OBJ_SET_FLAGS_KERNEL (c, MOO_OBJ_FLAGS_KERNEL_IMMATURE);
MOO_OBJ_SET_CLASS (c, (moo_oop_t)moo->_class); MOO_OBJ_SET_CLASS (c, (moo_oop_t)moo->_class);
c->spec = MOO_SMOOI_TO_OOP(spec); c->spec = MOO_SMOOI_TO_OOP(spec);
c->selfspec = MOO_SMOOI_TO_OOP(MOO_CLASS_SELFSPEC_MAKE(num_classvars, 0, class_flags)); c->selfspec = MOO_SMOOI_TO_OOP(MOO_CLASS_SELFSPEC_MAKE(num_classvars, 0, class_flags));

View File

@ -607,6 +607,7 @@ struct moo_cunit_class_t
moo_ioloc_t modname_loc; moo_ioloc_t modname_loc;
moo_oopbuf_t ifces; moo_oopbuf_t ifces;
int in_class_body; /* set to non-zero after '{' has been encountered */
/* instance variable, class variable, class instance variable, constant /* instance variable, class variable, class instance variable, constant
* var[0] - named instance variables * var[0] - named instance variables
@ -1426,6 +1427,20 @@ moo_oop_method_t moo_findmethod (
int super int super
); );
moo_oop_method_t moo_findmethodinclass (
moo_t* moo,
moo_oop_class_t _class,
int mth_type,
const moo_oocs_t* name
);
moo_oop_method_t moo_findmethodinclasschain (
moo_t* moo,
moo_oop_class_t _class,
int mth_type,
const moo_oocs_t* name
);
/* ========================================================================= */ /* ========================================================================= */
/* moo.c */ /* moo.c */
/* ========================================================================= */ /* ========================================================================= */

View File

@ -446,6 +446,10 @@ typedef enum moo_gcfin_t moo_gcfin_t;
(((moo_oow_t)(r)) << MOO_OBJ_FLAGS_TRAILER_SHIFT) \ (((moo_oow_t)(r)) << MOO_OBJ_FLAGS_TRAILER_SHIFT) \
) )
#define MOO_OBJ_FLAGS_KERNEL_USER 0
#define MOO_OBJ_FLAGS_KERNEL_IMMATURE 1
#define MOO_OBJ_FLAGS_KERNEL_MATURE 2
#define MOO_OBJ_HEADER \ #define MOO_OBJ_HEADER \
moo_oow_t _flags; \ moo_oow_t _flags; \
moo_oow_t _size; \ moo_oow_t _size; \
@ -1684,6 +1688,7 @@ enum moo_synerrnum_t
MOO_SYNERR_NAMEDUPL, /* duplicate name */ MOO_SYNERR_NAMEDUPL, /* duplicate name */
MOO_SYNERR_NAMEUNDEF, /* undefined name */ MOO_SYNERR_NAMEUNDEF, /* undefined name */
MOO_SYNERR_CLASSCONTRA, /* contradictory class */ MOO_SYNERR_CLASSCONTRA, /* contradictory class */
MOO_SYNERR_CLASSNCIFCE, /* class not conforming to interface */
MOO_SYNERR_NPINSTSIZEINVAL, /* invalid non-pointer instance size */ MOO_SYNERR_NPINSTSIZEINVAL, /* invalid non-pointer instance size */
MOO_SYNERR_INHERITBANNED, /* prohibited inheritance */ MOO_SYNERR_INHERITBANNED, /* prohibited inheritance */
MOO_SYNERR_VARDCLBANNED, /* variable declaration not allowed */ MOO_SYNERR_VARDCLBANNED, /* variable declaration not allowed */