]> gitweb.factorcode.org Git - factor.git/commitdiff
fix various memory corruption issues
authorSlava Pestov <slava@factorcode.org>
Fri, 27 Aug 2004 06:09:24 +0000 (06:09 +0000)
committerSlava Pestov <slava@factorcode.org>
Fri, 27 Aug 2004 06:09:24 +0000 (06:09 +0000)
22 files changed:
README.txt [new file with mode: 0644]
TODO.FACTOR.txt
library/platform/native/debugger.factor
library/test/crashes.factor
library/test/strings.factor
native/arithmetic.c
native/arithmetic.h
native/array.c
native/array.h
native/bignum.c
native/error.h
native/factor.h
native/fixnum.c
native/fixnum.h
native/float.c
native/s48_bignumint.h
native/sbuf.c
native/sbuf.h
native/string.c
native/string.h
native/types.c
native/vector.c

diff --git a/README.txt b/README.txt
new file mode 100644 (file)
index 0000000..045408a
--- /dev/null
@@ -0,0 +1,108 @@
+THE CONCATENATIVE LANGUAGE FACTOR
+
+* Introduction
+
+Factor supports various data types; atomic types include numbers of various kinds, strings of characters, and booleans. Compound data types include lists consisting of cons cells, vectors, and string buffers.
+
+Factor encourages programming in a functional style where new objects are returned and input parameters remain unmodified, but does not enforce this. No manifest type declarations are necessary, and all data types use exactly one slot each on the stack (unlike, say, FORTH).
+
+The internal representation of a Factor program is a linked list. Linked lists that are to be executed are referred to as ``quotations.'' The interpreter iterates the list, executing words, and pushing all other types of objects on the data stack. A word is a unique data type because it can be executed. Words come in two varieties: primitive and compound. Primitive words have an implementation coded in the host langauge (C or Java). Compound words are executed by invoking the interpreter recursively on their definition, which is also a linked list.
+
+* Control flow
+
+Control flow rests on two basic concepts: recursion, and branching. Words with compound definitions may refer to themselves, and there is exactly one primitive for performing conditional execution:
+
+    1 10 < [ "10 is less than 1." print ] [ "whoa!" print ] ifte
+    ==> 10 is less than 1.
+
+Here is an example of a word that uses these two concepts:
+
+: contains? ( element list -- remainder )
+    #! If the proper list contains the element, push the
+    #! remainder of the list, starting from the cell whose car
+    #! is elem. Otherwise push f.
+    dup [
+        2dup car = [ nip ] [ cdr contains? ] ifte
+    ] [
+        2drop f
+    ] ifte ;
+
+An example:
+
+    3 [ 1 2 3 4 ] contains?
+    ==> [ 3 4 ]
+    5 [ 1 2 3 4 ] contains?
+    ==> f
+
+It recurses down the list, until it reaches the end, in which case the outer ifte's 'false' branch is executed.
+
+A quick overview of the words used here:
+
+Shuffle words:
+
+dup ( x -- x x )
+nip ( x y -- y )
+2dup ( x y -- x y x y )
+2drop ( x y -- )
+
+Linked list deconstruction:
+
+car ( [ x | y ] -- x )
+cdr ( [ x | y ] -- y ) - push the "tail" of a list.
+
+Equality:
+
+= ( x y -- ? )
+
+More complicated control flow constructs, such as loops and higher order functions, are usually built with the help of another primitive that simply executes a quotation at the top of the stack, removing it from the stack:
+
+    [ 2 2 + . ] call
+    ==> 4
+
+Here is an example of a word that applies a quotation to each element of a list. Note that it uses 'call' to execute the given quotation:
+
+: each ( list quotation -- )
+    #! Push each element of a proper list in turn, and apply a
+    #! quotation to each element.
+    #!
+    #! In order to compile, the quotation must consume one more
+    #! value than it produces.
+    over [
+        >r uncons r> tuck >r >r call r> r> each
+    ] [
+        2drop
+    ] ifte ;
+
+An example:
+
+    [ 1 2 3 4 ] [ dup * . ] each
+    ==> 1
+        4
+       9
+       16
+
+A quick overview of the words used here:
+
+Printing top of stack:
+
+. ( x -- ) print top of stack in a form that is valid Factor syntax.
+
+Shuffle words:
+
+over ( x y -- x y x )
+tuck ( x y -- y x y )
+>r ( x -- r:x ) - move top of data stack to/from 'extra hand'.
+r> ( r:x -- x )
+
+Writing >r foo r> is analogous to [ foo ] in Joy. Occurrences of >r and r> must be balanced within a single word definition.
+
+Linked list deconstruction:
+
+uncons ( [ x | y ] -- x y )
+
+* Variables
+
+* Continuations
+
+* Reflection
+
index 7202a609b633c8496adfd101bc6dad0a34068ea8..f8e17c1927c0d4e0e76ab767760581a8e48f9a31 100644 (file)
@@ -1,19 +1,28 @@
+upgraded_arithmetic_type -> need a trick\r
+automatic to_bignum, to_fixnum for primitives:\r
+  - upgrading only\r
+generic >fixnum, >bignum in library\r
+  - downgrading\r
+don't crash on bad prim #\r
+fixnum/string pseudo-type for error reporting\r
+to_c_string allots too much\r
+primitive_index_of & index == string->capacity\r
+\r
 + bignums:\r
 \r
 - cached 0/-1/1 should be cross compiled in image\r
 - bignum cross compiling\r
 - move some s48_ functions into bignum.c\r
 - remove unused functions\r
