Пример #1
0
txInteger fxToInteger(txMachine* the, txSlot* theSlot)
{
#if mxOptimize
	if (XS_INTEGER_KIND == theSlot->kind)
		return theSlot->value.integer;				// this is the case over 90% of the time, so avoid the switch
#endif

again:
	switch (theSlot->kind) {
	case XS_UNDEFINED_KIND:
	case XS_NULL_KIND:
		theSlot->kind = XS_INTEGER_KIND;
		theSlot->value.integer = 0;
		break;
	case XS_BOOLEAN_KIND:
		theSlot->kind = XS_INTEGER_KIND;
		if (theSlot->value.boolean == 0)
			theSlot->value.integer = 0;
		else
			theSlot->value.integer = 1;
		break;
	case XS_INTEGER_KIND:
		break;
	case XS_NUMBER_KIND:
		theSlot->kind = XS_INTEGER_KIND;
		switch (c_fpclassify(theSlot->value.number)) {
		case C_FP_INFINITE:
		case C_FP_NAN:
		case C_FP_ZERO:
			theSlot->value.integer = 0;
			break;
		default: {
			#define MODULO 4294967296.0
			txNumber aNumber = c_fmod(c_trunc(theSlot->value.number), MODULO);
			if (aNumber >= MODULO / 2)
				aNumber -= MODULO;
			else if (aNumber < -MODULO / 2)
				aNumber += MODULO;
			theSlot->value.integer = (txInteger)aNumber;
			} break;
		}
		break;
	case XS_STRING_KIND:
	case XS_STRING_X_KIND:
		theSlot->kind = XS_NUMBER_KIND;
		theSlot->value.number = fxStringToNumber(the->dtoa, theSlot->value.string, 1);
		goto again;
	case XS_SYMBOL_KIND:
		mxTypeError("Cannot coerce symbol to integer");
		break;
	case XS_REFERENCE_KIND:
		fxToPrimitive(the, theSlot, XS_NUMBER_HINT);
		goto again;
	default:
		mxTypeError("Cannot coerce to integer");
		break;
	}
	return theSlot->value.integer;
}
Пример #2
0
txIndex fxArgToArrayLimit(txMachine* the, txInteger argi)
{
	if (mxArgc > argi) {
		txNumber i = c_trunc(fxToNumber(the, mxArgv(argi)));
		if (c_isnan(i))
			i = 0;
		else if (i < 0)
			i = 0;
		else if (i > XS_MAX_INDEX)
			i = XS_MAX_INDEX;
		return (txIndex)i;
	}
	return XS_MAX_INDEX;
}
Пример #3
0
void fx_Number_isInteger(txMachine* the)
{
	int fpclass;
	txSlot* slot = (mxArgc < 1) ?  C_NULL : fxCheckNumber(the, mxArgv(0));
	mxResult->kind = XS_BOOLEAN_KIND;
    mxResult->value.boolean = 0;
    if (slot) {
		fpclass = c_fpclassify(slot->value.number);
		if ((fpclass != FP_NAN) && (fpclass != FP_INFINITE)) {
			txNumber check = c_trunc(slot->value.number);
			if (slot->value.number == check)
				mxResult->value.boolean = 1;
		}
	}
}
Пример #4
0
txIndex fxArgToIndex(txMachine* the, txInteger argi, txIndex index, txIndex length)
{
	if (mxArgc > argi) {
		txNumber c = length;
		txNumber i = c_trunc(fxToNumber(the, mxArgv(argi)));
		if (c_isnan(i))
			i = 0;
		if (i < 0) {
			i = c + i;
			if (i < 0)
				i = 0;
		}
		else if (i > c)
			i = c;
		index = (txIndex)i;
	}
	return index;
}
Пример #5
0
void fx_Date_prototype_setTime(txMachine* the)
{
	txSlot* slot = fxCheckDate(the, mxThis);
	if (!slot) mxTypeError("this is no date");
	if (mxArgc < 1)
		slot->value.number = C_NAN;
	else {
		txNumber number = fxToNumber(the, mxArgv(0));
		int fpclass = c_fpclassify(number);
		if (fpclass != FP_NAN) {
			if (c_fabs(number) > 8.64e15)
				number = C_NAN;
			else
				number = c_trunc(number);
		}
		slot->value.number = number;
	}
	mxResult->value.number = slot->value.number;
	mxResult->kind = XS_NUMBER_KIND;
}
Пример #6
0
void fx_Date_prototype_set_aux(txMachine* the, txTimeDescription* td, txSlot* slot)
{
	c_time_t time;
	txNumber number;
	
	td->tm.tm_isdst = -1;
	time = c_mktime(&(td->tm));	
	if (time == -1)
		number = C_NAN;
	else {
		number = (time * 1000.0) + td->ms;
		if (c_fpclassify(number) != FP_NAN) {
			if (c_fabs(number) > 8.64e15)
				number = C_NAN;
			else
				number = c_trunc(number);
		}
	}
	mxResult->value.number = number;
	mxResult->kind = XS_NUMBER_KIND;
	slot->value.number = number;
}
Пример #7
0
txUnsigned fxToUnsigned(txMachine* the, txSlot* theSlot)
{
	txUnsigned result;
again:
	switch (theSlot->kind) {
	case XS_UNDEFINED_KIND:
	case XS_NULL_KIND:
		theSlot->kind = XS_INTEGER_KIND;
		result = theSlot->value.integer = 0;
		break;
	case XS_BOOLEAN_KIND:
		theSlot->kind = XS_INTEGER_KIND;
		if (theSlot->value.boolean == 0)
			result = theSlot->value.integer = 0;
		else
			result = theSlot->value.integer = 1;
		break;
	case XS_INTEGER_KIND:
		if (theSlot->value.integer >= 0)
			return (txUnsigned)theSlot->value.integer;
		theSlot->kind = XS_NUMBER_KIND;
		theSlot->value.number = theSlot->value.integer;
		// continue
	case XS_NUMBER_KIND:
		theSlot->kind = XS_INTEGER_KIND;
		switch (c_fpclassify(theSlot->value.number)) {
		case C_FP_INFINITE:
		case C_FP_NAN:
		case C_FP_ZERO:
			result = theSlot->value.integer = 0;
			break;
		default: {
			#define MODULO 4294967296.0
			txNumber aNumber = c_fmod(c_trunc(theSlot->value.number), MODULO);
			if (aNumber < 0)
				aNumber += MODULO;
			result = (txUnsigned)aNumber;
			if (((txInteger)result) >= 0) {
				theSlot->kind = XS_INTEGER_KIND;
				theSlot->value.integer = (txInteger)result;
			}
			else {
				theSlot->kind = XS_NUMBER_KIND;
				theSlot->value.number = aNumber;
			}
			} break;
		}
		break;
	case XS_STRING_KIND:
	case XS_STRING_X_KIND:
		theSlot->kind = XS_NUMBER_KIND;
		theSlot->value.number = fxStringToNumber(the->dtoa, theSlot->value.string, 1);
		goto again;
	case XS_SYMBOL_KIND:
		result = 0;
		mxTypeError("Cannot coerce symbol to unsigned");
		break;
	case XS_REFERENCE_KIND:
		fxToPrimitive(the, theSlot, XS_NUMBER_HINT);
		goto again;
	default:
		result = 0;
		mxTypeError("Cannot coerce to unsigned");
		break;
	}
	return result;
}