diff --git a/stix/kernel/Stdio.st b/stix/kernel/Stdio.st index 6feebdf..04d408e 100644 --- a/stix/kernel/Stdio.st +++ b/stix/kernel/Stdio.st @@ -1,9 +1,9 @@ #class(#byte) Stdio(Object) from 'stdio' { - #method(#class) _newInstSize - { - - } +## #method(#class) _newInstSize +## { +## +## } #method(#class) new: size { @@ -26,12 +26,12 @@ ## #method open: name for: mode ## { -## +## ## } ## #method close ## { -## +## ## } } diff --git a/stix/lib/comp.c b/stix/lib/comp.c index ee71c34..8f64a7c 100644 --- a/stix/lib/comp.c +++ b/stix/lib/comp.c @@ -2703,7 +2703,9 @@ static int compile_method_primitive (stix_t* stix) { /* * method-primitive := "<" "primitive:" integer ">" | - * "<" "exception" ">" + * "<" "primitive:" symbol ">" | + * "<" "exception" ">" | + * "<" "ensure" ">" */ stix_ooi_t pfnum; const stix_ooch_t* ptr, * end; @@ -2752,8 +2754,10 @@ static int compile_method_primitive (stix_t* stix) pfnum = stix_getpfnum (stix, tptr, tlen); if (pfnum <= -1) { + /* a built-in primitive function is not found + * check if it is a primitive function identifier */ +#if 0 const stix_ooch_t* us; - /* the primitive function is not found */ us = stix_findoochar (tptr, tlen, '_'); if (us > tptr && us < tptr + tlen - 1) { @@ -2768,6 +2772,18 @@ static int compile_method_primitive (stix_t* stix) break; } } +#else + stix_oow_t lit_idx; + + if (add_symbol_literal(stix, TOKEN_NAME(stix), 1, &lit_idx) >= 0 && + STIX_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(lit_idx)) + { + stix->c->mth.pftype = 2; /* named primitive */ + stix->c->mth.pfnum = lit_idx; + break; + } + +#endif /* wrong primitive number */ set_syntax_error (stix, STIX_SYNERR_PFID, TOKEN_LOC(stix), TOKEN_NAME(stix)); diff --git a/stix/lib/exec.c b/stix/lib/exec.c index df54abf..5cd908a 100644 --- a/stix/lib/exec.c +++ b/stix/lib/exec.c @@ -2745,7 +2745,7 @@ int stix_getpfnum (stix_t* stix, const stix_ooch_t* ptr, stix_oow_t len) for (i = 0; i < STIX_COUNTOF(pftab); i++) { - if (stix_compucxbcstr(ptr, len, pftab[i].name) == 0) + if (stix_compucharsbcstr(ptr, len, pftab[i].name) == 0) { return i; } diff --git a/stix/lib/stix-utl.h b/stix/lib/stix-utl.h index 92d4018..5aeae88 100644 --- a/stix/lib/stix-utl.h +++ b/stix/lib/stix-utl.h @@ -39,9 +39,10 @@ extern "C" { # define stix_compoocbcstr(str1,str2) stix_compucbcstr(str1,str2) # define stix_compoocstr(str1,str2) stix_compucstr(str1,str2) # define stix_copyoochars(dst,src,len) stix_copyuchars(dst,src,len) -# define stix_copybchtooochars(dst,src,len) stix_copybchtouchars(dst,src,len) +# define stix_copybctooochars(dst,src,len) stix_copybctouchars(dst,src,len) # define stix_copyoocstr(dst,len,src) stix_copyucstr(dst,len,src) # define stix_findoochar(ptr,len,c) stix_finduchar(ptr,len,c) +# define stix_rfindoochar(ptr,len,c) stix_rfinduchar(ptr,len,c) # define stix_countoocstr(str) stix_countucstr(str) #else # define stix_hashchars(ptr,len) stix_hashbchars(ptr,len) @@ -49,9 +50,10 @@ extern "C" { # define stix_compoocbcstr(str1,str2) stix_compbcstr(str1,str2) # define stix_compoocstr(str1,str2) stix_compbcstr(str1,str2) # define stix_copyoochars(dst,src,len) stix_copybchars(dst,src,len) -# define stix_copybchtooochars(dst,src,len) stix_copybchars(dst,src,len) +# define stix_copybctooochars(dst,src,len) stix_copybchars(dst,src,len) # define stix_copyoocstr(dst,len,src) stix_copybcstr(dst,len,src) # define stix_findoochar(ptr,len,c) stix_findbchar(ptr,len,c) +# define stix_rfindoochar(ptr,len,c) stix_rfindbchar(ptr,len,c) # define stix_countoocstr(str) stix_countbcstr(str) #endif @@ -102,7 +104,7 @@ STIX_EXPORT int stix_compucbcstr ( const stix_bch_t* str2 ); -STIX_EXPORT int stix_compucxbcstr ( +STIX_EXPORT int stix_compucharsbcstr ( const stix_uch_t* str1, stix_oow_t len, const stix_bch_t* str2 @@ -120,7 +122,7 @@ STIX_EXPORT void stix_copybchars ( stix_oow_t len ); -STIX_EXPORT void stix_copybchtouchars ( +STIX_EXPORT void stix_copybctouchars ( stix_uch_t* dst, const stix_bch_t* src, stix_oow_t len @@ -150,6 +152,19 @@ STIX_EXPORT stix_bch_t* stix_findbchar ( stix_bch_t c ); +STIX_EXPORT stix_uch_t* stix_rfinduchar ( + const stix_uch_t* ptr, + stix_oow_t len, + stix_uch_t c +); + +STIX_EXPORT stix_bch_t* stix_rfindbchar ( + const stix_bch_t* ptr, + stix_oow_t len, + stix_bch_t c +); + + STIX_EXPORT stix_oow_t stix_countucstr ( const stix_uch_t* str ); @@ -158,6 +173,18 @@ STIX_EXPORT stix_oow_t stix_countbcstr ( const stix_bch_t* str ); +STIX_EXPORT int stix_copyoocstrtosbuf ( + stix_t* stix, + const stix_ooch_t* str, + int id +); + +STIX_EXPORT int stix_concatoocstrtosbuf ( + stix_t* stix, + const stix_ooch_t* str, + int id +); + STIX_EXPORT stix_cmgr_t* stix_getutf8cmgr ( void ); diff --git a/stix/lib/stix.c b/stix/lib/stix.c index ea65936..8af5dc3 100644 --- a/stix/lib/stix.c +++ b/stix/lib/stix.c @@ -137,6 +137,7 @@ static stix_rbt_walk_t unload_module (stix_rbt_t* rbt, stix_rbt_pair_t* pair, vo void stix_fini (stix_t* stix) { stix_cb_t* cb; + stix_oow_t i; if (stix->sem_list) { @@ -176,6 +177,17 @@ void stix_fini (stix_t* stix) /* deregister all callbacks */ while (stix->cblist) stix_deregcb (stix, stix->cblist); + for (i = 0; i < STIX_COUNTOF(stix->sbuf); i++) + { + if (stix->sbuf[i].ptr) + { + stix_freemem (stix, stix->sbuf[i].ptr); + stix->sbuf[i].ptr = STIX_NULL; + stix->sbuf[i].len = 0; + stix->sbuf[i].capa = 0; + } + } + if (stix->log.ptr) { /* make sure to flush your log message */ @@ -442,7 +454,7 @@ stix_mod_data_t* stix_openmod (stix_t* stix, const stix_ooch_t* name, stix_oow_t stix_ooch_t buf[MOD_PREFIX_LEN + STIX_MOD_NAME_LEN_MAX + 1 + 1]; /* the terminating null isn't needed in buf here */ - stix_copybchtooochars (buf, MOD_PREFIX, MOD_PREFIX_LEN); + stix_copybctooochars (buf, MOD_PREFIX, MOD_PREFIX_LEN); if (namelen > STIX_COUNTOF(buf) - (MOD_PREFIX_LEN + 1 + 1)) { @@ -643,14 +655,14 @@ stix_pfimpl_t stix_querymod (stix_t* stix, const stix_ooch_t* pfid, stix_oow_t p stix_oow_t mod_name_len; stix_pfimpl_t handler; - sep = stix_findoochar (pfid, pfidlen, '_'); + sep = stix_findoochar (pfid, pfidlen, '.'); if (!sep) { /* i'm writing a conservative code here. the compiler should * guarantee that an underscore is included in an primitive identifer. * what if the compiler is broken? imagine a buggy compiler rewritten * in stix itself? */ - STIX_DEBUG2 (stix, "Internal error - no underscore in a primitive function identifier [%.*S] - buggy compiler?\n", pfidlen, pfid); + STIX_DEBUG2 (stix, "Internal error - no period in a primitive function identifier [%.*S] - buggy compiler?\n", pfidlen, pfid); stix->errnum = STIX_EINTERN; return STIX_NULL; } @@ -694,9 +706,12 @@ int stix_genpfmethod (stix_t* stix, stix_mod_t* mod, stix_oop_t _class, stix_met stix_oow_t tmp_count = 0, i; stix_ooi_t arg_count = 0; stix_oocs_t cs; + static stix_ooch_t dot[] = { '.', '\0' }; STIX_ASSERT (STIX_CLASSOF(stix, _class) == stix->_class); + if (!pfname) pfname = mthname; + cls = (stix_oop_class_t)_class; stix_pushtmp (stix, (stix_oop_t*)&cls); tmp_count++; STIX_ASSERT (STIX_CLASSOF(stix, (stix_oop_t)cls->mthdic[type]) == stix->_method_dictionary); @@ -727,10 +742,22 @@ int stix_genpfmethod (stix_t* stix, stix_mod_t* mod, stix_oop_t _class, stix_met if (!mnsym) goto oops; stix_pushtmp (stix, (stix_oop_t*)&mnsym); tmp_count++; -/* TODO:... */ -/* pfid => mod->name + '_' + pfname */ - pfidsym = (stix_oop_char_t)stix_makesymbol (stix, pfname, stix_countoocstr(pfname)); - if (!pfidsym) goto oops; + /* compose a full primitive function identifier to VM's string buffer. + * pfid => mod->name + '.' + pfname */ + if (stix_copyoocstrtosbuf(stix, mod->name, 0) <= -1 || + stix_concatoocstrtosbuf(stix, dot, 0) <= -1 || + stix_concatoocstrtosbuf(stix, pfname, 0) <= -1) + { + STIX_DEBUG2 (stix, "Cannot generate primitive function method [%S] in [%O] - VM memory shortage\n", mthname, cls->name); + return -1; + } + + pfidsym = (stix_oop_char_t)stix_makesymbol (stix, stix->sbuf[0].ptr, stix->sbuf[0].len); + if (!pfidsym) + { + STIX_DEBUG2 (stix, "Cannot generate primitive function method [%S] in [%O] - symbol instantiation failure\n", mthname, cls->name); + goto oops; + } stix_pushtmp (stix, (stix_oop_t*)&pfidsym); tmp_count++; #if defined(STIX_USE_OBJECT_TRAILER) @@ -738,12 +765,16 @@ int stix_genpfmethod (stix_t* stix, stix_mod_t* mod, stix_oop_t _class, stix_met #else mth = (stix_oop_method_t)stix_instantiate (stix, stix->_method, STIX_NULL, 1); #endif - if (!mth) goto oops; + if (!mth) + { + STIX_DEBUG2 (stix, "Cannot generate primitive function method [%S] in [%O] - method instantiation failure\n", mthname, cls->name); + goto oops; + } /* store the primitive function name symbol to the literal frame */ mth->slot[0] = (stix_oop_t)pfidsym; - /* premable should contain the index to the literal frame - 0 */ + /* premable should contain the index to the literal frame which is always 0 */ mth->owner = cls; mth->name = mnsym; mth->preamble = STIX_SMOOI_TO_OOP(STIX_METHOD_MAKE_PREAMBLE(STIX_METHOD_PREAMBLE_NAMED_PRIMITIVE, 0)); @@ -751,12 +782,20 @@ int stix_genpfmethod (stix_t* stix, stix_mod_t* mod, stix_oop_t _class, stix_met mth->preamble_data[1] = STIX_SMOOI_TO_OOP(0); mth->tmpr_count = STIX_SMOOI_TO_OOP(arg_count); mth->tmpr_nargs = STIX_SMOOI_TO_OOP(arg_count); - stix_poptmps (stix, tmp_count); tmp_count = 0; + + /* TODO: emit BCODE_RETURN_NIL ? */ - if (!stix_putatdic (stix, cls->mthdic[type], (stix_oop_t)mnsym, (stix_oop_t)mth)) goto oops; + if (!stix_putatdic (stix, cls->mthdic[type], (stix_oop_t)mnsym, (stix_oop_t)mth)) + { + STIX_DEBUG2 (stix, "Cannot generate primitive function method [%S] in [%O] - failed to add to method dictionary\n", mthname, cls->name); + goto oops; + } + STIX_DEBUG2 (stix, "Generated primitive function method [%S] in [%O]\n", mthname, cls->name); + + stix_poptmps (stix, tmp_count); tmp_count = 0; return 0; oops: diff --git a/stix/lib/stix.h b/stix/lib/stix.h index 4570161..cbbb1f7 100644 --- a/stix/lib/stix.h +++ b/stix/lib/stix.h @@ -782,6 +782,14 @@ struct stix_mod_data_t }; typedef struct stix_mod_data_t stix_mod_data_t; +struct stix_sbuf_t +{ + stix_ooch_t* ptr; + stix_oow_t len; + stix_oow_t capa; +}; +typedef struct stix_sbuf_t stix_sbuf_t; + /* ========================================================================= * STIX VM * ========================================================================= */ @@ -912,6 +920,8 @@ struct stix_t } rsrc; /* == END RSRC MANAGEMENT == */ + stix_sbuf_t sbuf[64]; + #if defined(STIX_INCLUDE_COMPILER) stix_compiler_t* c; #endif diff --git a/stix/lib/sym.c b/stix/lib/sym.c index 1b47cfa..5d329f2 100644 --- a/stix/lib/sym.c +++ b/stix/lib/sym.c @@ -175,7 +175,6 @@ stix_oop_t stix_makesymbol (stix_t* stix, const stix_ooch_t* ptr, stix_oow_t len { return find_or_make_symbol (stix, ptr, len, 1); } - stix_oop_t stix_findsymbol (stix_t* stix, const stix_ooch_t* ptr, stix_oow_t len) { return find_or_make_symbol (stix, ptr, len, 0); diff --git a/stix/lib/utl.c b/stix/lib/utl.c index d60fd2a..df6cc60 100644 --- a/stix/lib/utl.c +++ b/stix/lib/utl.c @@ -28,6 +28,12 @@ #define STIX_BCLEN_MAX 6 +/* some naming conventions + * bchars, uchars -> pointer and length + * bcstr, ucstr -> null-terminated string pointer + * bctouchars -> bchars to uchars + */ + stix_oow_t stix_hashbytes (const stix_oob_t* ptr, stix_oow_t len) { stix_oow_t h = 0; @@ -101,7 +107,7 @@ int stix_compucbcstr (const stix_uch_t* str1, const stix_bch_t* str2) return (*str1 > *str2)? 1: -1; } -int stix_compucxbcstr (const stix_uch_t* str1, stix_oow_t len, const stix_bch_t* str2) +int stix_compucharsbcstr (const stix_uch_t* str1, stix_oow_t len, const stix_bch_t* str2) { const stix_uch_t* end = str1 + len; while (str1 < end && *str2 != '\0' && *str1 == *str2) str1++, str2++; @@ -122,7 +128,7 @@ void stix_copybchars (stix_bch_t* dst, const stix_bch_t* src, stix_oow_t len) for (i = 0; i < len; i++) dst[i] = src[i]; } -void stix_copybchtouchars (stix_uch_t* dst, const stix_bch_t* src, stix_oow_t len) +void stix_copybctouchars (stix_uch_t* dst, const stix_bch_t* src, stix_oow_t len) { stix_oow_t i; for (i = 0; i < len; i++) dst[i] = src[i]; @@ -202,6 +208,73 @@ stix_bch_t* stix_findbchar (const stix_bch_t* ptr, stix_oow_t len, stix_bch_t c) return STIX_NULL; } +stix_uch_t* stix_rfinduchar (const stix_uch_t* ptr, stix_oow_t len, stix_uch_t c) +{ + const stix_uch_t* cur; + + cur = ptr + len; + while (cur > ptr) + { + --cur; + if (*cur == c) return (stix_uch_t*)cur; + } + + return STIX_NULL; +} + +stix_bch_t* stix_rfindbchar (const stix_bch_t* ptr, stix_oow_t len, stix_bch_t c) +{ + const stix_bch_t* cur; + + cur = ptr + len; + while (cur > ptr) + { + --cur; + if (*cur == c) return (stix_bch_t*)cur; + } + + return STIX_NULL; +} + +/* ----------------------------------------------------------------------- */ + +int stix_concatoocstrtosbuf (stix_t* stix, const stix_ooch_t* str, int id) +{ + stix_sbuf_t* p; + stix_oow_t len; + + p = &stix->sbuf[id]; + len = stix_countoocstr (str); + + if (len > p->capa - p->len) + { + stix_oow_t newcapa; + stix_ooch_t* tmp; + + newcapa = STIX_ALIGN(p->len + len, 512); /* TODO: adjust this capacity */ + + /* +1 to handle line ending injection more easily */ + tmp = stix_reallocmem (stix, p->ptr, (newcapa + 1) * STIX_SIZEOF(*tmp)); + if (!tmp) return -1; + + p->ptr = tmp; + p->capa = newcapa; + } + + stix_copyoochars (&p->ptr[p->len], str, len); + p->len += len; + p->ptr[p->len] = '\0'; + + return 0; +} + +int stix_copyoocstrtosbuf (stix_t* stix, const stix_ooch_t* str, int id) +{ + stix->sbuf[id].len = 0;; + return stix_concatoocstrtosbuf (stix, str, id); +} + + /* ----------------------------------------------------------------------- */ diff --git a/stix/mod/stdio.c b/stix/mod/stdio.c index 56b6a1e..82d2105 100644 --- a/stix/mod/stdio.c +++ b/stix/mod/stdio.c @@ -116,29 +116,33 @@ static int pf_newinstsize (stix_t* stix, stix_ooi_t nargs) typedef struct fnctab_t fnctab_t; struct fnctab_t { - const stix_bch_t* name; + const stix_bch_t* mthname; + const stix_bch_t* pfname; stix_pfimpl_t handler; }; static fnctab_t fnctab[] = { - { "close", pf_close }, - { "newInstSize", pf_newinstsize }, - { "open", pf_open }, - { "puts", pf_puts } + { "_newInstSize", STIX_NULL, pf_newinstsize }, + { "close", STIX_NULL, pf_close }, + { "open:for:", STIX_NULL, pf_open }, + { "puts", STIX_NULL, pf_puts } }; static stix_ooch_t voca_open_for[] = { 'o','p','e','n',':','f','o','r',':','\0' }; static stix_ooch_t voca_open[] = { 'o','p','e','n','\0' }; static stix_ooch_t voca_close[] = { 'c','l','o','s','e','\0' }; +static stix_ooch_t voca_newInstSize[] = { '_','n','e','w','I','n','s','t','S','i','z','e','\0' }; + /* ------------------------------------------------------------------------ */ static int import (stix_t* stix, stix_mod_t* mod, stix_oop_t _class) { stix_pushtmp (stix, &_class); - stix_genpfmethod (stix, mod, _class, STIX_METHOD_INSTANCE, voca_open_for, voca_open); - stix_genpfmethod (stix, mod, _class, STIX_METHOD_CLASS, voca_close, voca_close); + stix_genpfmethod (stix, mod, _class, STIX_METHOD_CLASS, voca_newInstSize, STIX_NULL); + stix_genpfmethod (stix, mod, _class, STIX_METHOD_INSTANCE, voca_open_for, STIX_NULL); + stix_genpfmethod (stix, mod, _class, STIX_METHOD_INSTANCE, voca_close, voca_close); stix_poptmp (stix); return 0; } @@ -153,7 +157,7 @@ static stix_pfimpl_t query (stix_t* stix, stix_mod_t* mod, const stix_ooch_t* na { mid = (left + right) / 2; - n = stix_compoocbcstr (name, fnctab[mid].name); + n = stix_compoocbcstr (name, fnctab[mid].mthname); if (n < 0) right = mid - 1; else if (n > 0) left = mid + 1; else