-- clean up type coercions in arithmetic.c\r
-- add a socket timeout\r
 \r
+- add a socket timeout\r
 - >lower, >upper for strings\r
 - telnetd should use multitasking\r
 - accept multi-line input in listener\r
 \r
 + docs:\r
 \r
-- USE: arithmetic in numbers game\r
+- USE: math in numbers game\r
 - numbers section\r
 - examples of assoc usage\r
 - unparse examples, and difference from prettyprint\r
index c2979a17fdf428b27634021496a9ad89a98eb337..0f4699ef38bb00da4b4507bd0389d288902020f8 100644 (file)
@@ -85,6 +85,9 @@ USE: vectors
 : profiling-disabled-error ( obj -- )
     drop "Recompile with the EXTRA_CALL_INFO flag." print ;
 
+: negative-array-size-error ( obj -- )
+    "Cannot allocate array with negative size " write . ;
+
 : kernel-error. ( obj n -- str )
     {
         expired-port-error
@@ -99,6 +102,7 @@ USE: vectors
         float-format-error
         signal-error
         profiling-disabled-error
+        negative-array-size-error
     } vector-nth execute ;
 
 : kernel-error? ( obj -- ? )
index d32f00ad012e17cdbbbb9fd978dbdb22b5bf0313..70f6b667973149f44b25730415c9cb9115d9458c 100644 (file)
@@ -1,11 +1,13 @@
 IN: scratchpad
 USE: errors
 USE: kernel
+USE: math
 USE: namespaces
 USE: parser
 USE: stack
 USE: strings
 USE: test
+USE: vectors
 
 ! Various things that broke CFactor at various times.
 ! This should run without issue (and tests nothing useful)
@@ -18,3 +20,15 @@ USE: test
     [ drop ] [ drop ] catch
     [ drop ] [ drop ] catch
 ] keep-datastack
+
+"hello" str>sbuf "x" set
+[ -5 "x" get set-sbuf-length ] [ drop ] catch
+"x" get sbuf>str drop
+
+10 <vector> "x" set
+[ -2 "x" get set-vector-length ] [ drop ] catch
+"x" get clone drop
+
+10 [ [ -1000000 <vector> ] [ drop ] catch ] times
+
+10 [ [ -1000000 <sbuf> ] [ drop ] catch ] times
index e564822a03ebd5d6ef8dba197d134966ddac9e7d..84909640520dca6cb54c4a6aa2528c932b857efb 100644 (file)
@@ -1,6 +1,8 @@
 IN: scratchpad
 USE: combinators
+USE: errors
 USE: kernel
+USE: logic
 USE: math
 USE: namespaces
 USE: stack
@@ -99,3 +101,5 @@ native? [
         "buf" get sbuf>str
     ] unit-test
 ] when
+
+[ f ] [ [ 0 10 "hello" substring ] [ not ] catch ] unit-test
index b52664e90db4aaaf993d0e6863bd44f281570fba..eb3b44b625e3dddd192de6cf7c692ea97a5a259d 100644 (file)
@@ -57,44 +57,6 @@ CELL upgraded_arithmetic_type(CELL type1, CELL type2)
        }
 }
 
