diff --git a/stix/lib/comp.c b/stix/lib/comp.c index bde642e..7804b56 100644 --- a/stix/lib/comp.c +++ b/stix/lib/comp.c @@ -52,11 +52,8 @@ typedef enum stix_stack_operand_t stix_stack_operand_t; enum class_mod_t { - CLASS_BYTE_INDEXED = (1 << 0), - CLASS_CHARACTER_INDEXED = (1 << 1), - CLASS_WORD_INDEXED = (1 << 2), - CLASS_POINTER_INDEXED = (1 << 3), - CLASS_EXTEND = (1 << 4) + CLASS_INDEXED = (1 << 0), + CLASS_EXTEND = (1 << 1) }; enum dcl_mod_t @@ -290,7 +287,6 @@ static int copy_string_to (stix_t* stix, const stix_ucs_t* src, stix_ucs_t* dst, return 0; } - static stix_ssize_t find_word_in_string (const stix_ucs_t* haystack, const stix_ucs_t* name) { /* this function is inefficient. but considering the typical number @@ -1307,7 +1303,7 @@ static int __add_symbol_literal ( static int finish_method (stix_t* fsc) { stix_vm_t* stx = fsc->stx; - stix_class_t* class_obj; + stix_oop_class_t class_obj; stix_method_t* method_obj; stix_word_t method, selector; @@ -1816,9 +1812,19 @@ static STIX_INLINE int set_superclass_name (stix_t* stix, const stix_ucs_t* name return copy_string_to (stix, name, &stix->c->_class.supername, &stix->c->_class.supername_capa, 0, '\0'); } -static int append_class_level_variable (stix_t* stix, int index, const stix_ucs_t* name) +static STIX_INLINE int append_class_level_variable (stix_t* stix, int index, const stix_ucs_t* name) { - return copy_string_to (stix, name, &stix->c->_class.vars[index], &stix->c->_class.vars_capa[index], 1, ' '); + int n; + + n = copy_string_to (stix, name, &stix->c->_class.vars[index], &stix->c->_class.vars_capa[index], 1, ' '); + + if (n >= 0) + { + stix->c->_class.var_count[index]++; + /* TODO: check if it exceeds STIX_MAX_NAMED_INSTVARS, STIX_MAX_CLASSVARS, STIX_MAX_CLASSINSTVARS */ + } + + return n; } static stix_ssize_t find_class_level_variable (stix_t* stix, int index, const stix_ucs_t* name) @@ -1843,13 +1849,13 @@ static stix_ssize_t find_class_level_variable (stix_t* stix, int index, const st { STIX_ASSERT (STIX_CLASSOF(stix, super) == stix->_class); - v = ((stix_class_t*)super)->instvars; -/* TODO: v = ((stix_class_t*)super)->classvars; */ + v = ((stix_oop_class_t)super)->instvars; +/* TODO: v = ((stix_oop_class_t)super)->classvars; */ hs.ptr = v->slot; hs.len = STIX_OBJ_GET_SIZE(v); pos = find_word_in_string(&hs, name); - super = ((stix_class_t*)super)->superclass; + super = ((stix_oop_class_t)super)->superclass; if (pos >= 0) goto done; } @@ -1861,7 +1867,7 @@ done: stix_oow_t spec; STIX_ASSERT (STIX_CLASSOF(stix, super) == stix->_class); - spec = STIX_OOP_TO_SMINT(((stix_class_t*)super)->spec); + spec = STIX_OOP_TO_SMINT(((stix_oop_class_t)super)->spec); pos += STIX_CLASS_SPEC_NAMED_INSTVAR(spec); } @@ -1917,6 +1923,7 @@ static int compile_class_level_variables (stix_t* stix) { /* #dcl(#instance) */ dcl_mod &= ~(DCL_CLASS | DCL_CLASSINST); + dcl_index = 0; } else { @@ -2222,7 +2229,7 @@ static int compile_class_function_expression (stix_t* stix) } } - stix_free (ident); + stix_freemem (ident); } else { @@ -2328,7 +2335,87 @@ static int compile_class_function (stix_t* stix) return 0; } -static int _compile_class_definition (stix_t* stix) +static int make_defined_class (stix_t* stix) +{ + /* this function make a class object with no functions/methods */ + + stix_oop_t tmp; + stix_oow_t spec, self_spec; + int just_made = 0; + + + spec = STIX_CLASS_SPEC_MAKE (stix->c->_class.var_count[0], + ((stix->c->_class.flags & CLASS_INDEXED)? 1: 0), + stix->c->_class.indexed_type); + self_spec = STIX_CLASS_SELFSPEC_MAKE(stix->c->_class.var_count[1], stix->c->_class.var_count[2]); + +print_ucs (&stix->c->_class.name); +printf (" instvars %d classvars %d classinstvars %d\n", (int)stix->c->_class.var_count[0], (int)stix->c->_class.var_count[1], (int)stix->c->_class.var_count[2]); + + if (stix->c->_class.self_oop) + { + STIX_ASSERT (STIX_CLASSOF(stix, stix->c->_class.self_oop) == stix->_class); + STIX_ASSERT (STIX_OBJ_GET_FLAGS_KERNEL (stix->c->_class.self_oop) == 1); + + if (spec != STIX_OOP_TO_SMINT(stix->c->_class.self_oop->spec) || + self_spec != STIX_OOP_TO_SMINT(stix->c->_class.self_oop->selfspec)) + { + /* it conflicts with internal defintion */ +printf (" DDDDDDDDDD CONFLICTING CLASS DEFINITION DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD %lu %lu %lu %lu\n", + (unsigned long)spec, (unsigned long)self_spec, + (unsigned long)STIX_OOP_TO_SMINT(stix->c->_class.self_oop->spec), (unsigned long)STIX_OOP_TO_SMINT(stix->c->_class.self_oop->selfspec) +); +/* TODO: set syntax error */ + return -1; + } + } + else + { + /* the class variables and class instance variables are placed + * inside the class object after the fixed part. */ + tmp = stix_instantiate (stix, stix->_class, STIX_NULL, + stix->c->_class.var_count[1] + stix->c->_class.var_count[2]); + if (!tmp) return -1; + + just_made = 1; + stix->c->_class.self_oop = (stix_oop_class_t)tmp; + + STIX_ASSERT (STIX_CLASSOF(stix, stix->c->_class.self_oop) == stix->_class); + + stix->c->_class.self_oop->spec = STIX_OOP_FROM_SMINT(spec); + stix->c->_class.self_oop->selfspec = STIX_OOP_FROM_SMINT(self_spec); + } + + STIX_OBJ_SET_FLAGS_KERNEL (stix->c->_class.self_oop, 2); + + tmp = stix_makesymbol(stix, stix->c->_class.name.ptr, stix->c->_class.name.len); + if (!tmp) return -1; + stix->c->_class.self_oop->name = (stix_oop_char_t)tmp; + + tmp = stix_makestring(stix, stix->c->_class.vars[0].ptr, stix->c->_class.vars[0].len); + if (!tmp) return -1; + stix->c->_class.self_oop->instvars = (stix_oop_char_t)tmp; + + tmp = stix_makestring(stix, stix->c->_class.vars[1].ptr, stix->c->_class.vars[1].len); + if (!tmp) return -1; + stix->c->_class.self_oop->classvars = (stix_oop_char_t)tmp; + + tmp = stix_makestring(stix, stix->c->_class.vars[2].ptr, stix->c->_class.vars[2].len); + if (!tmp) return -1; + stix->c->_class.self_oop->classinstvars = (stix_oop_char_t)tmp; + +/* TODO: initialize more fields??? method_dictionary. function dictionary */ + + if (just_made) + { + /* register the class to the system dictionary */ + if (!stix_putatsysdic(stix, (stix_oop_t)stix->c->_class.self_oop->name, (stix_oop_t)stix->c->_class.self_oop)) return -1; + } + + return 0; +} + +static int __compile_class_definition (stix_t* stix) { /* * class-definition := #class class-modifier? "{" class-body "}" @@ -2344,6 +2431,7 @@ static int _compile_class_definition (stix_t* stix) * function-actual-definition := function-name "{" function-tempraries? function-primitive? function-statements* "}" */ stix_ioloc_t class_name_loc; + stix_oop_association_t ass; if (stix->c->tok.type == STIX_IOTOK_LPAREN) { @@ -2351,37 +2439,48 @@ static int _compile_class_definition (stix_t* stix) do { + int this_flag = 0; + GET_TOKEN (stix); +/* TODO: should i check if #byte, #character, #word, #pointer have already been specified? */ if (is_token_ksym(stix, KSYM_BYTE)) { /* #class(#byte) */ - stix->c->_class.flags &= ~(CLASS_BYTE_INDEXED | CLASS_CHARACTER_INDEXED | CLASS_WORD_INDEXED | CLASS_POINTER_INDEXED); - stix->c->_class.flags |= CLASS_BYTE_INDEXED; + this_flag = CLASS_INDEXED; + stix->c->_class.indexed_type = STIX_OBJ_TYPE_BYTE; } else if (is_token_ksym(stix, KSYM_CHARACTER)) { /* #class(#character) */ - stix->c->_class.flags &= ~(CLASS_BYTE_INDEXED | CLASS_CHARACTER_INDEXED | CLASS_WORD_INDEXED | CLASS_POINTER_INDEXED); - stix->c->_class.flags |= CLASS_CHARACTER_INDEXED; + this_flag = CLASS_INDEXED; + stix->c->_class.indexed_type = STIX_OBJ_TYPE_CHAR; } else if (is_token_ksym(stix, KSYM_WORD)) { /* #class(#word) */ - stix->c->_class.flags &= ~(CLASS_BYTE_INDEXED | CLASS_CHARACTER_INDEXED | CLASS_WORD_INDEXED | CLASS_POINTER_INDEXED); - stix->c->_class.flags |= CLASS_WORD_INDEXED; + this_flag = CLASS_INDEXED; + stix->c->_class.indexed_type = STIX_OBJ_TYPE_WORD; } else if (is_token_ksym(stix, KSYM_POINTER)) { /* #class(#pointer) */ - stix->c->_class.flags &= ~(CLASS_BYTE_INDEXED | CLASS_CHARACTER_INDEXED | CLASS_WORD_INDEXED | CLASS_POINTER_INDEXED); - stix->c->_class.flags |= CLASS_POINTER_INDEXED; + this_flag = CLASS_INDEXED; + stix->c->_class.indexed_type = STIX_OBJ_TYPE_OOP; } /* place other modifiers here */ else { break; } + + STIX_ASSERT (this_flag != 0); + if (stix->c->_class.flags & this_flag) + { + set_syntax_error (stix, STIX_SYNERR_CLASSMODDUP, &stix->c->tok.loc, &stix->c->tok.name); + return -1; + } + stix->c->_class.flags |= this_flag; } while (1); @@ -2450,18 +2549,29 @@ printf ("\n"); GET_TOKEN (stix); - stix->c->_class.self_oop = stix_lookupsysdic(stix, &stix->c->_class.name); - if (stix->c->_class.self_oop) +printf ("FINDING......................["); print_ucs (&stix->c->_class.name); printf ("]\n"); +dump_system_dictionary(stix); + ass = (stix_oop_association_t)stix_lookupsysdic(stix, &stix->c->_class.name); +printf ("FINDING dONE.........................\n"); + if (ass) { - if (!STIX_CLASSOF(stix, stix->c->_class.self_oop) || - STIX_OBJ_GET_FLAGS_KERNEL(stix->c->_class.self_oop) > 1) + if (STIX_CLASSOF(stix, ass->value) != stix->_class || + STIX_OBJ_GET_FLAGS_KERNEL(ass->value) > 1) { /* the object found with the name is not a class object - * or the the class object found is a full defined kernel + * or the the class object found is a fully defined kernel * class object */ set_syntax_error (stix, STIX_SYNERR_CLASSDUP, &class_name_loc, &stix->c->_class.name); return -1; } + + stix->c->_class.self_oop = (stix_oop_class_t)ass->value; + } + else + { + /* no class of such a name is found. it's a new definition, + * which is normal for most new classes. */ + STIX_ASSERT (stix->c->_class.self_oop == STIX_NULL); } if (super_is_nil) @@ -2470,10 +2580,16 @@ printf ("\n"); } else { - stix->c->_class.super_oop = stix_lookupsysdic(stix, &stix->c->_class.supername); - if (!stix->c->_class.super_oop || - STIX_CLASSOF(stix, stix->c->_class.super_oop) != stix->_class || - STIX_OBJ_GET_FLAGS_KERNEL(stix->c->_class.super_oop) == 1) + ass = (stix_oop_association_t)stix_lookupsysdic(stix, &stix->c->_class.supername); + if (ass && + STIX_CLASSOF(stix, ass->value) == stix->_class && + STIX_OBJ_GET_FLAGS_KERNEL(ass->value) != 1) + { + /* the value found must be a class and it must not be + * an incomplete internal class object */ + stix->c->_class.super_oop = ass->value; + } + else { /* there is no object with such a name. or, * the object found with the name is not a class object. or, @@ -2499,17 +2615,24 @@ printf ("\n"); stix->c->_class.flags |= CLASS_EXTEND; - stix->c->_class.self_oop = stix_lookupsysdic(stix, &stix->c->_class.name); - if (!stix->c->_class.self_oop || - STIX_CLASSOF(stix, stix->c->_class.self_oop) != stix->_class || - STIX_OBJ_GET_FLAGS_KERNEL(stix->c->_class.self_oop) == 1) + ass = (stix_oop_association_t)stix_lookupsysdic(stix, &stix->c->_class.name); + if (ass && + STIX_CLASSOF(stix, ass->value) != stix->_class && + STIX_OBJ_GET_FLAGS_KERNEL(ass->value) != 1) + { + stix->c->_class.self_oop = (stix_oop_class_t)ass->value; + } + else { /* only an existing class can be extended. */ set_syntax_error (stix, STIX_SYNERR_CLASSUNDEF, &class_name_loc, &stix->c->_class.name); return -1; } - stix->c->_class.super_oop = ((stix_class_t*)stix->c->_class.self_oop)->superclass; + stix->c->_class.super_oop = stix->c->_class.self_oop->superclass; + + STIX_ASSERT ((stix_oop_t)stix->c->_class.super_oop == stix->_nil || + STIX_CLASSOF(stix, stix->c->_class.super_oop) == stix->_class); } if (stix->c->tok.type != STIX_IOTOK_LBRACE) @@ -2518,35 +2641,64 @@ printf ("\n"); return -1; } + if (stix->c->_class.super_oop != stix->_nil) + { + /* adjust the instance variable count and the class instance variable + * count to include that of a superclass */ + stix_oop_class_t c; + stix_oow_t spec, self_spec; + + c = (stix_oop_class_t)stix->c->_class.super_oop; + spec = STIX_OOP_TO_SMINT(c->spec); + self_spec = STIX_OOP_TO_SMINT(c->selfspec); + stix->c->_class.var_count[0] = STIX_CLASS_SPEC_NAMED_INSTVAR(spec); + stix->c->_class.var_count[2] = STIX_CLASS_SELFSPEC_CLASSINSTVAR(self_spec); + } + GET_TOKEN (stix); - while (1) + while (is_token_ksym(stix, KSYM_DCL) || is_token_ksym(stix, KSYM_DECLARE)) + { + if (stix->c->_class.flags & CLASS_EXTEND) + { + /* you cannot specify variables when extending a class */ + set_syntax_error (stix, STIX_SYNERR_DCLBANNED, &stix->c->tok.loc, STIX_NULL); + return -1; + } + + /* variable definition. #dcl or #declare */ + GET_TOKEN (stix); + if (compile_class_level_variables(stix) <= -1) return -1; + } + + if (stix->c->_class.flags & CLASS_EXTEND) { if (is_token_ksym(stix, KSYM_DCL) || is_token_ksym(stix, KSYM_DECLARE)) { - if (stix->c->_class.flags & CLASS_EXTEND) - { - /* you cannot specify variables when extending a class */ - set_syntax_error (stix, STIX_SYNERR_DCLBANNED, &stix->c->tok.loc, STIX_NULL); - return -1; - } - + set_syntax_error (stix, STIX_SYNERR_DCLBANNED, &stix->c->tok.loc, &stix->c->tok.name); + return -1; + } + } + else + { + /* a new class including an internally defined class object */ + while (is_token_ksym(stix, KSYM_DCL) || is_token_ksym(stix, KSYM_DECLARE)) + { /* variable definition. #dcl or #declare */ GET_TOKEN (stix); if (compile_class_level_variables(stix) <= -1) return -1; } - else if (is_token_ksym(stix, KSYM_FUN) || is_token_ksym(stix, KSYM_FUNCTION)) - { - /* function definition. #fun or #function */ - GET_TOKEN (stix); - if (compile_class_function(stix) <= -1) return -1; - } - else - { - break; - } + + if (make_defined_class(stix) <= -1) return -1; } + while (is_token_ksym(stix, KSYM_FUN) || is_token_ksym(stix, KSYM_FUNCTION)) + { + /* function definition. #fun or #function */ + GET_TOKEN (stix); + if (compile_class_function(stix) <= -1) return -1; + } + if (stix->c->tok.type != STIX_IOTOK_RBRACE) { set_syntax_error (stix, STIX_SYNERR_RBRACE, &stix->c->tok.loc, &stix->c->tok.name); @@ -2567,13 +2719,13 @@ static int compile_class_definition (stix_t* stix) stix->c->_class.name.len = 0; stix->c->_class.supername.len = 0; for (i = 0; i < STIX_COUNTOF(stix->c->_class.var_count); i++) - stix->c->_class.var_count[0] = 0; + stix->c->_class.var_count[i] = 0; stix->c->_class.self_oop = STIX_NULL; stix->c->_class.super_oop = STIX_NULL; /* do main compilation work */ - n = _compile_class_definition (stix); + n = __compile_class_definition (stix); /* reset these oops not to confuse gc_compiler() */ stix->c->_class.self_oop = STIX_NULL; @@ -2627,10 +2779,11 @@ static int compile_stream (stix_t* stix) static void gc_compiler (stix_t* stix) { + /* called when garbage collection is performed */ if (stix->c) { if (stix->c->_class.self_oop) - stix->c->_class.self_oop = stix_moveoop (stix, stix->c->_class.self_oop); + stix->c->_class.self_oop = (stix_oop_class_t)stix_moveoop (stix, (stix_oop_t)stix->c->_class.self_oop); if (stix->c->_class.super_oop) stix->c->_class.super_oop = stix_moveoop (stix, stix->c->_class.super_oop); @@ -2639,6 +2792,7 @@ static void gc_compiler (stix_t* stix) static void fini_compiler (stix_t* stix) { + /* called before the stix object is closed */ if (stix->c) { stix_size_t i; @@ -2737,6 +2891,5 @@ oops: void stix_getsynerr (stix_t* stix, stix_synerr_t* synerr) { STIX_ASSERT (stix->c != STIX_NULL); - if (synerr) *synerr = stix->c->synerr; } diff --git a/stix/lib/dic.c b/stix/lib/dic.c index e8f381b..be6cc95 100644 --- a/stix/lib/dic.c +++ b/stix/lib/dic.c @@ -156,7 +156,6 @@ stix_oop_t stix_getatsysdic (stix_t* stix, stix_oop_t key) return find_or_insert (stix, (stix_oop_char_t)key, STIX_NULL); } - stix_oop_t stix_lookupsysdic (stix_t* stix, const stix_ucs_t* name) { /* this is special version of stix_getatsysdic() that performs diff --git a/stix/lib/gc.c b/stix/lib/gc.c index fdaed26..e3b7a22 100644 --- a/stix/lib/gc.c +++ b/stix/lib/gc.c @@ -205,6 +205,7 @@ printf ("STARTING GC curheap base %p ptr %p newheap base %p ptr %p\n", stix->_nil_object = stix_moveoop (stix, stix->_nil_object); stix->_object = stix_moveoop (stix, stix->_object); stix->_array = stix_moveoop (stix, stix->_array); + stix->_string = stix_moveoop (stix, stix->_string); stix->_symbol = stix_moveoop (stix, stix->_symbol); stix->_symbol_set = stix_moveoop (stix, stix->_symbol_set); stix->_system_dictionary = stix_moveoop (stix, stix->_system_dictionary); diff --git a/stix/lib/ignite.c b/stix/lib/ignite.c index 4751f2f..7c29209 100644 --- a/stix/lib/ignite.c +++ b/stix/lib/ignite.c @@ -77,7 +77,8 @@ static stix_oop_t alloc_kernel_class (stix_t* stix, stix_oow_t indexed, stix_oow STIX_OBJ_SET_FLAGS_KERNEL (c, 1); STIX_OBJ_SET_CLASS (c, stix->_class); - c->spec = STIX_OOP_FROM_SMINT(spec); + c->spec = STIX_OOP_FROM_SMINT(spec); + c->selfspec = STIX_OOP_FROM_SMINT(STIX_CLASS_SELFSPEC_MAKE(indexed, 0)); return (stix_oop_t)c; } @@ -96,7 +97,7 @@ static int ignite_1 (stix_t* stix) * The instance of Class can have indexed instance variables * which are actually class variables. * -------------------------------------------------------------- */ - stix->_class = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE (STIX_CLASS_NAMED_INSTVARS, 1, STIX_OBJ_TYPE_OOP)); + stix->_class = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(STIX_CLASS_NAMED_INSTVARS, 1, STIX_OBJ_TYPE_OOP)); if (!stix->_class) return -1; STIX_ASSERT (STIX_OBJ_GET_CLASS(stix->_class) == STIX_NULL); @@ -106,6 +107,7 @@ static int ignite_1 (stix_t* stix) * Stix - proto-object with 1 class variable. * NilObject - class for the nil object. * Object - top of all ordinary objects. + * String * Symbol * Array * SymbolSet @@ -116,6 +118,7 @@ static int ignite_1 (stix_t* stix) stix->_nil_object = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(0, 0, STIX_OBJ_TYPE_OOP)); stix->_object = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(0, 0, STIX_OBJ_TYPE_OOP)); stix->_array = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(0, 1, STIX_OBJ_TYPE_OOP)); + stix->_string = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(0, 1, STIX_OBJ_TYPE_CHAR)); stix->_symbol = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(0, 1, STIX_OBJ_TYPE_CHAR)); stix->_symbol_set = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(STIX_SET_NAMED_INSTVARS, 0, STIX_OBJ_TYPE_OOP)); stix->_system_dictionary = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(STIX_SET_NAMED_INSTVARS, 0, STIX_OBJ_TYPE_OOP)); @@ -129,10 +132,10 @@ static int ignite_1 (stix_t* stix) stix->_character = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(0, 0, STIX_OBJ_TYPE_OOP)); stix->_small_integer = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(0, 0, STIX_OBJ_TYPE_OOP)); - if (!stix->_stix || !stix->_nil_object || !stix->_object || - !stix->_array || !stix->_symbol || !stix->_symbol_set || - !stix->_system_dictionary || !stix->_association || - !stix->_true_class || !stix->_false_class || + if (!stix->_stix || !stix->_nil_object || !stix->_object || + !stix->_array || !stix->_string || !stix->_symbol || + !stix->_symbol_set || !stix->_system_dictionary || !stix->_association || + !stix->_true_class || !stix->_false_class || !stix->_character || !stix->_small_integer) return -1; STIX_OBJ_SET_CLASS (stix->_nil, stix->_nil_object); return 0; @@ -186,8 +189,10 @@ static int ignite_3 (stix_t* stix) stix_uch_t str[16]; } symnames[] = { { 4, { 'S','t','i','x' } }, - { 6, { 'O','b','j','e','c','t' } }, + { 9, { 'N','i','l','O','b','j','e','c','t' } }, { 5, { 'C','l','a','s','s' } }, + { 6, { 'O','b','j','e','c','t' } }, + { 6, { 'S','t','r','i','n','g' } }, { 6, { 'S','y','m','b','o','l' } }, { 5, { 'A','r','r','a','y' } }, { 9, { 'S','y','m','b','o','l','S','e','t' } }, diff --git a/stix/lib/main.c b/stix/lib/main.c index afd1a4a..e066ca7 100644 --- a/stix/lib/main.c +++ b/stix/lib/main.c @@ -181,6 +181,36 @@ static void dump_symbol_table (stix_t* stix) printf ("--------------------------------------------\n"); } +void dump_system_dictionary (stix_t* stix) +{ + stix_oow_t i, j; + stix_oop_association_t ass; + + printf ("--------------------------------------------\n"); + printf ("Stix System Dictionary %lu\n", (unsigned long int)STIX_OBJ_GET_SIZE(stix->sysdic->bucket)); + printf ("--------------------------------------------\n"); + + for (i = 0; i < STIX_OBJ_GET_SIZE(stix->sysdic->bucket); i++) + { + ass = (stix_oop_association_t)stix->sysdic->bucket->slot[i]; + if ((stix_oop_t)ass != stix->_nil) + { + printf (" %lu [", (unsigned long int)i); + for (j = 0; j < STIX_OBJ_GET_SIZE(ass->key); j++) + { + printf ("%c", ((stix_oop_char_t)ass->key)->slot[j]); + } + printf ("]\n"); + } + } + printf ("--------------------------------------------\n"); +} + +void print_ucs (const stix_ucs_t* name) +{ + stix_size_t i; + for (i = 0; i < name->len; i++) printf ("%c", name->ptr[i]); +} static char* syntax_error_msg[] = { "no error", @@ -203,6 +233,7 @@ static char* syntax_error_msg[] = "primitive: expected", "wrong directive", "wrong class modifier", + "duplicate class modifier", "undefined class", "duplicate class", "#dcl not allowed", @@ -217,8 +248,11 @@ int main (int argc, char* argv[]) stix_t* stix; xtn_t* xtn; - printf ("Stix 1.0.0 - max named %lu max indexed %lu\n", - (unsigned long int)STIX_MAX_NAMED_INSTVARS, (unsigned long int)STIX_MAX_INDEXED_INSTVARS(STIX_MAX_NAMED_INSTVARS)); + printf ("Stix 1.0.0 - max named %lu max indexed %lu max class %lu max classinst %lu\n", + (unsigned long int)STIX_MAX_NAMED_INSTVARS, + (unsigned long int)STIX_MAX_INDEXED_INSTVARS(STIX_MAX_NAMED_INSTVARS), + (unsigned long int)STIX_MAX_CLASSVARS, + (unsigned long int)STIX_MAX_CLASSINSTVARS); if (argc != 2) @@ -227,7 +261,6 @@ int main (int argc, char* argv[]) return -1; } - { stix_oow_t x; @@ -252,9 +285,9 @@ int main (int argc, char* argv[]) stix_setoption (stix, STIX_DFL_SYSDIC_SIZE, &symtab_size); } - if (stix_ignite (stix) <= -1) + if (stix_ignite(stix) <= -1) { - printf ("cannot ignite stix\n"); + printf ("cannot ignite stix - %d\n", stix_geterrnum(stix)); stix_close (stix); return -1; } @@ -277,6 +310,9 @@ stix_gc (stix); a = stix_findsymbol (stix, x, 6); printf ("%p\n", a); dump_symbol_table (stix); + + + dump_system_dictionary (stix); } xtn = stix_getxtn (stix); @@ -321,12 +357,13 @@ printf ("%p\n", a); } else { - printf ("ERROR: cannot compile code\n"); + printf ("ERROR: cannot compile code - %d\n", stix_geterrnum(stix)); } stix_close (stix); return -1; } +dump_system_dictionary(stix); stix_close (stix); return 0; diff --git a/stix/lib/obj.c b/stix/lib/obj.c index 5afe2fc..4ae4141 100644 --- a/stix/lib/obj.c +++ b/stix/lib/obj.c @@ -119,15 +119,15 @@ stix_oop_t stix_alloccharobj (stix_t* stix, const stix_uch_t* ptr, stix_oow_t le return alloc_numeric_array (stix, ptr, len, STIX_OBJ_TYPE_CHAR, STIX_SIZEOF(stix_uch_t), 1); } -stix_oop_t stix_allocuint8obj (stix_t* stix, const stix_uint8_t* ptr, stix_oow_t len) +stix_oop_t stix_allocbyteobj (stix_t* stix, const stix_byte_t* ptr, stix_oow_t len) { - return alloc_numeric_array (stix, ptr, len, STIX_OBJ_TYPE_UINT8, STIX_SIZEOF(stix_uint8_t), 0); + return alloc_numeric_array (stix, ptr, len, STIX_OBJ_TYPE_BYTE, STIX_SIZEOF(stix_byte_t), 0); } -stix_oop_t stix_allocuint16obj (stix_t* stix, const stix_uint16_t* ptr, stix_oow_t len) +stix_oop_t stix_allocwordobj (stix_t* stix, const stix_oow_t* ptr, stix_oow_t len) { - return alloc_numeric_array (stix, ptr, len, STIX_OBJ_TYPE_UINT16, STIX_SIZEOF(stix_uint16_t), 0); + return alloc_numeric_array (stix, ptr, len, STIX_OBJ_TYPE_WORD, STIX_SIZEOF(stix_oow_t), 0); } stix_oop_t stix_instantiate (stix_t* stix, stix_oop_t _class, const void* vptr, stix_oow_t vlen) @@ -196,12 +196,12 @@ stix_oop_t stix_instantiate (stix_t* stix, stix_oop_t _class, const void* vptr, oop = stix_alloccharobj(stix, vptr, vlen); break; - case STIX_OBJ_TYPE_UINT8: - oop = stix_allocuint8obj(stix, vptr, vlen); + case STIX_OBJ_TYPE_BYTE: + oop = stix_allocbyteobj(stix, vptr, vlen); break; - case STIX_OBJ_TYPE_UINT16: - oop = stix_allocuint16obj(stix, vptr, vlen); + case STIX_OBJ_TYPE_WORD: + oop = stix_allocwordobj(stix, vptr, vlen); break; default: diff --git a/stix/lib/stix-prv.h b/stix/lib/stix-prv.h index e95776c..cdc601f 100644 --- a/stix/lib/stix-prv.h +++ b/stix/lib/stix-prv.h @@ -45,7 +45,6 @@ #define STIX_ALIGN(x,y) ((((x) + (y) - 1) / (y)) * (y)) - /* ========================================================================= */ /* CLASS SPEC ENCODING */ /* ========================================================================= */ @@ -123,6 +122,15 @@ #define STIX_MAX_INDEXED_INSTVARS(named_instvar) ((~(stix_oow_t)0) - named_instvar) +#define STIX_CLASS_SELFSPEC_MAKE(class_var,classinst_var) \ + (((stix_oow_t)class_var) << ((STIX_OOW_BITS - STIX_OOP_TAG_BITS) / 2)) | ((stix_oow_t)classinst_var) + +#define STIX_CLASS_SELFSPEC_CLASSVAR(spec) ((stix_oow_t)spec >> ((STIX_OOW_BITS - STIX_OOP_TAG_BITS) / 2)) +#define STIX_CLASS_SELFSPEC_CLASSINSTVAR(spec) (((stix_oow_t)spec) & STIX_LBMASK(stix_oow_t, (STIX_OOW_BITS - STIX_OOP_TAG_BITS) / 2)) + +#define STIX_MAX_CLASSVARS STIX_BITS_MAX(stix_oow_t, (STIX_OOW_BITS - STIX_OOP_TAG_BITS) / 2) +#define STIX_MAX_CLASSINSTVARS STIX_BITS_MAX(stix_oow_t, (STIX_OOW_BITS - STIX_OOP_TAG_BITS) / 2) + #if defined(STIX_INCLUDE_COMPILER) /* ========================================================================= */ @@ -270,6 +278,7 @@ enum stix_synerrnum_t STIX_SYNERR_PRIMITIVE, /* primitive: expected */ STIX_SYNERR_DIRECTIVE, /* wrong directive */ STIX_SYNERR_CLASSMOD, /* wrong class modifier */ + STIX_SYNERR_CLASSMODDUP, /* duplicate class modifier */ STIX_SYNERR_CLASSUNDEF, /* undefined class */ STIX_SYNERR_CLASSDUP, /* duplicate class */ STIX_SYNERR_DCLBANNED, /* #dcl not allowed */ @@ -502,9 +511,10 @@ struct stix_compiler_t struct { int flags; + int indexed_type; - stix_oop_t self_oop; - stix_oop_t super_oop; + stix_oop_class_t self_oop; + stix_oop_t super_oop; /* this may be nil. so the type is stix_oop_t */ stix_ucs_t name; stix_size_t name_capa; @@ -515,6 +525,8 @@ struct stix_compiler_t /* instance variable, class variable, class instance variable */ stix_ucs_t vars[3]; stix_size_t vars_capa[3]; + + /* var_count, unlike vars above, includes superclass counts as well.*/ stix_size_t var_count[3]; } _class; @@ -589,8 +601,8 @@ void* stix_allocheapmem ( /* stix.c */ /* ========================================================================= */ stix_size_t stix_hashbytes ( - const stix_uint8_t* ptr, - stix_size_t len + const stix_byte_t* ptr, + stix_size_t len ); stix_size_t stix_hashchars ( @@ -653,6 +665,12 @@ stix_oop_t stix_allocuint16obj ( stix_oow_t len ); +stix_oop_t stix_allocuint32obj ( + stix_t* stix, + const stix_uint32_t* ptr, + stix_oow_t len +); + /* ========================================================================= */ /* sym.c */ /* ========================================================================= */ @@ -668,6 +686,12 @@ stix_oop_t stix_findsymbol ( stix_oow_t len ); +stix_oop_t stix_makestring ( + stix_t* stix, + const stix_uch_t* ptr, + stix_oow_t len +); + /* ========================================================================= */ /* dic.c */ /* ========================================================================= */ diff --git a/stix/lib/stix.c b/stix/lib/stix.c index 197ac61..de10e81 100644 --- a/stix/lib/stix.c +++ b/stix/lib/stix.c @@ -186,7 +186,7 @@ void stix_deregcb (stix_t* stix, stix_cb_t* cb) stix_freemem (stix, cb); } -stix_size_t stix_hashbytes (const stix_uint8_t* ptr, stix_size_t len) +stix_size_t stix_hashbytes (const stix_byte_t* ptr, stix_size_t len) { stix_size_t h = 0; const stix_uint8_t* bp, * be; @@ -199,7 +199,7 @@ stix_size_t stix_hashbytes (const stix_uint8_t* ptr, stix_size_t len) stix_size_t stix_hashchars (const stix_uch_t* ptr, stix_size_t len) { - return stix_hashbytes ((const stix_uint8_t *)ptr, len * STIX_SIZEOF(*ptr)); + return stix_hashbytes ((const stix_byte_t *)ptr, len * STIX_SIZEOF(*ptr)); } int stix_equalchars (const stix_uch_t* str1, const stix_uch_t* str2, stix_size_t len) diff --git a/stix/lib/stix.h b/stix/lib/stix.h index f359f4e..8fccfd2 100644 --- a/stix/lib/stix.h +++ b/stix/lib/stix.h @@ -53,12 +53,11 @@ typedef unsigned long int stix_uintptr_t; typedef unsigned long int stix_size_t; typedef signed long int stix_ssize_t; +typedef stix_uint8_t stix_byte_t; typedef stix_uint16_t stix_uch_t; /* TODO ... wchar_t??? */ typedef stix_int32_t stix_uci_t; - typedef char stix_bch_t; - struct stix_ucs_t { stix_uch_t* ptr; @@ -364,8 +363,14 @@ enum stix_obj_type_t { STIX_OBJ_TYPE_OOP, STIX_OBJ_TYPE_CHAR, - STIX_OBJ_TYPE_UINT8, - STIX_OBJ_TYPE_UINT16 + STIX_OBJ_TYPE_BYTE, + STIX_OBJ_TYPE_WORD, + +/* + STIX_OBJ_TYPE_UINT8, + STIX_OBJ_TYPE_UINT16, + STIX_OBJ_TYPE_UINT32, +*/ /* NOTE: you can have STIX_OBJ_SHORT, STIX_OBJ_INT * STIX_OBJ_LONG, STIX_OBJ_FLOAT, STIX_OBJ_DOUBLE, etc @@ -385,7 +390,7 @@ typedef enum stix_obj_type_t stix_obj_type_t; * _flags: * type: the type of a payload item. * one of STIX_OBJ_TYPE_OOP, STIX_OBJ_TYPE_CHAR, - * STIX_OBJ_TYPE_UINT8, STIX_OBJ_TYPE_UINT16 + * STIX_OBJ_TYPE_BYTE, STIX_OBJ_TYPE_WORD * unit: the size of a payload item in bytes. * extra: 0 or 1. 1 indicates that the payload contains 1 more * item than the value of the size field. mostly used for a @@ -486,12 +491,13 @@ struct stix_obj_uint16_t stix_uint16_t slot[1]; }; -#define STIX_CLASS_NAMED_INSTVARS 8 +#define STIX_CLASS_NAMED_INSTVARS 10 struct stix_class_t { STIX_OBJ_HEADER; - stix_oop_t spec; /* SmallInteger */ + stix_oop_t spec; /* SmallInteger. instance specification */ + stix_oop_t selfspec; /* SmallInteger. specification of the class object itself */ stix_oop_t superclass; /* Another class */ stix_oop_t subclasses; /* Array of subclasses */ @@ -606,6 +612,7 @@ struct stix_t stix_oop_t _nil_object; /* NilObject */ stix_oop_t _class; /* Class */ stix_oop_t _object; /* Object */ + stix_oop_t _string; /* String */ stix_oop_t _symbol; /* Symbol */ stix_oop_t _array; /* Array */ stix_oop_t _symbol_set; /* SymbolSet */ diff --git a/stix/lib/sym.c b/stix/lib/sym.c index 37c8037..d5c3fc1 100644 --- a/stix/lib/sym.c +++ b/stix/lib/sym.c @@ -107,7 +107,7 @@ static stix_oop_t find_or_make_symbol (stix_t* stix, const stix_uch_t* ptr, stix * make sure that it has at least one free slot left * after having added a new symbol. this is to help * traversal end at a _nil slot if no entry is found. */ - bucket = expand_bucket (stix, stix->symtab->bucket); + bucket = expand_bucket(stix, stix->symtab->bucket); if (!bucket) return STIX_NULL; stix->symtab->bucket = bucket; @@ -120,7 +120,7 @@ static stix_oop_t find_or_make_symbol (stix_t* stix, const stix_uch_t* ptr, stix } /* create a new symbol since it isn't found in the symbol table */ - symbol = (stix_oop_char_t)stix_instantiate (stix, stix->_symbol, ptr, len); + symbol = (stix_oop_char_t)stix_instantiate(stix, stix->_symbol, ptr, len); if (symbol) { stix->symtab->tally = STIX_OOP_FROM_SMINT(tally + 1); @@ -139,3 +139,8 @@ stix_oop_t stix_findsymbol (stix_t* stix, const stix_uch_t* ptr, stix_oow_t len) { return find_or_make_symbol (stix, ptr, len, 0); } + +stix_oop_t stix_makestring (stix_t* stix, const stix_uch_t* ptr, stix_oow_t len) +{ + return stix_instantiate (stix, stix->_string, ptr, len); +}