Ejemplo n.º 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;
}
Ejemplo n.º 2
0
void fx_Number_prototype_toString(txMachine* the)
{
	char buffer[256];
	txInteger radix;
	txSlot* slot = fxCheckNumber(the, mxThis);
	if (!slot) mxTypeError("this is no number");
	if (mxArgc > 0) {
		radix = fxToInteger(the, mxArgv(0));
		if (radix) {
			if ((radix < 2) || (36 < radix))
				mxRangeError("invalid radix");
		}
		else	
			radix = 10;
	}
	else	
		radix = 10;
	mxResult->kind = slot->kind;
	mxResult->value = slot->value;
	if (radix == 10)
		fxToString(the, mxResult);
	else {
		static char gxDigits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		txString string = buffer + sizeof(buffer);
		txNumber value;
		txBoolean minus;
		value = mxResult->value.number;
		switch (c_fpclassify(value)) {
		case C_FP_INFINITE:
			if (value < 0)
				fxCopyStringC(the, mxResult, "-Infinity");
			else
				fxCopyStringC(the, mxResult, "Infinity");
			break;
		case C_FP_NAN:
			fxCopyStringC(the, mxResult, "NaN");
			break;
		case C_FP_ZERO:
			fxCopyStringC(the, mxResult, "0");
			break;
		default:
			*(--string) = 0;
			if (value < 0) {
				minus = 1;
				value = -value;
			} 
			else
				minus = 0;
			do {
				*(--string) = gxDigits[(txInteger)c_fmod(value, radix)];
				value = value / radix;
			} while (value >= 1);
			if (minus)
				*(--string) = '-';
			fxCopyStringC(the, mxResult, string);
		}
	}
}
Ejemplo n.º 3
0
void fx_isNaN(txMachine* the)
{
	int fpclass;
	txNumber number = (mxArgc < 1) ?  C_NAN : fxToNumber(the, mxArgv(0)); 
	mxResult->kind = XS_BOOLEAN_KIND;
    mxResult->value.boolean = 0;
	fpclass = c_fpclassify(number);
	if (fpclass == FP_NAN)
		mxResult->value.boolean = 1;
}
Ejemplo n.º 4
0
void fxSerializeJSONNumber(txMachine* the, txJSONSerializer* theSerializer, txNumber theNumber)
{
	int fpclass = c_fpclassify(theNumber);
	if ((fpclass != FP_NAN) && (fpclass != FP_INFINITE)) {
		char aBuffer[256];
		fxNumberToString(the, theNumber, aBuffer, sizeof(aBuffer), 0, 0);
		fxSerializeJSONChars(the, theSerializer, aBuffer);
	}
	else
		fxSerializeJSONChars(the, theSerializer, "null");
}
Ejemplo n.º 5
0
void fx_Number_isNaN(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)
			mxResult->value.boolean = 1;
	}
}
Ejemplo n.º 6
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;
		}
	}
}
Ejemplo n.º 7
0
txBoolean fxToBoolean(txMachine* the, txSlot* theSlot)
{
	switch (theSlot->kind) {
	case XS_UNDEFINED_KIND:
	case XS_NULL_KIND:
		theSlot->kind = XS_BOOLEAN_KIND;
		theSlot->value.boolean = 0;
		break;
	case XS_BOOLEAN_KIND:
		break;
	case XS_INTEGER_KIND:
		theSlot->kind = XS_BOOLEAN_KIND;
		theSlot->value.boolean = (theSlot->value.integer == 0) ? 0 : 1;
		break;
	case XS_NUMBER_KIND:
		theSlot->kind = XS_BOOLEAN_KIND;
		switch (c_fpclassify(theSlot->value.number)) {
		case FP_NAN:
		case FP_ZERO:
			theSlot->value.boolean = 0;
			break;
		default:
			theSlot->value.boolean = 1;
			break;
		}
		break;
	case XS_STRING_KIND:
	case XS_STRING_X_KIND:
		theSlot->kind = XS_BOOLEAN_KIND;
		if (c_strlen(theSlot->value.string) == 0)
			theSlot->value.boolean = 0;
		else
			theSlot->value.boolean = 1;
		break;
	case XS_SYMBOL_KIND:
	case XS_REFERENCE_KIND:
		theSlot->kind = XS_BOOLEAN_KIND;
		theSlot->value.boolean = 1;
		break;
	default:
		mxTypeError("Cannot coerce to boolean");
		break;
	}
	return theSlot->value.boolean;
}
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
0
txBoolean fxRunTest(txMachine* the)
{
	txBoolean result;
	
	switch (the->stack->kind) {
	case XS_UNDEFINED_KIND:
	case XS_NULL_KIND:
		result = 0;
		break;
	case XS_BOOLEAN_KIND:
		result = the->stack->value.boolean;
		break;
	case XS_INTEGER_KIND:
		result = (the->stack->value.integer == 0) ? 0 : 1;
		break;
	case XS_NUMBER_KIND:
		switch (c_fpclassify(the->stack->value.number)) {
		case FP_NAN:
		case FP_ZERO:
			result = 0;
			break;
		default:
			result = 1;
			break;
		}
		break;
	case XS_STRING_KIND:
	case XS_STRING_X_KIND:
		if (c_strlen(the->stack->value.string) == 0)
			result = 0;
		else
			result = 1;
		break;
	default:
		result = 1;
		break;
	}
	the->stack++;
	return result;
}
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
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;
}