-ARRAY* fixnum_to_bignum(CELL n)
-{
-       return s48_long_to_bignum(untag_fixnum_fast(n));
-}
-
-RATIO* fixnum_to_ratio(CELL n)
-{
-       return ratio(n,tag_fixnum(1));
-}
-
-FLOAT* fixnum_to_float(CELL n)
-{
-       return make_float((double)untag_fixnum_fast(n));
-}
-
-FIXNUM bignum_to_fixnum(CELL tagged)
-{
-       return (FIXNUM)s48_bignum_to_long(
-               (ARRAY*)UNTAG(tagged));
-}
-
-RATIO* bignum_to_ratio(CELL n)
-{
-       return ratio(n,tag_fixnum(1));
-}
-
-FLOAT* bignum_to_float(CELL tagged)
-{
-       return make_float(s48_bignum_to_double(
-               (ARRAY*)UNTAG(tagged)));
-}
-
-FLOAT* ratio_to_float(CELL tagged)
-{
-       RATIO* r = (RATIO*)UNTAG(tagged);
-       return (FLOAT*)UNTAG(divfloat(r->numerator,r->denominator));
-}
-
 bool realp(CELL tagged)
 {
        switch(type_of(tagged))
@@ -111,14 +73,10 @@ bool realp(CELL tagged)
        }
 }
 
-bool numberp(CELL tagged)
-{
-       return realp(tagged) || type_of(tagged) == COMPLEX_TYPE;
-}
-
 void primitive_numberp(void)
 {
-       drepl(tag_boolean(numberp(dpeek())));
+       CELL tagged = dpeek();
+       drepl(tag_boolean(realp(tagged) || type_of(tagged) == COMPLEX_TYPE));
 }
 
 bool zerop(CELL tagged)
index 78cf557ccd26ffa3873cd800e60ee6cd1d62bf8a..cdce0995141c16684d90e33886e70e7d45bd3dd8 100644 (file)
@@ -1,13 +1,6 @@
 #include "factor.h"
 
 CELL upgraded_arithmetic_type(CELL type1, CELL type2);
-ARRAY* fixnum_to_bignum(CELL n);
-RATIO* fixnum_to_ratio(CELL n);
-FLOAT* fixnum_to_float(CELL n);
-FIXNUM bignum_to_fixnum(CELL tagged);
-RATIO* bignum_to_ratio(CELL n);
-FLOAT* bignum_to_float(CELL n);
-FLOAT* ratio_to_float(CELL n);
 
 CELL tag_fixnum_or_bignum(FIXNUM x);
 
