factor/native/arithmetic.h

187 lines
3.8 KiB
C
Raw Normal View History

#include "factor.h"
CELL upgraded_arithmetic_type(CELL type1, CELL type2);
2004-08-25 02:00:52 -04:00
ARRAY* fixnum_to_bignum(CELL n);
2004-08-05 15:18:31 -04:00
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-26 22:21:17 -04:00
CELL tag_fixnum_or_bignum(FIXNUM x);
2004-08-07 19:59:54 -04:00
#define BINARY_OP(OP) \
CELL OP(CELL x, CELL y) \
{ \
switch(upgraded_arithmetic_type(type_of(x),type_of(y))) \
{ \
case FIXNUM_TYPE: \
return OP##_fixnum(x,y); \
2004-08-05 16:49:55 -04:00
case BIGNUM_TYPE: \
return OP##_bignum(to_bignum(x),to_bignum(y)); \
case RATIO_TYPE: \
return OP##_ratio(to_ratio(x),to_ratio(y)); \
2004-08-05 16:49:55 -04:00
case FLOAT_TYPE: \
return OP##_float(to_float(x),to_float(y)); \
case COMPLEX_TYPE: \
return OP##_complex(to_complex(x),to_complex(y)); \
default: \
2004-08-07 19:59:54 -04:00
return OP##_anytype(x,y); \
} \
} \
\
void primitive_##OP(void) \
{ \
CELL y = dpop(), x = dpop(); \
dpush(OP(x,y)); \
}
2004-08-26 19:37:22 -04:00
#define BINARY_OP_FIXNUM(OP) \
CELL OP(CELL x, FIXNUM y) \
{ \
switch(type_of(x)) \
{ \
case FIXNUM_TYPE: \
return OP##_fixnum(x,y); \
case BIGNUM_TYPE: \
return OP##_bignum(to_bignum(x),y); \
default: \
type_error(INTEGER_TYPE,x); \
return F; \
} \
} \
\
void primitive_##OP(void) \
{ \
CELL y = dpop(), x = dpop(); \
dpush(OP(x,to_fixnum(y))); \
}
2004-08-07 19:59:54 -04:00
#define BINARY_OP_INTEGER_ONLY(OP) \
\
CELL OP##_ratio(RATIO* x, RATIO* y) \
2004-08-07 19:59:54 -04:00
{ \
type_error(INTEGER_TYPE,tag_ratio(x)); \
2004-08-07 19:59:54 -04:00
return F; \
} \
\
CELL OP##_complex(COMPLEX* x, COMPLEX* y) \
2004-08-07 19:59:54 -04:00
{ \
type_error(INTEGER_TYPE,tag_complex(x)); \
2004-08-07 19:59:54 -04:00
return F; \
} \
\
CELL OP##_float(FLOAT* x, FLOAT* y) \
2004-08-07 19:59:54 -04:00
{ \
type_error(INTEGER_TYPE,tag_object(x)); \
2004-08-07 19:59:54 -04:00
return F; \
}
#define BINARY_OP_NUMBER_ONLY(OP) \
\
CELL OP##_anytype(CELL x, CELL y) \
{ \
type_error(NUMBER_TYPE,x); \
return F; \
}
2004-08-17 23:42:10 -04:00
#define UNARY_OP(OP) \
CELL OP(CELL x) \
{ \
switch(type_of(x)) \
{ \
case FIXNUM_TYPE: \
return OP##_fixnum(x); \
case RATIO_TYPE: \
return OP##_ratio((RATIO*)UNTAG(x)); \
case COMPLEX_TYPE: \
return OP##_complex((COMPLEX*)UNTAG(x)); \
case BIGNUM_TYPE: \
2004-08-25 02:00:52 -04:00
return OP##_bignum((ARRAY*)UNTAG(x)); \
case FLOAT_TYPE: \
return OP##_float((FLOAT*)UNTAG(x)); \
default: \
2004-08-17 23:42:10 -04:00
return OP##_anytype(x); \
} \
} \
\
void primitive_##OP(void) \
{ \
drepl(OP(dpeek())); \
}
2004-08-17 23:42:10 -04:00
#define UNARY_OP_INTEGER_ONLY(OP) \
\
CELL OP##_ratio(RATIO* x) \
2004-08-17 23:42:10 -04:00
{ \
type_error(INTEGER_TYPE,tag_ratio(x)); \
2004-08-17 23:42:10 -04:00
return F; \
} \
\
CELL OP##_complex(COMPLEX* x) \
2004-08-17 23:42:10 -04:00
{ \
type_error(INTEGER_TYPE,tag_complex(x)); \
2004-08-17 23:42:10 -04:00
return F; \
} \
\
CELL OP##_float(FLOAT* x) \
2004-08-17 23:42:10 -04:00
{ \
type_error(INTEGER_TYPE,tag_object(x)); \
2004-08-17 23:42:10 -04:00
return F; \
}
#define UNARY_OP_NUMBER_ONLY(OP) \
\
CELL OP##_anytype(CELL x) \
{ \
type_error(NUMBER_TYPE,x); \
return F; \
}
2004-08-05 20:29:52 -04:00
bool realp(CELL tagged);
bool numberp(CELL tagged);
void primitive_numberp(void);
2004-08-04 22:43:58 -04:00
2004-08-05 20:29:52 -04:00
bool zerop(CELL tagged);
void primitive_to_fixnum(void);
void primitive_to_bignum(void);
2004-08-04 22:43:58 -04:00
void primitive_to_integer(void);
CELL number_eq(CELL x, CELL y);
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-26 19:37:22 -04:00
CELL shift(CELL x, FIXNUM y);
void primitive_shift(void);
CELL gcd(CELL x, CELL y);
void primitive_gcd(void);