]> gitweb.factorcode.org Git - factor.git/commitdiff
hashtables bootstrap correctly
authorSlava Pestov <slava@factorcode.org>
Fri, 28 Jan 2005 01:06:10 +0000 (01:06 +0000)
committerSlava Pestov <slava@factorcode.org>
Fri, 28 Jan 2005 01:06:10 +0000 (01:06 +0000)
26 files changed:
Makefile
library/arrays.factor
library/bootstrap/image.factor
library/bootstrap/primitives.factor
library/generic/traits.factor
library/hashtables.factor
library/namespaces.factor
library/primitives.factor
library/test/hashtables.factor
library/test/vectors.factor
library/vectors.factor
native/array.c
native/array.h
native/factor.h
native/gc.c
native/gc.h
native/hashtable.c [new file with mode: 0644]
native/hashtable.h [new file with mode: 0644]
native/primitives.c
native/relocate.c
native/s48_bignumint.h
native/stack.c
native/types.c
native/types.h
native/vector.c
native/vector.h

index 879eca23bcc6705dd556c2584f978adee0f2ad28..76102d6865312c2bfa07ccceffe6a3bc6d9e088b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -24,7 +24,8 @@ OBJS = native/arithmetic.o native/array.o native/bignum.o \
        native/unix/read.o \
        native/unix/write.o \
        native/unix/ffi.o \
-       native/debug.o
+       native/debug.o \
+       native/hashtable.o
 
 default:
        @echo "Run 'make' with one of the following parameters:"
index 3026f58f4cbdc27570da18af59b73a15eaecc375..0e052d9b7c3c30efd8e776d1747085e1591055b0 100644 (file)
@@ -29,6 +29,7 @@ IN: kernel-internals
 USE: generic
 USE: math-internals
 USE: kernel
+USE: lists
 
 ! An array is a range of memory storing pointers to other
 ! objects. Arrays are not used directly, and their access words
@@ -42,7 +43,7 @@ USE: kernel
 
 BUILTIN: array 8
 
-: array-capacity   ( array -- n )   1 integer-slot ; inline
+: array-capacity   ( array -- n )   1 slot ; inline
 : vector-array     ( vec -- array ) 2 slot ; inline
 : set-vector-array ( array vec -- ) 2 set-slot ; inline
 
@@ -51,3 +52,14 @@ BUILTIN: array 8
 
 : set-array-nth ( obj n array -- )
     swap 2 fixnum+ set-slot ; inline
+
+: (array>list) ( n i array -- list )
+    pick pick fixnum<= [
+        3drop [ ]
+    ] [
+        2dup array-nth >r >r 1 fixnum+ r> (array>list) r>
+        swap cons
+    ] ifte ;
+
+: array>list ( n array -- list )
+    0 swap (array>list) ;
index 9b4e47857b54b978a64e5793303a91f643cb941d..3115837abc5200433ce82a272e860feacafe8e4b 100644 (file)
@@ -41,6 +41,7 @@
 IN: image
 USE: errors
 USE: generic
+USE: kernel-internals
 USE: hashtables
 USE: kernel
 USE: lists
@@ -86,12 +87,12 @@ SYMBOL: boot-quot
 : cons-tag    BIN: 010 ; inline
 : object-tag  BIN: 011 ; inline
 
-: f-type      6  ; inline
-: t-type      7  ; inline
-: array-type  8  ; inline
-: vector-type 11 ; inline
-: string-type 12 ; inline
-: word-type   17 ; inline
+: t-type         7  ; inline
+: array-type     8  ; inline
+: hashtable-type 10 ; inline
+: vector-type    11 ; inline
+: string-type    12 ; inline
+: word-type      17 ; inline
 
 : immediate ( x tag -- tagged ) swap tag-bits shift bitor ;
 : >header ( id -- tagged ) object-tag immediate ;
@@ -142,6 +143,8 @@ GENERIC: ' ( obj -- ptr )
 
 ( Fixnums )
 
