diff --git a/qse/lib/stx/array.c b/qse/lib/stx/array.c deleted file mode 100644 index 1f6c1800..00000000 --- a/qse/lib/stx/array.c +++ /dev/null @@ -1,18 +0,0 @@ -/* - * $Id: array.c 118 2008-03-03 11:21:33Z baconevi $ - */ - -#include -#include -#include - -qse_word_t qse_stx_new_array (qse_stx_t* stx, qse_word_t size) -{ - qse_word_t x; - - qse_assert (stx->class_array != stx->nil); - x = qse_stx_alloc_word_object (stx, QSE_NULL, 0, QSE_NULL, size); - QSE_STX_CLASS(stx,x) = stx->class_array; - - return x; -} diff --git a/qse/lib/stx/array.h b/qse/lib/stx/array.h deleted file mode 100644 index 90062704..00000000 --- a/qse/lib/stx/array.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * $Id: array.h 118 2008-03-03 11:21:33Z baconevi $ - */ - -#ifndef _QSE_STX_ARRAY_H_ -#define _QSE_STX_ARRAY_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -qse_word_t qse_stx_new_array (qse_stx_t* stx, qse_word_t size); - -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/qse/lib/stx/boot.c b/qse/lib/stx/boot.c index 532fda60..16aa71e9 100644 --- a/qse/lib/stx/boot.c +++ b/qse/lib/stx/boot.c @@ -5,22 +5,6 @@ #include "stx.h" #include -static int make_intrinsic_classes (qse_stx_t* stx); - -static qse_word_t __make_classvar_dic ( - qse_stx_t* stx, qse_word_t class, const qse_char_t* names); -static void __filein_kernel (qse_stx_t* stx); - -static qse_word_t __count_names (const qse_char_t* str); -static void __set_names ( - qse_stx_t* stx, qse_word_t* array, const qse_char_t* str); - -static qse_word_t __count_subclasses (const qse_char_t* str); -static void __set_subclasses ( - qse_stx_t* stx, qse_word_t* array, const qse_char_t* str); -static void __set_metaclass_subclasses ( - qse_stx_t* stx, qse_word_t* array, const qse_char_t* str); - struct class_info_t { const qse_char_t* name; @@ -39,7 +23,7 @@ static class_info_t class_info[] = QSE_T("Object"), QSE_NULL, QSE_NULL, - QSE_NULL, + QSE_T("classvar1 classvar2")/*QSE_NULL TODO: delete this.....*/, QSE_NULL, SPEC_FIXED_WORD }, @@ -54,7 +38,7 @@ static class_info_t class_info[] = { QSE_T("Behavior"), QSE_T("Object"), - QSE_T("spec methods superclass"), + QSE_T("spec methods superclass subclasses"), QSE_NULL, QSE_NULL, SPEC_FIXED_WORD @@ -280,164 +264,94 @@ static class_info_t class_info[] = qse_word_t QSE_INLINE new_string (qse_stx_t* stx, const qse_char_t* str) { - qse_word_t x; - QSE_ASSERT (REFISIDX(stx,stx->ref.class_string)); QSE_ASSERT (!ISNIL(stx,stx->ref.class_string)); - x = qse_stx_alloccharobj (stx, str, qse_strlen(str)); - if (x != stx->ref.nil) OBJCLASS(stx,x) = stx->ref.class_string; - - return x; + return qse_stx_instantiate ( + stx, stx->ref.class_string, QSE_NULL, str, qse_strlen(str)); } -static int make_intrinsic_classes (qse_stx_t* stx) +qse_word_t QSE_INLINE new_array (qse_stx_t* stx, qse_word_t capa) { - class_info_t* p; - qse_word_t n; - + QSE_ASSERT (REFISIDX(stx,stx->ref.class_array)); QSE_ASSERT (!ISNIL(stx,stx->ref.class_array)); - for (p = class_info; p->name != QSE_NULL; p++) - { - qse_word_t classref; - qse_stx_class_t* classptr; - qse_word_t nfixed; - - classref = qse_stx_findclass(stx, p->name); - if (ISNIL(stx,classref)) - { - classref = qse_stx_newclass (stx, p->name); - if (ISNIL(stx,classref)) return NIL(stx); - } - - classptr = (qse_stx_class_t*)PTRBYREF(stx,classref); - if (p->superclass) - { - classptr->superclass = qse_stx_findclass(stx,p->superclass); - QSE_ASSERT (!ISNIL(stx,classptr->superclass)); - } - - nfixed = 0; - - /* resolve the number of fixed fields in the superclass chain */ - if (p->superclass) - { - qse_word_t superref; - qse_stx_class_t* superptr; - - qse_word_t metaref; - qse_stx_metaclass_t* metaptr; - - superref = qse_stx_findclass (stx, p->superclass); - QSE_ASSERT (!ISNIL(stx,superref)); - - metaref = OBJCLASS(stx,classref); - metaptr = (qse_stx_metaclass_t*)PTRBYREF(stx,metaref); - metaptr->superclass = OBJCLASS(stx,superref); - metaptr->instance_class = classref; - - do - { - superptr = (qse_stx_class_t*)PTRBYREF(stx,superref); - nfixed += SPEC_GETFIXED(REFTOINT(stx,superptr->spec)); - superref = superptr->superclass; - } - while (!ISNIL(stx,superref)); - } - - /* add the number of instance variables to the number of - * fixed fields */ - if (p->instance_variables) - { - nfixed += __count_names (p->instance_variables); - classptr->variables = - new_string (stx, p->instance_variables); - if (ISNIL(stx,classptr->variables)) return -1; - } - - QSE_ASSERT ( - nfixed <= 0 || - (nfixed > 0 && (p->spec == SPEC_FIXED_WORD || - p->spec == SPEC_VARIABLE_WORD))); - - classptr->spec = SPEC_MAKE (nfixed, p->spec); - } - - for (p = class_info; p->name != QSE_NULL; p++) - { - qse_word_t classref; - qse_stx_class_t* classptr; - - classref = qse_stx_findclass (stx, p->name); - QSE_ASSERT (!ISNIL(stx,classref)); - - classptr = (qse_stx_class_t*)PTRBYREF(stx,classref); - - if (p->class_variables != QSE_NULL) - { - classptr->class_variables = - __make_classvar_dic(stx, classref, p->class_variables); - - if (ISNIL(stx,classptr->class_variables)) return NIL(stx); - } - - /* - TODO: - if (p->pool_dictionaries != QSE_NULL) { - classptr->pool_dictionaries = - __make_pool_dictionary(stx, class, p->pool_dictionaries); - } - */ - } - - /* fill subclasses */ - for (p = class_info; p->name != QSE_NULL; p++) - { - qse_word_t classref; - qse_stx_class_t* classptr; - qse_word_t array; - - n = __count_subclasses (p->name); - array = qse_stx_newarray (stx, n); - if (ISNIL(stx,array)) return NIL(stx); - - __set_subclasses (stx, &WORDAT(stx,array,0), p->name); - - classref = qse_stx_findclass (stx, p->name); - QSE_ASSERT (!ISNIL(stx,classref)); - - classptr = (qse_stx_class_t*)PTRBYREF(stx,classref); - classptr->subclasses = array; - } - - /* fill subclasses for metaclasses */ - for (p = class_info; p->name != QSE_NULL; p++) - { - qse_word_t classref; - qse_stx_class_t* classptr; - - qse_word_t metaref; - qse_stx_metaclass_t* metaptr; - - qse_word_t array; - - n = __count_subclasses (p->name); - array = qse_stx_new_array (stx, n); - __set_metaclass_subclasses (stx, &WORDAT(stx,array,0), p->name); - - classref = qse_stx_findclass (stx, p->name); - QSE_ASSERT (!ISNIL(stx,classref)); - - metaref = OBJCLASS(stx,classref); - metaptr = (qse_stx_metaclass_t*)PTRBYREF(stx,metaref); - metaptr->subclasses = array; - } - - return 0; + return qse_stx_instantiate ( + stx, stx->ref.class_array, QSE_NULL, QSE_NULL, capa); } -static qse_word_t __count_names (const qse_char_t* str) +qse_word_t QSE_INLINE new_systemdictionary (qse_stx_t* stx, qse_word_t capa) +{ + QSE_ASSERT (REFISIDX(stx,stx->ref.class_systemdictionary)); + QSE_ASSERT (!ISNIL(stx,stx->ref.class_systemdictionary)); + + /* the system dictionary uses 1 slot dedicated for nil. + * so we request to allocate 1 more slot than the given */ + return qse_stx_instantiate ( + stx, stx->ref.class_systemdictionary, + QSE_NULL, QSE_NULL, capa + 1); +} + +qse_word_t new_class (qse_stx_t* stx, const qse_char_t* name) +{ + qse_word_t meta, class, assoc; + qse_word_t class_name; + + QSE_ASSERT (REFISIDX(stx,stx->ref.class_metaclass)); + + meta = qse_stx_allocwordobj ( + stx, QSE_NULL, QSE_STX_METACLASS_SIZE, QSE_NULL, 0); + if (ISNIL(stx,meta)) return stx->ref.nil; + OBJCLASS(stx,meta) = stx->ref.class_metaclass; + + /* the spec of the metaclass must be the spec of its + * instance. so the QSE_STX_CLASS_SIZE is set */ + WORDAT(stx,meta,QSE_STX_METACLASS_SPEC) = + INTTOREF(stx,SPEC_MAKE(QSE_STX_CLASS_SIZE,SPEC_FIXED_WORD)); + + /* the spec of the class is set later in __create_builtin_classes */ + class = qse_stx_allocwordobj ( + stx, QSE_NULL, QSE_STX_CLASS_SIZE, QSE_NULL, 0); + OBJCLASS(stx,class) = meta; + + class_name = qse_stx_newsymbol (stx, name); + if (ISNIL(stx,class_name)) return stx->ref.nil; + + WORDAT(stx,class,QSE_STX_CLASS_NAME) = class_name; + WORDAT(stx,class,QSE_STX_CLASS_SPEC) = stx->ref.nil; + + assoc = qse_stx_putdic (stx, stx->ref.sysdic, class_name, class); + return (ISNIL(stx,assoc))? stx->ref.nil: class; +} + +qse_word_t find_class (qse_stx_t* stx, const qse_char_t* name) +{ + qse_word_t assoc, meta, value; + + /* look up the system dictionary for the name given */ + assoc = qse_stx_lookupdic (stx, stx->ref.sysdic, name); + if (ISNIL(stx,assoc)) + { + /*qse_stx_seterrnum (stx, QSE_STX_ENOCLASS, QSE_NULL);*/ + return stx->ref.nil; + } + + /* get the value part in the association for the name */ + value = WORDAT(stx,assoc,QSE_STX_ASSOCIATION_VALUE); + + /* check if its class is Metaclass because the class of + * a class object must be Metaclass. */ + meta = OBJCLASS(stx,value); + if (OBJCLASS(stx,meta) != stx->ref.class_metaclass) + { + /*qse_stx_seterrnum (stx, QSE_STX_ENOTCLASS, QSE_NULL);*/ + return stx->ref.nil; + } + + return value; +} + +static qse_word_t count_names (const qse_char_t* str) { qse_word_t n = 0; const qse_char_t* p = str; @@ -458,30 +372,7 @@ static qse_word_t __count_names (const qse_char_t* str) return n; } -static void __set_names ( - qse_stx_t* stx, qse_word_t* array, const qse_char_t* str) -{ - qse_word_t n = 0; - const qse_char_t* p = str; - const qse_char_t* name; - - do - { - while (*p == QSE_T(' ') || - *p == QSE_T('\t')) p++; - if (*p == QSE_T('\0')) break; - - name = p; - while (*p != QSE_T(' ') && - *p != QSE_T('\t') && - *p != QSE_T('\0')) p++; - - array[n++] = qse_stx_newsymbolx (stx, name, p - name); - } - while (1); -} - -static qse_word_t __count_subclasses (const qse_char_t* str) +static qse_word_t count_subclasses (const qse_char_t* str) { class_info_t* p; qse_word_t n = 0; @@ -495,7 +386,7 @@ static qse_word_t __count_subclasses (const qse_char_t* str) return n; } -static void __set_subclasses ( +static void set_subclasses ( qse_stx_t* stx, qse_word_t* array, const qse_char_t* str) { class_info_t* p; @@ -505,13 +396,13 @@ static void __set_subclasses ( { if (p->superclass == QSE_NULL) continue; if (qse_strcmp (str, p->superclass) != 0) continue; - class = qse_stx_findclass (stx, p->name); + class = find_class (stx, p->name); QSE_ASSERT (!ISNIL(stx,class)); array[n++] = class; } } -static void __set_metaclass_subclasses ( +static void set_metaclass_subclasses ( qse_stx_t* stx, qse_word_t* array, const qse_char_t* str) { class_info_t* p; @@ -521,13 +412,13 @@ static void __set_metaclass_subclasses ( { if (p->superclass == QSE_NULL) continue; if (qse_strcmp (str, p->superclass) != 0) continue; - class = qse_stx_findclass (stx, p->name); + class = find_class (stx, p->name); QSE_ASSERT (!ISNIL(stx,class)); array[n++] = OBJCLASS(stx,class); } } -static qse_word_t __make_classvar_dic ( +static qse_word_t make_classvar_dic ( qse_stx_t* stx, qse_word_t class, const qse_char_t* names) { qse_word_t dic, symbol, assoc; @@ -535,10 +426,8 @@ static qse_word_t __make_classvar_dic ( const qse_char_t* name; /* TODO: how to implement temporary GC prevention....???? */ - dic = qse_stx_instantiate ( - stx, stx->ref.class_systemdictionary, - QSE_NULL, QSE_NULL, __count_names(names)); - if (ISNIL(stx,dic)) return NIL(stx); + dic = new_systemdictionary (stx, count_names(names)); + if (ISNIL(stx,dic)) return stx->ref.nil; do { @@ -552,25 +441,16 @@ static qse_word_t __make_classvar_dic ( *p != QSE_T('\0')) p++; symbol = qse_stx_newsymbolx (stx, name, p - name); - if (ISNIL(stx,symbol)) return NIL(stx); + if (ISNIL(stx,symbol)) return stx->ref.nil; - assoc =qse_stx_putdic (stx, dic, symbol, stx->ref.nil); - if (ISNIL(stx,assoc)) return NIL(stx); + assoc = qse_stx_putdic (stx, dic, symbol, stx->ref.nil); + if (ISNIL(stx,assoc)) return stx->ref.nil; } while (1); return dic; } -static void __filein_kernel (qse_stx_t* stx) -{ - class_info_t* p; - - for (p = class_info; p->name != QSE_NULL; p++) { - /* TODO: */ - } -} - static int sketch_nil (qse_stx_t* stx) { qse_stx_objidx_t idx; @@ -597,12 +477,13 @@ static int sketch_nil (qse_stx_t* stx) ptr->h._class = stx->ref.nil; /* the class is yet to be set */ ptr->h._backref = ref; + return 0; } #define ALLOC_WORDOBJ_TO(stx,var,nflds,nvflds) QSE_BLOCK (\ var = qse_stx_allocwordobj ((stx), QSE_NULL, (nflds), QSE_NULL, nvflds); \ - if ((var) == (stx)->ref.nil) return -1; \ + if (ISNIL(stx,(var))) return -1; \ ) #define ADD_TO_SYSDIC(stx,key,value) QSE_BLOCK (\ @@ -611,12 +492,12 @@ static int sketch_nil (qse_stx_t* stx) #define NEW_SYMBOL_TO(stx,var,name) QSE_BLOCK (\ var = qse_stx_newsymbol ((stx), name); \ - if (var == (stx)->ref.nil) return -1; \ + if (ISNIL(stx,(var))) return -1; \ ) #define NEW_CLASS_TO(stx,var,name) QSE_BLOCK (\ - var = qse_stx_newclass ((stx), name); \ - if (var == (stx)->ref.nil) return -1; \ + var = new_class ((stx), name); \ + if (ISNIL(stx,(var))) return -1; \ ) static int sketch_key_objects (qse_stx_t* stx) @@ -628,21 +509,28 @@ static int sketch_key_objects (qse_stx_t* stx) qse_word_t symbol_metaclass; qse_word_t symbol_association; - /* allocate true and false. the class pointer is not correct yet */ - ALLOC_WORDOBJ_TO (stx, stx->ref.true, 0, 0); - ALLOC_WORDOBJ_TO (stx, stx->ref.false, 0, 0); + QSE_ASSERT (REFISIDX(stx,stx->ref.nil)); - /* create a symbol table partially initialized */ + /* Create a symbol table partially initialized. + * Especially, the class of the symbol table is not set yet. + * It must be corrected later */ /* TODO: initial symbol table size */ ALLOC_WORDOBJ_TO (stx, stx->ref.symtab, 1, SYMTAB_INIT_CAPA); - /* set tally to 0. */ + /* Set tally to 0. */ WORDAT(stx,stx->ref.symtab,QSE_STX_SYMTAB_TALLY) = INTTOREF(stx,0); - /* global system dictionary */ + /* Create a global system dictionary partially initialized. + * Especially, the class of the system dictionary is not set yet. + * It must be corrected later */ /* TODO: initial dictionary size */ ALLOC_WORDOBJ_TO (stx, stx->ref.sysdic, 1, SYSDIC_INIT_CAPA); - /* set tally to 0 */ - WORDAT(stx,stx->ref.sysdic,QSE_STX_DIC_TALLY) = INTTOREF(stx,0); + /* Set tally to 0 */ + WORDAT(stx,stx->ref.sysdic,QSE_STX_SYSTEMDICTIONARY_TALLY) = INTTOREF(stx,0); + + /* Create a few critical class objects needed for maintaining + * the symbol table and the system dictionary. At this point, + * new_class() cannot be used yet. So the process is + * pretty mundane as shown below. */ /* Symbol */ ALLOC_WORDOBJ_TO (stx, stx->ref.class_symbol, QSE_STX_CLASS_SIZE, 0); @@ -663,18 +551,18 @@ static int sketch_key_objects (qse_stx_t* stx) ALLOC_WORDOBJ_TO (stx, class_AssociationMeta, QSE_STX_METACLASS_SIZE, 0); /* (Symbol class) setClass: Metaclass */ - QSE_STX_OBJCLASS(stx,class_SymbolMeta) = stx->ref.class_metaclass; + OBJCLASS(stx,class_SymbolMeta) = stx->ref.class_metaclass; /* (Metaclass class) setClass: Metaclass */ - QSE_STX_OBJCLASS(stx,class_MetaclassMeta) = stx->ref.class_metaclass; + OBJCLASS(stx,class_MetaclassMeta) = stx->ref.class_metaclass; /* (Association class) setClass: Metaclass */ - QSE_STX_OBJCLASS(stx,class_AssociationMeta) = stx->ref.class_metaclass; + OBJCLASS(stx,class_AssociationMeta) = stx->ref.class_metaclass; /* Symbol setClass: (Symbol class) */ - QSE_STX_OBJCLASS(stx,stx->ref.class_symbol) = class_SymbolMeta; + OBJCLASS(stx,stx->ref.class_symbol) = class_SymbolMeta; /* Metaclass setClass: (Metaclass class) */ - QSE_STX_OBJCLASS(stx,stx->ref.class_metaclass) = class_MetaclassMeta; + OBJCLASS(stx,stx->ref.class_metaclass) = class_MetaclassMeta; /* Association setClass: (Association class) */ - QSE_STX_OBJCLASS(stx,stx->ref.class_association) = class_AssociationMeta; + OBJCLASS(stx,stx->ref.class_association) = class_AssociationMeta; /* (Symbol class) setSpec: CLASS_SIZE */ WORDAT(stx,class_SymbolMeta,QSE_STX_CLASS_SPEC) = @@ -687,7 +575,7 @@ static int sketch_key_objects (qse_stx_t* stx) INTTOREF (stx, SPEC_MAKE(QSE_STX_CLASS_SIZE,SPEC_FIXED_WORD)); /* specs for class_metaclass, class_association, - * class_symbol are set later in make_builtin_classes */ + * class_symbol are set later in make_intrinsic_classes */ /* #Symbol */ NEW_SYMBOL_TO (stx, symbol_symbol, QSE_T("Symbol")); @@ -703,6 +591,14 @@ static int sketch_key_objects (qse_stx_t* stx) /* Association setName: #Association */ WORDAT(stx,stx->ref.class_association,QSE_STX_CLASS_NAME) = symbol_association; + /* propagte the spec field in advance */ + WORDAT(stx,stx->ref.class_symbol,QSE_STX_CLASS_SPEC) = + INTTOREF (stx, SPEC_MAKE(0,SPEC_VARIABLE_CHAR)); + WORDAT(stx,stx->ref.class_metaclass,QSE_STX_CLASS_SPEC) = + INTTOREF (stx, SPEC_MAKE(QSE_STX_METACLASS_SIZE,SPEC_FIXED_WORD)); + WORDAT(stx,stx->ref.class_association,QSE_STX_CLASS_SPEC) = + INTTOREF (stx, SPEC_MAKE(QSE_STX_ASSOCIATION_SIZE,SPEC_FIXED_WORD)); + /* register class names into the system dictionary */ ADD_TO_SYSDIC (stx, symbol_symbol, stx->ref.class_symbol); ADD_TO_SYSDIC (stx, symbol_metaclass, stx->ref.class_metaclass); @@ -711,11 +607,12 @@ static int sketch_key_objects (qse_stx_t* stx) return 0; } -int make_key_classes (qse_stx_t* stx) +static int make_key_classes (qse_stx_t* stx) { /* object, class, and array are precreated for easier instantiation - * of intrinsic classes */ + * of intrinsic classes. */ NEW_CLASS_TO (stx, stx->ref.class_object, QSE_T("Object")); + NEW_CLASS_TO (stx, stx->ref.class_undefinedobject, QSE_T("UndefinedObject")); NEW_CLASS_TO (stx, stx->ref.class_class, QSE_T("Class")); NEW_CLASS_TO (stx, stx->ref.class_array, QSE_T("Array")); NEW_CLASS_TO (stx, stx->ref.class_bytearray, QSE_T("ByteArray")); @@ -726,65 +623,272 @@ int make_key_classes (qse_stx_t* stx) NEW_CLASS_TO (stx, stx->ref.class_systemdictionary, QSE_T("SystemDictionary")); NEW_CLASS_TO (stx, stx->ref.class_method, QSE_T("Method")); NEW_CLASS_TO (stx, stx->ref.class_smallinteger, QSE_T("SmallInteger")); + + /* set the spec field in advance so that new_string() and new_array() + * can call qse_stx_instantiate() from this point onwards */ + WORDAT(stx,stx->ref.class_string,QSE_STX_CLASS_SPEC) = + INTTOREF (stx, SPEC_MAKE(0,SPEC_VARIABLE_CHAR)); + WORDAT(stx,stx->ref.class_array,QSE_STX_CLASS_SPEC) = + INTTOREF (stx, SPEC_MAKE(0,SPEC_VARIABLE_WORD)); + return 0; } +static void set_class_of_more_key_objects (qse_stx_t* stx) +{ + /* nil setClass: UndefinedObject */ + OBJCLASS(stx,stx->ref.nil) = stx->ref.class_undefinedobject; + + /* sysdic(Smalltalk) setClass: SystemDictionary */ + OBJCLASS(stx,stx->ref.sysdic) = stx->ref.class_systemdictionary; + + /* symtab setClass: SystemSymbolTable */ + OBJCLASS(stx,stx->ref.symtab) = stx->ref.class_systemsymboltable; +} + +static int make_intrinsic_classes (qse_stx_t* stx) +{ + class_info_t* p; + + QSE_ASSERT (!ISNIL(stx,stx->ref.class_array)); + + for (p = class_info; p->name != QSE_NULL; p++) + { + qse_word_t classref; + qse_stx_class_t* classptr; + qse_word_t nfixed; + qse_word_t spec; + + classref = find_class(stx, p->name); + if (ISNIL(stx,classref)) + { + classref = new_class (stx, p->name); + if (ISNIL(stx,classref)) return stx->ref.nil; + } + + classptr = (qse_stx_class_t*)PTRBYREF(stx,classref); + if (p->superclass) + { + classptr->superclass = find_class(stx,p->superclass); + QSE_ASSERT (!ISNIL(stx,classptr->superclass)); + } + + nfixed = 0; + + /* resolve the number of fixed fields in the superclass chain */ + if (p->superclass) + { + qse_word_t superref; + qse_stx_class_t* superptr; + + qse_word_t metaref; + qse_stx_metaclass_t* metaptr; + + superref = find_class (stx, p->superclass); + QSE_ASSERT (!ISNIL(stx,superref)); + + metaref = OBJCLASS(stx,classref); + metaptr = (qse_stx_metaclass_t*)PTRBYREF(stx,metaref); + metaptr->superclass = OBJCLASS(stx,superref); + metaptr->instance_class = classref; + + do + { + superptr = (qse_stx_class_t*)PTRBYREF(stx,superref); + nfixed += SPEC_GETFIXED(REFTOINT(stx,superptr->spec)); + superref = superptr->superclass; + } + while (!ISNIL(stx,superref)); + } + + /* add the number of instance variables to the number of + * fixed fields */ + if (p->instance_variables) + { + nfixed += count_names (p->instance_variables); + classptr->variables = + new_string (stx, p->instance_variables); + if (ISNIL(stx,classptr->variables)) return -1; + } + + QSE_ASSERT ( + nfixed <= 0 || + (nfixed > 0 && (p->spec == SPEC_FIXED_WORD || + p->spec == SPEC_VARIABLE_WORD))); + + spec = INTTOREF (stx, SPEC_MAKE (nfixed, p->spec)); + + QSE_ASSERTX (ISNIL(stx,classptr->spec) || classptr->spec == spec, + "If the specfication field is already set before this function, " + "the specification in the class information table must match it. " + "Otherwise, something is very wrong"); + + classptr->spec = spec; + } + + /* make class variable dictionaries and pool dictionaries */ + for (p = class_info; p->name; p++) + { + qse_word_t classref; + qse_stx_class_t* classptr; + + classref = find_class (stx, p->name); + QSE_ASSERT (!ISNIL(stx,classref)); + + classptr = (qse_stx_class_t*)PTRBYREF(stx,classref); + + if (p->class_variables) + { + classptr->class_variables = + make_classvar_dic(stx, classref, p->class_variables); + if (ISNIL(stx,classptr->class_variables)) return stx->ref.nil; + } + + /* + TODO: + if (p->pool_dictionaries != QSE_NULL) { + classptr->pool_dictionaries = + __make_pool_dictionary(stx, class, p->pool_dictionaries); + } + */ + } + + /* fill subclasses */ + for (p = class_info; p->name != QSE_NULL; p++) + { + qse_word_t classref; + qse_stx_class_t* classptr; + qse_word_t array; + qse_word_t n; + + n = count_subclasses (p->name); + array = new_array (stx, n); + if (ISNIL(stx,array)) return -1; + + set_subclasses (stx, &WORDAT(stx,array,0), p->name); + + classref = find_class (stx, p->name); + QSE_ASSERT (!ISNIL(stx,classref)); + + classptr = (qse_stx_class_t*)PTRBYREF(stx,classref); + classptr->subclasses = array; + } + + /* fill subclasses for metaclasses */ + for (p = class_info; p->name != QSE_NULL; p++) + { + qse_word_t classref; + + qse_word_t metaref; + qse_stx_metaclass_t* metaptr; + + qse_word_t array; + qse_word_t n; + + n = count_subclasses (p->name); + array = new_array (stx, n); + if (ISNIL(stx,array)) return -1; + + set_metaclass_subclasses (stx, &WORDAT(stx,array,0), p->name); + + classref = find_class (stx, p->name); + QSE_ASSERT (!ISNIL(stx,classref)); + + metaref = OBJCLASS(stx,classref); + metaptr = (qse_stx_metaclass_t*)PTRBYREF(stx,metaref); + metaptr->subclasses = array; + } + + return 0; +} + + +static void make_metaclass_top_hierarchy (qse_stx_t* stx) +{ + qse_word_t metaclass_of_object; + + /* make the superclass of Object class to be Class */ + + /* metaclass_of_object := Object class */ + metaclass_of_object = OBJCLASS (stx, stx->ref.class_object); + + /* (Object class) setSuperclass: Class */ + WORDAT(stx,metaclass_of_object,QSE_STX_METACLASS_SUPERCLASS) = stx->ref.class_class; + + /* Set the instance class for Object here as it is not + * set in make_intrisic_classes */ + WORDAT(stx,metaclass_of_object,QSE_STX_METACLASS_INSTANCE_CLASS) = stx->ref.class_object; +} + + +static int make_key_objects_accessible_by_name (qse_stx_t* stx) +{ + qse_word_t tmp; + +#if 0 + /* create #nil, #true, #false */ + NEW_SYMBOL_TO (stx, tmp, QSE_T("nil")); + NEW_SYMBOL_TO (stx, tmp, QSE_T("true")); + NEW_SYMBOL_TO (stx, tmp, QSE_T("false")); +#endif + + NEW_SYMBOL_TO (stx, tmp, QSE_T("Smalltalk")); + /* Smalltalk at: #Smalltalk put: stx->ref.sysdic */ + ADD_TO_SYSDIC (stx, tmp, stx->ref.sysdic); + + NEW_SYMBOL_TO (stx, tmp, QSE_T("SymbolTable")); + /* Smalltalk at: #SymbolTable put: stx->ref.sysdic */ + ADD_TO_SYSDIC (stx, tmp, stx->ref.symtab); + + return 0; +} + +static int make_true_and_false (qse_stx_t* stx) +{ + stx->ref.true = qse_stx_instantiate ( + stx, find_class(stx,QSE_T("True")), + QSE_NULL, QSE_NULL, 0 + ); + if (ISNIL(stx,stx->ref.true)) return -1; + + stx->ref.false = qse_stx_instantiate ( + stx, find_class(stx,QSE_T("False")), + QSE_NULL, QSE_NULL, 0 + ); + if (ISNIL(stx,stx->ref.false)) return -1; + return 0; +} + +static void filein_kernel_source (qse_stx_t* stx) +{ + class_info_t* p; + + for (p = class_info; p->name != QSE_NULL; p++) + { + /* TODO: */ + } +} int qse_stx_boot (qse_stx_t* stx) { - qse_word_t symbol_smalltalk; - qse_word_t object_meta; - - /* create a partially initialized nil object for bootstrapping */ - if (sketch_nil (stx) <= -1) goto oops; + /* create nil, true, false references */ + if (sketch_nil (stx) <= -1) return -1; /* continue intializing other key objects */ - if (sketch_key_objects (stx) <= -1) goto oops; + if (sketch_key_objects (stx) <= -1) return -1; - if (make_key_classes (stx) <= -1) goto oops; + if (make_key_classes (stx) <= -1) return -1; - if (make_intrisic_classes (stx) <= -1) goto oops; + set_class_of_more_key_objects (stx); + + if (make_intrinsic_classes (stx) <= -1) return -1; + + make_metaclass_top_hierarchy (stx); + + if (make_key_objects_accessible_by_name (stx) <= -1) return -1; + + if (make_true_and_false (stx) <= -1) return -1; return 0; - -#if 0 - /* (Object class) setSuperclass: Class */ - object_meta = QSE_STX_CLASS(stx,stx->class_object); - QSE_STX_WORD_AT(stx,object_meta,QSE_STX_METACLASS_SUPERCLASS) = stx->class_class; - /* instance class for Object is set here as it is not - * set in make_intrisic_classes */ - QSE_STX_WORD_AT(stx,object_meta,QSE_STX_METACLASS_INSTANCE_CLASS) = stx->class_object; - - /* for some fun here */ - { - qse_word_t array; - array = qse_stx_new_array (stx, 1); - QSE_STX_WORD_AT(stx,array,0) = object_meta; - QSE_STX_WORD_AT(stx,stx->class_class,QSE_STX_CLASS_SUBCLASSES) = array; - } - - /* more initialization */ - OBJCLASS(stx,stx->ref.sysdic) = stx->class_systemdictionary; - NEW_SYMBOL_TO (stx, symbol_smalltalk, QSE_T("Smalltalk")); - ADD_TO_SYSDIC (stx, symbol_smalltalk, stx->ref.sysdic); - - /* create #nil, #true, #false */ - NEW_SYMBOL_TO (stx, symbol_nil, QSE_T("nil")); - NEW_SYMBOL_TO (stx, symbol_true, QSE_T("true")); - NEW_SYMBOL_TO (stx, symbol_false, QSE_T("false")); - - /* nil setClass: UndefinedObject */ - OBJCLASS(stx,stx->ref.nil) = qse_stx_findclass (stx, QSE_T("UndefinedObject")); - /* true setClass: True */ - OBJCLASS(stx,stx->ref.true) = qse_stx_findclass (stx, QSE_T("True")); - /* fales setClass: False */ - OBJCLASS(stx,stx->ref.false) = qse_stx_findclass (stx, QSE_T("False")); - - __filein_kernel (stx); - return 0; -#endif - -oops: - return -1; } diff --git a/qse/lib/stx/cls.c b/qse/lib/stx/cls.c index 1603e406..45629e61 100644 --- a/qse/lib/stx/cls.c +++ b/qse/lib/stx/cls.c @@ -1,66 +1,9 @@ /* - * $Id: class.c 118 2008-03-03 11:21:33Z baconevi $ + * $Id$ */ #include "stx.h" -qse_word_t qse_stx_newclass (qse_stx_t* stx, const qse_char_t* name) -{ - qse_word_t meta, class; - qse_word_t class_name; - - QSE_ASSERT (REFISIDX(stx,stx->ref.class_metaclass)); - - meta = qse_stx_allocwordobj ( - stx, QSE_NULL, QSE_STX_METACLASS_SIZE, QSE_NULL, 0); - if (meta == stx->ref.nil) return stx->ref.nil; - OBJCLASS(stx,meta) = stx->ref.class_metaclass; - - /* the spec of the metaclass must be the spec of its - * instance. so the QSE_STX_CLASS_SIZE is set */ - WORDAT(stx,meta,QSE_STX_METACLASS_SPEC) = - INTTOREF(stx,SPEC_MAKE(QSE_STX_CLASS_SIZE,SPEC_FIXED_WORD)); - - /* the spec of the class is set later in __create_builtin_classes */ - class = qse_stx_allocwordobj ( - stx, QSE_NULL, QSE_STX_CLASS_SIZE, QSE_NULL, 0); - OBJCLASS(stx,class) = meta; - - class_name = qse_stx_newsymbol (stx, name); - if (class_name == stx->ref.nil) return stx->ref.nil; - - WORDAT(stx,class,QSE_STX_CLASS_NAME) = class_name; - - return (qse_stx_putdic (stx, stx->ref.sysdic, class_name, class) == stx->ref.nil)? stx->ref.nil: class; -} - -qse_word_t qse_stx_findclass (qse_stx_t* stx, const qse_char_t* name) -{ - qse_word_t assoc, meta, value; - - /* look up the system dictionary for the name given */ - assoc = qse_stx_lookupdic (stx, stx->ref.sysdic, name); - if (assoc == stx->ref.nil) - { - /*qse_stx_seterrnum (stx, QSE_STX_ENOCLASS, QSE_NULL);*/ - return stx->ref.nil; - } - - /* get the value part in the association for the name */ - value = WORDAT(stx,assoc,QSE_STX_ASSOC_VALUE); - - /* check if its class is Metaclass because the class of - * a class object must be Metaclass. */ - meta = OBJCLASS(stx,value); - if (OBJCLASS(stx,meta) != stx->ref.class_metaclass) - { - /*qse_stx_seterrnum (stx, QSE_STX_ENOTCLASS, QSE_NULL);*/ - return stx->ref.nil; - } - - return value; -} - #if 0 int qse_stx_get_instance_variable_index ( qse_stx_t* stx, qse_word_t class_index, @@ -189,7 +132,6 @@ qse_word_t qse_stx_instantiate ( qse_word_t spec, nflds, inst; int variable; - QSE_ASSERT (REFISIDX(stx,classref)); /* don't instantiate a metaclass whose instance must be @@ -197,6 +139,7 @@ qse_word_t qse_stx_instantiate ( QSE_ASSERT (OBJCLASS(stx,classref) != stx->ref.class_metaclass); classptr = (qse_stx_class_t*)PTRBYREF(stx,classref); +qse_printf (QSE_T("instantiating ... %s\n"), ((qse_stx_charobj_t*)PTRBYREF(stx,classptr->name))->fld); QSE_ASSERT (REFISINT(stx,classptr->spec)); spec = REFTOINT(stx,classptr->spec); diff --git a/qse/lib/stx/cls.h b/qse/lib/stx/cls.h index c24b1ace..1fcd82d5 100644 --- a/qse/lib/stx/cls.h +++ b/qse/lib/stx/cls.h @@ -56,8 +56,8 @@ typedef struct qse_stx_metaclass_t qse_stx_metaclass_t; #define SPEC_VARIABLE_BYTE 0x02 #define SPEC_VARIABLE_CHAR 0x03 -#define SPEC_MAKE(fixed,variable) \ - (((fixed) << SPEC_VARIABLE_BITS) | (variable)) +#define SPEC_MAKE(nfixed,variable) \ + (((nfixed) << SPEC_VARIABLE_BITS) | (variable)) #define SPEC_GETFIXED(spec) ((spec) >> SPEC_VARIABLE_BITS) diff --git a/qse/lib/stx/dic.c b/qse/lib/stx/dic.c index d8761420..ab2b4135 100644 --- a/qse/lib/stx/dic.c +++ b/qse/lib/stx/dic.c @@ -10,15 +10,15 @@ * Dictionary, on the contrary, can accept any object as a key. */ -struct qse_stx_assoc_t +struct qse_stx_association_t { qse_stx_objhdr_t h; qse_word_t key; qse_word_t value; }; -typedef struct qse_stx_assoc_t qse_stx_assoc_t; +typedef struct qse_stx_association_t qse_stx_association_t; -struct qse_stx_dic_t +struct qse_stx_systemdictionary_t { qse_stx_objhdr_t h; qse_word_t tally; @@ -26,30 +26,46 @@ struct qse_stx_dic_t /* variable part begins here */ qse_word_t slot[1]; }; -typedef struct qse_stx_dic_t qse_stx_dic_t; +typedef struct qse_stx_systemdictionary_t qse_stx_systemdictionary_t; -static qse_word_t new_assoc ( +static qse_word_t new_association ( qse_stx_t* stx, qse_word_t key, qse_word_t value) { +#if 0 qse_word_t x; x = qse_stx_allocwordobj ( - stx, QSE_NULL, QSE_STX_ASSOC_SIZE, QSE_NULL, 0); - if (x == stx->ref.nil) return stx->ref.nil; + stx, QSE_NULL, QSE_STX_ASSOCIATION_SIZE, QSE_NULL, 0); + if (ISNIL(stx,x)) return stx->ref.nil; OBJCLASS(stx,x) = stx->ref.class_association; - WORDAT(stx,x,QSE_STX_ASSOC_KEY) = key; - WORDAT(stx,x,QSE_STX_ASSOC_VALUE) = value; + WORDAT(stx,x,QSE_STX_ASSOCIATION_KEY) = key; + WORDAT(stx,x,QSE_STX_ASSOCIATION_VALUE) = value; + return x; +#endif + + qse_word_t x; + + QSE_ASSERT (REFISIDX(stx,stx->ref.class_association)); + QSE_ASSERT (!ISNIL(stx,stx->ref.class_association)); + + x = qse_stx_instantiate ( + stx, stx->ref.class_association, QSE_NULL, QSE_NULL, 0); + if (!ISNIL(stx,x)) + { + WORDAT(stx,x,QSE_STX_ASSOCIATION_KEY) = key; + WORDAT(stx,x,QSE_STX_ASSOCIATION_VALUE) = value; + } return x; } static qse_word_t expand (qse_stx_t* stx, qse_word_t dic) { qse_word_t oldcapa, newdic, newcapa; - qse_stx_dic_t* oldptr, * newptr; + qse_stx_systemdictionary_t* oldptr, * newptr; QSE_ASSERT (REFISIDX(stx,stx->ref.class_systemdictionary)); - QSE_ASSERT (stx->ref.class_systemdictionary != stx->ref.nil); + QSE_ASSERT (!ISNIL(stx,stx->ref.class_systemdictionary)); QSE_ASSERTX ( REFISIDX(stx,dic), @@ -74,11 +90,11 @@ static qse_word_t expand (qse_stx_t* stx, qse_word_t dic) stx, OBJCLASS(stx,dic), QSE_NULL, QSE_NULL, newcapa ); - if (newdic == stx->ref.nil) return stx->ref.nil; + if (ISNIL(stx,newdic)) return stx->ref.nil; /* get object pointers for easier access without using macros */ - oldptr = (qse_stx_dic_t*)PTRBYREF(stx,dic); - newptr = (qse_stx_dic_t*)PTRBYREF(stx,newdic); + oldptr = (qse_stx_systemdictionary_t*)PTRBYREF(stx,dic); + newptr = (qse_stx_systemdictionary_t*)PTRBYREF(stx,newdic); newptr->tally = INTTOREF(stx,0); QSE_ASSERT (newcapa == OBJSIZE(stx,newdic)-1); @@ -89,12 +105,12 @@ static qse_word_t expand (qse_stx_t* stx, qse_word_t dic) qse_word_t assoc; assoc = oldptr->slot[--oldcapa]; - if (assoc != stx->ref.nil) + if (!ISNIL(stx,assoc)) { qse_word_t index; - index = qse_stx_hashobj (stx, WORDAT(stx,assoc,QSE_STX_ASSOC_KEY)) % newcapa; - while (newptr->slot[index] != stx->ref.nil) + index = qse_stx_hashobj (stx, WORDAT(stx,assoc,QSE_STX_ASSOCIATION_KEY)) % newcapa; + while (!ISNIL(stx,newptr->slot[index])) index = (index + 1) % newcapa; newptr->slot[index] = assoc; } @@ -112,13 +128,13 @@ static qse_word_t find_basic_index ( qse_stx_t* stx, qse_word_t dic, qse_word_t key) { qse_word_t capa, index; - qse_stx_dic_t* dicptr; + qse_stx_systemdictionary_t* dicptr; /* ensure that dic is a system dictionary */ QSE_ASSERT (REFISIDX(stx,dic)); QSE_ASSERT (OBJTYPE(stx,dic) == WORDOBJ); QSE_ASSERT (dic == stx->ref.sysdic || - OBJCLASS(stx,key) == stx->ref.class_systemdictionary); + OBJCLASS(stx,dic) == stx->ref.class_systemdictionary); /* ensure that the key is a symbol */ QSE_ASSERT (REFISIDX(stx,key)); @@ -128,16 +144,16 @@ static qse_word_t find_basic_index ( capa = OBJSIZE(stx,dic) - 1; /* exclude the tally field */ index = qse_stx_hashobj (stx, key) % capa; - dicptr = (qse_stx_dic_t*)PTRBYREF(stx,dic); + dicptr = (qse_stx_systemdictionary_t*)PTRBYREF(stx,dic); do { qse_word_t assoc, sym; assoc = dicptr->slot[index]; - if (assoc == stx->ref.nil) break; /* not found */ + if (ISNIL(stx,assoc)) break; /* not found */ - sym = WORDAT (stx, assoc, QSE_STX_ASSOC_KEY); + sym = WORDAT (stx, assoc, QSE_STX_ASSOCIATION_KEY); /* make sure that the key is a symbol */ QSE_ASSERT (REFISIDX(stx,sym)); @@ -163,7 +179,7 @@ qse_word_t qse_stx_lookupdic ( qse_stx_t* stx, qse_word_t dic, const qse_char_t* skey) { qse_word_t capa, index; - qse_stx_dic_t* dicptr; + qse_stx_systemdictionary_t* dicptr; QSE_ASSERT (REFISIDX(stx,dic)); QSE_ASSERT (OBJTYPE(stx,dic) == WORDOBJ); @@ -173,16 +189,16 @@ qse_word_t qse_stx_lookupdic ( capa = OBJSIZE(stx,dic) - 1; /* exclude the tally field */ index = qse_stx_hashstr (stx, skey) % capa; - dicptr = (qse_stx_dic_t*)PTRBYREF(stx,dic); + dicptr = (qse_stx_systemdictionary_t*)PTRBYREF(stx,dic); do { qse_word_t assoc, keyref; assoc = dicptr->slot[index]; - if (assoc == stx->ref.nil) break; /* not found */ + if (ISNIL(stx,assoc)) break; /* not found */ - keyref = WORDAT(stx,assoc,QSE_STX_ASSOC_KEY); + keyref = WORDAT(stx,assoc,QSE_STX_ASSOCIATION_KEY); QSE_ASSERT (REFISIDX(stx,keyref)); QSE_ASSERT (OBJCLASS(stx,keyref) == stx->ref.class_symbol); @@ -209,13 +225,13 @@ qse_word_t qse_stx_putdic ( qse_stx_t* stx, qse_word_t dic, qse_word_t key, qse_word_t value) { qse_word_t index, capa, tally, assoc; - qse_stx_dic_t* dicptr; + qse_stx_systemdictionary_t* dicptr; /* the dicionary must have at least one slot excluding tally */ QSE_ASSERT (OBJSIZE(stx,dic) > 1); capa = OBJSIZE(stx,dic) - 1; - dicptr = (qse_stx_dic_t*)PTRBYREF(stx,dic); + dicptr = (qse_stx_systemdictionary_t*)PTRBYREF(stx,dic); tally = REFTOINT(stx,dicptr->tally); index = find_basic_index (stx, dic, key) - 1; @@ -223,7 +239,7 @@ qse_word_t qse_stx_putdic ( /*assoc = WORDAT(stx,dic,slot);*/ - if (assoc == stx->ref.nil) + if (ISNIL(stx,assoc)) { /* the key is not found */ @@ -235,10 +251,10 @@ qse_word_t qse_stx_putdic ( * - make sure that lookup never enters a infinite loop. * - the slot's index can be returned when no key is found. */ - if (expand (stx, dic) == stx->ref.nil) return stx->ref.nil; + if (ISNIL(stx, expand (stx, dic))) return stx->ref.nil; capa = OBJSIZE(stx,dic) - 1; - dicptr = (qse_stx_dic_t*)PTRBYREF(stx,dic); + dicptr = (qse_stx_systemdictionary_t*)PTRBYREF(stx,dic); /* tally must remain the same after expansion */ QSE_ASSERT (tally == REFTOINT(stx,dicptr->tally)); @@ -246,11 +262,11 @@ qse_word_t qse_stx_putdic ( index = find_basic_index (stx, dic, key) - 1; /* the basic index returned must point to nil meaning * the key is not found */ - QSE_ASSERT (dicptr->slot[index] == stx->ref.nil); + QSE_ASSERT (ISNIL(stx,dicptr->slot[index])); } - assoc = new_assoc (stx, key, value); - if (assoc == stx->ref.nil) return stx->ref.nil; + assoc = new_association (stx, key, value); + if (ISNIL(stx,assoc)) return stx->ref.nil; dicptr->slot[index] = assoc; dicptr->tally = INTTOREF(stx,tally+1); @@ -258,7 +274,7 @@ qse_word_t qse_stx_putdic ( else { /* found the key. change the value */ - WORDAT(stx,assoc,QSE_STX_ASSOC_VALUE) = value; + WORDAT(stx,assoc,QSE_STX_ASSOCIATION_VALUE) = value; } return assoc; diff --git a/qse/lib/stx/dic.h b/qse/lib/stx/dic.h index ad087210..2a354728 100644 --- a/qse/lib/stx/dic.h +++ b/qse/lib/stx/dic.h @@ -5,14 +5,14 @@ #ifndef _QSE_LIB_STX_DIC_H_ #define _QSE_LIB_STX_DIC_H_ -#define QSE_STX_ASSOC_SIZE 2 -#define QSE_STX_ASSOC_KEY 0 -#define QSE_STX_ASSOC_VALUE 1 +#define QSE_STX_ASSOCIATION_SIZE 2 +#define QSE_STX_ASSOCIATION_KEY 0 +#define QSE_STX_ASSOCIATION_VALUE 1 /* The SystemDictionary is a variable word class. * The info below is for the fixed part only */ -#define QSE_STX_DIC_SIZE 1 -#define QSE_STX_DIC_TALLY 0 +#define QSE_STX_SYSTEMDICTIONARY_SIZE 1 +#define QSE_STX_SYSTEMDICTIONARY_TALLY 0 #ifdef __cplusplus extern "C" diff --git a/qse/lib/stx/dict.c b/qse/lib/stx/dict.c deleted file mode 100644 index 6df797d8..00000000 --- a/qse/lib/stx/dict.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * $Id: dict.c 118 2008-03-03 11:21:33Z baconevi $ - */ - -#include -#include -#include - -/* NOTE: - * The code here implements SystemDictionary whose key is always a symbol. - * Dictionary, on the contrary, can accept any object as a key. - */ - -qse_word_t __new_association ( - qse_stx_t* stx, qse_word_t key, qse_word_t value) -{ - qse_word_t x; - qse_word_t data[2]; - data[0] = key; - data[1] = value; - - x = qse_stx_alloc_word_object ( - stx, data, QSE_STX_ASSOCIATION_SIZE, QSE_NULL, 0); - QSE_STX_CLASS(stx,x) = stx->class_association; - return x; -} - -static qse_word_t __dict_find_slot ( - qse_stx_t* stx, qse_word_t dict, qse_word_t key) -{ - qse_word_t size, hash, index, assoc, symbol; - qse_stx_word_object_t* dict_obj; - - qse_assert (!QSE_STX_ISSMALLINT(dict) && - QSE_STX_ISWORDOBJECT(stx, dict)); - qse_assert (dict == stx->smalltalk || - qse_stx_classof(stx,dict) == stx->class_system_dictionary); - qse_assert (qse_stx_classof(stx,key) == stx->class_symbol); - - size = QSE_STX_SIZE(stx,dict); - hash = qse_stx_hash_object(stx, key); - - /* consider tally, the only instance variable of a system dictionary */ - index = hash % (size - 1) + 1; - - dict_obj = QSE_STX_WORD_OBJECT(stx,dict); - - while (1) { - assoc = dict_obj->data[index]; - if (assoc == stx->nil) break; - - symbol = QSE_STX_WORD_AT(stx,assoc,QSE_STX_ASSOCIATION_KEY); - qse_assert (qse_stx_classof(stx,symbol) == stx->class_symbol); - - /* NOTE: - * shallow comparison is enough for identity check - * because a symbol can just be a key of a system dictionary - */ - if (qse_strxncmp( - QSE_STX_DATA(stx,key), QSE_STX_SIZE(stx,key), - QSE_STX_DATA(stx,symbol), QSE_STX_SIZE(stx,symbol)) == 0) break; - - /* consider tally here too */ - index = index % (size - 1) + 1; - } - - return index; -} - -static void __grow_dict (qse_stx_t* stx, qse_word_t dict) -{ - qse_word_t new, size, index, assoc; - - /* WARNING: - * if this assertion fails, adjust the initial size of the - * system dictionary. i don't want this function to be called - * during the bootstrapping. - */ - qse_assert (stx->class_system_dictionary != stx->nil); - qse_assert (qse_stx_classof(stx,dict) == stx->class_system_dictionary); - - size = QSE_STX_SIZE(stx,dict); - new = qse_stx_instantiate (stx, - QSE_STX_CLASS(stx,dict), QSE_NULL, QSE_NULL, (size - 1) * 2); - QSE_STX_WORD_AT(stx,new,0) = QSE_STX_TO_SMALLINT(0); - - for (index = 1; index < size; index++) { - assoc = QSE_STX_WORD_AT(stx,dict,index); - if (assoc == stx->nil) continue; - - qse_stx_dict_put (stx, new, - QSE_STX_WORD_AT(stx,assoc,QSE_STX_ASSOCIATION_KEY), - QSE_STX_WORD_AT(stx,assoc,QSE_STX_ASSOCIATION_VALUE)); - } - - /* TODO: explore if dict can be immediately destroyed. */ - - qse_assert (qse_sizeof(qse_stx_object_t*) == qse_sizeof(qse_uint_t)); - - QSE_SWAP ( - QSE_STX_OBJPTR(stx,dict), - QSE_STX_OBJPTR(stx,new), - qse_stx_object_t*, - qse_uint_t - ); -} - -qse_word_t qse_stx_dict_lookup ( - qse_stx_t* stx, qse_word_t dict, const qse_char_t* key) -{ - qse_word_t size, hash, index, assoc, symbol; - qse_stx_word_object_t* dict_obj; - - qse_assert (!QSE_STX_ISSMALLINT(dict) && - QSE_STX_ISWORDOBJECT(stx, dict)); - qse_assert (dict == stx->smalltalk || - qse_stx_classof(stx,dict) == stx->class_system_dictionary); - - size = QSE_STX_SIZE(stx,dict); - hash = qse_stx_hash(key, qse_strlen(key) * qse_sizeof(qse_char_t)); - - /* consider tally, the only instance variable of a system dictionary */ - index = hash % (size - 1) + 1; - - dict_obj = QSE_STX_WORD_OBJECT(stx,dict); - - while (1) - { - assoc = dict_obj->data[index]; - if (assoc == stx->nil) break; - - symbol = QSE_STX_WORD_AT(stx,assoc,QSE_STX_ASSOCIATION_KEY); - qse_assert (qse_stx_classof(stx,symbol) == stx->class_symbol); - - if (qse_strxcmp (QSE_STX_DATA(stx,symbol), - QSE_STX_SIZE(stx,symbol), key) == 0) break; - - /* consider tally here too */ - index = index % (size - 1) + 1; - } - - return QSE_STX_WORD_AT(stx,dict,index); -} - -qse_word_t qse_stx_dict_get (qse_stx_t* stx, qse_word_t dict, qse_word_t key) -{ - return QSE_STX_WORD_AT(stx,dict,__dict_find_slot(stx, dict, key)); -} - -qse_word_t qse_stx_dict_put ( - qse_stx_t* stx, qse_word_t dict, qse_word_t key, qse_word_t value) -{ - qse_word_t slot, capa, tally, assoc; - - /* the dictionary must have at least one slot excluding tally */ - qse_assert (QSE_STX_SIZE(stx,dict) > 1); - - capa = QSE_STX_SIZE(stx,dict) - 1; - tally = QSE_STX_FROMSMALLINT(QSE_STX_WORD_AT(stx,dict,0)); - if (capa <= tally + 1) - { - __grow_dict (stx, dict); - /* refresh tally */ - tally = QSE_STX_FROMSMALLINT(QSE_STX_WORD_AT(stx,dict,0)); - } - - slot = __dict_find_slot (stx, dict, key); - - assoc = QSE_STX_WORD_AT(stx,dict,slot); - if (assoc == stx->nil) - { - QSE_STX_WORD_AT(stx,dict,slot) = - __new_association (stx, key, value); - QSE_STX_WORD_AT(stx,dict,0) = QSE_STX_TO_SMALLINT(tally + 1); - } - else QSE_STX_WORD_AT(stx,assoc,QSE_STX_ASSOCIATION_VALUE) = value; - - return QSE_STX_WORD_AT(stx,dict,slot); -} - -void qse_stx_dict_traverse ( - qse_stx_t* stx, qse_word_t dict, - void (*func) (qse_stx_t*,qse_word_t,void*), void* data) -{ - qse_word_t index, assoc; - qse_word_t size = QSE_STX_SIZE(stx,dict); - - for (index = 1; index < size; index++) { - assoc = QSE_STX_WORD_AT(stx,dict,index); - if (assoc == stx->nil) continue; - func (stx, assoc, data); - } -} - diff --git a/qse/lib/stx/dict.h b/qse/lib/stx/dict.h deleted file mode 100644 index 44f72e11..00000000 --- a/qse/lib/stx/dict.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * $Id: dict.h 118 2008-03-03 11:21:33Z baconevi $ - */ - -#ifndef _QSE_STX_DICT_H_ -#define _QSE_STX_DICT_H_ - -#include - -#define QSE_STX_ASSOCIATION_SIZE 2 -#define QSE_STX_ASSOCIATION_KEY 0 -#define QSE_STX_ASSOCIATION_VALUE 1 - -struct qse_stx_association_t -{ - qse_stx_objhdr_t header; - qse_word_t key; - qse_word_t value; -}; - -typedef struct qse_stx_association_t qse_stx_association_t; - -#ifdef __cplusplus -extern "C" -#endif - -qse_word_t qse_stx_dict_lookup ( - qse_stx_t* stx, qse_word_t dict, const qse_char_t* key); -qse_word_t qse_stx_dict_get ( - qse_stx_t* stx, qse_word_t dict, qse_word_t key); -qse_word_t qse_stx_dict_put ( - qse_stx_t* stx, qse_word_t dict, qse_word_t key, qse_word_t value); -void qse_stx_dict_traverse ( - qse_stx_t* stx, qse_word_t dict, - void (*func) (qse_stx_t*,qse_word_t,void*), void* data); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/qse/lib/stx/memory.c b/qse/lib/stx/memory.c deleted file mode 100644 index 0f9eb954..00000000 --- a/qse/lib/stx/memory.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * $Id: memory.c 118 2008-03-03 11:21:33Z baconevi $ - */ - -#include -#include - -qse_stx_memory_t* qse_stx_memory_open ( - qse_stx_memory_t* mem, qse_word_t capacity) -{ - qse_stx_object_t** slots; - qse_word_t n; - - qse_assert (capacity > 0); - if (mem == QSE_NULL) { - mem = (qse_stx_memory_t*)qse_malloc(qse_sizeof(qse_stx_memory_t)); - if (mem == QSE_NULL) return QSE_NULL; - mem->__dynamic = qse_true; - } - else mem->__dynamic = qse_false; - - slots = (qse_stx_object_t**)qse_malloc ( - capacity * qse_sizeof(qse_stx_object_t*)); - if (slots == QSE_NULL) { - if (mem->__dynamic) qse_free (mem); - mem = QSE_NULL; - } - - mem->capacity = capacity; - mem->slots = slots; - - /* weave the free slot list */ - mem->free = &slots[0]; - for (n = 0; n < capacity - 1; n++) { - mem->slots[n] = (qse_stx_object_t*)&mem->slots[n + 1]; - } - mem->slots[n] = QSE_NULL; - - return mem; -} - -void qse_stx_memory_close (qse_stx_memory_t* mem) -{ - /* TODO: free all linked objects... */ - - qse_free (mem->slots); - mem->capacity = 0; - mem->slots = QSE_NULL; - mem->free = QSE_NULL; - if (mem->__dynamic) qse_free (mem); -} - -void qse_stx_memory_gc (qse_stx_memory_t* mem) -{ - /* TODO: implement this function */ -} - -qse_word_t qse_stx_memory_alloc (qse_stx_memory_t* mem, qse_word_t nbytes) -{ - qse_stx_object_t** slot; - qse_stx_object_t* object; - - /* find the free object slot */ - if (mem->free == QSE_NULL) { - qse_stx_memory_gc (mem); - if (mem->free == QSE_NULL) return mem->capacity;; - } - - object = (qse_stx_object_t*)qse_malloc (nbytes); - if (object == QSE_NULL) { - qse_stx_memory_gc (mem); - object = (qse_stx_object_t*)qse_malloc (nbytes); - /*if (object == QSE_NULL) return mem->capacity;*/ -if (object == QSE_NULL) { -qse_assert (QSE_T("MEMORY ALLOCATION ERROR\n") == QSE_NULL); -exit (1); -} - } - - slot = mem->free; - mem->free = (qse_stx_object_t**)*slot; - *slot = object; - - return (qse_word_t)(slot - mem->slots); -} - -void qse_stx_memory_dealloc (qse_stx_memory_t* mem, qse_word_t object_index) -{ - /* - * THIS IS PRIMITIVE LOW-LEVEL DEALLOC. THIS WILL NOT - * DEALLOCATE MEMORY ALLOCATED FOR ITS INSTANCE VARIABLES. - */ - - qse_free (mem->slots[object_index]); - mem->slots[object_index] = (qse_stx_object_t*)mem->free; - mem->free = &mem->slots[object_index]; -} - diff --git a/qse/lib/stx/memory.h b/qse/lib/stx/memory.h deleted file mode 100644 index e60c2f9e..00000000 --- a/qse/lib/stx/memory.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * $Id: memory.h 118 2008-03-03 11:21:33Z baconevi $ - */ - -#ifndef _QSE_STX_MEMORY_H_ -#define _QSE_STX_MEMORY_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -qse_stx_memory_t* qse_stx_initmem ( - qse_stx_memory_t* mem, - qse_word_t capacity -); - -void qse_stx_finimem ( - qse_stx_memory_t* mem -); - -void qse_stx_gcmem ( - qse_stx_memory_t* mem -); - -qse_word_t qse_stx_alloc ( - qse_stx_memory_t* mem, qse_word_t size -); - -void qse_stx_memory_dealloc ( - qse_stx_memory_t* mem, qse_word_t object_index -); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/qse/lib/stx/parser.c b/qse/lib/stx/parser.c index 6c4d0d96..3394c09d 100644 --- a/qse/lib/stx/parser.c +++ b/qse/lib/stx/parser.c @@ -1008,39 +1008,47 @@ static int __parse_primary_ident ( *is_super = qse_false; - if (qse_strcmp(ident, QSE_T("self")) == 0) { + if (qse_strcmp(ident, QSE_T("self")) == 0) + { EMIT_CODE (parser, PUSH_RECEIVER); return 0; } - else if (qse_strcmp(ident, QSE_T("super")) == 0) { + else if (qse_strcmp(ident, QSE_T("super")) == 0) + { *is_super = qse_true; EMIT_CODE (parser, PUSH_RECEIVER); return 0; } - else if (qse_strcmp(ident, QSE_T("nil")) == 0) { + else if (qse_strcmp(ident, QSE_T("nil")) == 0) + { EMIT_CODE (parser, PUSH_NIL); return 0; } - else if (qse_strcmp(ident, QSE_T("true")) == 0) { + else if (qse_strcmp(ident, QSE_T("true")) == 0) + { EMIT_CODE (parser, PUSH_TRUE); return 0; } - else if (qse_strcmp(ident, QSE_T("false")) == 0) { + else if (qse_strcmp(ident, QSE_T("false")) == 0) + { EMIT_CODE (parser, PUSH_FALSE); return 0; } /* Refer to __parse_assignment for identifier lookup */ - for (i = 0; i < parser->temporary_count; i++) { - if (qse_strcmp(ident, parser->temporaries[i]) == 0) { + for (i = 0; i < parser->temporary_count; i++) + { + if (qse_strcmp(ident, parser->temporaries[i]) == 0) + { EMIT_PUSH_TEMPORARY_LOCATION (parser, i); return 0; } } if (qse_stx_get_instance_variable_index ( - stx, parser->method_class, ident, &i) == 0) { + stx, parser->method_class, ident, &i) == 0) + { EMIT_PUSH_RECEIVER_VARIABLE (parser, i); return 0; } @@ -1074,20 +1082,25 @@ static int __parse_block_constructor (qse_stx_parser_t* parser) * ::= ':' identifier */ - if (parser->token.type == QSE_STX_TOKEN_COLON) { - do { + if (parser->token.type == QSE_STX_TOKEN_COLON) + { + do + { GET_TOKEN (parser); - if (parser->token.type != QSE_STX_TOKEN_IDENT) { + if (parser->token.type != QSE_STX_TOKEN_IDENT) + { parser->error_code = QSE_STX_PARSER_ERROR_BLOCK_ARGUMENT_NAME; return -1; } /* TODO : store block arguments */ GET_TOKEN (parser); - } while (parser->token.type == QSE_STX_TOKEN_COLON); + } + while (parser->token.type == QSE_STX_TOKEN_COLON); - if (!__is_vbar_token(&parser->token)) { + if (!__is_vbar_token(&parser->token)) + { parser->error_code = QSE_STX_PARSER_ERROR_BLOCK_ARGUMENT_LIST; return -1; } @@ -1099,7 +1112,8 @@ static int __parse_block_constructor (qse_stx_parser_t* parser) if (__parse_temporaries(parser) == -1) return -1; if (__parse_block_statements(parser) == -1) return -1; - if (parser->token.type != QSE_STX_TOKEN_RBRACKET) { + if (parser->token.type != QSE_STX_TOKEN_RBRACKET) + { parser->error_code = QSE_STX_PARSER_ERROR_BLOCK_NOT_CLOSED; return -1; } @@ -1123,7 +1137,8 @@ static int __parse_message_continuation ( */ if (__parse_keyword_message(parser, is_super) == -1) return -1; - while (parser->token.type == QSE_STX_TOKEN_SEMICOLON) { + while (parser->token.type == QSE_STX_TOKEN_SEMICOLON) + { EMIT_CODE_TEST (parser, QSE_T("DoSpecial(DUP_RECEIVER(CASCADE))"), QSE_T("")); GET_TOKEN (parser); diff --git a/qse/lib/stx/stx.h b/qse/lib/stx/stx.h index 5ed27657..5fc0cda5 100644 --- a/qse/lib/stx/stx.h +++ b/qse/lib/stx/stx.h @@ -120,6 +120,7 @@ struct qse_stx_t qse_word_t class_association; qse_word_t class_object; + qse_word_t class_undefinedobject; qse_word_t class_class; qse_word_t class_array; qse_word_t class_bytearray; diff --git a/qse/lib/stx/sym.c b/qse/lib/stx/sym.c index 3e5547d0..23808695 100644 --- a/qse/lib/stx/sym.c +++ b/qse/lib/stx/sym.c @@ -49,7 +49,7 @@ static qse_word_t expand (qse_stx_t* stx, qse_word_t tabref) stx, OBJCLASS(stx,tabref), QSE_NULL, QSE_NULL, newcapa ); - if (ISNIL(stx,newtab)) return NIL(stx); + if (ISNIL(stx,newtab)) return stx->ref.nil; oldptr = (qse_stx_symtab_t*)PTRBYREF(stx,tabref); newptr = (qse_stx_symtab_t*)PTRBYREF(stx,newtab); @@ -91,7 +91,7 @@ static qse_word_t expand (qse_stx_t* stx, qse_word_t tabref) static qse_word_t new_symbol ( - qse_stx_t* stx, qse_word_t tabref, const qse_char_t* name) + qse_stx_t* stx, qse_word_t tabref, const qse_char_t* name, qse_size_t len) { qse_stx_symtab_t* tabptr; qse_word_t symref; @@ -135,7 +135,7 @@ static qse_word_t new_symbol ( * 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. */ - if (ISNIL (stx, expand (stx, tabref))) return NIL(stx); + if (ISNIL (stx, expand (stx, tabref))) return stx->ref.nil; /* refresh the object pointer */ tabptr = (qse_stx_symtab_t*)PTRBYREF(stx,tabref); @@ -148,7 +148,7 @@ static qse_word_t new_symbol ( QSE_ASSERT (tally == REFTOINT (stx, tabptr->tally)); } - symref = qse_stx_alloccharobj (stx, name, qse_strlen(name)); + symref = qse_stx_alloccharobj (stx, name, len); if (!ISNIL(stx,symref)) { OBJCLASS(stx,symref) = stx->ref.class_symbol; @@ -161,7 +161,12 @@ static qse_word_t new_symbol ( qse_word_t qse_stx_newsymbol (qse_stx_t* stx, const qse_char_t* name) { - return new_symbol (stx, stx->ref.symtab, name); + return new_symbol (stx, stx->ref.symtab, name, qse_strlen(name)); +} + +qse_word_t qse_stx_newsymbolx (qse_stx_t* stx, const qse_char_t* name, qse_size_t len) +{ + return new_symbol (stx, stx->ref.symtab, name, len); } #if 0 diff --git a/qse/lib/stx/sym.h b/qse/lib/stx/sym.h index e8d3d9ee..1c587118 100644 --- a/qse/lib/stx/sym.h +++ b/qse/lib/stx/sym.h @@ -19,6 +19,12 @@ qse_word_t qse_stx_newsymbol ( const qse_char_t* name ); +qse_word_t qse_stx_newsymbolx ( + qse_stx_t* stx, + const qse_char_t* name, + qse_size_t len +); + #ifdef __cplusplus } #endif diff --git a/qse/lib/stx/symbol.c b/qse/lib/stx/symbol.c deleted file mode 100644 index e6f236d1..00000000 --- a/qse/lib/stx/symbol.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * $Id: symbol.c 118 2008-03-03 11:21:33Z baconevi $ - */ - -#include -#include -#include - -static void __grow_symtab (qse_stx_t* stx) -{ - qse_word_t capa, ncapa, i, j; - qse_word_t* nspace; - - capa = stx->symtab.capacity; - ncapa = capa << 1; - - nspace = (qse_word_t*)qse_malloc(qse_sizeof(qse_word_t) * ncapa); - if (nspace == QSE_NULL) - { - /* TODO: handle memory error */ - } - - for (i = 0; i < capa; i++) - { - qse_word_t x = stx->symtab.datum[i]; - if (x == stx->nil) continue; - - j = qse_stx_strxhash ( - QSE_STX_DATA(stx,x), QSE_STX_SIZE(stx,x)) % ncapa; - - while (1) - { - if (nspace[j] == stx->nil) - { - nspace[j] = x; - break; - } - j = (j % ncapa) + 1; - } - } - - stx->symtab.capacity = ncapa; - qse_free (stx->symtab.datum); - stx->symtab.datum = nspace; -} - -qse_word_t qse_stx_new_symbol (qse_stx_t* stx, const qse_char_t* name) -{ - return qse_stx_new_symbolx (stx, name, qse_strlen(name)); -} - -qse_word_t qse_stx_new_symbolx ( - qse_stx_t* stx, const qse_char_t* name, qse_word_t len) -{ - qse_word_t capa, hash, index, size, x; - - capa = stx->symtab.capacity; - size = stx->symtab.size; - - if (capa <= size + 1) - { - __grow_symtab (stx); - capa = stx->symtab.capacity; - } - - hash = qse_stx_strxhash(name,len); - index = hash % stx->symtab.capacity; - - while (1) - { - x = stx->symtab.datum[index]; - if (x == stx->nil) - { - /* insert a new item into an empty slot */ - x = qse_stx_alloc_char_objectx (stx, name, len); - QSE_STX_CLASS(stx,x) = stx->class_symbol; - stx->symtab.datum[index] = x; - stx->symtab.size++; - break; - } - - if (qse_strxncmp(name, len, - QSE_STX_DATA(stx,x), QSE_STX_SIZE(stx,x)) == 0) break; - - index = (index % stx->symtab.capacity) + 1; - } - - return x; -} - -void qse_stx_traverse_symbol_table ( - qse_stx_t* stx, void (*func) (qse_stx_t*,qse_word_t,void*), void* data) -{ - qse_word_t index, x; - - for (index = 0; index < stx->symtab.capacity; index++) - { - x = stx->symtab.datum[index]; - if (x != stx->nil) func (stx, x, data); - } -} - diff --git a/qse/lib/stx/symbol.h b/qse/lib/stx/symbol.h deleted file mode 100644 index cc1975db..00000000 --- a/qse/lib/stx/symbol.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * $Id: symbol.h 118 2008-03-03 11:21:33Z baconevi $ - */ - -#ifndef _QSE_STX_SYMBOL_H_ -#define _QSE_STX_SYMBOL_H_ - -#include - -#define QSE_STX_SYMLINK_SIZE 2 -#define QSE_STX_SYMLINK_LINK 0 -#define QSE_STX_SYMLINK_SYMBOL 1 - -struct qse_stx_symlink_t -{ - qse_stx_objhdr_t header; - qse_word_t link; - qse_word_t symbol; -}; - -typedef struct qse_stx_symlink_t qse_stx_symlink_t; - -#ifdef __cplusplus -extern "C" { -#endif - -qse_word_t qse_stx_new_symbol_link (qse_stx_t* stx, qse_word_t sym); - -qse_word_t qse_stx_new_symbol ( - qse_stx_t* stx, const qse_char_t* name); -qse_word_t qse_stx_new_symbolx ( - qse_stx_t* stx, const qse_char_t* name, qse_word_t len); -void qse_stx_traverse_symbol_table ( - qse_stx_t* stx, void (*func) (qse_stx_t*,qse_word_t,void*), void* data); - -#ifdef __cplusplus -} -#endif - -#endif