@@ -17,7 +10,7 @@ CELL OP(CELL x, CELL y) \
        switch(upgraded_arithmetic_type(type_of(x),type_of(y))) \
        { \
        case FIXNUM_TYPE: \
-               return OP##_fixnum(x,y); \
+               return OP##_fixnum(untag_fixnum_fast(x),untag_fixnum_fast(y)); \
        case BIGNUM_TYPE: \
                return OP##_bignum(to_bignum(x),to_bignum(y)); \
        case RATIO_TYPE: \
@@ -43,9 +36,9 @@ CELL OP(CELL x, FIXNUM y) \
        switch(type_of(x)) \
        { \
        case FIXNUM_TYPE: \
-               return OP##_fixnum(x,y); \
+               return OP##_fixnum(untag_fixnum_fast(x),y); \
        case BIGNUM_TYPE: \
-               return OP##_bignum(to_bignum(x),y); \
+               return OP##_bignum((ARRAY*)UNTAG(x),y); \
        default: \
                type_error(INTEGER_TYPE,x); \
                return F; \
@@ -92,7 +85,7 @@ CELL OP(CELL x) \
        switch(type_of(x)) \
        { \
        case FIXNUM_TYPE: \
-               return OP##_fixnum(x); \
+               return OP##_fixnum(untag_fixnum_fast(x)); \
        case RATIO_TYPE: \
                return OP##_ratio((RATIO*)UNTAG(x)); \
        case COMPLEX_TYPE: \
@@ -140,7 +133,6 @@ CELL OP##_anytype(CELL x) \
 }
 
 bool realp(CELL tagged);
-bool numberp(CELL tagged);
 void primitive_numberp(void);
 
 bool zerop(CELL tagged);
index 52491d656ff6791d012fff0e194c6526cd49bde3..80fe2a0650775940f09da0f94b67374826de973e 100644 (file)
@@ -1,15 +1,18 @@
 #include "factor.h"
 
 /* untagged */
-ARRAY* allot_array(CELL type, CELL capacity)
+ARRAY* allot_array(CELL type, FIXNUM capacity)
 {
-       ARRAY* array = allot_object(type,sizeof(ARRAY) + capacity * CELLS);
+       ARRAY* array;
+       if(capacity < 0)
+               general_error(ERROR_NEGATIVE_ARRAY_SIZE,tag_fixnum(capacity));
+       array = allot_object(type,sizeof(ARRAY) + capacity * CELLS);
        array->capacity = capacity;
        return array;
 }
 
 /* untagged */
-ARRAY* array(CELL capacity, CELL fill)
+ARRAY* array(FIXNUM capacity, CELL fill)
 {
        int i;
 
@@ -21,7 +24,7 @@ ARRAY* array(CELL capacity, CELL fill)
        return array;
 }
 
-ARRAY* grow_array(ARRAY* array, CELL capacity, CELL fill)
+ARRAY* grow_array(ARRAY* array, FIXNUM capacity, CELL fill)
 {
        /* later on, do an optimization: if end of array is here, just grow */
        int i;
@@ -36,7 +39,7 @@ ARRAY* grow_array(ARRAY* array, CELL capacity, CELL fill)
        return new_array;
 }
 
-ARRAY* shrink_array(ARRAY* array, CELL capacity)
+ARRAY* shrink_array(ARRAY* array, FIXNUM capacity)
 {
        ARRAY* new_array = allot_array(untag_header(array->header),capacity);
        memcpy(new_array + 1,array + 1,capacity * CELLS);
index 0ad56f06f570a2d3aeb7d36d73557b05082c7f7a..73bdd1ad7ef8ecdbe53a010e496050eab036a613 100644 (file)
@@ -10,15 +10,15 @@ INLINE ARRAY* untag_array(CELL tagged)
        return (ARRAY*)UNTAG(tagged);
 }
 
-ARRAY* allot_array(CELL type, CELL capacity);
-ARRAY* array(CELL capacity, CELL fill);
-ARRAY* grow_array(ARRAY* array, CELL capacity, CELL fill);
-ARRAY* shrink_array(ARRAY* array, CELL capacity);
+ARRAY* allot_array(CELL type, FIXNUM capacity);
+ARRAY* array(FIXNUM capacity, CELL fill);
+ARRAY* grow_array(ARRAY* array, FIXNUM capacity, CELL fill);
+ARRAY* shrink_array(ARRAY* array, FIXNUM capacity);
 
-#define AREF(array,index) ((CELL)array + sizeof(ARRAY) + index * CELLS)
+#define AREF(array,index) ((CELL)(array) + sizeof(ARRAY) + (index) * CELLS)
 
 #define ASIZE(pointer) align8(sizeof(ARRAY) + \
-       ((ARRAY*)pointer)->capacity * CELLS)
+       ((ARRAY*)(pointer))->capacity * CELLS)
 
 /* untagged & unchecked */
 INLINE CELL array_nth(ARRAY* array, CELL index)
index 369e0dbe610bedbdea99e5db53db80b85511d1ec..c30347b1cfee62cb87ced371542e52027e470304 100644 (file)
@@ -24,7 +24,7 @@ ARRAY* to_bignum(CELL tagged)
        switch(type_of(tagged))
        {
        case FIXNUM_TYPE:
-               return fixnum_to_bignum(tagged);
+               return s48_long_to_bignum(untag_fixnum_fast(tagged));
        case BIGNUM_TYPE:
                return (ARRAY*)UNTAG(tagged);
        case RATIO_TYPE:
index 07598157157482d35979b8c0dd7e69636d2f9924..c0d5d66f32ad4e6694759e0a5e20b2e14067d51b 100644 (file)
@@ -10,6 +10,7 @@
 #define ERROR_FLOAT_FORMAT (9<<3)
 #define ERROR_SIGNAL (10<<3)
 #define ERROR_PROFILING_DISABLED (11<<3)
+#define ERROR_NEGATIVE_ARRAY_SIZE (12<<3)
 
 void fatal_error(char* msg, CELL tagged);
 void critical_error(char* msg, CELL tagged);
index be30f7c8dc56fc80bceef33a68b0c309b5d67a5a..cb7912b7dfc57818ab9f83a7aa2fa6ec70838d38 100644 (file)
@@ -44,10 +44,10 @@ and allows profiling. */
 #include "error.h"
 #include "gc.h"
 #include "types.h"
-#include "array.h"
 #include "word.h"
 #include "run.h"
 #include "fixnum.h"
+#include "array.h"
 #include "s48_bignumint.h"
 #include "s48_bignum.h"
 #include "bignum.h"
index 02df81396b7cd3394919e226366f6816dadab6a4..2be68bd2aa3c7d0412c1f487486276d8774b636a 100644 (file)
@@ -15,7 +15,7 @@ FIXNUM to_fixnum(CELL tagged)
        case FIXNUM_TYPE:
                return untag_fixnum_fast(tagged);
        case BIGNUM_TYPE:
-               return bignum_to_fixnum(tagged);
+               return (FIXNUM)s48_bignum_to_long((ARRAY*)UNTAG(tagged));
        case RATIO_TYPE:
                r = (RATIO*)UNTAG(tagged);
                return to_fixnum(divint(r->numerator,r->denominator));
@@ -33,66 +33,48 @@ void primitive_to_fixnum(void)
        drepl(tag_fixnum(to_fixnum(dpeek())));
 }
 
