From b4a513cf40b60bff3c09321484f58e1cfa690a2b Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Sat, 3 Dec 2016 18:08:31 +0000 Subject: [PATCH] added more code to stix_genpfmethod(). still incomplete --- stix/kernel/Stdio.st | 18 +++---- stix/lib/comp.c | 116 +++++++++++++++++++++++++++---------------- stix/lib/exec.c | 22 ++++---- stix/lib/main.c | 2 +- stix/lib/stix-prv.h | 30 +++++------ stix/lib/stix.c | 87 +++++++++++++++++++++----------- stix/lib/stix.h | 43 +++++++++++++--- stix/mod/console.c | 32 ------------ stix/mod/stdio.c | 20 +++----- 9 files changed, 210 insertions(+), 160 deletions(-) diff --git a/stix/kernel/Stdio.st b/stix/kernel/Stdio.st index 0efedd9..6feebdf 100644 --- a/stix/kernel/Stdio.st +++ b/stix/kernel/Stdio.st @@ -21,18 +21,18 @@ #method(#class) open: name for: mode { - ^(super new: 1) open: name for: mode + ^(self new) open: name for: mode } - #method open: name for: mode - { - - } +## #method open: name for: mode +## { +## +## } - #method close - { - - } +## #method close +## { +## +## } } #extend Stdio diff --git a/stix/lib/comp.c b/stix/lib/comp.c index fb72597..ee71c34 100644 --- a/stix/lib/comp.c +++ b/stix/lib/comp.c @@ -45,12 +45,6 @@ enum class_mod_t CLASS_INDEXED = (1 << 0) }; -enum mth_type_t -{ - MTH_INSTANCE, - MTH_CLASS -}; - enum var_type_t { /* NEVER Change the order and the value of 3 items below. @@ -1985,20 +1979,20 @@ static STIX_INLINE int add_class_level_variable (stix_t* stix, var_type_t index, static STIX_INLINE int add_pool_dictionary (stix_t* stix, const stix_oocs_t* name, stix_oop_set_t pooldic_oop) { - if (stix->c->cls.pooldic_count >= stix->c->cls.pooldic_oop_capa) + if (stix->c->cls.pooldic_count >= stix->c->cls.pooldic_imp_oops_capa) { stix_oow_t new_capa; stix_oop_set_t* tmp; - new_capa = STIX_ALIGN(stix->c->cls.pooldic_oop_capa + 1, POOLDIC_OOP_BUFFER_ALIGN); - tmp = stix_reallocmem (stix, stix->c->cls.pooldic_oops, new_capa * STIX_SIZEOF(stix_oop_set_t)); + new_capa = STIX_ALIGN(stix->c->cls.pooldic_imp_oops_capa + 1, POOLDIC_OOP_BUFFER_ALIGN); + tmp = stix_reallocmem (stix, stix->c->cls.pooldic_imp_oops, new_capa * STIX_SIZEOF(stix_oop_set_t)); if (!tmp) return -1; - stix->c->cls.pooldic_oop_capa = new_capa; - stix->c->cls.pooldic_oops = tmp; + stix->c->cls.pooldic_imp_oops_capa = new_capa; + stix->c->cls.pooldic_imp_oops = tmp; } - stix->c->cls.pooldic_oops[stix->c->cls.pooldic_count] = pooldic_oop; + stix->c->cls.pooldic_imp_oops[stix->c->cls.pooldic_count] = pooldic_oop; stix->c->cls.pooldic_count++; /* TODO: check if pooldic_count overflows */ @@ -2195,7 +2189,11 @@ static int add_method_name_fragment (stix_t* stix, const stix_oocs_t* name) static int method_exists (stix_t* stix, const stix_oocs_t* name) { /* check if the current class contains a method of the given name */ +#ifdef MTHDIC return stix_lookupdic (stix, stix->c->cls.mthdic_oop[stix->c->mth.type], name) != STIX_NULL; +#else + return stix_lookupdic (stix, stix->c->cls.self_oop->mthdic[stix->c->mth.type], name) != STIX_NULL; +#endif } static int add_temporary_variable (stix_t* stix, const stix_oocs_t* name) @@ -2365,7 +2363,7 @@ static int resolve_pooldic (stix_t* stix, int dotted, const stix_oocs_t* name) /* check if the same dictionary pool has been declared for import */ for (i = 0; i < stix->c->cls.pooldic_count; i++) { - if ((stix_oop_set_t)ass->value == stix->c->cls.pooldic_oops[i]) + if ((stix_oop_set_t)ass->value == stix->c->cls.pooldic_imp_oops[i]) { set_syntax_error (stix, STIX_SYNERR_POOLDICDUP, TOKEN_LOC(stix), name); return -1; @@ -2391,7 +2389,7 @@ static int import_pool_dictionary (stix_t* stix, stix_oop_set_t ns_oop, const st /* check if the same dictionary pool has been declared for import */ for (i = 0; i < stix->c->cls.pooldic_count; i++) { - if ((stix_oop_set_t)ass->value == stix->c->cls.pooldic_oops[i]) + if ((stix_oop_set_t)ass->value == stix->c->cls.pooldic_imp_oops[i]) { set_syntax_error (stix, STIX_SYNERR_POOLDICDUP, tok_loc, tok_name); return -1; @@ -2897,7 +2895,7 @@ static int get_variable_info (stix_t* stix, const stix_oocs_t* name, const stix_ switch (var->type) { case VAR_INSTANCE: - if (stix->c->mth.type == MTH_CLASS) + if (stix->c->mth.type == STIX_METHOD_CLASS) { /* a class method cannot access an instance variable */ set_syntax_error (stix, STIX_SYNERR_VARINACC, name_loc, name); @@ -2918,7 +2916,7 @@ static int get_variable_info (stix_t* stix, const stix_oocs_t* name, const stix_ case VAR_CLASSINST: /* class instance variable can be accessed by only class methods */ - if (stix->c->mth.type == MTH_INSTANCE) + if (stix->c->mth.type == STIX_METHOD_INSTANCE) { /* an instance method cannot access a class-instance variable */ set_syntax_error (stix, STIX_SYNERR_VARINACC, name_loc, name); @@ -2958,7 +2956,7 @@ static int get_variable_info (stix_t* stix, const stix_oocs_t* name, const stix_ /* attempt to find the variable in pool dictionaries */ for (i = 0; i < stix->c->cls.pooldic_count; i++) { - ass = stix_lookupdic (stix, stix->c->cls.pooldic_oops[i], name); + ass = stix_lookupdic (stix, stix->c->cls.pooldic_imp_oops[i], name); if (ass) { if (ass2) @@ -4344,7 +4342,7 @@ static int add_compiled_method (stix_t* stix) else if (stix->c->mth.pftype == 2) { preamble_code = STIX_METHOD_PREAMBLE_NAMED_PRIMITIVE; - preamble_index = stix->c->mth.pfnum; + preamble_index = stix->c->mth.pfnum; /* index to literal frame */ } else if (stix->c->mth.pftype == 3) { @@ -4385,7 +4383,11 @@ need to write code to collect string. stix_poptmps (stix, tmp_count); tmp_count = 0; +#ifdef MTHDIC if (!stix_putatdic(stix, stix->c->cls.mthdic_oop[stix->c->mth.type], (stix_oop_t)name, (stix_oop_t)mth)) goto oops; +#else + if (!stix_putatdic(stix, stix->c->cls.self_oop->mthdic[stix->c->mth.type], (stix_oop_t)name, (stix_oop_t)mth)) goto oops; +#endif return 0; @@ -4397,7 +4399,7 @@ oops: static int compile_method_definition (stix_t* stix) { /* clear data required to compile a method */ - stix->c->mth.type = MTH_INSTANCE; + stix->c->mth.type = STIX_METHOD_INSTANCE; stix->c->mth.text.len = 0; stix->c->mth.assignees.len = 0; stix->c->mth.binsels.len = 0; @@ -4423,7 +4425,7 @@ static int compile_method_definition (stix_t* stix) if (is_token_symbol(stix, VOCA_CLASS)) { /* #method(#class) */ - stix->c->mth.type = MTH_CLASS; + stix->c->mth.type = STIX_METHOD_CLASS; GET_TOKEN (stix); } @@ -4544,12 +4546,20 @@ static int make_defined_class (stix_t* stix) /* TOOD: good dictionary size */ tmp = (stix_oop_t)stix_makedic (stix, stix->_method_dictionary, INSTANCE_METHOD_DICTIONARY_SIZE); if (!tmp) return -1; - stix->c->cls.mthdic_oop[MTH_INSTANCE] = (stix_oop_set_t)tmp; +#ifdef MTHDIC + stix->c->cls.mthdic_oop[STIX_METHOD_INSTANCE] = (stix_oop_set_t)tmp; +#else + stix->c->cls.self_oop->mthdic[STIX_METHOD_INSTANCE] = (stix_oop_set_t)tmp; +#endif /* TOOD: good dictionary size */ tmp = (stix_oop_t)stix_makedic (stix, stix->_method_dictionary, CLASS_METHOD_DICTIONARY_SIZE); if (!tmp) return -1; - stix->c->cls.mthdic_oop[MTH_CLASS] = (stix_oop_set_t)tmp; +#ifdef MTHDIC + stix->c->cls.mthdic_oop[STIX_METHOD_CLASS] = (stix_oop_set_t)tmp; +#else + stix->c->cls.self_oop->mthdic[STIX_METHOD_CLASS] = (stix_oop_set_t)tmp; +#endif /* TODO: initialize more fields??? whatelse. */ @@ -4814,7 +4824,9 @@ static int __compile_class_definition (stix_t* stix, int extend) return -1; } - if (TOKEN_NAME_LEN(stix) < 1 || TOKEN_NAME_LEN(stix) > STIX_MOD_NAME_LEN_MAX) + if (TOKEN_NAME_LEN(stix) < 1 || + TOKEN_NAME_LEN(stix) > STIX_MOD_NAME_LEN_MAX || + stix_findoochar(TOKEN_NAME_PTR(stix), TOKEN_NAME_LEN(stix), '_')) { set_syntax_error (stix, STIX_SYNERR_MODNAME, TOKEN_LOC(stix), TOKEN_NAME(stix)); return -1; @@ -4860,16 +4872,18 @@ static int __compile_class_definition (stix_t* stix, int extend) return -1; } + +#ifdef MTHDIC /* use the method dictionary of an existing class object */ - stix->c->cls.mthdic_oop[MTH_INSTANCE] = stix->c->cls.self_oop->mthdic[STIX_CLASS_MTHDIC_INSTANCE]; - stix->c->cls.mthdic_oop[MTH_CLASS] = stix->c->cls.self_oop->mthdic[STIX_CLASS_MTHDIC_CLASS]; + stix->c->cls.mthdic_oop[STIX_METHOD_INSTANCE] = stix->c->cls.self_oop->mthdic[STIX_METHOD_INSTANCE]; + stix->c->cls.mthdic_oop[STIX_METHOD_CLASS] = stix->c->cls.self_oop->mthdic[STIX_METHOD_CLASS]; +#endif /* load the pooldic definition from the existing class object */ pds = stix->c->cls.self_oop->pooldics; if ((stix_oop_t)pds != stix->_nil) { stix_ooch_t* ptr, * end; - STIX_ASSERT (STIX_CLASSOF(stix, pds) == stix->_string); @@ -4947,12 +4961,15 @@ static int __compile_class_definition (stix_t* stix, int extend) return -1; } +#ifdef MTHDIC if (!extend) { + /* link the method dictionaries created to the actual class object */ /* TODO: anything else to set? */ - stix->c->cls.self_oop->mthdic[STIX_CLASS_MTHDIC_INSTANCE] = stix->c->cls.mthdic_oop[MTH_INSTANCE]; - stix->c->cls.self_oop->mthdic[STIX_CLASS_MTHDIC_CLASS] = stix->c->cls.mthdic_oop[MTH_CLASS]; + stix->c->cls.self_oop->mthdic[STIX_CLASS_MTHDIC_INSTANCE] = stix->c->cls.mthdic_oop[STIX_METHOD_INSTANCE]; + stix->c->cls.self_oop->mthdic[STIX_CLASS_MTHDIC_CLASS] = stix->c->cls.mthdic_oop[STIX_METHOD_CLASS]; } +#endif GET_TOKEN (stix); return 0; @@ -4984,8 +5001,10 @@ static int compile_class_definition (stix_t* stix, int extend) stix->c->cls.self_oop = STIX_NULL; stix->c->cls.super_oop = STIX_NULL; - stix->c->cls.mthdic_oop[MTH_INSTANCE] = STIX_NULL; - stix->c->cls.mthdic_oop[MTH_CLASS] = STIX_NULL; +#ifdef MTHDIC + stix->c->cls.mthdic_oop[STIX_METHOD_INSTANCE] = STIX_NULL; + stix->c->cls.mthdic_oop[STIX_METHOD_CLASS] = STIX_NULL; +#endif stix->c->cls.ns_oop = STIX_NULL; stix->c->cls.superns_oop = STIX_NULL; stix->c->mth.literal_count = 0; @@ -4998,8 +5017,10 @@ static int compile_class_definition (stix_t* stix, int extend) /* reset these oops plus literal pointers not to confuse gc_compiler() */ stix->c->cls.self_oop = STIX_NULL; stix->c->cls.super_oop = STIX_NULL; - stix->c->cls.mthdic_oop[MTH_INSTANCE] = STIX_NULL; - stix->c->cls.mthdic_oop[MTH_CLASS] = STIX_NULL; +#ifdef MTHDIC + stix->c->cls.mthdic_oop[STIX_METHOD_INSTANCE] = STIX_NULL; + stix->c->cls.mthdic_oop[STIX_METHOD_CLASS] = STIX_NULL; +#endif stix->c->cls.ns_oop = STIX_NULL; stix->c->cls.superns_oop = STIX_NULL; stix->c->mth.literal_count = 0; @@ -5152,19 +5173,21 @@ static int __compile_pooldic_definition (stix_t* stix) /*TODO: tally and arlit_count range check */ /*if (!STIX_IN_SMOOI_RANGE(tally)) ERROR??*/ - stix->c->cls.mthdic_oop[0] = stix_makedic (stix, stix->_pool_dictionary, STIX_ALIGN(tally + 10, POOL_DICTIONARY_SIZE_ALIGN)); - if (!stix->c->cls.mthdic_oop[0]) return -1; + /* i use mthdic_oop[0] when compling #pooldic. it's not a real method dictionary. + * i just use it not to declare another field into the compiler */ + stix->c->cls.pooldic_oop = stix_makedic (stix, stix->_pool_dictionary, STIX_ALIGN(tally + 10, POOL_DICTIONARY_SIZE_ALIGN)); + if (!stix->c->cls.pooldic_oop) return -1; for (i = 0; i < stix->c->mth.arlit_count; i += 2) { /* TODO: handle duplicate keys? */ - if (!stix_putatdic(stix, stix->c->cls.mthdic_oop[0], stix->c->mth.arlit[i], stix->c->mth.arlit[i + 1])) return -1; + if (!stix_putatdic(stix, stix->c->cls.pooldic_oop, stix->c->mth.arlit[i], stix->c->mth.arlit[i + 1])) return -1; } /* eveything seems ok. register the pool dictionary to the main * system dictionary or to the name space it belongs to */ lit = stix_makesymbol (stix, stix->c->cls.name.ptr, stix->c->cls.name.len); - if (!lit || !stix_putatdic (stix, stix->c->cls.ns_oop, lit, (stix_oop_t)stix->c->cls.mthdic_oop[0])) return -1; + if (!lit || !stix_putatdic (stix, stix->c->cls.ns_oop, lit, (stix_oop_t)stix->c->cls.pooldic_oop)) return -1; return 0; } @@ -5176,7 +5199,7 @@ static int compile_pooldic_definition (stix_t* stix) * i'll be reusing some fields reserved for compling a class */ stix->c->cls.name.len = 0; STIX_MEMSET (&stix->c->cls.fqn_loc, 0, STIX_SIZEOF(stix->c->cls.fqn_loc)); - stix->c->cls.mthdic_oop[0] = STIX_NULL; + stix->c->cls.pooldic_oop = STIX_NULL; stix->c->cls.ns_oop = STIX_NULL; stix->c->mth.balit_count = 0; stix->c->mth.arlit_count = 0; @@ -5184,7 +5207,7 @@ static int compile_pooldic_definition (stix_t* stix) n = __compile_pooldic_definition (stix); /* reset these oops plus literal pointers not to confuse gc_compiler() */ - stix->c->cls.mthdic_oop[0] = STIX_NULL; + stix->c->cls.pooldic_oop = STIX_NULL; stix->c->cls.ns_oop = STIX_NULL; stix->c->mth.balit_count = 0; stix->c->mth.arlit_count = 0; @@ -5258,11 +5281,16 @@ static void gc_compiler (stix_t* stix) if (stix->c->cls.super_oop) stix->c->cls.super_oop = stix_moveoop (stix, stix->c->cls.super_oop); - if (stix->c->cls.mthdic_oop[MTH_INSTANCE]) - stix->c->cls.mthdic_oop[MTH_INSTANCE] = (stix_oop_set_t)stix_moveoop (stix, (stix_oop_t)stix->c->cls.mthdic_oop[MTH_INSTANCE]); +#ifdef MTHDIC + if (stix->c->cls.mthdic_oop[STIX_METHOD_INSTANCE]) + stix->c->cls.mthdic_oop[STIX_METHOD_INSTANCE] = (stix_oop_set_t)stix_moveoop (stix, (stix_oop_t)stix->c->cls.mthdic_oop[STIX_METHOD_INSTANCE]); - if (stix->c->cls.mthdic_oop[MTH_CLASS]) - stix->c->cls.mthdic_oop[MTH_CLASS] = (stix_oop_set_t)stix_moveoop (stix, (stix_oop_t)stix->c->cls.mthdic_oop[MTH_CLASS]); + if (stix->c->cls.mthdic_oop[STIX_METHOD_CLASS]) + stix->c->cls.mthdic_oop[STIX_METHOD_CLASS] = (stix_oop_set_t)stix_moveoop (stix, (stix_oop_t)stix->c->cls.mthdic_oop[STIX_METHOD_CLASS]); +#endif + + if (stix->c->cls.pooldic_oop) + stix->c->cls.pooldic_oop = (stix_oop_set_t)stix_moveoop (stix, (stix_oop_t)stix->c->cls.pooldic_oop); if (stix->c->cls.ns_oop) stix->c->cls.ns_oop = (stix_oop_set_t)stix_moveoop (stix, (stix_oop_t)stix->c->cls.ns_oop); @@ -5272,7 +5300,7 @@ static void gc_compiler (stix_t* stix) for (i = 0; i < stix->c->cls.pooldic_count; i++) { - stix->c->cls.pooldic_oops[i] = (stix_oop_set_t)stix_moveoop (stix, (stix_oop_t)stix->c->cls.pooldic_oops[i]); + stix->c->cls.pooldic_imp_oops[i] = (stix_oop_set_t)stix_moveoop (stix, (stix_oop_t)stix->c->cls.pooldic_imp_oops[i]); } for (i = 0; i < stix->c->mth.literal_count; i++) @@ -5306,7 +5334,7 @@ static void fini_compiler (stix_t* stix) } if (stix->c->cls.pooldic.ptr) stix_freemem (stix, stix->c->cls.pooldic.ptr); - if (stix->c->cls.pooldic_oops) stix_freemem (stix, stix->c->cls.pooldic_oops); + if (stix->c->cls.pooldic_imp_oops) stix_freemem (stix, stix->c->cls.pooldic_imp_oops); if (stix->c->mth.text.ptr) stix_freemem (stix, stix->c->mth.text.ptr); if (stix->c->mth.assignees.ptr) stix_freemem (stix, stix->c->mth.assignees.ptr); diff --git a/stix/lib/exec.c b/stix/lib/exec.c index 07a2bd8..df54abf 100644 --- a/stix/lib/exec.c +++ b/stix/lib/exec.c @@ -992,13 +992,13 @@ static stix_oop_method_t find_method (stix_t* stix, stix_oop_t receiver, const s { /* receiver is a class object (an instance of Class) */ c = receiver; - dic_no = STIX_CLASS_MTHDIC_CLASS; + dic_no = STIX_METHOD_CLASS; } else { /* receiver is not a class object. so take its class */ c = (stix_oop_t)cls; - dic_no = STIX_CLASS_MTHDIC_INSTANCE; + dic_no = STIX_METHOD_INSTANCE; } STIX_ASSERT (c != stix->_nil); @@ -1039,7 +1039,7 @@ not_found: { /* the object is an instance of Class. find the method * in an instance method dictionary of Class also */ - mthdic = ((stix_oop_class_t)cls)->mthdic[STIX_CLASS_MTHDIC_INSTANCE]; + mthdic = ((stix_oop_class_t)cls)->mthdic[STIX_METHOD_INSTANCE]; STIX_ASSERT ((stix_oop_t)mthdic != stix->_nil); STIX_ASSERT (STIX_CLASSOF(stix, mthdic) == stix->_method_dictionary); @@ -2893,7 +2893,7 @@ static int start_method (stix_t* stix, stix_oop_method_t method, stix_oow_t narg STIX_ASSERT (STIX_OBJ_GET_FLAGS_EXTRA(name)); STIX_ASSERT (STIX_CLASSOF(stix,name) == stix->_symbol); - handler = stix_querymodforpfimpl (stix, ((stix_oop_char_t)name)->slot, STIX_OBJ_GET_SIZE(name)); + handler = stix_querymod (stix, ((stix_oop_char_t)name)->slot, STIX_OBJ_GET_SIZE(name)); } if (handler) @@ -2915,15 +2915,19 @@ static int start_method (stix_t* stix, stix_oop_method_t method, stix_oow_t narg return -1; /* hard primitive failure */ } if (n >= 1) break; /* primitive ok*/ - } - /* soft primitive failure or handler not found. - * if handler is not found, 0 must be printed in the debug message. */ - STIX_DEBUG1 (stix, "Soft failure indicated by primitive function %p\n", handler); + /* soft primitive failure */ + STIX_DEBUG1 (stix, "Soft failure indicated by primitive function %p\n", handler); + } + else + { + /* no handler found */ + STIX_DEBUG0 (stix, "Soft failure for non-existent primitive function\n"); + } #if defined(STIX_USE_OBJECT_TRAILER) STIX_ASSERT (STIX_OBJ_GET_FLAGS_TRAILER(method)); - if (method->slot[STIX_OBJ_GET_SIZE(method)] == 0) /* this trailer size field not a small integer */ + if (STIX_METHOD_GET_CODE_SIZE(method) == 0) /* this trailer size field not a small integer */ #else if (method->code == stix->_nil) #endif diff --git a/stix/lib/main.c b/stix/lib/main.c index bb7235a..71ebe74 100644 --- a/stix/lib/main.c +++ b/stix/lib/main.c @@ -411,7 +411,7 @@ static void log_write (stix_t* stix, stix_oow_t mask, const stix_ooch_t* msg, st struct tm tm, *tmp; time_t now; -/*if (mask & STIX_LOG_GC) return;*/ /* don't show gc logs */ +if (mask & STIX_LOG_GC) return; /* don't show gc logs */ /* TODO: beautify the log message. * do classification based on mask. */ diff --git a/stix/lib/stix-prv.h b/stix/lib/stix-prv.h index 08bc71f..38f98e4 100644 --- a/stix/lib/stix-prv.h +++ b/stix/lib/stix-prv.h @@ -45,7 +45,7 @@ #define STIX_USE_MAKE_BLOCK /* this is for gc debugging */ -/*#define STIX_DEBUG_GC*/ +#define STIX_DEBUG_GC #define STIX_DEBUG_COMPILER /*#define STIX_DEBUG_VM_PROCESSOR*/ /*#define STIX_DEBUG_VM_EXEC*/ @@ -479,8 +479,10 @@ struct stix_compiler_t stix_oop_class_t self_oop; stix_oop_t super_oop; /* this may be nil. so the type is stix_oop_t */ - stix_oop_set_t mthdic_oop[2]; - +#ifdef MTHDIC + stix_oop_set_t mthdic_oop[2]; /* used when compiling a method definition */ +#endif + stix_oop_set_t pooldic_oop; /* used when compiling a pooldic definition */ stix_oop_set_t ns_oop; stix_oocs_t fqn; stix_oocs_t name; @@ -503,18 +505,20 @@ struct stix_compiler_t * var_count[2] - number of class instance variables */ stix_oow_t var_count[3]; + /* buffer to hold pooldic import declaration */ stix_oocs_t pooldic; stix_oow_t pooldic_capa; stix_oow_t pooldic_count; - stix_oop_set_t* pooldic_oops; - stix_oow_t pooldic_oop_capa; + /* used to hold imported pool dictionarie objects */ + stix_oop_set_t* pooldic_imp_oops; + stix_oow_t pooldic_imp_oops_capa; } cls; - /* information about a function being comipled */ + /* information about a method being comipled */ struct { - int type; + stix_method_type_t type; /* method source text */ stix_oocs_t text; @@ -590,16 +594,8 @@ struct stix_oochbuf_t stix_oow_t capa; }; -struct stix_decoder_t -{ - stix_oochbuf_t fltout; - stix_bchbuf_t fltfmt; -}; - #endif - - #if defined(STIX_USE_OBJECT_TRAILER) /* let it point to the trailer of the method */ # define SET_ACTIVE_METHOD_CODE(stix) ((stix)->active_code = (stix_oob_t*)&(stix)->active_method->slot[STIX_OBJ_GET_SIZE((stix)->active_method) + 1 - STIX_METHOD_NAMED_INSTVARS]) @@ -1268,10 +1264,10 @@ int stix_importmod ( ); /* - * The stix_querymodforpfimpl() function finds a primitive function in modules + * The stix_querymod() function finds a primitive function in modules * with a full primitive identifier. */ -stix_pfimpl_t stix_querymodforpfimpl ( +stix_pfimpl_t stix_querymod ( stix_t* stix, const stix_ooch_t* pfid, stix_oow_t pfidlen diff --git a/stix/lib/stix.c b/stix/lib/stix.c index 13e564e..ea65936 100644 --- a/stix/lib/stix.c +++ b/stix/lib/stix.c @@ -505,7 +505,7 @@ stix_mod_data_t* stix_openmod (stix_t* stix, const stix_ooch_t* name, stix_oow_t /* attempt to find an external module */ STIX_MEMSET (&md, 0, STIX_SIZEOF(md)); - stix_copyoochars (md.name, name, namelen); + stix_copyoochars ((stix_ooch_t*)md.mod.name, name, namelen); if (stix->vmprim.dl_open && stix->vmprim.dl_getsym && stix->vmprim.dl_close) { md.handle = stix->vmprim.dl_open (stix, &buf[MOD_PREFIX_LEN]); @@ -551,7 +551,7 @@ stix_mod_data_t* stix_openmod (stix_t* stix, const stix_ooch_t* name, stix_oow_t mdp->pair = pair; - STIX_DEBUG2 (stix, "Opened a module [%S] - %p\n", mdp->name, mdp->handle); + STIX_DEBUG2 (stix, "Opened a module [%S] - %p\n", mdp->mod.name, mdp->handle); /* the module loader must ensure to set a proper query handler */ STIX_ASSERT (mdp->mod.query != STIX_NULL); @@ -566,14 +566,14 @@ void stix_closemod (stix_t* stix, stix_mod_data_t* mdp) if (mdp->handle) { stix->vmprim.dl_close (stix, mdp->handle); - STIX_DEBUG2 (stix, "Closed a module [%S] - %p\n", mdp->name, mdp->handle); + STIX_DEBUG2 (stix, "Closed a module [%S] - %p\n", mdp->mod.name, mdp->handle); mdp->handle = STIX_NULL; } if (mdp->pair) { /*mdp->pair = STIX_NULL;*/ /* this reset isn't needed as the area will get freed by stix_rbt_delete()) */ - stix_rbt_delete (&stix->modtab, mdp->name, stix_countoocstr(mdp->name)); + stix_rbt_delete (&stix->modtab, mdp->mod.name, stix_countoocstr(mdp->mod.name)); } } @@ -583,6 +583,11 @@ int stix_importmod (stix_t* stix, stix_oop_t _class, const stix_ooch_t* name, st stix_mod_data_t* mdp; int r = 0; + /* stix_openmod(), stix_closemod(), etc calls a user-defined callback. + * i need to protect _class in case the user-defined callback allocates + * a OOP memory chunk and GC occurs */ + stix_pushtmp (stix, &_class); + pair = stix_rbt_search (&stix->modtab, name, len); if (pair) { @@ -601,7 +606,7 @@ int stix_importmod (stix_t* stix, stix_oop_t _class, const stix_ooch_t* name, st if (!mdp->mod.import) { - STIX_DEBUG1 (stix, "Cannot import module [%S] - importing not supported by the module\n", mdp->name); + STIX_DEBUG1 (stix, "Cannot import module [%S] - importing not supported by the module\n", mdp->mod.name); stix->errnum = STIX_ENOIMPL; r = -1; goto done; @@ -609,7 +614,7 @@ int stix_importmod (stix_t* stix, stix_oop_t _class, const stix_ooch_t* name, st if (mdp->mod.import (stix, &mdp->mod, _class) <= -1) { - STIX_DEBUG1 (stix, "Cannot import module [%S] - module's import() returned failure\n", mdp->name); + STIX_DEBUG1 (stix, "Cannot import module [%S] - module's import() returned failure\n", mdp->mod.name); r = -1; goto done; } @@ -621,10 +626,11 @@ done: stix_closemod (stix, mdp); } + stix_poptmp (stix); return r; } -stix_pfimpl_t stix_querymodforpfimpl (stix_t* stix, const stix_ooch_t* pfid, stix_oow_t pfidlen) +stix_pfimpl_t stix_querymod (stix_t* stix, const stix_ooch_t* pfid, stix_oow_t pfidlen) { /* primitive function identifier * _funcname @@ -666,41 +672,66 @@ stix_pfimpl_t stix_querymodforpfimpl (stix_t* stix, const stix_ooch_t* pfid, sti if ((handler = mdp->mod.query (stix, &mdp->mod, sep + 1)) == STIX_NULL) { /* the primitive function is not found. keep the module open */ - STIX_DEBUG2 (stix, "Cannot find a primitive function [%S] in a module [%S]\n", sep + 1, mdp->name); + STIX_DEBUG2 (stix, "Cannot find a primitive function [%S] in a module [%S]\n", sep + 1, mdp->mod.name); stix->errnum = STIX_ENOENT; /* TODO: proper error code and handling */ return STIX_NULL; } - STIX_DEBUG3 (stix, "Found a primitive function [%S] in a module [%S] - %p\n", sep + 1, mdp->name, handler); + STIX_DEBUG3 (stix, "Found a primitive function [%S] in a module [%S] - %p\n", sep + 1, mdp->mod.name, handler); return handler; } /* -------------------------------------------------------------------------- */ /* add a new primitive method */ -int stix_addmethod (stix_t* stix, stix_oop_t _class, const stix_ooch_t* name, stix_pfimpl_t func) +int stix_genpfmethod (stix_t* stix, stix_mod_t* mod, stix_oop_t _class, stix_method_type_t type, const stix_ooch_t* mthname, const stix_ooch_t* pfname) { /* NOTE: this function is a subset of add_compiled_method() in comp.c */ - stix_oop_char_t nsym; + stix_oop_char_t mnsym, pfidsym; stix_oop_method_t mth; stix_oop_class_t cls; stix_oow_t tmp_count = 0, i; stix_ooi_t arg_count = 0; + stix_oocs_t cs; STIX_ASSERT (STIX_CLASSOF(stix, _class) == stix->_class); 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); - /* TODO: check if name is a valid method name */ - for (i = 0; name[i]; i++) + for (i = 0; mthname[i]; i++) { - if (name[i] == ':') arg_count++; + if (mthname[i] == ':') arg_count++; + } +/* TODO: check if name is a valid method name - more checks... */ +/* TOOD: if the method name is a binary selector, it can still have an argument.. so the check below is invalid... */ + if (arg_count > 0 && mthname[i - 1] != ':') + { + STIX_DEBUG2 (stix, "Cannot generate primitive function method [%S] in [%O] - invalid name\n", mthname, cls->name); + stix->errnum = STIX_EINVAL; + goto oops; } - nsym = (stix_oop_char_t)stix_makesymbol (stix, name, i); - if (!nsym) return -1; - stix_pushtmp (stix, (stix_oop_t*)&name); tmp_count++; + cs.ptr = (stix_ooch_t*)mthname; + cs.len = i; + if (stix_lookupdic (stix, cls->mthdic[type], &cs) != STIX_NULL) + { + STIX_DEBUG2 (stix, "Cannot generate primitive function method [%S] in [%O] - duplicate\n", mthname, cls->name); + stix->errnum = STIX_EEXIST; + goto oops; + } + + mnsym = (stix_oop_char_t)stix_makesymbol (stix, mthname, i); + 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; + stix_pushtmp (stix, (stix_oop_t*)&pfidsym); tmp_count++; #if defined(STIX_USE_OBJECT_TRAILER) mth = (stix_oop_method_t)stix_instantiatewithtrailer (stix, stix->_method, 1, STIX_NULL, 0); @@ -709,23 +740,23 @@ int stix_addmethod (stix_t* stix, stix_oop_t _class, const stix_ooch_t* name, st #endif if (!mth) goto oops; - /* store the symbol name to the literal frame */ - mth->slot[0] = (stix_oop_t)nsym; + /* store the primitive function name symbol to the literal frame */ + mth->slot[0] = (stix_oop_t)pfidsym; - /* add the primitive as a name primitive with index of -1. - * set the preamble_data to the pointer to the primitive function. */ + /* premable should contain the index to the literal frame - 0 */ mth->owner = cls; - mth->name = nsym; - mth->preamble = STIX_SMOOI_TO_OOP(STIX_METHOD_MAKE_PREAMBLE(STIX_METHOD_PREAMBLE_NAMED_PRIMITIVE, -1)); - mth->preamble_data[0] = STIX_SMOOI_TO_OOP((stix_oow_t)func >> (STIX_OOW_BITS / 2)); - mth->preamble_data[1] = STIX_SMOOI_TO_OOP((stix_oow_t)func & STIX_LBMASK(stix_oow_t, STIX_OOW_BITS / 2)); + mth->name = mnsym; + mth->preamble = STIX_SMOOI_TO_OOP(STIX_METHOD_MAKE_PREAMBLE(STIX_METHOD_PREAMBLE_NAMED_PRIMITIVE, 0)); + mth->preamble_data[0] = STIX_SMOOI_TO_OOP(0); + 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: class method? */ - /* instance method */ - if (!stix_putatdic (stix, cls->mthdic[STIX_CLASS_MTHDIC_INSTANCE], (stix_oop_t)nsym, (stix_oop_t)mth)) goto oops; +/* TODO: emit BCODE_RETURN_NIL ? */ + + if (!stix_putatdic (stix, cls->mthdic[type], (stix_oop_t)mnsym, (stix_oop_t)mth)) goto oops; + return 0; oops: diff --git a/stix/lib/stix.h b/stix/lib/stix.h index 4f16be8..4570161 100644 --- a/stix/lib/stix.h +++ b/stix/lib/stix.h @@ -52,6 +52,7 @@ enum stix_errnum_t STIX_ESYSMEM, /**< insufficient system memory */ STIX_EOOMEM, /**< insufficient object memory */ STIX_EINVAL, /**< invalid parameter or data */ + STIX_EEXIST, /**< existing/duplicate data */ STIX_ETOOBIG, /**< data too large */ STIX_EMSGSND, /**< message sending error. even doesNotUnderstand: is not found */ STIX_ERANGE, /**< range error. overflow and underflow */ @@ -159,6 +160,17 @@ typedef struct stix_obj_word_t* stix_oop_word_t; #endif + +enum stix_method_type_t +{ + STIX_METHOD_INSTANCE, + STIX_METHOD_CLASS, + + /* --------------------------- */ + STIX_METHOD_TYPE_COUNT +}; +typedef enum stix_method_type_t stix_method_type_t; + /* * OOP encoding * An object pointer(OOP) is an ordinary pointer value to an object. @@ -424,13 +436,11 @@ struct stix_class_t /* [0] - instance methods, MethodDictionary * [1] - class methods, MethodDictionary */ - stix_oop_set_t mthdic[2]; + stix_oop_set_t mthdic[STIX_METHOD_TYPE_COUNT]; /* indexed part afterwards */ stix_oop_t slot[1]; /* class instance variables and class variables. */ }; -#define STIX_CLASS_MTHDIC_INSTANCE 0 -#define STIX_CLASS_MTHDIC_CLASS 1 #define STIX_ASSOCIATION_NAMED_INSTVARS 2 typedef struct stix_association_t stix_association_t; @@ -757,6 +767,7 @@ typedef void (*stix_mod_unload_t) ( struct stix_mod_t { + const stix_ooch_t name[STIX_MOD_NAME_LEN_MAX + 1]; stix_mod_import_t import; stix_mod_query_t query; stix_mod_unload_t unload; @@ -765,7 +776,6 @@ struct stix_mod_t struct stix_mod_data_t { - stix_ooch_t name[STIX_MOD_NAME_LEN_MAX + 1]; void* handle; stix_rbt_pair_t* pair; /* internal backreference to stix->modtab */ stix_mod_t mod; @@ -1081,10 +1091,6 @@ STIX_EXPORT void stix_gc ( stix_t* stix ); -STIX_EXPORT stix_oow_t stix_getpayloadbytes ( - stix_t* stix, - stix_oop_t oop -); /** * The stix_instantiate() function creates a new object of the class @@ -1176,6 +1182,22 @@ STIX_EXPORT void stix_freemem ( ); +/* ========================================================================= + * PRIMITIVE METHOD MANIPULATION + * ========================================================================= */ +STIX_EXPORT int stix_genpfmethod ( + stix_t* stix, + stix_mod_t* mod, + stix_oop_t _class, + stix_method_type_t type, + const stix_ooch_t* mthname, + const stix_ooch_t* name +); + +/* ========================================================================= + * STRING ENCODING CONVERSION + * ========================================================================= */ + #if defined(STIX_OOCH_IS_UCH) # define stix_oocstobcs(stix,oocs,oocslen,bcs,bcslen) stix_ucstobcs(stix,oocs,oocslen,bcs,bcslen) # define stix_bcstooocs(stix,bcs,bcslen,oocs,oocslen) stix_bcstoucs(stix,bcs,bcslen,oocs,oocslen) @@ -1201,6 +1223,11 @@ STIX_EXPORT int stix_ucstobcs ( stix_oow_t* bcslen ); + +/* ========================================================================= + * STIX VM LOGGING + * ========================================================================= */ + STIX_EXPORT stix_ooi_t stix_logbfmt ( stix_t* stix, stix_oow_t mask, diff --git a/stix/mod/console.c b/stix/mod/console.c index 6ae371f..137a0ea 100644 --- a/stix/mod/console.c +++ b/stix/mod/console.c @@ -302,37 +302,5 @@ int stix_mod_console (stix_t* stix, stix_mod_t* mod) mod->query = query; mod->unload = unload; mod->ctx = STIX_NULL; - -#if 0 - -#include 'Stix.st'. -#import 'Console'. - - c = stix_findclass (stix, "Console"); - if (!c) c = stix_makeclass (stix, "Console", "x y"); <- provides an API to create a simple class - - stix_addmethod (stix, c, "open", pf_open); - stix_addmethod (stix, c, "close:", pf_close); - stix_addmethod (stix, c, "setCursorTo:", pf_setcursor); - stix_addmethod (stix, c, "clear", pf_clear ); - stix_addmethod (stix, c, "write", pf_write ); - - - - -/* GRAMMER ENHANCEMENT */ -fun abc (a, b, c) <----- this style, register C style method -{ -} - -fun abc: a with: b c: c <----- smalltalk style -{ -} - -abc->def (a, b, c) <------- use -> as an c style method indicator -abc abc: a with: b c: c - -#endif - return 0; } diff --git a/stix/mod/stdio.c b/stix/mod/stdio.c index 807400a..56b6a1e 100644 --- a/stix/mod/stdio.c +++ b/stix/mod/stdio.c @@ -128,10 +128,18 @@ static fnctab_t fnctab[] = { "puts", 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 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_poptmp (stix); return 0; } @@ -186,18 +194,6 @@ int stix_mod_stdio (stix_t* stix, stix_mod_t* mod) #include 'Stix.st'. #import 'Console'. - c = stix_findclass (stix, "Console"); - if (!c) c = stix_makeclass (stix, "Console", "x y"); <- provides an API to create a simple class - - stix_addmethod (stix, c, "open", pf_open); - stix_addmethod (stix, c, "close:", pf_close); - stix_addmethod (stix, c, "setCursorTo:", pf_setcursor); - stix_addmethod (stix, c, "clear", pf_clear ); - stix_addmethod (stix, c, "write", pf_write ); - - - - /* GRAMMER ENHANCEMENT */ fun abc (a, b, c) <----- this style, register C style method {