2004-07-28 19:02:24 -04:00
|
|
|
#include "factor.h"
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
void primitive_numberp(void)
|
|
|
|
{
|
|
|
|
check_non_empty(env.dt);
|
|
|
|
|
|
|
|
switch(type_of(env.dt))
|
|
|
|
{
|
|
|
|
case FIXNUM_TYPE:
|
|
|
|
case BIGNUM_TYPE:
|
|
|
|
return T;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return F;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-07-29 17:18:41 -04:00
|
|
|
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 */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
void primitive_to_fixnum(void)
|
|
|
|
{
|
|
|
|
return tag_fixnum(to_fixnum(env.dt));
|
|
|
|
}
|
|
|
|
|
|
|
|
BIGNUM* to_bignum(CELL tagged)
|
|
|
|
{
|
|
|
|
switch(type_of(tagged))
|
|
|
|
{
|
|
|
|
case FIXNUM_TYPE:
|
|
|
|
return fixnum_to_bignum(tagged);
|
|
|
|
case BIGNUM_TYPE:
|
|
|
|
return tagged;
|
|
|
|
default:
|
|
|
|
type_error(BIGNUM_TYPE,tagged);
|
|
|
|
return -1; /* can't happen */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void primitive_to_bignum(void)
|
|
|
|
{
|
|
|
|
return tag_bignum(to_bignum(env.dt));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* EQUALITY */
|
|
|
|
INLINE CELL number_eq_fixnum(CELL x, CELL y)
|
|
|
|
{
|
|
|
|
return tag_boolean(x == y);
|
|
|
|
}
|
|
|
|
|
|
|
|
CELL number_eq_bignum(CELL x, CELL y)
|
|
|
|
{
|
|
|
|
return tag_boolean(((BIGNUM*)UNTAG(x))->n
|
|
|
|
== ((BIGNUM*)UNTAG(y))->n);
|
|
|
|
}
|
|
|
|
|
|
|
|
CELL number_eq_anytype(CELL x, CELL y)
|
|
|
|
{
|
|
|
|
return F;
|
|
|
|
}
|
|
|
|
|
|
|
|
BINARY_OP(number_eq,true)
|
|
|
|
|
2004-07-28 19:02:24 -04:00
|
|
|
/* ADDITION */
|
2004-08-04 18:25:29 -04:00
|
|
|
INLINE CELL add_fixnum(CELL x, CELL y)
|
2004-07-28 19:02:24 -04:00
|
|
|
{
|
2004-07-29 17:18:41 -04:00
|
|
|
CELL_TO_INTEGER(untag_fixnum_fast(x) + untag_fixnum_fast(y));
|
2004-07-28 19:02:24 -04:00
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
CELL add_bignum(CELL x, CELL y)
|
2004-07-28 19:02:24 -04:00
|
|
|
{
|
2004-08-04 18:25:29 -04:00
|
|
|
return tag_object(bignum(((BIGNUM*)UNTAG(x))->n
|
2004-07-28 19:02:24 -04:00
|
|
|
+ ((BIGNUM*)UNTAG(y))->n));
|
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
BINARY_OP(add,false)
|
2004-07-28 19:02:24 -04:00
|
|
|
|
|
|
|
/* SUBTRACTION */
|
2004-08-04 18:25:29 -04:00
|
|
|
INLINE CELL subtract_fixnum(CELL x, CELL y)
|
2004-07-28 19:02:24 -04:00
|
|
|
{
|
2004-07-29 17:18:41 -04:00
|
|
|
CELL_TO_INTEGER(untag_fixnum_fast(x) - untag_fixnum_fast(y));
|
2004-07-28 19:02:24 -04:00
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
CELL subtract_bignum(CELL x, CELL y)
|
2004-07-28 19:02:24 -04:00
|
|
|
{
|
2004-08-04 18:25:29 -04:00
|
|
|
return tag_object(bignum(((BIGNUM*)UNTAG(x))->n
|
2004-07-28 19:02:24 -04:00
|
|
|
- ((BIGNUM*)UNTAG(y))->n));
|
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
BINARY_OP(subtract,false)
|
2004-07-28 19:02:24 -04:00
|
|
|
|
|
|
|
/* MULTIPLICATION */
|
2004-08-04 18:25:29 -04:00
|
|
|
INLINE CELL multiply_fixnum(CELL x, CELL y)
|
2004-07-28 19:02:24 -04:00
|
|
|
{
|
2004-07-29 17:18:41 -04:00
|
|
|
BIGNUM_2_TO_INTEGER((BIGNUM_2)untag_fixnum_fast(x)
|
|
|
|
* (BIGNUM_2)untag_fixnum_fast(y));
|
2004-07-28 19:02:24 -04:00
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
CELL multiply_bignum(CELL x, CELL y)
|
2004-07-28 19:02:24 -04:00
|
|
|
{
|
2004-08-04 18:25:29 -04:00
|
|
|
return tag_object(bignum(((BIGNUM*)UNTAG(x))->n
|
2004-07-28 19:02:24 -04:00
|
|
|
* ((BIGNUM*)UNTAG(y))->n));
|
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
BINARY_OP(multiply,false)
|
2004-07-28 19:02:24 -04:00
|
|
|
|
|
|
|
/* DIVMOD */
|
2004-08-04 18:25:29 -04:00
|
|
|
INLINE CELL divmod_fixnum(CELL x, CELL y)
|
2004-07-28 19:02:24 -04:00
|
|
|
{
|
|
|
|
ldiv_t q = ldiv(x,y);
|
|
|
|
/* division takes common factor of 8 out. */
|
|
|
|
dpush(tag_fixnum(q.quot));
|
2004-08-04 18:25:29 -04:00
|
|
|
return q.rem;
|
2004-07-28 19:02:24 -04:00
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
CELL divmod_bignum(CELL x, CELL y)
|
2004-07-28 19:02:24 -04:00
|
|
|
{
|
|
|
|
dpush(tag_object(bignum(((BIGNUM*)UNTAG(x))->n
|
|
|
|
/ ((BIGNUM*)UNTAG(y))->n)));
|
2004-08-04 18:25:29 -04:00
|
|
|
return tag_object(bignum(((BIGNUM*)UNTAG(x))->n
|
2004-07-28 19:02:24 -04:00
|
|
|
% ((BIGNUM*)UNTAG(y))->n));
|
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
BINARY_OP(divmod,false)
|
2004-07-28 19:02:24 -04:00
|
|
|
|
2004-07-29 17:18:41 -04:00
|
|
|
/* MOD */
|
2004-08-04 18:25:29 -04:00
|
|
|
INLINE CELL mod_fixnum(CELL x, CELL y)
|
2004-07-29 17:18:41 -04:00
|
|
|
{
|
2004-08-04 18:25:29 -04:00
|
|
|
return x % y;
|
2004-07-29 17:18:41 -04:00
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
CELL mod_bignum(CELL x, CELL y)
|
2004-07-29 17:18:41 -04:00
|
|
|
{
|
2004-08-04 18:25:29 -04:00
|
|
|
return tag_object(bignum(((BIGNUM*)UNTAG(x))->n
|
2004-07-29 17:18:41 -04:00
|
|
|
% ((BIGNUM*)UNTAG(y))->n));
|
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
BINARY_OP(mod,false)
|
2004-07-29 17:18:41 -04:00
|
|
|
|
|
|
|
/* AND */
|
2004-08-04 18:25:29 -04:00
|
|
|
INLINE CELL and_fixnum(CELL x, CELL y)
|
2004-07-29 17:18:41 -04:00
|
|
|
{
|
2004-08-04 18:25:29 -04:00
|
|
|
return x & y;
|
2004-07-29 17:18:41 -04:00
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
CELL and_bignum(CELL x, CELL y)
|
2004-07-29 17:18:41 -04:00
|
|
|
{
|
2004-08-04 18:25:29 -04:00
|
|
|
return tag_object(bignum(((BIGNUM*)UNTAG(x))->n
|
2004-07-29 17:18:41 -04:00
|
|
|
& ((BIGNUM*)UNTAG(y))->n));
|
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
BINARY_OP(and,false)
|
2004-07-29 17:18:41 -04:00
|
|
|
|
|
|
|
/* OR */
|
2004-08-04 18:25:29 -04:00
|
|
|
INLINE CELL or_fixnum(CELL x, CELL y)
|
2004-07-29 17:18:41 -04:00
|
|
|
{
|
2004-08-04 18:25:29 -04:00
|
|
|
return x | y;
|
2004-07-29 17:18:41 -04:00
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
CELL or_bignum(CELL x, CELL y)
|
2004-07-29 17:18:41 -04:00
|
|
|
{
|
2004-08-04 18:25:29 -04:00
|
|
|
return tag_object(bignum(((BIGNUM*)UNTAG(x))->n
|
2004-07-29 17:18:41 -04:00
|
|
|
| ((BIGNUM*)UNTAG(y))->n));
|
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
BINARY_OP(or,false)
|
2004-07-29 17:18:41 -04:00
|
|
|
|
|
|
|
/* XOR */
|
2004-08-04 18:25:29 -04:00
|
|
|
INLINE CELL xor_fixnum(CELL x, CELL y)
|
2004-07-29 17:18:41 -04:00
|
|
|
{
|
2004-08-04 18:25:29 -04:00
|
|
|
return x ^ y;
|
2004-07-29 17:18:41 -04:00
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
CELL xor_bignum(CELL x, CELL y)
|
2004-07-29 17:18:41 -04:00
|
|
|
{
|
2004-08-04 18:25:29 -04:00
|
|
|
return tag_object(bignum(((BIGNUM*)UNTAG(x))->n
|
2004-07-29 17:18:41 -04:00
|
|
|
^ ((BIGNUM*)UNTAG(y))->n));
|
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
BINARY_OP(xor,false)
|
2004-07-29 17:18:41 -04:00
|
|
|
|
|
|
|
/* SHIFTLEFT */
|
2004-08-04 18:25:29 -04:00
|
|
|
INLINE CELL shiftleft_fixnum(CELL x, CELL y)
|
2004-07-29 17:18:41 -04:00
|
|
|
{
|
|
|
|
BIGNUM_2_TO_INTEGER((BIGNUM_2)untag_fixnum_fast(x)
|
|
|
|
<< (BIGNUM_2)untag_fixnum_fast(y));
|
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
CELL shiftleft_bignum(CELL x, CELL y)
|
2004-07-29 17:18:41 -04:00
|
|
|
{
|
2004-08-04 18:25:29 -04:00
|
|
|
return tag_object(bignum(((BIGNUM*)UNTAG(x))->n
|
2004-07-29 17:18:41 -04:00
|
|
|
<< ((BIGNUM*)UNTAG(y))->n));
|
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
BINARY_OP(shiftleft,false)
|
2004-07-29 17:18:41 -04:00
|
|
|
|
|
|
|
/* SHIFTRIGHT */
|
2004-08-04 18:25:29 -04:00
|
|
|
INLINE CELL shiftright_fixnum(CELL x, CELL y)
|
2004-07-29 17:18:41 -04:00
|
|
|
{
|
|
|
|
BIGNUM_2_TO_INTEGER((BIGNUM_2)untag_fixnum_fast(x)
|
|
|
|
>> (BIGNUM_2)untag_fixnum_fast(y));
|
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
CELL shiftright_bignum(CELL x, CELL y)
|
2004-07-29 17:18:41 -04:00
|
|
|
{
|
2004-08-04 18:25:29 -04:00
|
|
|
return tag_object(bignum(((BIGNUM*)UNTAG(x))->n
|
2004-07-29 17:18:41 -04:00
|
|
|
>> ((BIGNUM*)UNTAG(y))->n));
|
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
BINARY_OP(shiftright,false)
|
2004-07-29 17:18:41 -04:00
|
|
|
|
2004-07-28 19:02:24 -04:00
|
|
|
/* LESS */
|
2004-08-04 18:25:29 -04:00
|
|
|
INLINE CELL less_fixnum(CELL x, CELL y)
|
2004-07-28 19:02:24 -04:00
|
|
|
{
|
2004-08-04 18:25:29 -04:00
|
|
|
return tag_boolean((FIXNUM)x < (FIXNUM)y);
|
2004-07-28 19:02:24 -04:00
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
CELL less_bignum(CELL x, CELL y)
|
2004-07-28 19:02:24 -04:00
|
|
|
{
|
2004-08-04 18:25:29 -04:00
|
|
|
return tag_boolean(((BIGNUM*)UNTAG(x))->n
|
2004-07-28 19:02:24 -04:00
|
|
|
< ((BIGNUM*)UNTAG(y))->n);
|
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
BINARY_OP(less,false)
|
2004-07-28 19:02:24 -04:00
|
|
|
|
|
|
|
/* LESSEQ */
|
2004-08-04 18:25:29 -04:00
|
|
|
INLINE CELL lesseq_fixnum(CELL x, CELL y)
|
2004-07-28 19:02:24 -04:00
|
|
|
{
|
2004-08-04 18:25:29 -04:00
|
|
|
return tag_boolean((FIXNUM)x <= (FIXNUM)y);
|
2004-07-28 19:02:24 -04:00
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
CELL lesseq_bignum(CELL x, CELL y)
|
2004-07-28 19:02:24 -04:00
|
|
|
{
|
2004-08-04 18:25:29 -04:00
|
|
|
return tag_boolean(((BIGNUM*)UNTAG(x))->n
|
2004-07-28 19:02:24 -04:00
|
|
|
<= ((BIGNUM*)UNTAG(y))->n);
|
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
BINARY_OP(lesseq,false)
|
2004-07-28 19:02:24 -04:00
|
|
|
|
|
|
|
/* GREATER */
|
2004-08-04 18:25:29 -04:00
|
|
|
INLINE CELL greater_fixnum(CELL x, CELL y)
|
2004-07-28 19:02:24 -04:00
|
|
|
{
|
2004-08-04 18:25:29 -04:00
|
|
|
return tag_boolean((FIXNUM)x > (FIXNUM)y);
|
2004-07-28 19:02:24 -04:00
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
CELL greater_bignum(CELL x, CELL y)
|
2004-07-28 19:02:24 -04:00
|
|
|
{
|
2004-08-04 18:25:29 -04:00
|
|
|
return tag_boolean(((BIGNUM*)UNTAG(x))->n
|
2004-07-28 19:02:24 -04:00
|
|
|
> ((BIGNUM*)UNTAG(y))->n);
|
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
BINARY_OP(greater,false)
|
2004-07-28 19:02:24 -04:00
|
|
|
|
|
|
|
/* GREATEREQ */
|
2004-08-04 18:25:29 -04:00
|
|
|
INLINE CELL greatereq_fixnum(CELL x, CELL y)
|
2004-07-28 19:02:24 -04:00
|
|
|
{
|
2004-08-04 18:25:29 -04:00
|
|
|
return tag_boolean((FIXNUM)x >= (FIXNUM)y);
|
2004-07-28 19:02:24 -04:00
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
CELL greatereq_bignum(CELL x, CELL y)
|
2004-07-28 19:02:24 -04:00
|
|
|
{
|
2004-08-04 18:25:29 -04:00
|
|
|
return tag_boolean(((BIGNUM*)UNTAG(x))->n
|
2004-07-28 19:02:24 -04:00
|
|
|
>= ((BIGNUM*)UNTAG(y))->n);
|
|
|
|
}
|
|
|
|
|
2004-08-04 18:25:29 -04:00
|
|
|
BINARY_OP(greatereq,false)
|