-CELL number_eq_fixnum(CELL x, CELL y)
+CELL number_eq_fixnum(FIXNUM x, FIXNUM y)
 {
        return tag_boolean(x == y);
 }
 
-CELL add_fixnum(CELL x, CELL y)
+CELL add_fixnum(FIXNUM x, FIXNUM y)
 {
-       return tag_fixnum_or_bignum(untag_fixnum_fast(x)
-               + untag_fixnum_fast(y));
+       return tag_fixnum_or_bignum(x + y);
 }
 
-CELL subtract_fixnum(CELL x, CELL y)
+CELL subtract_fixnum(FIXNUM x, FIXNUM y)
 {
-       return tag_fixnum_or_bignum(untag_fixnum_fast(x)
-               - untag_fixnum_fast(y));
+       return tag_fixnum_or_bignum(x - y);
 }
 
-CELL multiply_fixnum(CELL _x, CELL _y)
+CELL multiply_fixnum(FIXNUM x, FIXNUM y)
 {
-       FIXNUM x = untag_fixnum_fast(_x);
-       FIXNUM y = untag_fixnum_fast(_y);
        long long result = (long long)x * (long long)y;
        if(result < FIXNUM_MIN || result > FIXNUM_MAX)
-       {
-               return tag_object(s48_bignum_multiply(
-                       s48_long_to_bignum(x),
-                       s48_long_to_bignum(y)));
-       }
+               return tag_object(s48_long_long_to_bignum(result));
        else
                return tag_fixnum(result);
 }
 
-CELL divint_fixnum(CELL x, CELL y)
+CELL divint_fixnum(FIXNUM x, FIXNUM y)
 {
-       /* division takes common factor of 8 out. */
-       /* we have to do SIGNED division here */
-       return tag_fixnum_or_bignum((FIXNUM)x / (FIXNUM)y);
+       return tag_fixnum_or_bignum(x / y);
 }
 
-CELL divfloat_fixnum(CELL x, CELL y)
+CELL divfloat_fixnum(FIXNUM x, FIXNUM y)
 {
-       /* division takes common factor of 8 out. */
-       /* we have to do SIGNED division here */
-       FIXNUM _x = (FIXNUM)x;
-       FIXNUM _y = (FIXNUM)y;
-       return tag_object(make_float((double)_x / (double)_y));
+       return tag_object(make_float((double)x / (double)y));
 }
 
-CELL divmod_fixnum(CELL _x, CELL _y)
+CELL divmod_fixnum(FIXNUM x, FIXNUM y)
 {
-       FIXNUM x = untag_fixnum_fast(_x);
-       FIXNUM y = untag_fixnum_fast(_y);
        dpush(tag_fixnum_or_bignum(x / y));
        return tag_fixnum_or_bignum(x % y);
 }
 
-CELL mod_fixnum(CELL _x, CELL _y)
+CELL mod_fixnum(FIXNUM x, FIXNUM y)
 {
-       FIXNUM x = untag_fixnum_fast(_x);
-       FIXNUM y = untag_fixnum_fast(_y);
        return tag_fixnum(x % y);
 }
 
@@ -123,55 +105,52 @@ FIXNUM gcd_fixnum(FIXNUM x, FIXNUM y)
        }
 }
 