+: emit-fixnum ( n -- ) fixnum-tag immediate emit ;
+
 M: fixnum ' ( n -- tagged ) fixnum-tag immediate ;
 
 ( Bignums )
@@ -154,7 +157,7 @@ M: bignum ' ( bignum -- tagged )
         [[ 0  [ 1 0   ] ]]
         [[ -1 [ 2 1 1 ] ]]
         [[ 1  [ 2 0 1 ] ]]
-    ] assoc [ emit ] each align-here r> ;
+    ] assoc unswons emit-fixnum [ emit ] each align-here r> ;
 
 ( Special objects )
 
@@ -175,7 +178,7 @@ M: f ' ( obj -- ptr )
 : -1, -1 >bignum ' drop ;
 
 ( Beginning of the image )
-! The image proper begins with the header, then T,
+! The image begins with the header, then T,
 ! and the bignums 0, 1, and -1.
 
 : begin ( -- ) header t, 0, 1, -1, ;
@@ -249,7 +252,7 @@ M: cons ' ( c -- tagged )
     object-tag here-as swap
     string-type >header emit
     dup str-length emit
-    dup hashcode fixnum-tag immediate emit
+    dup hashcode emit-fixnum
     pack-string
     align-here ;
 
@@ -266,7 +269,7 @@ M: string ' ( string -- pointer )
     [ ' ] map
     object-tag here-as >r
     array-type >header emit
-    dup length emit
+    dup length emit-fixnum
     ( elements -- ) [ emit ] each
     align-here r> ;
 
@@ -274,7 +277,7 @@ M: string ' ( string -- pointer )
     dup vector>list emit-array swap vector-length
     object-tag here-as >r
     vector-type >header emit
-    emit ( length )
+    emit-fixnum ( length )
     emit ( array ptr )
     align-here r> ;
 
@@ -284,24 +287,30 @@ M: vector ' ( vector -- pointer )
 : rehash ( hashtable -- )
     ! Now make a rehashing boot quotation
     dup hash>alist [
-        >r dup vector-length [
-            [ f swap pick set-vector-nth ] keep
-        ] repeat r>
+        over hash-clear
         [ unswons rot set-hash ] each-with
     ] cons cons
     boot-quot [ append ] change ;
 
+: emit-hashtable ( hash -- pointer )
+    dup buckets>list emit-array swap hash-size
+    object-tag here-as >r
+    hashtable-type >header emit
+    emit-fixnum ( length )
+    emit ( array ptr )
+    align-here r> ;
+
 M: hashtable ' ( hashtable -- pointer )
     #! Only hashtables are pooled, not vectors!
     dup pooled-object [
-        [ dup emit-vector [ pool-object ] keep ] keep rehash
+        [ dup emit-hashtable [ pool-object ] keep ] keep rehash
     ] ?unless ;
 
 ( End of the image )
 
 : vocabularies, ( vocabularies -- )
     [
-        cdr dup vector? [
+        cdr dup hashtable? [
             [
                 cdr dup word? [ word, ] [ drop ] ifte
             ] hash-each
index 0b45a454ae93f2bf4cff7d45b18d44486338d033..8484cc844abdc730b2aebc58f05d05bc9d9595da 100644 (file)
@@ -218,11 +218,14 @@ vocabularies get [
     [[ "vectors" ">vector" ]]
     [[ "strings" ">string" ]]
     [[ "words" ">word" ]]
+    [[ "hashtables" ">hashtable" ]]
     [[ "kernel-internals" "slot" ]]
     [[ "kernel-internals" "set-slot" ]]
     [[ "kernel-internals" "integer-slot" ]]
     [[ "kernel-internals" "set-integer-slot" ]]
     [[ "kernel-internals" "grow-array" ]]
+    [[ "hashtables" "<hashtable>" ]]
+    [[ "kernel-internals" "<array>" ]]
 ] [
     unswons create swap 1 + [ f define ] keep
 ] each drop
index 3240fb16f0433cdb437ba8c61ad168bdefad4e15..2bafb8053cdb3df83a8f72703602822246013a31 100644 (file)
@@ -39,7 +39,7 @@ USE: vectors
 ! Traits metaclass for user-defined classes based on hashtables
 
 : traits ( object -- symbol )
-    dup vector? [ \ traits swap hash ] [ drop f ] ifte ;
+    dup hashtable? [ \ traits swap hash ] [ drop f ] ifte ;
 
 ! Hashtable slot holding an optional delegate. Any undefined
 ! methods are called on the delegate. The object can also
@@ -58,7 +58,7 @@ SYMBOL: delegate
     ] ifte ;
 
 : add-traits-dispatch ( word vtable -- )
-    >r unit [ car traits-dispatch call ] cons \ vector r>
+    >r unit [ car traits-dispatch call ] cons \ hashtable r>
     set-vtable ;
 
 \ traits [
index 9750f2430e316463c76e9041454601d3be113e2c..1bcc3fe9d1c85362bfa514d47de6a2fc539ae761 100644 (file)
 ! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-IN: kernel-internals
+IN: hashtables
 USE: generic
 USE: kernel
 USE: lists
 USE: math
 USE: vectors
 
-: hash-array vector-array ; inline
-: bucket-count >vector hash-array array-capacity ; inline
+BUILTIN: hashtable 10
+
+! A hashtable is implemented as an array of buckets. The
+! array index is determined using a hash function, and the
+! buckets are associative lists which are searched
+! linearly.
+
+IN: kernel-internals
+
+: hash-array 2 slot ; inline
 
 : hash-bucket ( n hash -- alist )
-    swap >fixnum swap >vector hash-array array-nth ; inline
+    swap >fixnum swap >hashtable hash-array array-nth ; inline
 
 : set-hash-bucket ( obj n hash -- )
-    >r >fixnum r> hash-array set-array-nth ; inline
+    swap >fixnum swap >hashtable hash-array set-array-nth ;
+    inline
 
-IN: hashtables
+: hash-size+ ( hash -- )
+    >hashtable dup 1 slot 1 + swap 1 set-slot ; inline
+
+: hash-size- ( hash -- )
+    >hashtable dup 1 slot 1 - swap 1 set-slot ; inline
 
-! Note that the length of a hashtable vector must not change
-! for the lifetime of the hashtable, otherwise problems will
-! occur. Do not use vector words with hashtables.
+IN: hashtables
 
-PREDICATE: vector hashtable ( obj -- ? )
-    [ assoc? ] vector-all? ;
+: hash-size ( hash -- n )
+    #! Number of elements in the hashtable.
+    >hashtable 1 slot ;
 
-: <hashtable> ( buckets -- )
-    #! A hashtable is implemented as an array of buckets. The
-    #! array index is determined using a hash function, and the
-    #! buckets are associative lists which are searched
-    #! linearly. The number of buckets must be a power of two.
-    empty-vector ;
+: bucket-count ( hash -- n )
+    >hashtable hash-array array-capacity ; inline
 
 : (hashcode) ( key table -- index )
     #! Compute the index of the bucket for a key.
@@ -74,6 +82,8 @@ PREDICATE: vector hashtable ( obj -- ? )
 
 : set-hash* ( key table quot -- )
     #! Apply the quotation to yield a new association list.
+    #! If the association list already contains the key,
+    #! decrement the hash size, since it will get removed.
     >r
         2dup (hashcode)
     r> pick >r
@@ -86,27 +96,46 @@ PREDICATE: vector hashtable ( obj -- ? )
     #! Store the value in the hashtable. Either replaces an
     #! existing value in the appropriate bucket, or adds a new
     #! key/value pair.
+    dup hash-size+
     [ set-assoc ] set-hash* ;
 
 : remove-hash ( key table -- )
     #! Remove a value from a hashtable.
     [ remove-assoc ] set-hash* ;
 
-: hash-each ( hash code -- )
-    #! Apply the code to each key/value pair of the hashtable.
-    swap [ swap dup >r each r> ] vector-each drop ; inline
+: hash-clear ( hash -- )
+    #! Remove all entries from a hashtable.
+    dup bucket-count [
+        [ f swap pick set-hash-bucket ] keep
+    ] repeat drop ;
+
+: buckets>list ( hash -- list )
+    #! Push a list of key/value pairs in a hashtable.
+    dup bucket-count swap hash-array array>list ;
+
+: (hash>alist) ( alist n hash -- alist )
+    2dup bucket-count >= [
+        2drop
+    ] [
+        [ hash-bucket [ swons ] each ] 2keep
+        >r 1 + r> (hash>alist)
+    ] ifte ;
+
+: hash>alist ( hash -- alist )
+    #! Push a list of key/value pairs in a hashtable.
+    [ ] 0 rot (hash>alist) ;
+
+: alist>hash ( alist -- hash )
+    dup length <hashtable> swap [ unswons pick set-hash ] each ;
 
 : hash-keys ( hash -- list )
     #! Push a list of keys in a hashtable.
-    [ ] swap [ car swons ] hash-each ;
+    hash>alist [ car ] map ;
 
 : hash-values ( hash -- alist )
     #! Push a list of values in a hashtable.
-    [ ] swap [ cdr swons ] hash-each ;
+    hash>alist [ cdr ] map ;
 
-: hash>alist ( hash -- list )
-    #! Push a list of key/value pairs in a hashtable.
-    [ ] swap [ swons ] hash-each ;
-
-: alist>hash ( alist -- hash )
-    37 <hashtable> swap [ unswons pick set-hash ] each ;
+: hash-each ( hash code -- )
+    #! Apply the code to each key/value pair of the hashtable.
+    >r hash>alist r> each ; inline
index 362f0f3754643eb2c77ee83eb683f30127e6bb54..32cad49a1a76e0799ec2b99d77deb2fb77ae741d 100644 (file)
@@ -61,7 +61,7 @@ USE: math
 
 : >n ( namespace -- n:namespace )
     #! Push a namespace on the namespace stack.
-    >vector namestack cons set-namestack ; inline
+    >hashtable namestack cons set-namestack ; inline
 
 : n> ( n:namespace -- namespace )
     #! Pop the top of the namespace stack.
index 14fe6e7421f4de18ec170cd3daa4cac62721e302..d0484b0f98719cce32906ae4d66017880aac0a87 100644 (file)
@@ -26,6 +26,7 @@
 ! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 IN: alien
+USE: hashtables
 DEFER: alien
 DEFER: dll
 
@@ -215,12 +216,15 @@ USE: words
     [ >cons                  [ [ object ] [ cons ] ] ]
     [ >vector                [ [ object ] [ vector ] ] ]
     [ >string                [ [ object ] [ string ] ] ]
-    [ >word                  [ [ word ] [ word ] ] ]
+    [ >word                  [ [ object ] [ word ] ] ]
+    [ >hashtable             [ [ object ] [ hashtable ] ] ]
     [ slot                   [ [ object fixnum ] [ object ] ] ]
     [ set-slot               [ [ object object fixnum ] [ ] ] ]
     [ integer-slot           [ [ object fixnum ] [ integer ] ] ]
     [ set-integer-slot       [ [ integer object fixnum ] [ ] ] ]
     [ grow-array             [ [ integer array ] [ object ] ] ]
+    [ <hashtable>            [ [ number ] [ hashtable ] ] ]
+    [ <array>                [ [ number ] [ array ] ] ]
 ] [
     2unlist dup string? [
         "stack-effect" set-word-property
index 77cf386e866f7c85489a3c077c211b6831f8be5d..37e74d53d7d280c8b90e612d8e8b1f7d3c835c4e 100644 (file)
@@ -58,3 +58,17 @@ f 100000000000000000000000000 "testhash" get set-hash
     "visual basic" "testhash" get remove-hash
     "visual basic" "testhash" get hash*
 ] unit-test
+
+[ 4 ] [
+    "hey"
+    {{ [[ "hey" 4 ]] [[ "whey" 5 ]] }} 2dup (hashcode)
+    >r buckets>list r> [ cdr ] times car assoc
+] unit-test
+
+! Testing the hash element counting
+
+<namespace> "counting" set
+"key" "value" "counting" get set-hash
+[ 1 ] [ "counting" get hash-size ] unit-test
+"key" "value" "counting" get set-hash
+[ 1 ] [ "counting" get hash-size ] unit-test
index 8a8afb976ca5db4eaf5394723de437528a9fc782..d55b1fe1687b2a34d81fadba4da8a2484d8b0b2e 100644 (file)
@@ -78,7 +78,7 @@ unit-test
 [ "funky" ] [ "funny-stack" get vector-pop ] unit-test
 
 [ t ] [
-    10 <vector> dup vector-array array-capacity
+    { 1 2 3 4 } dup vector-array array-capacity
     >r vector-clone vector-array array-capacity r>
     =
 ] unit-test
index 48f149c7ad88592bf23432bfea4e988b249f7089..57124a65cd3a1ca6c4de4c8ffd71192ffa6545bd 100644 (file)
@@ -36,11 +36,11 @@ USE: math-internals
 
 BUILTIN: vector 11
 
-: vector-length ( vec -- len ) >vector 1 integer-slot ; inline
+: vector-length ( vec -- len ) >vector 1 slot ; inline
 
 IN: kernel-internals
 
-: (set-vector-length) ( len vec -- ) 1 set-integer-slot ; inline
+: (set-vector-length) ( len vec -- ) 1 set-slot ; inline
 
 : assert-positive ( fx -- )
     0 fixnum<
@@ -107,15 +107,8 @@ IN: vectors
 : >pop> ( stack -- stack )
     dup vector-pop drop ;
 
-: (vector>list) ( i vec -- list )
-    2dup vector-length >= [
-        2drop [ ]
-    ] [
-        2dup vector-nth >r >r 1 + r> (vector>list) r> swons
-    ] ifte ;
-
-: vector>list ( str -- list )
-    0 swap (vector>list) ;
+: vector>list ( vec -- list )
+    dup vector-length swap vector-array array>list ;
 
 : vector-each ( vector quotation -- )
     #! Execute the quotation with each element of the vector
index 2531fa9754b90d3e124498da9ccdf3e952a6a722..191d234470f8c01c1d7fa2f440c2d035cdda3cae 100644 (file)
@@ -5,7 +5,7 @@ F_ARRAY* allot_array(CELL type, CELL capacity)
 {
        F_ARRAY* array;
        array = allot_object(type,sizeof(F_ARRAY) + capacity * CELLS);
-       array->capacity = capacity;
+       array->capacity = tag_fixnum(capacity);
        return array;
 }
 
@@ -22,20 +22,30 @@ F_ARRAY* array(CELL capacity, CELL fill)
        return array;
 }
 
+void primitive_array(void)
+{
+       F_FIXNUM capacity = to_fixnum(dpop());
+       if(capacity < 0)
+               general_error(ERROR_NEGATIVE_ARRAY_SIZE,tag_fixnum(capacity));
+       maybe_garbage_collection();
+       dpush(tag_object(array(capacity,F)));
+}
+
 F_ARRAY* grow_array(F_ARRAY* array, CELL capacity, CELL fill)
 {
        /* later on, do an optimization: if end of array is here, just grow */
        int i;
        F_ARRAY* new_array;
+       CELL curr_cap = untag_fixnum_fast(array->capacity);
 
-       if(array->capacity >= capacity)
+       if(curr_cap >= capacity)
                return array;
 
        new_array = allot_array(untag_header(array->header),capacity);
 
        memcpy(new_array + 1,array + 1,array->capacity * CELLS);
 
-       for(i = array->capacity; i < capacity; i++)
+       for(i = curr_cap; i < capacity; i++)
                put(AREF(new_array,i),fill);
 
        return new_array;
@@ -43,8 +53,11 @@ F_ARRAY* grow_array(F_ARRAY* array, CELL capacity, CELL fill)
 
 void primitive_grow_array(void)
 {
-       F_ARRAY* array = untag_array(dpop());
-       CELL capacity = to_fixnum(dpop());
+       F_ARRAY* array;
+       CELL capacity;
+       maybe_garbage_collection();
+       array = untag_array(dpop());
+       capacity = to_fixnum(dpop());
        dpush(tag_object(grow_array(array,capacity,F)));
 }
 
@@ -58,13 +71,15 @@ F_ARRAY* shrink_array(F_ARRAY* array, CELL capacity)
 void fixup_array(F_ARRAY* array)
 {
        int i = 0;
-       for(i = 0; i < array->capacity; i++)
+       CELL capacity = untag_fixnum_fast(array->capacity);
+       for(i = 0; i < capacity; i++)
                data_fixup((void*)AREF(array,i));
 }
 
 void collect_array(F_ARRAY* array)
 {
        int i = 0;
-       for(i = 0; i < array->capacity; i++)
+       CELL capacity = untag_fixnum_fast(array->capacity);
+       for(i = 0; i < capacity; i++)
                copy_object((void*)AREF(array,i));
 }
index acc77a099177a787c2cc7dce327c95661ffcac70..28d71a4b4134648f2839b7582078d56d8050fc4f 100644 (file)
@@ -1,17 +1,18 @@
 typedef struct {
        CELL header;
-       /* untagged */
+       /* tagged */
        CELL capacity;
 } F_ARRAY;
 
 INLINE F_ARRAY* untag_array(CELL tagged)
 {
-       /* type_check(ARRAY_TYPE,tagged); */
-       return (F_ARRAY*)UNTAG(tagged); /* FIXME */
+       type_check(ARRAY_TYPE,tagged);
+       return (F_ARRAY*)UNTAG(tagged);
 }
 
 F_ARRAY* allot_array(CELL type, CELL capacity);
 F_ARRAY* array(CELL capacity, CELL fill);
+void primitive_array(void);
 F_ARRAY* grow_array(F_ARRAY* array, CELL capacity, CELL fill);
 void primitive_grow_array(void);
 F_ARRAY* shrink_array(F_ARRAY* array, CELL capacity);
@@ -19,7 +20,7 @@ F_ARRAY* shrink_array(F_ARRAY* array, CELL capacity);
 #define AREF(array,index) ((CELL)(array) + sizeof(F_ARRAY) + (index) * CELLS)
 
 #define ASIZE(pointer) align8(sizeof(F_ARRAY) + \
-       ((F_ARRAY*)(pointer))->capacity * CELLS)
+       untag_fixnum_fast(((F_ARRAY*)(pointer))->capacity) * CELLS)
 
 void fixup_array(F_ARRAY* array);
 void collect_array(F_ARRAY* array);
index 2c1d399f407eeaa4363704e36a23d5b310c92fff..49f7ed2a60170fe1e2b1d1ddf82db764015948d9 100644 (file)
@@ -135,6 +135,7 @@ typedef unsigned char BYTE;
 #include "image.h"
 #include "primitives.h"
 #include "vector.h"
+#include "hashtable.h"
 #include "stack.h"
 #include "compiler.h"
 #include "relocate.h"
index b075429cada40de63389b4b02ba057a76f8ed3b8..5e2c880970ad64d950d028402d1f87ca4c91678e 100644 (file)
@@ -71,6 +71,9 @@ INLINE void collect_object(CELL scan)
        case ARRAY_TYPE:
                collect_array((F_ARRAY*)scan);
                break;
+       case HASHTABLE_TYPE:
+               collect_hashtable((F_HASHTABLE*)scan);
+               break;
        case VECTOR_TYPE:
                collect_vector((F_VECTOR*)scan);
                break;
index 50664383fb302d41cb2e130effef6d20b0da3210..1c03e41e489c935833149326e424b5b4f7f56584 100644 (file)
@@ -27,6 +27,9 @@ INLINE void copy_object(CELL* handle)
        if(tag == FIXNUM_TYPE)
                return;
 
+       if(headerp(pointer))
+               critical_error("Asked to copy header",pointer);
+
        header = get(UNTAG(pointer));
        if(TAG(header) == GC_COLLECTED)
                newpointer = UNTAG(header);
diff --git a/native/hashtable.c b/native/hashtable.c
new file mode 100644 (file)
index 0000000..cb27bd4
--- /dev/null
@@ -0,0 +1,33 @@
+#include "factor.h"
+
+F_HASHTABLE* hashtable(F_FIXNUM capacity)
+{
+       F_HASHTABLE* hash;
+       if(capacity < 0)
+               general_error(ERROR_NEGATIVE_ARRAY_SIZE,tag_fixnum(capacity));
+       hash = allot_object(HASHTABLE_TYPE,sizeof(F_VECTOR));
+       hash->count = tag_fixnum(0);
+       hash->array = tag_object(array(capacity,F));
+       return hash;
+}
+
+void primitive_hashtable(void)
+{
+       maybe_garbage_collection();
+       drepl(tag_object(hashtable(to_fixnum(dpeek()))));
+}
+
+void primitive_to_hashtable(void)
+{
+       type_check(HASHTABLE_TYPE,dpeek());
+}
+
+void fixup_hashtable(F_HASHTABLE* hashtable)
+{
+       data_fixup(&hashtable->array);
+}
+
+void collect_hashtable(F_HASHTABLE* hashtable)
+{
+       copy_object(&hashtable->array);
+}
diff --git a/native/hashtable.h b/native/hashtable.h
new file mode 100644 (file)
index 0000000..e464b2c
--- /dev/null
@@ -0,0 +1,15 @@
+typedef struct {
+       /* always tag_header(HASHTABLE_TYPE) */
+       CELL header;
+       /* tagged */
+       CELL count;
+       /* tagged */
+       CELL array;
+} F_HASHTABLE;
+
+F_HASHTABLE* hashtable(F_FIXNUM capacity);
+
+void primitive_hashtable(void);
+void primitive_to_hashtable(void);
+void fixup_hashtable(F_HASHTABLE* hashtable);
+void collect_hashtable(F_HASHTABLE* hashtable);
index 07dd50f0343da06d3d3872387624f095453b4cee..bf0723d7a9140bf4df3c517005bcb94cebc3f7d4 100644 (file)
@@ -168,11 +168,14 @@ void* primitives[] = {
        primitive_to_vector,
        primitive_to_string,
        primitive_to_word,
+       primitive_to_hashtable,
        primitive_slot,
        primitive_set_slot,
        primitive_integer_slot,
        primitive_set_integer_slot,
-       primitive_grow_array
+       primitive_grow_array,
+       primitive_hashtable,
+       primitive_array
 };
 
 CELL primitive_to_xt(CELL primitive)
index 62052431281195b1dbe146aa153777a396a4db53..c6dfd0e73b935ea3ba863e8012cedee98a0c63bb 100644 (file)
@@ -10,6 +10,9 @@ void relocate_object(CELL relocating)
        case ARRAY_TYPE:
                fixup_array((F_ARRAY*)relocating);
                break;
+       case HASHTABLE_TYPE:
+               fixup_hashtable((F_HASHTABLE*)relocating);
+               break;
        case VECTOR_TYPE:
                fixup_vector((F_VECTOR*)relocating);
                break;
index 3150b1bf7ae3460a15721190b3ec0fc26afe9994..5ce1f95059daef6f41a2100e087d886fec4fce6d 100644 (file)
@@ -83,7 +83,7 @@ typedef long bignum_length_type;
 #define BIGNUM_START_PTR(bignum)                                       \
   ((BIGNUM_TO_POINTER (bignum)) + 1)
 
-#define BIGNUM_LENGTH(bignum) ((bignum)->capacity - 1)
+#define BIGNUM_LENGTH(bignum) (untag_fixnum_fast((bignum)->capacity) - 1)
 
 #define BIGNUM_NEGATIVE_P(bignum) (get(AREF(bignum,0)) != 0)
 #define BIGNUM_SET_NEGATIVE_P(bignum,neg) put(AREF(bignum,0),neg)
index 8e89917dd1c69538d5b0081420fea0230c1e2e1f..66d32c067867b7b8621754c5e91828d7eabf6ed6 100644 (file)
@@ -81,7 +81,7 @@ F_VECTOR* stack_to_vector(CELL bottom, CELL top)
        F_VECTOR* v = vector(depth);
        F_ARRAY* a = untag_array(v->array);
        memcpy(a + 1,(void*)bottom,depth * CELLS);
-       v->top = depth;
+       v->top = tag_fixnum(depth);
        return v;
 }
 
@@ -101,7 +101,7 @@ void primitive_callstack(void)
 CELL vector_to_stack(F_VECTOR* vector, CELL bottom)
 {
        CELL start = bottom;
-       CELL len = vector->top * CELLS;
+       CELL len = untag_fixnum_fast(vector->top) * CELLS;
        memcpy((void*)start,untag_array(vector->array) + 1,len);
        return start + len - CELLS;
 }
index cc81333e63c3b83b8ae88216b3500ea74e4e9f52..a4048d22ed2b64d460943024d5079b8491e52531 100644 (file)
@@ -55,6 +55,9 @@ CELL untagged_object_size(CELL pointer)
        case BIGNUM_TYPE:
                size = ASIZE(pointer);
                break;
+       case HASHTABLE_TYPE:
+               size = sizeof(F_HASHTABLE);
+               break;
        case VECTOR_TYPE:
                size = sizeof(F_VECTOR);
                break;
index 8dddd2165227905f2f8849924f6e056b542ccb0d..ac481e47dab5d988c1dfef6769a953ba07fd58bf 100644 (file)
@@ -27,6 +27,7 @@ CELL T;
 #define F_TYPE 9
 #define F RETAG(0,OBJECT_TYPE)
 
+#define HASHTABLE_TYPE 10
 #define VECTOR_TYPE 11
 #define STRING_TYPE 12
 #define SBUF_TYPE 13
index 2b2e4a686651648836e9058c8175b4214e0b73bf..010c1f6b58c6f6ee082a3e5c5ad5727d759ec565 100644 (file)
@@ -6,7 +6,7 @@ F_VECTOR* vector(F_FIXNUM capacity)
        if(capacity < 0)
                general_error(ERROR_NEGATIVE_ARRAY_SIZE,tag_fixnum(capacity));
        vector = allot_object(VECTOR_TYPE,sizeof(F_VECTOR));
-       vector->top = 0;
+       vector->top = tag_fixnum(0);
        vector->array = tag_object(array(capacity,F));
        return vector;
 }
index cffc5a7ff404906aad37671acd5849c13dfbb758..8f0eb5a9ba22f7b76d58cf4a0b7c9685cf2e9945 100644 (file)
@@ -1,7 +1,7 @@
 typedef struct {
        /* always tag_header(VECTOR_TYPE) */
        CELL header;
-       /* untagged */
+       /* tagged */
        CELL top;
        /* tagged */
        CELL array;