diff --git a/stix/lib/Stix.st b/stix/lib/Stix.st index 13e1836..8e5a7a4 100644 --- a/stix/lib/Stix.st +++ b/stix/lib/Stix.st @@ -241,6 +241,10 @@ { } +#class Namespace(Set) +{ +} + #class MethodDictionary(Dictionary) { diff --git a/stix/lib/comp.c b/stix/lib/comp.c index 2d1d496..ca8e8c7 100644 --- a/stix/lib/comp.c +++ b/stix/lib/comp.c @@ -37,6 +37,7 @@ /* initial method dictionary size */ #define INSTANCE_METHOD_DICTIONARY_SIZE 256 /* TODO: choose the right size */ #define CLASS_METHOD_DICTIONARY_SIZE 128 /* TODO: choose the right size */ +#define NAMESPACE_SIZE 128 /* TODO: choose the right size */ enum class_mod_t { @@ -4313,63 +4314,105 @@ static int compile_class_definition (stix_t* stix, int extend) return n; } +static int add_namespace (stix_t* stix, stix_oop_set_t dic, const stix_ucs_t* name) +{ + stix_size_t tmp_count = 0; + stix_oop_t sym; + stix_oop_set_t ns; + + stix_pushtmp (stix, (stix_oop_t*)&dic); tmp_count++; + + sym = stix_makesymbol (stix, name->ptr, name->len); + if (!sym) goto oops; + + stix_pushtmp (stix, &sym); tmp_count++; + + ns = stix_makedic (stix, stix->_namespace, NAMESPACE_SIZE); + if (!ns) goto oops; + + /*stix_pushtmp (stix, &ns); tmp_count++;*/ + + if (!stix_putatdic (stix, dic, sym, (stix_oop_t)ns)) goto oops; + + stix_poptmps (stix, tmp_count); + return 0; + +oops: + stix_poptmps (stix, tmp_count); + return -1; +} + static int compile_namespace (stix_t* stix) { - /* the name sapce path must not contain any space between segments - * #namespace Abc.Def .Hij - * Abc.Def comprises a valid name space. a period before Hij acts - * as a terminator for the namespace declaration. Hij itself causes - * a syntax error */ + const stix_uch_t* ptr, * dot; + stix_size_t len; + stix_ucs_t seg; + stix_oop_set_t dic; + stix_oop_association_t ass; - stix_iotok_t seg_tok; - - if (stix->c->tok.type != STIX_IOTOK_IDENT) + if (stix->c->tok.type != STIX_IOTOK_IDENT && + stix->c->tok.type != STIX_IOTOK_IDENT_DOTTED) { set_syntax_error (stix, STIX_SYNERR_IDENT, &stix->c->tok.loc, &stix->c->tok.name); return -1; } - seg_tok = stix->c->tok; +/* TODO: handle namespace attribute like dupok or missingok. #namespace(dupok) XXX. */ -/*clone_nameseg_segment ().*/ - - GET_TOKEN (stix); - while (stix->c->tok.type == STIX_IOTOK_PERIOD) + dic = stix->sysdic; + ptr = stix->c->tok.name.ptr; + len = stix->c->tok.name.len; + while (1) { - GET_TOKEN (stix); - if (stix->c->tok.type != STIX_IOTOK_IDENT) goto ok; + seg.ptr = (stix_uch_t*)ptr; - if (stix->c->tok.loc.line == seg_tok.loc.line && - stix->c->tok.loc.colm == seg_tok.loc.colm + seg_tok.name.len + 1) + dot = stix_findchar (ptr, len, '.'); + if (dot) { - stix_oop_association_t ass; + seg.len = dot - ptr; - ass = stix_lookupsysdic (stix, &seg_tok.name); - if (ass == STIX_NULL || STIX_CLASSOF(stix, ass->value) != stix->_namespace) + ass = stix_lookupdic (stix, dic, &seg); + if (ass && (STIX_CLASSOF(stix, ass->value) == stix->_namespace || + (seg.ptr == stix->c->tok.name.ptr && ass->value == (stix_oop_t)stix->sysdic))) { - /* unknown name space */ - /*set_syntax_error (stix, STIX_SYNERR_UNKNOW*/ + /* ok */ + dic = (stix_oop_set_t)ass->value; + } + else + { + set_syntax_error (stix, STIX_SYNERR_NAMESPACE, &stix->c->tok.loc, &stix->c->tok.name); return -1; } - - seg_tok = stix->c->tok; - GET_TOKEN (stix); } else { - goto ok; + /* this is the last segment. */ + seg.len = len; + + ass = stix_lookupdic (stix, dic, &seg); + if (ass) + { + /* duplicate name space or conflicting name */ + set_syntax_error (stix, STIX_SYNERR_NAMESPACEDUP, &stix->c->tok.loc, &stix->c->tok.name); + return -1; + } + + if (add_namespace (stix, dic, &seg) <= -1) return -1; + break; } + + ptr = dot + 1; + len -= seg.len + 1; } - set_syntax_error (stix, STIX_SYNERR_PERIOD, &stix->c->tok.loc, &stix->c->tok.name); - return -1; + GET_TOKEN (stix); + if (stix->c->tok.type != STIX_IOTOK_PERIOD) + { + set_syntax_error (stix, STIX_SYNERR_PERIOD, &stix->c->tok.loc, &stix->c->tok.name); + return -1; + } -ok: -/* - name = stix_makesymbol (stix, seg_tok.name); - ns = stix_instantiate (stix, stix->_namespace, XXXXXXXXXXX); - stix_putatdic (stix, dic, name, ns); -*/ + GET_TOKEN (stix); return 0; } diff --git a/stix/lib/exec.c b/stix/lib/exec.c index 943dcea..e82e924 100644 --- a/stix/lib/exec.c +++ b/stix/lib/exec.c @@ -109,7 +109,7 @@ static STIX_INLINE int activate_new_method (stix_t* stix, stix_oop_method_t mth) * | .... | slot[..] * | receiver | slot[..] <-- sp - nargs(1) * | arg1 | slot[..] <-- sp - * | .... | slot[..] + * | .... | slot[..] * | | slot[stack_size - 1] * +---------------------+ */ diff --git a/stix/lib/ignite.c b/stix/lib/ignite.c index 97d7906..9861b1f 100644 --- a/stix/lib/ignite.c +++ b/stix/lib/ignite.c @@ -226,6 +226,8 @@ static int ignite_3 (stix_t* stix) { 12, { 'S','m','a','l','l','I','n','t','e','g','e','r' } } }; + static stix_uch_t stix_str[] = { 'S','t','a','x' }; + stix_oow_t i; stix_oop_t sym; stix_oop_t* stix_ptr; @@ -239,10 +241,14 @@ static int ignite_3 (stix_t* stix) sym = stix_makesymbol (stix, symnames[i].str, symnames[i].len); if (!sym) return -1; - if (!stix_putatsysdic (stix, sym, *stix_ptr)) return -1; + if (!stix_putatsysdic(stix, sym, *stix_ptr)) return -1; stix_ptr++; } + sym = stix_makesymbol (stix, stix_str, 4); + if (!sym) return -1; + if (!stix_putatsysdic(stix, sym, (stix_oop_t)stix->sysdic)) return -1; + return 0; } diff --git a/stix/lib/main.c b/stix/lib/main.c index 68d0cd1..b4bce7b 100644 --- a/stix/lib/main.c +++ b/stix/lib/main.c @@ -214,7 +214,9 @@ static char* syntax_error_msg[] = "too many block arguments", "too large block", "wrong primitive number", - "#include error" + "#include error", + "wrong namespace name", + "duplicate namespace name" }; stix_uch_t str_stix[] = { 'S', 't', 'i', 'x' }; diff --git a/stix/lib/stix-prv.h b/stix/lib/stix-prv.h index 7c714a9..bd4bc50 100644 --- a/stix/lib/stix-prv.h +++ b/stix/lib/stix-prv.h @@ -328,7 +328,9 @@ enum stix_synerrnum_t STIX_SYNERR_BLKARGFLOOD, /* too many block arguments */ STIX_SYNERR_BLKFLOOD, /* too large block */ STIX_SYNERR_PRIMNO, /* wrong primitive number */ - STIX_SYNERR_INCLUDE /* #include error */ + STIX_SYNERR_INCLUDE, /* #include error */ + STIX_SYNERR_NAMESPACE, /* wrong namespace name */ + STIX_SYNERR_NAMESPACEDUP /* duplicate namespace name */ }; typedef enum stix_synerrnum_t stix_synerrnum_t; @@ -842,7 +844,13 @@ int stix_equalchars ( void stix_copychars ( stix_uch_t* dst, const stix_uch_t* src, - stix_size_t len + stix_size_t len +); + +stix_uch_t* stix_findchar ( + const stix_uch_t* ptr, + stix_size_t len, + stix_uch_t c ); /* ========================================================================= */ @@ -1038,7 +1046,7 @@ int stix_compile ( ); void stix_getsynerr ( - stix_t* stix, + stix_t* stix, stix_synerr_t* synerr ); diff --git a/stix/lib/stix.c b/stix/lib/stix.c index 421b868..b392a84 100644 --- a/stix/lib/stix.c +++ b/stix/lib/stix.c @@ -217,6 +217,20 @@ void stix_copychars (stix_uch_t* dst, const stix_uch_t* src, stix_size_t len) for (i = 0; i < len; i++) dst[i] = src[i]; } +stix_uch_t* stix_findchar (const stix_uch_t* ptr, stix_size_t len, stix_uch_t c) +{ + const stix_uch_t* end; + + end = ptr + len; + while (ptr < end) + { + if (*ptr == c) return (stix_uch_t*)ptr; + ptr++; + } + + return STIX_NULL; +} + void* stix_allocmem (stix_t* stix, stix_size_t size) { void* ptr;