added some code to check interface conformance of a class

This commit is contained in:
hyunghwan.chung 2018-10-11 10:01:34 +00:00
parent 6676e349ca
commit 1cbe741508
6 changed files with 174 additions and 94 deletions

View File

@ -5,8 +5,19 @@ interface X11able
method(#dual) abc.
method(#dual) def.
}
interface X11able2
{
method(#dual) abc2.
method(#dual) def.
}
class X11(Object) [X11able] from 'x11'
interface X11able3
{
method(#dual) abc3.
}
class X11(Object) [X11able,selfns.X11able3] from 'x11'
{
## =====================================================================
## this part of the class must match the internal
@ -21,6 +32,11 @@ class X11(Object) [X11able] from 'x11'
var event_loop_sem, event_loop_proc.
var llevent_blocks.
interface X11able3
{
method(#dual) abc55.
}
class Exception(System.Exception)
{
}

View File

@ -78,7 +78,7 @@ class MyObject(Object)
'wrong directive'
'wrong name'
'duplicate name'
'undefined class'
'undefined name'
'contradictory class definition'
'invalid non-pointer instance size'
'prohibited inheritance'

View File

@ -548,6 +548,45 @@ static int fetch_word_from_string (const moo_oocs_t* haystack, moo_oow_t xindex,
return -1;
}
static int add_oop_to_oopbuf (moo_t* moo, moo_oopbuf_t* oopbuf, moo_oop_t item)
{
if (oopbuf->count >= oopbuf->capa)
{
moo_oop_t* tmp;
moo_oow_t new_capa;
new_capa = MOO_ALIGN (oopbuf->count + 1, ARLIT_BUFFER_ALIGN);
tmp = (moo_oop_t*)moo_reallocmem(moo, oopbuf->ptr, new_capa * MOO_SIZEOF(*tmp));
if (!tmp) return -1;
oopbuf->capa = new_capa;
oopbuf->ptr = tmp;
}
/* TODO: overflow check of oopbuf->count itself */
oopbuf->ptr[oopbuf->count++] = item;
return 0;
}
static int add_oop_to_oopbuf_nodup (moo_t* moo, moo_oopbuf_t* oopbuf, moo_oop_t item, moo_oow_t* index)
{
moo_oow_t i;
for (i = 0; i < oopbuf->count; i++)
{
if (oopbuf->ptr[i] == item)
{
*index = i;
return 0;
}
}
if (add_oop_to_oopbuf(moo, oopbuf, item) <= -1) return -1;
*index = oopbuf->count - 1;
return 0;
}
#define CHAR_TO_NUM(c,base) \
((c >= '0' && c <= '9')? ((c - '0' < base)? (c - '0'): base): \
(c >= 'A' && c <= 'Z')? ((c - 'A' + 10 < base)? (c - 'A' + 10): base): \
@ -2696,8 +2735,9 @@ static void eliminate_instructions (moo_t* moo, moo_oow_t start, moo_oow_t end)
* Compiler
* --------------------------------------------------------------------- */
static int add_literal (moo_t* moo, moo_oop_t lit, moo_oow_t* index)
static MOO_INLINE int add_literal (moo_t* moo, moo_oop_t lit, moo_oow_t* index)
{
#if 0
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
moo_oow_t i;
@ -2711,27 +2751,22 @@ static int add_literal (moo_t* moo, moo_oop_t lit, moo_oow_t* index)
if (cc->mth.literals.ptr[i] == lit)
{
*index = i;
return i;
}
}
if (cc->mth.literals.count >= cc->mth.literals.capa)
{
moo_oop_t* tmp;
moo_oow_t new_capa;
new_capa = MOO_ALIGN (cc->mth.literals.count + 1, LITERAL_BUFFER_ALIGN);
tmp = (moo_oop_t*)moo_reallocmem (moo, cc->mth.literals.ptr, new_capa * MOO_SIZEOF(*tmp));
if (!tmp) return -1;
cc->mth.literals.capa = new_capa;
cc->mth.literals.ptr = tmp;
}
*index = cc->mth.literals.count;
cc->mth.literals.ptr[cc->mth.literals.count++] = lit;
return 0;
}
}
if (add_oop_to_oopbuf(moo, &cc->mth.literals, lit) <= -1) return -1;
*index = cc->mth.literals.count - 1;
return 0;
#else
/*
* this removes redundancy of symbols, characters, and small integers.
* more complex redundacy check may be done somewhere else like
* in add_string_literal().
*/
return add_oop_to_oopbuf_nodup(moo, &((moo_cunit_class_t*)moo->c->cunit)->mth.literals, lit, index);
#endif
}
static int add_string_literal (moo_t* moo, const moo_oocs_t* str, moo_oow_t* index)
{
@ -4672,24 +4707,9 @@ static int add_to_byte_array_literal_buffer (moo_t* moo, moo_oob_t b)
return 0;
}
static int add_to_array_literal_buffer (moo_t* moo, moo_oop_t item)
static MOO_INLINE int add_to_array_literal_buffer (moo_t* moo, moo_oop_t item)
{
if (moo->c->arlit.count >= moo->c->arlit.capa)
{
moo_oop_t* tmp;
moo_oow_t new_capa;
new_capa = MOO_ALIGN (moo->c->arlit.count + 1, ARLIT_BUFFER_ALIGN);
tmp = (moo_oop_t*)moo_reallocmem(moo, moo->c->arlit.ptr, new_capa * MOO_SIZEOF(*tmp));
if (!tmp) return -1;
moo->c->arlit.capa = new_capa;
moo->c->arlit.ptr = tmp;
}
/* TODO: overflow check of moo->c->arlit.count itself */
moo->c->arlit.ptr[moo->c->arlit.count++] = item;
return 0;
return add_oop_to_oopbuf(moo, &moo->c->arlit, item);
}
static int read_byte_array_literal (moo_t* moo, int rdonly, moo_oop_t* xlit)
@ -7694,7 +7714,7 @@ static int process_class_superclass (moo_t* moo)
* the object found with the name is not a class object. or,
* the class object found is a internally defined kernel
* class object. */
moo_setsynerr (moo, MOO_SYNERR_CLASSUNDEF, &cc->superfqn_loc, &cc->superfqn);
moo_setsynerrbfmt (moo, MOO_SYNERR_NAMEUNDEF, &cc->superfqn_loc, &cc->superfqn, "superclass name undefined");
return -1;
}
}
@ -7702,51 +7722,6 @@ static int process_class_superclass (moo_t* moo)
return 0;
}
static int process_class_interfaces (moo_t* moo)
{
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
GET_TOKEN (moo); /* skip [ */
if (TOKEN_TYPE(moo) != MOO_IOTOK_IDENT && TOKEN_TYPE(moo) != MOO_IOTOK_IDENT_DOTTED)
{
moo_setsynerrbfmt (moo, MOO_SYNERR_IDENT, TOKEN_LOC(moo), TOKEN_NAME(moo), "interface name expected");
return -1;
}
do
{
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 -1;
if (var.type != VAR_GLOBAL || MOO_CLASSOF(moo, var.u.gbl->value) != moo->_interface)
{
moo_setsynerr (moo, MOO_SYNERR_CLASSUNDEF, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;
}
// TODO: store to interfaces....
//cc->interfaces[];
GET_TOKEN (moo);
if (TOKEN_TYPE(moo) != MOO_IOTOK_COMMA) break;
GET_TOKEN (moo);
}
while (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT || TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED);
if (TOKEN_TYPE(moo) != MOO_IOTOK_RBRACK)
{
moo_setsynerr (moo, MOO_SYNERR_RBRACK, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;
}
GET_TOKEN (moo); /* skip ] and read the next token */
return 0;
}
static int process_class_module_import (moo_t* moo)
{
/* handle the module importing(from) part.
@ -7781,6 +7756,80 @@ static int process_class_module_import (moo_t* moo)
return 0;
}
static int process_class_interfaces (moo_t* moo)
{
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
GET_TOKEN (moo); /* skip [ */
if (TOKEN_TYPE(moo) != MOO_IOTOK_IDENT && TOKEN_TYPE(moo) != MOO_IOTOK_IDENT_DOTTED)
{
moo_setsynerrbfmt (moo, MOO_SYNERR_IDENT, TOKEN_LOC(moo), TOKEN_NAME(moo), "interface name expected");
return -1;
}
do
{
var_info_t var;
moo_oow_t old_ifce_count;
moo_oow_t ifce_index;
if (get_variable_info(moo, TOKEN_NAME(moo), TOKEN_LOC(moo), TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED, &var) <= -1 ||
var.type != VAR_GLOBAL || MOO_CLASSOF(moo, var.u.gbl->value) != moo->_interface)
{
moo_setsynerrbfmt (moo, MOO_SYNERR_NAMEUNDEF, TOKEN_LOC(moo), TOKEN_NAME(moo), "interface name undefined");
return -1;
}
old_ifce_count = cc->ifces.count;
if (add_oop_to_oopbuf_nodup(moo, &cc->ifces, var.u.gbl->value, &ifce_index) <= -1) return -1;
if (ifce_index < old_ifce_count)
{
moo_setsynerrbfmt (moo, MOO_SYNERR_NAMEDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo), "duplicate interface name");
return -1;
}
#if 0
if (find_word_in_string(&cc->ifce_names, TOKEN_NAME(moo), MOO_NULL) >= 0)
{
moo_setsynerrbfmt (moo, MOO_SYNERR_NAMEDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo), "duplicate interface name");
return -1;
}
/* just store the interface name instead of resolved interface object */
if (copy_string_to(moo, TOKEN_NAME(moo), &cc->ifce_names, &cc->ifce_names_capa, 1, ' ') <= -1) return -1;
#endif
GET_TOKEN (moo);
if (TOKEN_TYPE(moo) != MOO_IOTOK_COMMA) break;
GET_TOKEN (moo);
}
while (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT || TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED);
if (TOKEN_TYPE(moo) != MOO_IOTOK_RBRACK)
{
moo_setsynerr (moo, MOO_SYNERR_RBRACK, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;
}
GET_TOKEN (moo); /* skip ] and read the next token */
return 0;
}
static int check_class_interface_conformance (moo_t* moo)
{
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
moo_oow_t i;
for (i = 0; i < cc->ifces.count; i++)
{
// TODO: check conformance...
}
return 0;
}
static int __compile_class_definition (moo_t* moo, int class_type)
{
/*
@ -7884,7 +7933,7 @@ static int __compile_class_definition (moo_t* moo, int class_type)
else
{
/* only an existing class can be extended. */
moo_setsynerr (moo, MOO_SYNERR_CLASSUNDEF, &cc->fqn_loc, &cc->name);
moo_setsynerrbfmt (moo, MOO_SYNERR_NAMEUNDEF, &cc->fqn_loc, &cc->name, "class name undefined");
return -1;
}
@ -8162,6 +8211,12 @@ static int __compile_class_definition (moo_t* moo, int class_type)
return -1;
}
if (cc->ifces.count > 0)
{
/* interface has been specified. */
if (check_class_interface_conformance(moo) <= -1) return -1;
}
GET_TOKEN (moo);
return 0;
}
@ -8936,6 +8991,12 @@ static void gc_cunit_chain (moo_t* moo)
c->superns_oop = (moo_oop_nsdic_t)x;
}
for (i = 0; i < c->ifces.count; i++)
{
register moo_oop_t x = moo_moveoop(moo, c->ifces.ptr[i]);
c->ifces.ptr[i] = x;
}
for (i = 0; i < c->pdimp.dcl_count; i++)
{
register moo_oop_t x = moo_moveoop(moo, (moo_oop_t)c->pdimp.oops[i]);
@ -9061,9 +9122,10 @@ static void pop_cunit (moo_t* moo)
moo_cunit_class_t* c;
c = (moo_cunit_class_t*)cunit;
if (c->fqn.ptr) moo_freemem (moo, c->fqn.ptr);
if (c->superfqn.ptr) moo_freemem (moo, c->superfqn.ptr);
if (c->modname.ptr) moo_freemem (moo, c->modname.ptr);
if (c->fqn.ptr) moo_freemem (moo, c->fqn.ptr); /* strbuf */
if (c->superfqn.ptr) moo_freemem (moo, c->superfqn.ptr); /* strbuf */
if (c->modname.ptr) moo_freemem (moo, c->modname.ptr); /* strbuf */
if (c->ifces.ptr) moo_freemem (moo, c->ifces.ptr); /* oopbuf */
for (i = 0; i < MOO_COUNTOF(c->var); i++)
{

View File

@ -107,7 +107,7 @@ 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_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_31[] = {'u','n','d','e','f','i','n','e','d',' ','c','l','a','s','s','\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_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_34[] = {'p','r','o','h','i','b','i','t','e','d',' ','i','n','h','e','r','i','t','a','n','c','e','\0'};

View File

@ -606,6 +606,8 @@ struct moo_cunit_class_t
moo_oow_t modname_capa;
moo_ioloc_t modname_loc;
moo_oopbuf_t ifces;
/* instance variable, class variable, class instance variable, constant
* var[0] - named instance variables
* var[1] - class instance variables

View File

@ -1682,7 +1682,7 @@ enum moo_synerrnum_t
MOO_SYNERR_DIRECTIVEINVAL, /* wrong directive */
MOO_SYNERR_NAMEINVAL, /* wrong name */
MOO_SYNERR_NAMEDUPL, /* duplicate name */
MOO_SYNERR_CLASSUNDEF, /* undefined class */
MOO_SYNERR_NAMEUNDEF, /* undefined name */
MOO_SYNERR_CLASSCONTRA, /* contradictory class */
MOO_SYNERR_NPINSTSIZEINVAL, /* invalid non-pointer instance size */
MOO_SYNERR_INHERITBANNED, /* prohibited inheritance */