work in progress - enhancing the compiler to implement 'interface'

This commit is contained in:
hyunghwan.chung 2018-07-04 08:27:13 +00:00
parent 389a7a3d76
commit 78a8fb2274

View File

@ -7165,6 +7165,39 @@ static int make_default_initial_values (moo_t* moo, var_type_t var_type)
return 0;
}
static int make_defined_interface (moo_t* moo)
{
moo_oop_t tmp;
/* TODO: instantiate differently... */
tmp = moo_instantiate(moo, moo->_class, MOO_NULL, 0);
if (!tmp) return -1;
moo->c->cls.self_oop = (moo_oop_class_t)tmp;
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;
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_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_dic_t)tmp;
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;
moo->c->cls.self_oop->spec = MOO_SMOOI_TO_OOP(0);
moo->c->cls.self_oop->selfspec = MOO_SMOOI_TO_OOP(0);
/* TODO: .......... */
return 0;
}
static int make_defined_class (moo_t* moo)
{
/* this function make a class object with no functions/methods */
@ -7569,7 +7602,24 @@ static int __compile_class_definition (moo_t* moo, int class_type)
}
GET_TOKEN (moo);
if (class_type == CLASS_TYPE_EXTEND)
if (class_type == CLASS_TYPE_INTERFACE)
{
MOO_ASSERT (moo, moo->c->cls.flags == 0);
MOO_INFO2 (moo, "Defining an interface %.*js\n", moo->c->cls.fqn.len, moo->c->cls.fqn.ptr);
ass = moo_lookupdic(moo, (moo_oop_dic_t)moo->c->cls.ns_oop, &moo->c->cls.name);
if (ass)
{
// The interface name already exists. An interface cannot be defined with an existing name
moo_setsynerr (moo, MOO_SYNERR_CLASSDUPL, &moo->c->cls.fqn_loc, &moo->c->cls.name); /* TODO: change the error code to MOO_SYNERR_IFCEDUPL? */
return -1;
}
/* an interface doesn't inherit anything */
moo->c->cls.super_oop = moo->_nil;
}
else if (class_type == CLASS_TYPE_EXTEND)
{
/* extending class */
MOO_ASSERT (moo, moo->c->cls.flags == 0);
@ -7807,12 +7857,29 @@ static int __compile_class_definition (moo_t* moo, int class_type)
GET_TOKEN (moo);
if (class_type == CLASS_TYPE_EXTEND)
if (class_type == CLASS_TYPE_INTERFACE)
{
/* an interface cannot have variables */
if (is_token_word(moo, VOCA_VAR) || is_token_word(moo, VOCA_VARIABLE) ||
is_token_binary_selector(moo, VOCA_VBAR) ||
is_token_binary_selector(moo, VOCA_VBAR_PLUS) ||
is_token_binary_selector(moo, VOCA_VBAR_ASTER))
{
moo_setsynerr (moo, MOO_SYNERR_VARDCLBANNED, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;
}
if (make_defined_interface(moo) <= -1) return -1;
}
else if (class_type == CLASS_TYPE_EXTEND)
{
moo_oop_char_t pds;
/* when a class is extended, a new variable cannot be added */
if (is_token_word(moo, VOCA_VAR) || is_token_word(moo, VOCA_VARIABLE))
if (is_token_word(moo, VOCA_VAR) || is_token_word(moo, VOCA_VARIABLE) ||
is_token_binary_selector(moo, VOCA_VBAR) ||
is_token_binary_selector(moo, VOCA_VBAR_PLUS) ||
is_token_binary_selector(moo, VOCA_VBAR_ASTER))
{
moo_setsynerr (moo, MOO_SYNERR_VARDCLBANNED, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;