allowed class and class extension nesting inside a class

This commit is contained in:
hyunghwan.chung 2018-10-08 06:51:31 +00:00
parent e7265f44bc
commit 9ad9299dea
11 changed files with 193 additions and 73 deletions

View File

@ -4,8 +4,26 @@ class Apex(nil)
class(#limited) Error(Apex)
{
pooldic Code
{
ENOERR := #\E0.
EGENERIC := #\E1.
ENOIMPL := #\E2.
ESYSERR := #\E3.
EINTERN := #\E4.
ESYSMEM := #\E5.
EOOMEM := #\E6.
EINVAL := #\E7.
ENOENT := #\E8.
EPERM := #\E12.
ERANGE := #\E20.
ELIMIT := #\E9999.
## add more items...
}
}
(*
pooldic Error.Code
{
ENOERR := #\E0.
@ -21,8 +39,8 @@ pooldic Error.Code
ERANGE := #\E20.
ELIMIT := #\E9999.
(* add more items... *)
}
## add more items...
} *)
(*pooldic Error.Code2
{

View File

@ -231,6 +231,19 @@ class Socket(Object) from 'sck'
## the internal representation used by various modules. (e.g. sck)
var(#get) handle := -1.
## TODO: generate these family and type from the C header
pooldic Family
{
INET := 2.
INET6 := 10.
}
pooldic Type
{
STREAM := 1.
DGRAM := 2.
}
method(#primitive) open(family, type, proto).
## map the open primitive again with a different name for strict internal use only.
## this method is supposed to be used to handle an accepted socket in server sockets.
@ -284,19 +297,6 @@ class Socket(Object) from 'sck'
}
}
(* TODO: generate these family and type from the C header *)
pooldic Socket.Family
{
INET := 2.
INET6 := 10.
}
pooldic Socket.Type
{
STREAM := 1.
DGRAM := 2.
}
class SyncSocket(Socket)
{
var iosem, tmoutsem, sg.

View File

@ -12,6 +12,20 @@ class System(Apex)
{
var(#class) asyncsg.
pooldic Log
{
## -----------------------------------------------------------
## defines log levels
## these items must follow defintions in moo.h
## -----------------------------------------------------------
DEBUG := 1.
INFO := 2.
WARN := 4.
ERROR := 8.
FATAL := 16.
}
method(#class) addAsyncSemaphore: sem
{
^self.asyncsg addSemaphore: sem
@ -124,24 +138,7 @@ class System(Apex)
s signalAfterSecs: secs nanosecs: nanosecs.
s wait.
}
}
pooldic System.Log
{
## -----------------------------------------------------------
## defines log levels
## these items must follow defintions in moo.h
## -----------------------------------------------------------
DEBUG := 1.
INFO := 2.
WARN := 4.
ERROR := 8.
FATAL := 16.
}
extend System
{
## the following methods may not look suitable to be placed
## inside a system dictionary. but they are here for quick and dirty
## output production from the moo code.

View File

@ -15,6 +15,38 @@ class X11(Object) from 'x11'
var event_loop_sem, event_loop_proc.
var llevent_blocks.
class Exception(System.Exception)
{
}
class Point(Object)
{
var(#get,#set) x := 0, y := 0.
}
class Dimension(Object)
{
var(#get,#set) width := 0, height := 0.
}
class Rectangle(Object)
{
var(#get,#set)
x := 0,
y := 0,
width := 0,
height := 0.
}
extend Point
{
method print
{
x dump.
y dump.
}
}
method(#primitive,#liberal) _open_display(name).
method(#primitive) _close_display.
method(#primitive) _get_fd.
@ -47,29 +79,6 @@ class X11(Object) from 'x11'
}
}
class X11.Exception(System.Exception)
{
}
class X11.Point(Object)
{
var(#get,#set) x := 0, y := 0.
}
class X11.Dimension(Object)
{
var(#get,#set) width := 0, height := 0.
}
class X11.Rectangle(Object)
{
var(#get,#set)
x := 0,
y := 0,
width := 0,
height := 0.
}
## ---------------------------------------------------------------------------
## Event
## ---------------------------------------------------------------------------

View File

@ -247,6 +247,7 @@ enum voca_id_t
};
typedef enum voca_id_t voca_id_t;
static int compile_class_definition (moo_t* moo, int class_type);
static int compile_pooldic_definition (moo_t* moo);
static int compile_block_statement (moo_t* moo);
static int compile_method_statement (moo_t* moo);
@ -7656,8 +7657,15 @@ static int __compile_class_definition (moo_t* moo, int class_type)
return -1;
}
if (cc->cunit_parent && cc->cunit_parent->cunit_type == MOO_CUNIT_CLASS && TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED)
{
/* the name of a nested class cannot be multi-segmented */
moo_setsynerrbfmt (moo, MOO_SYNERR_IDENT, TOKEN_LOC(moo), TOKEN_NAME(moo), "undotted identifier expected");
return -1;
}
#if 0
if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT && is_restricted_word (TOKEN_NAME(moo)))
if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT && is_restricted_word(TOKEN_NAME(moo)))
{
/* wrong class name */
moo_setsynerr (moo, MOO_SYNERR_CLASSNAMEINVAL, TOKEN_LOC(moo), TOKEN_NAME(moo));
@ -7665,10 +7673,25 @@ static int __compile_class_definition (moo_t* moo, int class_type)
}
#endif
/* copy the class name */
/* [NOTE] TOKEN_NAME(moo) doesn't contain the full name if it's nested
* inside a class. it is merely a name that appeared in the source
* code.
* TODO: compose the full name by traversing the namespace chain. */
if (set_class_fqn(moo, cc, TOKEN_NAME(moo)) <= -1) return -1;
cc->fqn_loc = moo->c->tok.loc;
if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED)
if (cc->cunit_parent && cc->cunit_parent->cunit_type == MOO_CUNIT_CLASS)
{
moo_cunit_class_t* c = (moo_cunit_class_t*)cc->cunit_parent;
if ((moo_oop_t)c->self_oop->nsdic == moo->_nil)
{
/* attach a new namespace dictionary to the nsdic field of the class */
if (!attach_nsdic_to_class(moo, c->self_oop)) return -1;
}
cc->ns_oop = c->self_oop->nsdic; /* TODO: if c->nsdic is nil, create one? */
}
else if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED)
{
if (preprocess_dotted_name(moo, (class_type == CLASS_TYPE_EXTEND? PDN_DONT_ADD_NS: 0), MOO_NULL, &cc->fqn, &cc->fqn_loc, &cc->name, &cc->ns_oop) <= -1) return -1;
}
@ -7724,8 +7747,7 @@ static int __compile_class_definition (moo_t* moo, int class_type)
cc->super_oop = cc->self_oop->superclass;
MOO_ASSERT (moo, cc->super_oop == moo->_nil ||
MOO_CLASSOF(moo, cc->super_oop) == moo->_class);
MOO_ASSERT (moo, cc->super_oop == moo->_nil || MOO_CLASSOF(moo, cc->super_oop) == moo->_class);
}
else
{
@ -8096,6 +8118,18 @@ static int __compile_class_definition (moo_t* moo, int class_type)
GET_TOKEN (moo);
if (compile_pooldic_definition(moo) <= -1) return -1;
}
else if (is_token_word(moo, VOCA_CLASS))
{
/* class definition nested inside another class definition */
GET_TOKEN (moo);
if (compile_class_definition(moo, CLASS_TYPE_NORMAL) <= -1) return -1;
}
else if (is_token_word(moo, VOCA_EXTEND))
{
/* class extension nested inside another class definition */
GET_TOKEN (moo);
if (compile_class_definition(moo, CLASS_TYPE_EXTEND) <= -1) return -1;
}
else break;
}
while (1);
@ -8263,10 +8297,14 @@ static int __compile_pooldic_definition (moo_t* moo)
if (pd->cunit_parent && pd->cunit_parent->cunit_type == MOO_CUNIT_CLASS && TOKEN_TYPE(moo) == MOO_IOTOK_IDENT_DOTTED)
{
/* the pool dictionary nested inside a class cannot be multi-segmented */
moo_setsynerr (moo, MOO_SYNERR_IDENT, TOKEN_LOC(moo), TOKEN_NAME(moo));
moo_setsynerrbfmt (moo, MOO_SYNERR_IDENT, TOKEN_LOC(moo), TOKEN_NAME(moo), "undotted identifier expected");
goto oops;
}
/* [NOTE] TOKEN_NAME(moo) doesn't contain the full name if it's nested
* inside a class. it is merely a name that appeared in the source
* code.
* TODO: compose the full name by traversing the namespace chain. */
if (set_pooldic_fqn(moo, pd, TOKEN_NAME(moo)) <= -1) goto oops;
pd->fqn_loc = moo->c->tok.loc;

View File

@ -405,7 +405,19 @@ void moo_setsynerrbfmt (moo_t* moo, moo_synerrnum_t num, const moo_ioloc_t* loc,
if (tgt)
{
moo->c->synerr.tgt = *tgt;
if (tgt->len >= MOO_COUNTOF(moo->c->synerr_tgtbuf) &&
moo_copyoocharstosbuf(moo, tgt->ptr, tgt->len, MOO_SBUF_ID_SYNERR) >= 0)
{
moo->c->synerr.tgt.ptr = moo->sbuf[MOO_SBUF_ID_SYNERR].ptr;
moo->c->synerr.tgt.len = moo->sbuf[MOO_SBUF_ID_SYNERR].len;
}
else
{
moo->c->synerr.tgt.ptr = moo->c->synerr_tgtbuf;
moo->c->synerr.tgt.len = (tgt->len < MOO_COUNTOF(moo->c->synerr_tgtbuf))? tgt->len: (MOO_COUNTOF(moo->c->synerr_tgtbuf) - 1);
moo->c->synerr.tgt.ptr[moo->c->synerr.tgt.len] = '\0';
moo_copy_oochars (moo->c->synerr.tgt.ptr, tgt->ptr, moo->c->synerr.tgt.len);
}
}
else
{
@ -456,7 +468,19 @@ void moo_setsynerrufmt (moo_t* moo, moo_synerrnum_t num, const moo_ioloc_t* loc,
if (tgt)
{
moo->c->synerr.tgt = *tgt;
if (tgt->len >= MOO_COUNTOF(moo->c->synerr_tgtbuf) &&
moo_copyoocharstosbuf(moo, tgt->ptr, tgt->len, MOO_SBUF_ID_SYNERR) >= 0)
{
moo->c->synerr.tgt.ptr = moo->sbuf[MOO_SBUF_ID_SYNERR].ptr;
moo->c->synerr.tgt.len = moo->sbuf[MOO_SBUF_ID_SYNERR].len;
}
else
{
moo->c->synerr.tgt.ptr = moo->c->synerr_tgtbuf;
moo->c->synerr.tgt.len = (tgt->len < MOO_COUNTOF(moo->c->synerr_tgtbuf))? tgt->len: (MOO_COUNTOF(moo->c->synerr_tgtbuf) - 1);
moo->c->synerr.tgt.ptr[moo->c->synerr.tgt.len] = '\0';
moo_copy_oochars (moo->c->synerr.tgt.ptr, tgt->ptr, moo->c->synerr.tgt.len);
}
}
else
{

View File

@ -666,6 +666,7 @@ struct moo_compiler_t
/* syntax error information */
moo_synerr_t synerr;
moo_ooch_t synerr_tgtbuf[256];
/* temporary space used when dealing with an illegal character */
moo_ooch_t ilchr;

View File

@ -336,15 +336,31 @@ MOO_EXPORT moo_oow_t moo_count_bcstr (
MOO_EXPORT int moo_copyoocstrtosbuf (
moo_t* moo,
const moo_ooch_t* str,
int id
int id
);
MOO_EXPORT int moo_concatoocstrtosbuf (
moo_t* moo,
const moo_ooch_t* str,
int id
int id
);
MOO_EXPORT int moo_copyoocharstosbuf (
moo_t* moo,
const moo_ooch_t* ptr,
moo_oow_t len,
int id
);
MOO_EXPORT int moo_concatoocharstosbuf (
moo_t* moo,
const moo_ooch_t* ptr,
moo_oow_t len,
int id
);
#if defined(MOO_OOCH_IS_UCH)
# define moo_conv_oocs_to_bcs_with_cmgr(oocs,oocslen,bcs,bcslen,cmgr) moo_conv_ucs_to_bcs_with_cmgr(oocs,oocslen,bcs,bcslen,cmgr)
# define moo_conv_oochars_to_bchars_with_cmgr(oocs,oocslen,bcs,bcslen,cmgr) moo_conv_uchars_to_bchars_with_cmgr(oocs,oocslen,bcs,bcslen,cmgr)

View File

@ -837,15 +837,15 @@ int moo_genpfmethod (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class, moo_met
/* compose a full primitive function identifier to VM's string buffer.
* pfid => mod->name + '.' + pfname */
if (moo_copyoocstrtosbuf(moo, mod->name, 0) <= -1 ||
moo_concatoocstrtosbuf(moo, dot, 0) <= -1 ||
moo_concatoocstrtosbuf(moo, pfname, 0) <= -1)
if (moo_copyoocstrtosbuf(moo, mod->name, MOO_SBUF_TMP) <= -1 ||
moo_concatoocstrtosbuf(moo, dot, MOO_SBUF_TMP) <= -1 ||
moo_concatoocstrtosbuf(moo, pfname, MOO_SBUF_TMP) <= -1)
{
MOO_DEBUG2 (moo, "Cannot generate primitive function method [%js] in [%O] - VM memory shortage\n", mthname, _class->name);
return -1;
}
pfidsym = (moo_oop_char_t)moo_makesymbol (moo, moo->sbuf[0].ptr, moo->sbuf[0].len);
pfidsym = (moo_oop_char_t)moo_makesymbol(moo, moo->sbuf[MOO_SBUF_TMP].ptr, moo->sbuf[MOO_SBUF_TMP].len);
if (!pfidsym)
{
MOO_DEBUG2 (moo, "Cannot generate primitive function method [%js] in [%O] - symbol instantiation failure\n", mthname, _class->name);

View File

@ -1327,6 +1327,14 @@ typedef struct moo_compiler_t moo_compiler_t;
#define MOO_ERRMSG_CAPA (2048)
enum moo_sbuf_id_t
{
MOO_SBUF_ID_TMP = 0,
MOO_SBUF_ID_SYNERR = 1
/* more? */
};
struct moo_t
{
moo_mmgr_t* mmgr;

View File

@ -352,12 +352,15 @@ moo_bch_t* moo_find_bchar_in_bcstr (const moo_bch_t* ptr, moo_bch_t c)
/* ----------------------------------------------------------------------- */
int moo_concatoocstrtosbuf (moo_t* moo, const moo_ooch_t* str, int id)
{
return moo_concatoocharstosbuf(moo, str, moo_count_oocstr(str), id);
}
int moo_concatoocharstosbuf (moo_t* moo, const moo_ooch_t* ptr, moo_oow_t len, int id)
{
moo_sbuf_t* p;
moo_oow_t len;
p = &moo->sbuf[id];
len = moo_count_oocstr (str);
if (len > p->capa - p->len)
{
@ -374,7 +377,7 @@ int moo_concatoocstrtosbuf (moo_t* moo, const moo_ooch_t* str, int id)
p->capa = newcapa;
}
moo_copy_oochars (&p->ptr[p->len], str, len);
moo_copy_oochars (&p->ptr[p->len], ptr, len);
p->len += len;
p->ptr[p->len] = '\0';
@ -384,7 +387,13 @@ int moo_concatoocstrtosbuf (moo_t* moo, const moo_ooch_t* str, int id)
int moo_copyoocstrtosbuf (moo_t* moo, const moo_ooch_t* str, int id)
{
moo->sbuf[id].len = 0;;
return moo_concatoocstrtosbuf (moo, str, id);
return moo_concatoocstrtosbuf(moo, str, id);
}
int moo_copyoocharstosbuf (moo_t* moo, const moo_ooch_t* ptr, moo_oow_t len, int id)
{
moo->sbuf[id].len = 0;;
return moo_concatoocharstosbuf(moo, ptr, len, id);
}
/* ----------------------------------------------------------------------- */