added some code to check interface conformance of a class
This commit is contained in:
parent
6676e349ca
commit
1cbe741508
@ -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)
|
||||
{
|
||||
}
|
||||
|
@ -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'
|
||||
|
236
moo/lib/comp.c
236
moo/lib/comp.c
@ -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++)
|
||||
{
|
||||
|
@ -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'};
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user