-CELL divide_fixnum(CELL x, CELL y)
+CELL divide_fixnum(FIXNUM x, FIXNUM y)
 {
-       FIXNUM _x = untag_fixnum_fast(x);
-       FIXNUM _y = untag_fixnum_fast(y);
        FIXNUM gcd;
 
-       if(_y == 0)
+       if(y == 0)
                raise(SIGFPE);
-       else if(_y < 0)
+       else if(y < 0)
        {
-               _x = -_x;
-               _y = -_y;
+               x = -x;
+               y = -y;
        }
 
-       gcd = gcd_fixnum(_x,_y);
+       gcd = gcd_fixnum(x,y);
        if(gcd != 1)
        {
-               _x /= gcd;
-               _y /= gcd;
+               x /= gcd;
+               y /= gcd;
        }
 
-       if(_y == 1)
-               return tag_fixnum_or_bignum(_x);
+       if(y == 1)
+               return tag_fixnum_or_bignum(x);
        else
        {
                return tag_ratio(ratio(
-                       tag_fixnum_or_bignum(_x),
-                       tag_fixnum_or_bignum(_y)));
+                       tag_fixnum_or_bignum(x),
+                       tag_fixnum_or_bignum(y)));
        }
 }
 
-CELL and_fixnum(CELL x, CELL y)
+CELL and_fixnum(FIXNUM x, FIXNUM y)
 {
        return x & y;
 }
 
-CELL or_fixnum(CELL x, CELL y)
+CELL or_fixnum(FIXNUM x, FIXNUM y)
 {
        return x | y;
 }
 
-CELL xor_fixnum(CELL x, CELL y)
+CELL xor_fixnum(FIXNUM x, FIXNUM y)
 {
        return x ^ y;
 }
 
-CELL shift_fixnum(CELL _x, FIXNUM y)
+CELL shift_fixnum(FIXNUM x, FIXNUM y)
 {
-       FIXNUM x = untag_fixnum_fast(_x);
        if(y > -CELLS * 8 && y < CELLS * 8)
        {
                long long result = (y < 0
@@ -186,27 +165,27 @@ CELL shift_fixnum(CELL _x, FIXNUM y)
                s48_long_to_bignum(x),y));
 }
 
-CELL less_fixnum(CELL x, CELL y)
+CELL less_fixnum(FIXNUM x, FIXNUM y)
 {
-       return tag_boolean((FIXNUM)x < (FIXNUM)y);
+       return tag_boolean(x < y);
 }
 
-CELL lesseq_fixnum(CELL x, CELL y)
+CELL lesseq_fixnum(FIXNUM x, FIXNUM y)
 {
-       return tag_boolean((FIXNUM)x <= (FIXNUM)y);
+       return tag_boolean(x <= y);
 }
 
-CELL greater_fixnum(CELL x, CELL y)
+CELL greater_fixnum(FIXNUM x, FIXNUM y)
 {
-       return tag_boolean((FIXNUM)x > (FIXNUM)y);
+       return tag_boolean(x > y);
 }
 
-CELL greatereq_fixnum(CELL x, CELL y)
+CELL greatereq_fixnum(FIXNUM x, FIXNUM y)
 {
-       return tag_boolean((FIXNUM)x >= (FIXNUM)y);
+       return tag_boolean(x >= y);
 }
 
-CELL not_fixnum(CELL n)
+CELL not_fixnum(FIXNUM x)
 {
-       return RETAG(UNTAG(~n),FIXNUM_TYPE);
+       return tag_fixnum(~x);
 }
index b5d87018b397a9ac5bf95ba47914246df3afb982..9c463845765f80b1554fb8b6aebda79b81a7ef52 100644 (file)
@@ -19,22 +19,22 @@ void primitive_not(void);
 FIXNUM to_fixnum(CELL tagged);
 void primitive_to_fixnum(void);
 
-CELL number_eq_fixnum(CELL x, CELL y);
-CELL add_fixnum(CELL x, CELL y);
-CELL subtract_fixnum(CELL x, CELL y);
-CELL multiply_fixnum(CELL x, CELL y);
+CELL number_eq_fixnum(FIXNUM x, FIXNUM y);
+CELL add_fixnum(FIXNUM x, FIXNUM y);
+CELL subtract_fixnum(FIXNUM x, FIXNUM y);
+CELL multiply_fixnum(FIXNUM x, FIXNUM y);
 FIXNUM gcd_fixnum(FIXNUM x, FIXNUM y);
