rm *.o
export CC=gcc34
-export CFLAGS="-pedantic -Wall -Winline -O3 -march=pentium4 -fomit-frame-pointer"
+export CFLAGS="-pedantic -Wall -Winline -Os -march=pentium4 -fomit-frame-pointer"
$CC $CFLAGS -o f native/*.c
bitor
bitxor
bitnot
- shift>
shift<
+ shift>
<
<=
>
: object-tag BIN: 011 ;
: header-tag BIN: 100 ;
+: fixnum-mask HEX: 1fffffff ;
: immediate ( x tag -- tagged ) swap tag-bits shift< bitor ;
: >header ( id -- tagged ) header-tag immediate ;
object-tag here-as swap
11 >header emit
dup str-length emit
- dup hashcode emit
+ dup hashcode fixnum-mask bitand emit
pack-string
pad ;
USE: words
USE: unparser
+: init-gc ( -- )
+ [ garbage-collection ] 7 setenv ;
+
: boot ( -- )
+ init-gc
init-namespaces
-
- ! Some flags are *on* by default, unless user specifies
- ! -no-<flag> CLI switch
- t "user-init" set
- t "interactive" set
-
init-stdio
"stdio" get <ansi-stream> "stdio" set
init-errors
init-scratchpad
init-styles
init-vocab-styles
+
+ ! Some flags are *on* by default, unless user specifies
+ ! -no-<flag> CLI switch
+ t "user-init" set
+ t "interactive" set
+
10 "base" set
print-banner
room.
#include "factor.h"
+FIXNUM to_fixnum(CELL tagged)
+{
+ switch(type_of(tagged))
+ {
+ case FIXNUM_TYPE:
+ return untag_fixnum_fast(tagged);
+ case BIGNUM_TYPE:
+ return bignum_to_fixnum(tagged);
+ default:
+ type_error(FIXNUM_TYPE,tagged);
+ return -1; /* can't happen */
+ }
+}
+
+#define CELL_TO_INTEGER(result) \
+ FIXNUM _result = (result); \
+ if(_result < FIXNUM_MIN || _result > FIXNUM_MAX) \
+ env.dt = tag_bignum(fixnum_to_bignum(_result)); \
+ else \
+ env.dt = tag_fixnum(_result);
+
+#define BIGNUM_2_TO_INTEGER(result) \
+ BIGNUM_2 _result = (result); \
+ if(_result < FIXNUM_MIN || _result > FIXNUM_MAX) \
+ env.dt = tag_bignum(bignum(_result)); \
+ else \
+ env.dt = tag_fixnum(_result);
+
/* ADDITION */
INLINE void add_fixnum(CELL x, CELL y)
{
- FIXNUM result = untag_fixnum_fast(x) + untag_fixnum_fast(y);
- if(result < FIXNUM_MIN || result > FIXNUM_MAX)
- env.dt = tag_bignum(fixnum_to_bignum(result));
- else
- env.dt = tag_fixnum(result);
+ CELL_TO_INTEGER(untag_fixnum_fast(x) + untag_fixnum_fast(y));
}
INLINE void add_bignum(CELL x, CELL y)
/* SUBTRACTION */
INLINE void subtract_fixnum(CELL x, CELL y)
{
- FIXNUM result = untag_fixnum_fast(x) - untag_fixnum_fast(y);
- if(result < FIXNUM_MIN || result > FIXNUM_MAX)
- env.dt = tag_bignum(fixnum_to_bignum(result));
- else
- env.dt = tag_fixnum(result);
+ CELL_TO_INTEGER(untag_fixnum_fast(x) - untag_fixnum_fast(y));
}
INLINE void subtract_bignum(CELL x, CELL y)
/* MULTIPLICATION */
INLINE void multiply_fixnum(CELL x, CELL y)
{
- BIGNUM_2 result = (BIGNUM_2)untag_fixnum_fast(x)
- * (BIGNUM_2)untag_fixnum_fast(y);
- if(result < FIXNUM_MIN || result > FIXNUM_MAX)
- env.dt = tag_bignum(bignum(result));
- else
- env.dt = tag_fixnum(result);
+ BIGNUM_2_TO_INTEGER((BIGNUM_2)untag_fixnum_fast(x)
+ * (BIGNUM_2)untag_fixnum_fast(y));
}
INLINE void multiply_bignum(CELL x, CELL y)
BINARY_OP(divmod)
+/* MOD */
+INLINE void mod_fixnum(CELL x, CELL y)
+{
+ env.dt = x % y;
+}
+
+INLINE void mod_bignum(CELL x, CELL y)
+{
+ env.dt = tag_object(bignum(((BIGNUM*)UNTAG(x))->n
+ % ((BIGNUM*)UNTAG(y))->n));
+}
+
+BINARY_OP(mod)
+
+/* AND */
+INLINE void and_fixnum(CELL x, CELL y)
+{
+ env.dt = x & y;
+}
+
+INLINE void and_bignum(CELL x, CELL y)
+{
+ env.dt = tag_object(bignum(((BIGNUM*)UNTAG(x))->n
+ & ((BIGNUM*)UNTAG(y))->n));
+}
+
+BINARY_OP(and)
+
+/* OR */
+INLINE void or_fixnum(CELL x, CELL y)
+{
+ env.dt = x | y;
+}
+
+INLINE void or_bignum(CELL x, CELL y)
+{
+ env.dt = tag_object(bignum(((BIGNUM*)UNTAG(x))->n
+ | ((BIGNUM*)UNTAG(y))->n));
+}
+
+BINARY_OP(or)
+
+/* XOR */
+INLINE void xor_fixnum(CELL x, CELL y)
+{
+ env.dt = x ^ y;
+}
+
+INLINE void xor_bignum(CELL x, CELL y)
+{
+ env.dt = tag_object(bignum(((BIGNUM*)UNTAG(x))->n
+ ^ ((BIGNUM*)UNTAG(y))->n));
+}
+
+BINARY_OP(xor)
+
+/* SHIFTLEFT */
+INLINE void shiftleft_fixnum(CELL x, CELL y)
+{
+ BIGNUM_2_TO_INTEGER((BIGNUM_2)untag_fixnum_fast(x)
+ << (BIGNUM_2)untag_fixnum_fast(y));
+}
+
+INLINE void shiftleft_bignum(CELL x, CELL y)
+{
+ env.dt = tag_object(bignum(((BIGNUM*)UNTAG(x))->n
+ << ((BIGNUM*)UNTAG(y))->n));
+}
+
+BINARY_OP(shiftleft)
+
+/* SHIFTRIGHT */
+INLINE void shiftright_fixnum(CELL x, CELL y)
+{
+ BIGNUM_2_TO_INTEGER((BIGNUM_2)untag_fixnum_fast(x)
+ >> (BIGNUM_2)untag_fixnum_fast(y));
+}
+
+INLINE void shiftright_bignum(CELL x, CELL y)
+{
+ env.dt = tag_object(bignum(((BIGNUM*)UNTAG(x))->n
+ >> ((BIGNUM*)UNTAG(y))->n));
+}
+
+BINARY_OP(shiftright)
+
/* LESS */
INLINE void less_fixnum(CELL x, CELL y)
{
switch(object_type(y)) \
{ \
case BIGNUM_TYPE: \
- OP##_bignum(fixnum_to_bignum(x),y); \
+ OP##_bignum((CELL)fixnum_to_bignum(x),y); \
break; \
default: \
type_error(FIXNUM_TYPE,y); \
switch(TAG(y)) \
{ \
case FIXNUM_TYPE: \
- OP##_bignum(x,fixnum_to_bignum(y)); \
+ OP##_bignum(x,(CELL)fixnum_to_bignum(y)); \
break; \
case OBJECT_TYPE: \
\
} \
}
+FIXNUM to_fixnum(CELL tagged);
+
void primitive_add(void);
void primitive_subtract(void);
void primitive_multiply(void);
void primitive_lesseq(void);
void primitive_greater(void);
void primitive_greatereq(void);
+void primitive_mod(void);
+void primitive_and(void);
+void primitive_or(void);
+void primitive_xor(void);
+void primitive_shiftleft(void);
+void primitive_shiftright(void);
switch(type)
{
case FIXNUM_TYPE:
- write_fd_char_8(h,untag_fixnum(text));
+ write_fd_char_8(h,to_fixnum(text));
break;
case STRING_TYPE:
write_fd_string_8(h,untag_string(text));
void primitive_shutdown_fd(void)
{
- HANDLE* h = untag_handle(HANDLE_FD,env.dt);
+ /* HANDLE* h = untag_handle(HANDLE_FD,env.dt);
int fd = h->object;
- /* if(shutdown(fd,SHUT_RDWR) < 0)
+ if(shutdown(fd,SHUT_RDWR) < 0)
io_error(__FUNCTION__); */
env.dt = dpop();
env.dt = tag_fixnum(x / y);
}
-void primitive_mod(void)
-{
- BINARY_OP(x,y);
- env.dt = x % y;
-}
-
-void primitive_and(void)
-{
- BINARY_OP(x,y);
- env.dt = x & y;
-}
-
-void primitive_or(void)
-{
- BINARY_OP(x,y);
- env.dt = x | y;
-}
-
-void primitive_xor(void)
-{
- BINARY_OP(x,y);
- env.dt = x ^ y;
-}
-
void primitive_not(void)
{
type_check(FIXNUM_TYPE,env.dt);
env.dt = RETAG(UNTAG(~env.dt),FIXNUM_TYPE);
}
-
-void primitive_shiftleft(void)
-{
- BINARY_OP(x,y);
- env.dt = UNTAG(x >> (y >> TAG_BITS));
-}
-
-void primitive_shiftright(void)
-{
- BINARY_OP(x,y);
- env.dt = x << (y >> TAG_BITS);
-}
-
#define FIXNUM_MAX (LONG_MAX >> TAG_BITS)
#define FIXNUM_MIN (LONG_MIN >> TAG_BITS)
return ((FIXNUM)tagged) >> TAG_BITS;
}
-INLINE FIXNUM untag_fixnum(CELL tagged)
-{
- type_check(FIXNUM_TYPE,tagged);
- return untag_fixnum_fast(tagged);
-}
-
INLINE CELL tag_fixnum(FIXNUM untagged)
{
return RETAG(untagged << TAG_BITS,FIXNUM_TYPE);
void primitive_fixnump(void);
void primitive_divide(void);
-void primitive_mod(void);
-void primitive_and(void);
-void primitive_or(void);
-void primitive_xor(void);
void primitive_not(void);
-void primitive_shiftleft(void);
-void primitive_shiftright(void);
if(z->base == 0)
fatal_error("Cannot allocate zone",size);
z->limit = z->base + size;
+ z->alarm = z->base + (size * 3) / 4;
z->base = align8(z->base);
return z;
}
{
CELL h = active->here;
active->here = align8(active->here + a);
+
if(active->here > active->limit)
{
printf("Out of memory\n");
printf("request = %ld\n",a);
exit(1);
}
+ else if(active->here > active->alarm)
+ {
+ /* Execute the 'garbage-collection' word */
+ cpush(env.cf);
+ env.cf = env.user[GC_ENV];
+ }
+
return h;
}
typedef struct {
CELL base;
CELL here;
+ CELL alarm;
CELL limit;
} ZONE;
if(primitive < 0 || primitive >= PRIMITIVE_COUNT)
general_error(ERROR_BAD_PRIMITIVE,tag_fixnum(primitive));
- return primitives[primitive];
+ return (CELL)primitives[primitive];
}
void primitive_eq(void)
if(TAG(next) == WORD_TYPE)
{
env.w = (WORD*)UNTAG(next);
+ /* printf("EXECUTE %d\n",env.w->primitive); */
EXECUTE(env.w);
}
else
{
+ /* printf("DPUSH %d\n",type_of(next)); */
dpush(env.dt);
env.dt = next;
}
void primitive_getenv(void)
{
- FIXNUM e = untag_fixnum(env.dt);
+ FIXNUM e = to_fixnum(env.dt);
if(e < 0 || e >= USER_ENV)
range_error(F,e,USER_ENV);
env.dt = env.user[e];
void primitive_setenv(void)
{
- FIXNUM e = untag_fixnum(env.dt);
+ FIXNUM e = to_fixnum(env.dt);
CELL value = dpop();
if(e < 0 || e >= USER_ENV)
range_error(F,e,USER_ENV);
void primitive_exit(void)
{
- exit(untag_fixnum(env.dt));
+ exit(to_fixnum(env.dt));
}
#define USER_ENV 16
-#define STDIN_ENV 0
-#define STDOUT_ENV 1
-#define STDERR_ENV 2
-#define NAMESTACK_ENV 3
-#define GLOBAL_ENV 4
-#define BREAK_ENV 5
+#define STDIN_ENV 0
+#define STDOUT_ENV 1
+#define STDERR_ENV 2
+#define NAMESTACK_ENV 3
+#define GLOBAL_ENV 4
+#define BREAK_ENV 5
+#define CATCHSTACK_ENV 6
+#define GC_ENV 7
/* Error handlers restore this */
jmp_buf toplevel;
void primitive_sbuf(void)
{
- env.dt = tag_object(sbuf(untag_fixnum(env.dt)));
+ env.dt = tag_object(sbuf(to_fixnum(env.dt)));
}
void primitive_sbuf_length(void)
void primitive_set_sbuf_length(void)
{
SBUF* sbuf = untag_sbuf(env.dt);
- FIXNUM length = untag_fixnum(dpop());
+ FIXNUM length = to_fixnum(dpop());
sbuf->top = length;
if(length < 0)
range_error(env.dt,length,sbuf->top);
void primitive_sbuf_nth(void)
{
SBUF* sbuf = untag_sbuf(env.dt);
- CELL index = untag_fixnum(dpop());
+ CELL index = to_fixnum(dpop());
if(index < 0 || index >= sbuf->top)
range_error(env.dt,index,sbuf->top);
void primitive_set_sbuf_nth(void)
{
SBUF* sbuf = untag_sbuf(env.dt);
- FIXNUM index = untag_fixnum(dpop());
+ FIXNUM index = to_fixnum(dpop());
CELL value = dpop();
check_non_empty(value);
switch(type_of(object))
{
case FIXNUM_TYPE:
- set_sbuf_nth(sbuf,sbuf->top,untag_fixnum(object));
+ case BIGNUM_TYPE:
+ set_sbuf_nth(sbuf,sbuf->top,to_fixnum(object));
break;
case STRING_TYPE:
sbuf_append_string(sbuf,untag_string(object));
void primitive_server_socket(void)
{
- CHAR port = (CHAR)untag_fixnum(env.dt);
+ CHAR port = (CHAR)to_fixnum(env.dt);
env.dt = handle(HANDLE_FD,make_server_socket(port));
}
void primitive_string_nth(void)
{
STRING* string = untag_string(env.dt);
- CELL index = untag_fixnum(dpop());
+ CELL index = to_fixnum(dpop());
if(index < 0 || index >= string->capacity)
range_error(tag_object(string),index,string->capacity);
CELL result;
check_non_empty(ch);
string = untag_string(dpop());
- index = untag_fixnum(dpop());
+ index = to_fixnum(dpop());
if(TAG(ch) == FIXNUM_TYPE)
- result = index_of_ch(index,string,untag_fixnum(ch));
+ result = index_of_ch(index,string,to_fixnum(ch));
else
result = index_of_str(index,string,untag_string(ch));
env.dt = tag_fixnum(result);
void primitive_substring(void)
{
STRING* string = untag_string(env.dt);
- CELL end = untag_fixnum(dpop());
- CELL start = untag_fixnum(dpop());
+ CELL end = to_fixnum(dpop());
+ CELL start = to_fixnum(dpop());
env.dt = tag_object(substring(start,end,string));
}
void primitive_vector(void)
{
- env.dt = tag_object(vector(untag_fixnum(env.dt)));
+ env.dt = tag_object(vector(to_fixnum(env.dt)));
}
void primitive_vector_length(void)
void primitive_set_vector_length(void)
{
VECTOR* vector = untag_vector(env.dt);
- FIXNUM length = untag_fixnum(dpop());
+ FIXNUM length = to_fixnum(dpop());
vector->top = length;
if(length < 0)
range_error(tag_object(vector),length,vector->top);
void primitive_vector_nth(void)
{
VECTOR* vector = untag_vector(env.dt);
- CELL index = untag_fixnum(dpop());
+ CELL index = to_fixnum(dpop());
if(index < 0 || index >= vector->top)
range_error(tag_object(vector),index,vector->top);
void primitive_set_vector_nth(void)
{
VECTOR* vector = untag_vector(env.dt);
- FIXNUM index = untag_fixnum(dpop());
+ FIXNUM index = to_fixnum(dpop());
CELL value = dpop();
check_non_empty(value);
CELL parameter = dpop();
check_non_empty(plist);
check_non_empty(parameter);
- primitive = untag_fixnum(dpop());
+ primitive = to_fixnum(dpop());
env.dt = tag_word(word(primitive,parameter,plist));
}
void primitive_set_word_primitive(void)
{
WORD* word = untag_word(env.dt);
- word->primitive = untag_fixnum(dpop());
+ word->primitive = to_fixnum(dpop());
update_xt(word);
env.dt = dpop();
}