2004-07-27 22:52:35 -04:00
|
|
|
#include "factor.h"
|
|
|
|
|
2004-08-05 15:18:31 -04:00
|
|
|
BIGNUM* fixnum_to_bignum(CELL n);
|
|
|
|
RATIO* fixnum_to_ratio(CELL n);
|
2004-08-05 16:49:55 -04:00
|
|
|
FLOAT* fixnum_to_float(CELL n);
|
2004-08-05 15:18:31 -04:00
|
|
|
FIXNUM bignum_to_fixnum(CELL tagged);
|
|
|
|
RATIO* bignum_to_ratio(CELL n);
|
2004-08-05 16:49:55 -04:00
|
|
|
FLOAT* bignum_to_float(CELL n);
|
|
|
|
FLOAT* ratio_to_float(CELL n);
|
2004-08-04 22:43:58 -04:00
|
|
|
|
2004-08-03 02:08:11 -04:00
|
|
|
#define CELL_TO_INTEGER(result) \
|
|
|
|
FIXNUM _result = (result); \
|
|
|
|
if(_result < FIXNUM_MIN || _result > FIXNUM_MAX) \
|
2004-08-05 16:49:55 -04:00
|
|
|
return tag_object(fixnum_to_bignum(_result)); \
|
2004-08-03 02:08:11 -04:00
|
|
|
else \
|
2004-08-04 18:25:29 -04:00
|
|
|
return tag_fixnum(_result);
|
2004-08-03 02:08:11 -04:00
|
|
|
|
|
|
|
#define BIGNUM_2_TO_INTEGER(result) \
|
|
|
|
BIGNUM_2 _result = (result); \
|
|
|
|
if(_result < FIXNUM_MIN || _result > FIXNUM_MAX) \
|
2004-08-05 16:49:55 -04:00
|
|
|
return tag_object(bignum(_result)); \
|
2004-08-03 02:08:11 -04:00
|
|
|
else \
|
2004-08-04 18:25:29 -04:00
|
|
|
return tag_fixnum(_result);
|
2004-08-03 02:08:11 -04:00
|
|
|
|
2004-08-05 15:18:31 -04:00
|
|
|
#define BINARY_OP(OP,anytype,integerOnly) \
|
2004-08-04 18:25:29 -04:00
|
|
|
CELL OP(CELL x, CELL y) \
|
2004-07-27 22:52:35 -04:00
|
|
|
{ \
|
2004-08-05 16:49:55 -04:00
|
|
|
switch(type_of(x)) \
|
2004-07-27 22:52:35 -04:00
|
|
|
{ \
|
|
|
|
case FIXNUM_TYPE: \
|
|
|
|
\
|
2004-08-05 16:49:55 -04:00
|
|
|
switch(type_of(y)) \
|
2004-07-27 22:52:35 -04:00
|
|
|
{ \
|
|
|
|
case FIXNUM_TYPE: \
|
2004-08-04 18:25:29 -04:00
|
|
|
return OP##_fixnum(x,y); \
|
2004-08-04 22:43:58 -04:00
|
|
|
case RATIO_TYPE: \
|
2004-08-05 15:18:31 -04:00
|
|
|
if(integerOnly) \
|
2004-08-05 20:29:52 -04:00
|
|
|
{ \
|
2004-08-06 18:40:44 -04:00
|
|
|
type_error(INTEGER_TYPE,y); \
|
2004-08-05 20:29:52 -04:00
|
|
|
return F; \
|
|
|
|
} \
|
2004-08-05 15:18:31 -04:00
|
|
|
else \
|
|
|
|
return OP##_ratio((CELL)fixnum_to_ratio(x),y); \
|
2004-08-05 20:29:52 -04:00
|
|
|
case COMPLEX_TYPE: \
|
|
|
|
if(integerOnly) \
|
|
|
|
{ \
|
2004-08-06 18:40:44 -04:00
|
|
|
type_error(INTEGER_TYPE,y); \
|
2004-08-05 20:29:52 -04:00
|
|
|
return F; \
|
|
|
|
} \
|
|
|
|
else \
|
|
|
|
return OP##_complex((CELL)complex(x,tag_fixnum(0)),y); \
|
2004-08-05 16:49:55 -04:00
|
|
|
case BIGNUM_TYPE: \
|
|
|
|
return OP##_bignum((CELL)fixnum_to_bignum(x),y); \
|
|
|
|
case FLOAT_TYPE: \
|
|
|
|
if(integerOnly) \
|
2004-08-05 20:29:52 -04:00
|
|
|
{ \
|
2004-08-06 18:40:44 -04:00
|
|
|
type_error(INTEGER_TYPE,y); \
|
2004-08-05 20:29:52 -04:00
|
|
|
return F; \
|
|
|
|
} \
|
2004-08-05 16:49:55 -04:00
|
|
|
else \
|
|
|
|
return OP##_float((CELL)fixnum_to_float(x),y); \
|
2004-07-27 22:52:35 -04:00
|
|
|
default: \
|
2004-08-04 18:25:29 -04:00
|
|
|
if(anytype) \
|
|
|
|
return OP##_anytype(x,y); \
|
|
|
|
else \
|
2004-08-06 18:40:44 -04:00
|
|
|
{ \
|
|
|
|
type_error(NUMBER_TYPE,x); \
|
|
|
|
return F; \
|
|
|
|
} \
|
2004-07-27 22:52:35 -04:00
|
|
|
} \
|
|
|
|
\
|
2004-08-05 16:49:55 -04:00
|
|
|
case RATIO_TYPE: \
|
2004-08-05 20:29:52 -04:00
|
|
|
\
|
|
|
|
if(integerOnly) \
|
|
|
|
{ \
|
2004-08-06 18:40:44 -04:00
|
|
|
type_error(INTEGER_TYPE,x); \
|
2004-08-05 20:29:52 -04:00
|
|
|
return F; \
|
|
|
|
} \
|
2004-07-27 22:52:35 -04:00
|
|
|
\
|
2004-08-05 16:49:55 -04:00
|
|
|
switch(type_of(y)) \
|
2004-07-27 22:52:35 -04:00
|
|
|
{ \
|
2004-08-05 16:49:55 -04:00
|
|
|
case FIXNUM_TYPE: \
|
2004-08-05 20:29:52 -04:00
|
|
|
return OP##_ratio(x,(CELL)fixnum_to_ratio(y)); \
|
2004-08-05 16:49:55 -04:00
|
|
|
case RATIO_TYPE: \
|
2004-08-05 20:29:52 -04:00
|
|
|
return OP##_ratio(x,y); \
|
|
|
|
case COMPLEX_TYPE: \
|
|
|
|
return OP##_complex((CELL)complex(x,tag_fixnum(0)),y); \
|
2004-07-27 22:52:35 -04:00
|
|
|
case BIGNUM_TYPE: \
|
2004-08-05 20:29:52 -04:00
|
|
|
return OP##_ratio(x,(CELL)bignum_to_ratio(y)); \
|
2004-08-05 16:49:55 -04:00
|
|
|
case FLOAT_TYPE: \
|
2004-08-05 20:29:52 -04:00
|
|
|
return OP##_float((CELL)ratio_to_float(x),y); \
|
|
|
|
default: \
|
|
|
|
if(anytype) \
|
|
|
|
return OP##_anytype(x,y); \
|
2004-08-05 16:49:55 -04:00
|
|
|
else \
|
2004-08-06 18:40:44 -04:00
|
|
|
{ \
|
|
|
|
type_error(NUMBER_TYPE,x); \
|
|
|
|
return F; \
|
|
|
|
} \
|
2004-08-05 20:29:52 -04:00
|
|
|
} \
|
|
|
|
\
|
|
|
|
case COMPLEX_TYPE: \
|
|
|
|
\
|
|
|
|
if(integerOnly) \
|
|
|
|
{ \
|
2004-08-06 18:40:44 -04:00
|
|
|
type_error(INTEGER_TYPE,x); \
|
2004-08-05 20:29:52 -04:00
|
|
|
return F; \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
switch(type_of(y)) \
|
|
|
|
{ \
|
|
|
|
case FIXNUM_TYPE: \
|
|
|
|
return OP##_complex(x,(CELL)complex(y,tag_fixnum(0))); \
|
|
|
|
case RATIO_TYPE: \
|
|
|
|
return OP##_complex(x,(CELL)complex(y,tag_fixnum(0))); \
|
|
|
|
case COMPLEX_TYPE: \
|
|
|
|
return OP##_complex(x,y); \
|
|
|
|
case BIGNUM_TYPE: \
|
|
|
|
return OP##_complex(x,(CELL)complex(y,tag_fixnum(0))); \
|
|
|
|
case FLOAT_TYPE: \
|
|
|
|
return OP##_complex(x,(CELL)complex(y,tag_fixnum(0))); \
|
2004-07-27 22:52:35 -04:00
|
|
|
default: \
|
2004-08-04 18:25:29 -04:00
|
|
|
if(anytype) \
|
|
|
|
return OP##_anytype(x,y); \
|
|
|
|
else \
|
2004-08-06 18:40:44 -04:00
|
|
|
{ \
|
|
|
|
type_error(NUMBER_TYPE,x); \
|
|
|
|
return F; \
|
|
|
|
} \
|
2004-07-27 22:52:35 -04:00
|
|
|
} \
|
2004-07-28 19:02:24 -04:00
|
|
|
\
|
2004-08-05 16:49:55 -04:00
|
|
|
case BIGNUM_TYPE: \
|
|
|
|
\
|
|
|
|
switch(type_of(y)) \
|
|
|
|
{ \
|
|
|
|
case FIXNUM_TYPE: \
|
|
|
|
return OP##_bignum(x,(CELL)fixnum_to_bignum(y)); \
|
|
|
|
case RATIO_TYPE: \
|
|
|
|
if(integerOnly) \
|
2004-08-05 20:29:52 -04:00
|
|
|
{ \
|
2004-08-06 18:40:44 -04:00
|
|
|
type_error(INTEGER_TYPE,y); \
|
2004-08-05 20:29:52 -04:00
|
|
|
return F; \
|
|
|
|
} \
|
2004-08-05 16:49:55 -04:00
|
|
|
else \
|
|
|
|
return OP##_ratio((CELL)bignum_to_ratio(x),y); \
|
2004-08-05 20:29:52 -04:00
|
|
|
case COMPLEX_TYPE: \
|
|
|
|
if(integerOnly) \
|
|
|
|
{ \
|
2004-08-06 18:40:44 -04:00
|
|
|
type_error(INTEGER_TYPE,y); \
|
2004-08-05 20:29:52 -04:00
|
|
|
return F; \
|
|
|
|
} \
|
|
|
|
else \
|
|
|
|
return OP##_complex((CELL)complex(x,tag_fixnum(0)),y); \
|
2004-08-05 16:49:55 -04:00
|
|
|
case BIGNUM_TYPE: \
|
|
|
|
return OP##_bignum(x,y); \
|
|
|
|
case FLOAT_TYPE: \
|
|
|
|
if(integerOnly) \
|
2004-08-05 20:29:52 -04:00
|
|
|
{ \
|
2004-08-06 18:40:44 -04:00
|
|
|
type_error(INTEGER_TYPE,y); \
|
2004-08-05 20:29:52 -04:00
|
|
|
return F; \
|
|
|
|
} \
|
2004-08-05 16:49:55 -04:00
|
|
|
else \
|
|
|
|
return OP##_float((CELL)bignum_to_float(x),y); \
|
|
|
|
default: \
|
|
|
|
if(anytype) \
|
|
|
|
return OP##_anytype(x,y); \
|
|
|
|
else \
|
2004-08-06 18:40:44 -04:00
|
|
|
{ \
|
|
|
|
type_error(NUMBER_TYPE,x); \
|
|
|
|
return F; \
|
|
|
|
} \
|
2004-08-05 16:49:55 -04:00
|
|
|
} \
|
2004-08-04 22:43:58 -04:00
|
|
|
\
|
2004-08-05 16:49:55 -04:00
|
|
|
case FLOAT_TYPE: \
|
2004-08-05 20:29:52 -04:00
|
|
|
\
|
|
|
|
if(integerOnly) \
|
|
|
|
{ \
|
2004-08-06 18:40:44 -04:00
|
|
|
type_error(INTEGER_TYPE,x); \
|
2004-08-05 20:29:52 -04:00
|
|
|
return F; \
|
|
|
|
} \
|
|
|
|
\
|
2004-08-05 16:49:55 -04:00
|
|
|
switch(type_of(y)) \
|
2004-08-04 22:43:58 -04:00
|
|
|
{ \
|
|
|
|
case FIXNUM_TYPE: \
|
2004-08-05 20:29:52 -04:00
|
|
|
return OP##_float(x,(CELL)fixnum_to_float(y)); \
|
2004-08-04 22:43:58 -04:00
|
|
|
case RATIO_TYPE: \
|
2004-08-05 20:29:52 -04:00
|
|
|
return OP##_float(x,(CELL)ratio_to_float(y)); \
|
|
|
|
case COMPLEX_TYPE: \
|
|
|
|
return OP##_complex((CELL)complex(x,tag_fixnum(0)),y); \
|
2004-08-05 16:49:55 -04:00
|
|
|
case BIGNUM_TYPE: \
|
2004-08-05 20:29:52 -04:00
|
|
|
return OP##_float(x,(CELL)bignum_to_float(y)); \
|
2004-08-05 16:49:55 -04:00
|
|
|
case FLOAT_TYPE: \
|
2004-08-05 20:29:52 -04:00
|
|
|
return OP##_float(x,y); \
|
2004-08-04 22:43:58 -04:00
|
|
|
default: \
|
2004-08-06 18:40:44 -04:00
|
|
|
if(anytype) \
|
|
|
|
return OP##_anytype(x,y); \
|
|
|
|
else \
|
|
|
|
{ \
|
|
|
|
type_error(NUMBER_TYPE,x); \
|
|
|
|
return F; \
|
|
|
|
} \
|
2004-08-04 22:43:58 -04:00
|
|
|
} \
|
2004-07-27 22:52:35 -04:00
|
|
|
\
|
|
|
|
default: \
|
|
|
|
\
|
2004-08-04 18:25:29 -04:00
|
|
|
if(anytype) \
|
|
|
|
return OP##_anytype(x,y); \
|
|
|
|
else \
|
2004-08-06 18:40:44 -04:00
|
|
|
{ \
|
|
|
|
type_error(NUMBER_TYPE,x); \
|
|
|
|
return F; \
|
|
|
|
} \
|
2004-07-27 22:52:35 -04:00
|
|
|
} \
|
2004-08-04 18:25:29 -04:00
|
|
|
} \
|
|
|
|
\
|
|
|
|
void primitive_##OP(void) \
|
|
|
|
{ \
|
|
|
|
CELL x = dpop(), y = env.dt; \
|
|
|
|
env.dt = OP(x,y); \
|
2004-07-27 22:52:35 -04:00
|
|
|
}
|
|
|
|
|
2004-08-06 18:40:44 -04:00
|
|
|
#define UNARY_OP(OP,anytype,integerOnly) \
|
|
|
|
CELL OP(CELL x) \
|
|
|
|
{ \
|
|
|
|
switch(type_of(x)) \
|
|
|
|
{ \
|
|
|
|
case FIXNUM_TYPE: \
|
|
|
|
return OP##_fixnum(x); \
|
|
|
|
case RATIO_TYPE: \
|
|
|
|
if(integerOnly) \
|
|
|
|
{ \
|
|
|
|
type_error(INTEGER_TYPE,x); \
|
|
|
|
return F; \
|
|
|
|
} \
|
|
|
|
else \
|
|
|
|
return OP##_ratio(x); \
|
|
|
|
case COMPLEX_TYPE: \
|
|
|
|
if(integerOnly) \
|
|
|
|
{ \
|
|
|
|
type_error(INTEGER_TYPE,x); \
|
|
|
|
return F; \
|
|
|
|
} \
|
|
|
|
else \
|
|
|
|
return OP##_complex(x); \
|
|
|
|
case BIGNUM_TYPE: \
|
|
|
|
return OP##_bignum(x); \
|
|
|
|
case FLOAT_TYPE: \
|
|
|
|
if(integerOnly) \
|
|
|
|
{ \
|
|
|
|
type_error(INTEGER_TYPE,x); \
|
|
|
|
return F; \
|
|
|
|
} \
|
|
|
|
else \
|
|
|
|
return OP##_float(x); \
|
|
|
|
default: \
|
|
|
|
if(anytype) \
|
|
|
|
return OP##_anytype(x); \
|
|
|
|
else \
|
|
|
|
{ \
|
|
|
|
type_error(NUMBER_TYPE,x); \
|
|
|
|
return F; \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
void primitive_##OP(void) \
|
|
|
|
{ \
|
|
|
|
env.dt = OP(env.dt); \
|
|
|
|
}
|
|
|
|
|
2004-08-05 20:29:52 -04:00
|
|
|
bool realp(CELL tagged);
|
|
|
|
bool numberp(CELL tagged);
|
2004-08-04 18:25:29 -04:00
|
|
|
void primitive_numberp(void);
|
2004-08-04 22:43:58 -04:00
|
|
|
|
2004-08-05 20:29:52 -04:00
|
|
|
bool zerop(CELL tagged);
|
|
|
|
|
2004-07-29 17:18:41 -04:00
|
|
|
FIXNUM to_fixnum(CELL tagged);
|
2004-08-04 18:25:29 -04:00
|
|
|
void primitive_to_fixnum(void);
|
|
|
|
BIGNUM* to_bignum(CELL tagged);
|
|
|
|
void primitive_to_bignum(void);
|
2004-08-04 22:43:58 -04:00
|
|
|
CELL to_integer(CELL tagged);
|
|
|
|
void primitive_to_integer(void);
|
|
|
|
CELL number_eq(CELL x, CELL y);
|
2004-08-04 18:25:29 -04:00
|
|
|
void primitive_number_eq(void);
|
2004-08-05 15:18:31 -04:00
|
|
|
CELL add(CELL x, CELL y);
|
2004-07-28 19:02:24 -04:00
|
|
|
void primitive_add(void);
|
2004-08-05 15:18:31 -04:00
|
|
|
CELL subtract(CELL x, CELL y);
|
2004-07-28 19:02:24 -04:00
|
|
|
void primitive_subtract(void);
|
2004-08-05 15:18:31 -04:00
|
|
|
CELL multiply(CELL x, CELL y);
|
2004-07-28 19:02:24 -04:00
|
|
|
void primitive_multiply(void);
|
2004-08-05 15:18:31 -04:00
|
|
|
CELL divide(CELL x, CELL y);
|
2004-07-28 19:02:24 -04:00
|
|
|
void primitive_divmod(void);
|
2004-08-05 15:18:31 -04:00
|
|
|
CELL divint(CELL x, CELL y);
|
2004-08-04 22:43:58 -04:00
|
|
|
void primitive_divint(void);
|
2004-08-05 16:49:55 -04:00
|
|
|
CELL divfloat(CELL x, CELL y);
|
|
|
|
void primitive_divfloat(void);
|
|
|
|
CELL divide(CELL x, CELL y);
|
2004-08-04 22:43:58 -04:00
|
|
|
void primitive_divide(void);
|
2004-08-05 16:49:55 -04:00
|
|
|
CELL less(CELL x, CELL y);
|
2004-07-28 19:02:24 -04:00
|
|
|
void primitive_less(void);
|
2004-08-05 16:49:55 -04:00
|
|
|
CELL lesseq(CELL x, CELL y);
|
2004-07-28 19:02:24 -04:00
|
|
|
void primitive_lesseq(void);
|
2004-08-05 16:49:55 -04:00
|
|
|
CELL greater(CELL x, CELL y);
|
2004-07-28 19:02:24 -04:00
|
|
|
void primitive_greater(void);
|
2004-08-05 16:49:55 -04:00
|
|
|
CELL greatereq(CELL x, CELL y);
|
2004-07-28 19:02:24 -04:00
|
|
|
void primitive_greatereq(void);
|
2004-08-05 16:49:55 -04:00
|
|
|
CELL mod(CELL x, CELL y);
|
2004-07-29 17:18:41 -04:00
|
|
|
void primitive_mod(void);
|
2004-08-05 16:49:55 -04:00
|
|
|
CELL and(CELL x, CELL y);
|
2004-07-29 17:18:41 -04:00
|
|
|
void primitive_and(void);
|
2004-08-05 16:49:55 -04:00
|
|
|
CELL or(CELL x, CELL y);
|
2004-07-29 17:18:41 -04:00
|
|
|
void primitive_or(void);
|
2004-08-05 16:49:55 -04:00
|
|
|
CELL xor(CELL x, CELL y);
|
2004-07-29 17:18:41 -04:00
|
|
|
void primitive_xor(void);
|
2004-08-05 16:49:55 -04:00
|
|
|
CELL shiftleft(CELL x, CELL y);
|
2004-07-29 17:18:41 -04:00
|
|
|
void primitive_shiftleft(void);
|
2004-08-05 16:49:55 -04:00
|
|
|
CELL shiftright(CELL x, CELL y);
|
2004-07-29 17:18:41 -04:00
|
|
|
void primitive_shiftright(void);
|
2004-08-06 18:40:44 -04:00
|
|
|
CELL gcd(CELL x, CELL y);
|
|
|
|
void primitive_gcd(void);
|