-CELL divide_fixnum(CELL x, CELL y);
-CELL divint_fixnum(CELL x, CELL y);
-CELL divfloat_fixnum(CELL x, CELL y);
-CELL divmod_fixnum(CELL x, CELL y);
-CELL mod_fixnum(CELL x, CELL y);
-CELL and_fixnum(CELL x, CELL y);
-CELL or_fixnum(CELL x, CELL y);
-CELL xor_fixnum(CELL x, CELL y);
-CELL shift_fixnum(CELL x, FIXNUM y);
-CELL less_fixnum(CELL x, CELL y);
-CELL lesseq_fixnum(CELL x, CELL y);
-CELL greater_fixnum(CELL x, CELL y);
-CELL greatereq_fixnum(CELL x, CELL y);
-CELL not_fixnum(CELL n);
+CELL divide_fixnum(FIXNUM x, FIXNUM y);
+CELL divint_fixnum(FIXNUM x, FIXNUM y);
+CELL divfloat_fixnum(FIXNUM x, FIXNUM y);
+CELL divmod_fixnum(FIXNUM x, FIXNUM y);
+CELL mod_fixnum(FIXNUM x, FIXNUM y);
+CELL and_fixnum(FIXNUM x, FIXNUM y);
+CELL or_fixnum(FIXNUM x, FIXNUM y);
+CELL xor_fixnum(FIXNUM x, FIXNUM y);
+CELL shift_fixnum(FIXNUM x, FIXNUM y);
+CELL less_fixnum(FIXNUM x, FIXNUM y);
+CELL lesseq_fixnum(FIXNUM x, FIXNUM y);
+CELL greater_fixnum(FIXNUM x, FIXNUM y);
+CELL greatereq_fixnum(FIXNUM x, FIXNUM y);
+CELL not_fixnum(FIXNUM n);
index a795eaa5f4d82617de2d936b79e55b3ce11d37d5..de096fe32f531303650ad2547cb8436d57456072 100644 (file)
@@ -7,14 +7,17 @@ void primitive_floatp(void)
 
 FLOAT* to_float(CELL tagged)
 {
+       RATIO* r;
+
        switch(type_of(tagged))
        {
        case FIXNUM_TYPE:
-               return fixnum_to_float(tagged);
+               return make_float((double)untag_fixnum_fast(tagged));
        case BIGNUM_TYPE:
-               return bignum_to_float(tagged);
+               return make_float(s48_bignum_to_double((ARRAY*)UNTAG(tagged)));
        case RATIO_TYPE:
-               return ratio_to_float(tagged);
+               r = (RATIO*)UNTAG(tagged);
+               return (FLOAT*)UNTAG(divfloat(r->numerator,r->denominator));
        case FLOAT_TYPE:
                return (FLOAT*)UNTAG(tagged);
        default:
index 4284782ca9f3d4a83e56cfec983f159da2fdbf77..aa3fca6c812dd15ac2c31a33b7b43b7d421e30cb 100644 (file)
@@ -58,7 +58,7 @@ typedef long bignum_length_type;
    space when a bignum's length is reduced from its original value. */
 #define BIGNUM_REDUCE_LENGTH(target, source, length)            \
      target = shrink_array(source, length + 1)
-extern ARRAY* shrink_array(ARRAY* array, CELL capacity);
+/* extern ARRAY* shrink_array(ARRAY* array, CELL capacity); */
 
 /* BIGNUM_DEALLOCATE is called when disposing of bignums which are
    created as intermediate temporaries; Scheme doesn't need this. */
index f4d5862d87d15bbe2259a29eef87e06c4eb7202e..7b05c1436ea478e1fa09abd124397bc44ee748bd 100644 (file)
@@ -27,10 +27,10 @@ void primitive_set_sbuf_length(void)
 {
        SBUF* sbuf = untag_sbuf(dpop());
        FIXNUM length = to_fixnum(dpop());
-       sbuf->top = length;
        if(length < 0)
                range_error(tag_object(sbuf),length,sbuf->top);
-       else if(length > sbuf->string->capacity)
+       sbuf->top = length;
+       if(length > sbuf->string->capacity)
                sbuf->string = grow_string(sbuf->string,length,F);
 }
 
@@ -44,7 +44,7 @@ void primitive_sbuf_nth(void)
        dpush(string_nth(sbuf->string,index));
 }
 
-void sbuf_ensure_capacity(SBUF* sbuf, int top)
+void sbuf_ensure_capacity(SBUF* sbuf, FIXNUM top)
 {
        STRING* string = sbuf->string;
        CELL capacity = string->capacity;
index 782b6ccff2f5cf28ccea35d26ec95ceb54733454..149cf0eec675912051b308ad0e684c0ea5684711 100644 (file)
@@ -20,7 +20,7 @@ void primitive_sbuf(void);
 void primitive_sbuf_length(void);
 void primitive_set_sbuf_length(void);
 void primitive_sbuf_nth(void);
-void sbuf_ensure_capacity(SBUF* sbuf, int top);
+void sbuf_ensure_capacity(SBUF* sbuf, FIXNUM top);
 void set_sbuf_nth(SBUF* sbuf, CELL index, CHAR value);
 void primitive_set_sbuf_nth(void);
 void sbuf_append_string(SBUF* sbuf, STRING* string);
index e1e5336ea66d9a6357fbc55a4ffbecc5d20f143f..091f33171fcf681b6ef1312d9e6ebc3176a2012c 100644 (file)
@@ -1,9 +1,12 @@
 #include "factor.h"
 
 /* untagged */
-STRING* allot_string(CELL capacity)
+STRING* allot_string(FIXNUM capacity)
 {
-       STRING* string = allot_object(STRING_TYPE,
+       STRING* string;
+       if(capacity < 0)
+               general_error(ERROR_NEGATIVE_ARRAY_SIZE,tag_fixnum(capacity));
+       string = allot_object(STRING_TYPE,
                sizeof(STRING) + capacity * CHARS);
        string->capacity = capacity;
        return string;
@@ -21,7 +24,7 @@ void hash_string(STRING* str)
 }
 
 /* untagged */
-STRING* string(CELL capacity, CELL fill)
+STRING* string(FIXNUM capacity, CELL fill)
 {
        CELL i;
 
@@ -35,7 +38,7 @@ STRING* string(CELL capacity, CELL fill)
        return string;
 }
 
-STRING* grow_string(STRING* string, CELL capacity, CHAR fill)
+STRING* grow_string(STRING* string, FIXNUM capacity, CHAR fill)
 {
        /* later on, do an optimization: if end of array is here, just grow */
        CELL i;
@@ -167,9 +170,6 @@ void primitive_string_hashcode(void)
 
 CELL index_of_ch(CELL index, STRING* string, CELL ch)
 {
-       if(index < 0)
-               range_error(tag_object(string),index,string->capacity);
-
        while(index < string->capacity)
        {
                if(string_nth(string,index) == ch)
@@ -240,7 +240,7 @@ INLINE STRING* substring(CELL start, CELL end, STRING* string)
        if(start < 0)
                range_error(tag_object(string),start,string->capacity);
 
-       if(end < start)
+       if(end < start || end > string->capacity)
                range_error(tag_object(string),end,string->capacity);
 
        result = allot_string(end - start);
index e3e769fe8e348d25f94f50bb256a9c0da284e5c0..556052fc8cdb99516abef698891845d3c6108b44 100644 (file)
@@ -12,10 +12,10 @@ INLINE STRING* untag_string(CELL tagged)
        return (STRING*)UNTAG(tagged);
 }
 
-STRING* allot_string(CELL capacity);
-STRING* string(CELL capacity, CELL fill);
+STRING* allot_string(FIXNUM capacity);
+STRING* string(FIXNUM capacity, CELL fill);
 void hash_string(STRING* str);
-STRING* grow_string(STRING* string, CELL capacity, CHAR fill);
+STRING* grow_string(STRING* string, FIXNUM capacity, CHAR fill);
 char* to_c_string(STRING* s);
 STRING* from_c_string(const char* c_string);
 
index 53acec103efcaaa52d4a784813b541e1e9503b33..ea268728bc7bb9a0d2aab187d01c1ad5f757faa4 100644 (file)
@@ -71,7 +71,8 @@ CELL untagged_object_size(CELL pointer)
        switch(untag_header(get(pointer)))
        {
        case WORD_TYPE:
-               return align8(sizeof(WORD));
+               size = sizeof(WORD);
+               break;
        case F_TYPE:
        case T_TYPE:
                size = CELLS * 2;
index c41acc9884547dd1b3a871771648ed43a508e02f..4dbc708657db28e78e8c6be501e91b636fe316e1 100644 (file)
@@ -27,10 +27,10 @@ void primitive_set_vector_length(void)
 {
        VECTOR* vector = untag_vector(dpop());
        FIXNUM length = to_fixnum(dpop());
-       vector->top = length;
        if(length < 0)
                range_error(tag_object(vector),length,vector->top);
-       else if(length > vector->array->capacity)
+       vector->top = length;
+       if(length > vector->array->capacity)
                vector->array = grow_array(vector->array,length,F);
 }