Support building without floats

This commit is contained in:
K. Lange 2023-05-30 07:59:28 +09:00
parent cd28d82939
commit 358c6b1c78
10 changed files with 83 additions and 14 deletions

View File

@ -76,6 +76,10 @@ ifdef KRK_NO_STRESS_GC
CFLAGS += -DKRK_NO_STRESS_GC=1
endif
ifdef KRK_NO_FLOAT
CFLAGS += -DKRK_NO_FLOAT=1
endif
ifdef KRK_HEAP_TAG_BYTE
CFLAGS += -DKRK_HEAP_TAG_BYTE=${KRK_HEAP_TAG_BYTE}
endif

View File

@ -1217,9 +1217,11 @@ KRK_Function(abs) {
if (IS_INTEGER(argv[0])) {
krk_integer_type i = AS_INTEGER(argv[0]);
return INTEGER_VAL(i >= 0 ? i : -i);
#ifndef KRK_NO_FLOAT
} else if (IS_FLOATING(argv[0])) {
double i = AS_FLOATING(argv[0]);
return FLOATING_VAL(i >= 0 ? i : -i);
#endif
} else {
trySlowMethod(OBJECT_VAL(S("__abs__")));
return krk_runtimeError(vm.exceptions->typeError, "bad operand type for 'abs()': '%T'", argv[0]);

View File

@ -785,8 +785,12 @@ static void number(struct GlobalState * state, int exprType, RewindState *rewind
for (size_t j = 0; j < state->parser.previous.length; ++j) {
if (state->parser.previous.start[j] == '.') {
#ifndef KRK_NO_FLOAT
double value = strtod(start, NULL);
emitConstant(FLOATING_VAL(value));
#else
error("no float support");
#endif
return;
}
}

View File

@ -273,7 +273,7 @@ static void dumpInnerException(KrkValue exception, int depth) {
lineNo,
(function->name ? function->name->chars : "(unnamed)"));
#ifndef NO_SOURCE_IN_TRACEBACK
#ifndef KRK_NO_SOURCE_IN_TRACEBACK
/* Try to open the file */
if (function->chunk.filename) {
FILE * f = fopen(function->chunk.filename->chars, "r");

View File

@ -1298,6 +1298,7 @@ KRK_StaticMethod(long,__new__) {
}
}
#ifndef KRK_NO_FLOAT
/**
* Float conversions.
*
@ -1389,6 +1390,7 @@ KRK_Method(long,__rtruediv__) {
else return NOTIMPL_VAL();
return _krk_long_truediv(tmp,self->value);
}
#endif
#define PRINTER(name,base,prefix) \
KRK_Method(long,__ ## name ## __) { \
@ -1473,8 +1475,13 @@ KRK_Method(long,__int__) {
}
#define BASIC_BIN_OP(a,b) BASIC_BIN_OP_FLOATS(a,b,,)
#ifndef KRK_NO_FLOAT
#define FLOAT_A(op) else if (IS_FLOATING(argv[1])) return FLOATING_VAL(krk_long_get_double(self->value) op AS_FLOATING(argv[1]));
#define FLOAT_B(op) else if (IS_FLOATING(argv[1])) return FLOATING_VAL(AS_FLOATING(argv[1]) op krk_long_get_double(self->value));
#else
#define FLOAT_A(op) else if (IS_FLOATING(argv[1])) return krk_runtimeError(vm.exceptions->valueError, "no float support");
#define FLOAT_B(op) else if (IS_FLOATING(argv[1])) return krk_runtimeError(vm.exceptions->valueError, "no float support");
#endif
#define BASIC_BIN_OP_FLOAT(a,b,op) BASIC_BIN_OP_FLOATS(a,b,FLOAT_A(op),FLOAT_B(op))
BASIC_BIN_OP_FLOAT(add,krk_long_add,+)
@ -1583,12 +1590,18 @@ BASIC_BIN_OP(mod,_krk_long_mod)
BASIC_BIN_OP(floordiv,_krk_long_div)
BASIC_BIN_OP(pow,_krk_long_pow)
#ifndef KRK_NO_FLOAT
#define KRK_FLOAT_COMPARE(comp) else if (IS_FLOATING(argv[1])) return BOOLEAN_VAL(krk_long_get_double(self->value) comp AS_FLOATING(argv[1]));
#else
#define KRK_FLOAT_COMPARE(comp)
#endif
#define COMPARE_OP(name, comp) \
KRK_Method(long,__ ## name ## __) { \
krk_long tmp; \
if (IS_long(argv[1])) krk_long_init_copy(tmp, AS_long(argv[1])->value); \
else if (IS_INTEGER(argv[1])) krk_long_init_si(tmp, AS_INTEGER(argv[1])); \
else if (IS_FLOATING(argv[1])) return BOOLEAN_VAL(krk_long_get_double(self->value) comp AS_FLOATING(argv[1])); \
KRK_FLOAT_COMPARE(comp) \
else return NOTIMPL_VAL(); \
int cmp = krk_long_compare(self->value,tmp); \
krk_long_clear(tmp); \
@ -2047,7 +2060,6 @@ void _createAndBind_longClass(void) {
BIND_METHOD(long,__bin__);
BIND_METHOD(long,__int__);
BIND_METHOD(long,__len__);
BIND_METHOD(long,__float__);
BIND_METHOD(long,__pos__);
krk_defineNative(&_long->methods,"__repr__", FUNC_NAME(long,__str__));
@ -2060,10 +2072,14 @@ void _createAndBind_longClass(void) {
BIND_TRIPLET(long,lshift);
BIND_TRIPLET(long,rshift);
BIND_TRIPLET(long,mod);
BIND_TRIPLET(long,truediv);
BIND_TRIPLET(long,floordiv);
BIND_TRIPLET(long,pow);
#ifndef KRK_NO_FLOAT
BIND_METHOD(long,__float__);
BIND_TRIPLET(long,truediv);
#endif
BIND_METHOD(long,__lt__);
BIND_METHOD(long,__gt__);
BIND_METHOD(long,__le__);

View File

@ -54,7 +54,9 @@ KRK_StaticMethod(int,__new__) {
if (IS_BOOLEAN(x)) return INTEGER_VAL(AS_INTEGER(x));
if (IS_INTEGER(x)) return x;
if (krk_isInstanceOf(x, KRK_BASE_CLASS(long))) return x;
#ifndef KRK_NO_FLOAT
if (IS_FLOATING(x)) return krk_int_from_float(AS_FLOATING(x));
#endif
if (IS_BOOLEAN(x)) return INTEGER_VAL(AS_BOOLEAN(x));
return krk_runtimeError(vm.exceptions->typeError, "%s() argument must be a string or a number, not '%T'", "int", x);
}
@ -66,7 +68,10 @@ KRK_Method(int,__str__) {
}
KRK_Method(int,__int__) { return argv[0]; }
#ifndef KRK_NO_FLOAT
KRK_Method(int,__float__) { return FLOATING_VAL(self); }
#endif
KRK_Method(int,__chr__) {
unsigned char bytes[5] = {0};
@ -77,7 +82,9 @@ KRK_Method(int,__chr__) {
KRK_Method(int,__eq__) {
METHOD_TAKES_EXACTLY(1);
if (likely(IS_INTEGER(argv[1]))) return BOOLEAN_VAL(self == AS_INTEGER(argv[1]));
#ifndef KRK_NO_FLOAT
else if (IS_FLOATING(argv[1])) return BOOLEAN_VAL(self == AS_FLOATING(argv[1]));
#endif
return NOTIMPL_VAL();
}
@ -355,15 +362,21 @@ OVERFLOW_CHECKED_INT_OPERATION(add,+)
OVERFLOW_CHECKED_INT_OPERATION(sub,-)
OVERFLOW_CHECKED_INT_OPERATION(mul,*)
#ifndef KRK_NO_FLOAT
# define MAYBE_FLOAT(x) x
#else
# define MAYBE_FLOAT(x) krk_runtimeError(vm.exceptions->valueError, "no float support")
#endif
#define BASIC_BIN_OP(name,operator) \
KRK_Method(int,__ ## name ## __) { \
if (likely(IS_INTEGER(argv[1]))) return krk_int_op_ ## name(self, AS_INTEGER(argv[1])); \
else if (likely(IS_FLOATING(argv[1]))) return FLOATING_VAL((double)self operator AS_FLOATING(argv[1])); \
else if (likely(IS_FLOATING(argv[1]))) return MAYBE_FLOAT(FLOATING_VAL((double)self operator AS_FLOATING(argv[1]))); \
return NOTIMPL_VAL(); \
} \
KRK_Method(int,__r ## name ## __) { \
if (likely(IS_INTEGER(argv[1]))) return krk_int_op_ ## name(AS_INTEGER(argv[1]), self); \
else if (likely(IS_FLOATING(argv[1]))) return FLOATING_VAL(AS_FLOATING(argv[1]) operator (double)self); \
else if (likely(IS_FLOATING(argv[1]))) return MAYBE_FLOAT(FLOATING_VAL(AS_FLOATING(argv[1]) operator (double)self)); \
return NOTIMPL_VAL(); \
}
@ -380,7 +393,7 @@ OVERFLOW_CHECKED_INT_OPERATION(mul,*)
#define COMPARE_OP(name,operator) \
KRK_Method(int,__ ## name ## __) { \
if (likely(IS_INTEGER(argv[1]))) return BOOLEAN_VAL(self operator AS_INTEGER(argv[1])); \
else if (likely(IS_FLOATING(argv[1]))) return BOOLEAN_VAL((double)self operator AS_FLOATING(argv[1])); \
else if (likely(IS_FLOATING(argv[1]))) return MAYBE_FLOAT(BOOLEAN_VAL((double)self operator AS_FLOATING(argv[1]))); \
return NOTIMPL_VAL(); \
}
@ -415,6 +428,7 @@ COMPARE_OP(ge, >=)
#undef INT_ONLY_BIN_OP
#undef COMPARE_OP
#ifndef KRK_NO_FLOAT
KRK_Method(int,__truediv__) {
METHOD_TAKES_EXACTLY(1);
if (likely(IS_INTEGER(argv[1]))) {
@ -436,6 +450,7 @@ KRK_Method(int,__rtruediv__) {
else if (likely(IS_FLOATING(argv[1]))) return FLOATING_VAL(AS_FLOATING(argv[1]) / (double)self);
return NOTIMPL_VAL();
}
#endif
#ifdef __TINYC__
#include <math.h>
@ -495,9 +510,13 @@ KRK_Method(int,__floordiv__) {
if (likely(IS_INTEGER(argv[1]))) {
return _krk_int_div(self,AS_INTEGER(argv[1]));
} else if (likely(IS_FLOATING(argv[1]))) {
#ifndef KRK_NO_FLOAT
double b = AS_FLOATING(argv[1]);
if (unlikely(b == 0.0)) return krk_runtimeError(vm.exceptions->zeroDivisionError, "float division by zero");
return FLOATING_VAL(__builtin_floor((double)self / b));
#else
return krk_runtimeError(vm.exceptions->valueError, "no float support");
#endif
}
return NOTIMPL_VAL();
}
@ -506,7 +525,7 @@ KRK_Method(int,__rfloordiv__) {
METHOD_TAKES_EXACTLY(1);
if (unlikely(self == 0)) return krk_runtimeError(vm.exceptions->zeroDivisionError, "integer division by zero");
else if (likely(IS_INTEGER(argv[1]))) return _krk_int_div(AS_INTEGER(argv[1]), self);
else if (likely(IS_FLOATING(argv[1]))) return FLOATING_VAL(__builtin_floor(AS_FLOATING(argv[1]) / (double)self));
else if (likely(IS_FLOATING(argv[1]))) return MAYBE_FLOAT(FLOATING_VAL(__builtin_floor(AS_FLOATING(argv[1]) / (double)self)));
return NOTIMPL_VAL();
}
@ -585,6 +604,7 @@ KRK_Method(int,__pos__) {
} \
} while (0)
#ifndef KRK_NO_FLOAT
KRK_StaticMethod(float,__new__) {
FUNCTION_TAKES_AT_MOST(2);
if (argc < 2) return FLOATING_VAL(0.0);
@ -716,6 +736,7 @@ KRK_Method(float,__rfloordiv__) {
KRK_Method(float,__pos__) {
return argv[0];
}
#endif
#undef CURRENT_CTYPE
#define CURRENT_CTYPE krk_integer_type
@ -789,7 +810,6 @@ void _createAndBind_numericClasses(void) {
BIND_METHOD(int,__str__);
BIND_METHOD(int,__int__);
BIND_METHOD(int,__chr__);
BIND_METHOD(int,__float__);
BIND_METHOD(int,__eq__);
BIND_METHOD(int,__hash__);
BIND_METHOD(int,__format__);
@ -803,10 +823,14 @@ void _createAndBind_numericClasses(void) {
BIND_TRIPLET(int,lshift);
BIND_TRIPLET(int,rshift);
BIND_TRIPLET(int,mod);
BIND_TRIPLET(int,truediv);
BIND_TRIPLET(int,floordiv);
BIND_TRIPLET(int,pow);
#ifndef KRK_NO_FLOAT
BIND_METHOD(int,__float__);
BIND_TRIPLET(int,truediv);
#endif
BIND_METHOD(int,__lt__);
BIND_METHOD(int,__gt__);
BIND_METHOD(int,__le__);
@ -827,6 +851,7 @@ void _createAndBind_numericClasses(void) {
KrkClass * _float = ADD_BASE_CLASS(vm.baseClasses->floatClass, "float", vm.baseClasses->objectClass);
_float->obj.flags |= KRK_OBJ_FLAGS_NO_INHERIT;
_float->allocSize = 0;
#ifndef KRK_NO_FLOAT
BIND_STATICMETHOD(float,__new__);
BIND_METHOD(float,__int__);
BIND_METHOD(float,__float__);
@ -846,6 +871,7 @@ void _createAndBind_numericClasses(void) {
BIND_METHOD(float,__abs__);
BIND_METHOD(float,__pos__);
krk_defineNative(&_float->methods, "__repr__", FUNC_NAME(float,__str__));
#endif
krk_finalizeClass(_float);
KRK_DOC(_float, "Convert a number or string type to a float representation.");

View File

@ -101,7 +101,11 @@ KRK_Method(str,__int__) {
/* str.__float__() */
KRK_Method(str,__float__) {
METHOD_TAKES_NONE();
#ifndef KRK_NO_FLOAT
return FLOATING_VAL(strtod(AS_CSTRING(argv[0]),NULL));
#else
return krk_runtimeError(vm.exceptions->valueError, "no float support");
#endif
}
KRK_Method(str,__getitem__) {

View File

@ -302,6 +302,7 @@ int krk_parseVArgs(
break;
}
#ifndef KRK_NO_FLOAT
/**
* @c f Accept a Kuroko float as C float.
*/
@ -343,6 +344,12 @@ int krk_parseVArgs(
}
break;
}
#else
case 'f':
case 'd':
krk_runtimeError(vm.exceptions->typeError, "no float support");
goto _error;
#endif
/**
* @c p Accept any value and examine its truthiness, returning an @c int.

View File

@ -9,7 +9,7 @@
#include <kuroko/threads.h>
#include <kuroko/util.h>
#define TABLE_MAX_LOAD 0.75
#define TABLE_MAX_LOAD 3 / 4
void krk_initTable(KrkTable * table) {
table->count = 0;
@ -38,8 +38,12 @@ inline int krk_hashValue(KrkValue value, uint32_t *hashOut) {
}
break;
default:
#ifndef KRK_NO_FLOAT
*hashOut = (uint32_t)AS_FLOATING(value);
return 0;
#else
break;
#endif
}
KrkClass * type = krk_getType(value);
if (type && type->_hash) {

View File

@ -864,7 +864,9 @@ int krk_isFalsey(KrkValue value) {
break;
}
default:
#ifndef KRK_NO_FLOAT
if (IS_FLOATING(value)) return !AS_FLOATING(value);
#endif
break;
}
KrkClass * type = krk_getType(value);
@ -2994,7 +2996,7 @@ _finishPopBlock:
case OP_REVERSE: {
ONE_BYTE_OPERAND;
krk_push(NONE_VAL()); /* Storage space */
for (ssize_t i = 0; i < OPERAND / 2; ++i) {
for (ssize_t i = 0; i < (ssize_t)OPERAND / 2; ++i) {
krk_currentThread.stackTop[-1] = krk_currentThread.stackTop[-i-2];
krk_currentThread.stackTop[-i-2] = krk_currentThread.stackTop[-(OPERAND-i)-1];
krk_currentThread.stackTop[-(OPERAND-i)-1] = krk_currentThread.stackTop[-1];
@ -3046,7 +3048,7 @@ _finishPopBlock:
struct StringBuilder sb = {0};
for (ssize_t i = 0; i < OPERAND; ++i) {
for (ssize_t i = 0; i < (ssize_t)OPERAND; ++i) {
KrkValue s = krk_currentThread.stackTop[-(ssize_t)OPERAND+i];
if (unlikely(!IS_STRING(s))) {
discardStringBuilder(&sb);
@ -3056,7 +3058,7 @@ _finishPopBlock:
pushStringBuilderStr(&sb, (char*)AS_STRING(s)->chars, AS_STRING(s)->length);
}
for (ssize_t i = 0; i < OPERAND; ++i) {
for (ssize_t i = 0; i < (ssize_t)OPERAND; ++i) {
krk_pop();
}