/* This functions is only used when unmarshalling. * The assumptions made here are therefore safe. * String#to_f uses string_to_double */ OBJECT float_from_string(STATE, char *str) { char *endp; double d; d = strtod(str, &endp); if (str != endp && *endp == '\0') { return float_new(state, d); } /* When we get here, we might have a system that doesn't conform to C99 (OpenBSD is at least one) that can't handle Infinity / NaN. We test the strings here manually and fix it if needed. */ int sign = 0; if (*str == '-') { sign = 1; str++; } else if (*str == '+') { str++; } if (*str == 'I' || *str == 'i') { return float_new(state, sign ? -HUGE_VAL : HUGE_VAL); } if (*str == 'N' || *str == 'n') { word0(d) = 0x7ff80000; word1(d) = 0; return float_new(state, d); } return Qnil; }
OBJECT float_coerce(STATE, OBJECT value) { if(FIXNUM_P(value)) { return float_new(state, (double)N2I(value)); } else if(BIGNUM_P(value)) { return float_new(state, bignum_to_double(state, value)); } return value; }
/* Perform type promotion of boxed values according to the following rules: First Second First Second float float -> float float float integer -> float float integer float -> float float integer integer -> integer integer quotation quotation -> quotation quotation quotation * -> word word -> word word * -> * quotation -> * word -> Supplies promoted values as out parameters, either as new values or as boxed copies. Returns whether the given values are of compatible type. */ int boxed_promote(Boxed unpromoted_a, Boxed unpromoted_b, Boxed *promoted_a, Boxed *promoted_b) { assert(unpromoted_a); assert(unpromoted_b); assert(promoted_a); assert(promoted_b); switch (boxed_type(unpromoted_a)) { case FLOAT: switch (boxed_type(unpromoted_b)) { case FLOAT: *promoted_a = boxed_copy(unpromoted_a); *promoted_b = boxed_copy(unpromoted_b); return 1; case INTEGER: *promoted_a = boxed_copy(unpromoted_a); *promoted_b = float_new(integer_value(unpromoted_b)); return 1; case QUOTATION: case WORD: return 0; } case INTEGER: switch (boxed_type(unpromoted_b)) { case FLOAT: *promoted_a = float_new(integer_value(unpromoted_a)); *promoted_b = boxed_copy(unpromoted_b); return 1; case INTEGER: *promoted_a = boxed_copy(unpromoted_a); *promoted_b = boxed_copy(unpromoted_b); return 1; case QUOTATION: case WORD: return 0; } case QUOTATION: switch (boxed_type(unpromoted_b)) { case QUOTATION: *promoted_a = boxed_copy(unpromoted_a); *promoted_b = boxed_copy(unpromoted_b); return 1; default: return 0; } case WORD: switch (boxed_type(unpromoted_b)) { case WORD: *promoted_a = boxed_copy(unpromoted_a); *promoted_b = boxed_copy(unpromoted_b); return 1; default: return 0; } } return 0; }
obj_t float_new_wc(obj_t obj) { ASSERT(!obj || (obj->type != OBJ_FLOAT), "bad object"); return OBJ(float_new(FLOAT(obj)->v)); error: return NULL; }
/* This functions is only used when unmarshalling. * The assumptions made here are therefore safe. * String#to_f uses string_to_double */ OBJECT float_from_string(STATE, char *str) { char *endp; double d; d = ruby_strtod(str, &endp); if (str != endp && *endp == '\0') { return float_new(state, d); } return Qnil; }
PmReturn_t obj_loadFromImg(PmMemSpace_t memspace, uint8_t const **paddr, pPmObj_t *r_pobj) { PmReturn_t retval = PM_RET_OK; PmObj_t obj; /* Get the object descriptor */ obj.od = (PmObjDesc_t)0x0000; OBJ_SET_TYPE(&obj, mem_getByte(memspace, paddr)); switch (OBJ_GET_TYPE(&obj)) { case OBJ_TYPE_NON: /* If it's the None object, return global None */ *r_pobj = PM_NONE; break; case OBJ_TYPE_INT: /* Read an integer and create an integer object with the value */ retval = int_new(mem_getInt(memspace, paddr), r_pobj); break; #ifdef HAVE_FLOAT case OBJ_TYPE_FLT: /* Read a float and create an float object with the value */ retval = float_new(mem_getFloat(memspace, paddr), r_pobj); break; #endif /* HAVE_FLOAT */ case OBJ_TYPE_STR: retval = string_loadFromImg(memspace, paddr, r_pobj); break; case OBJ_TYPE_TUP: retval = tuple_loadFromImg(memspace, paddr, r_pobj); break; case OBJ_TYPE_NIM: /* If it's a native code img, load into a code obj */ retval = no_loadFromImg(memspace, paddr, r_pobj); break; case OBJ_TYPE_CIM: /* If it's a code img, load into a code obj */ retval = co_loadFromImg(memspace, paddr, r_pobj); break; default: /* All other types should not be in an img obj */ PM_RAISE(retval, PM_RET_EX_SYS); break; } return retval; }
/*----------------------------------------------------------------------------*/ PmReturn_t tres_pm_get_state(pPmFrame_t *ppframe) { PmReturn_t retv = PM_RET_OK; pPmObj_t pobj; pPmObj_t pobj_new; pPmInstance_t pcli; pPmDict_t pdict; int16_t index; float fval; int32_t ival; if(NATIVE_GET_NUM_ARGS() != 1) { PM_RAISE(retv, PM_RET_EX_TYPE); return retv; } pobj = NATIVE_GET_LOCAL(0); if(OBJ_GET_TYPE(pobj) != OBJ_TYPE_CLI) { PM_RAISE(retv, PM_RET_EX_TYPE); return retv; } pcli = (pPmInstance_t)pobj; pdict = pcli->cli_attrs; if(*tres_pm_io.state_len > 0) { // restore each attribute of the object for(index = pdict->length - 1; index >= 0; index--) { seglist_getItem(pdict->d_keys, index, &pobj); retv = seglist_getItem(pdict->d_vals, index, &pobj); PM_RETURN_IF_ERROR(retv); switch (OBJ_GET_TYPE(pobj)) { case OBJ_TYPE_INT: //pop int pop_int(&ival); retv = int_new(ival, &pobj_new); break; case OBJ_TYPE_FLT: //pop float pop_float(&fval); retv = float_new(fval, &pobj_new); break; default: /* Raise TypeError */ PM_RAISE(retv, PM_RET_EX_TYPE); } if (retv == PM_RET_OK) { seglist_setItem(pdict->d_vals, pobj_new, index); } } } NATIVE_SET_TOS((pPmObj_t)pcli); return retv; }
// FIXME: this function will be be removed when JSON will be used PmReturn_t tres_pm_get_float_input(pPmFrame_t *ppframe) { PmReturn_t retv = PM_RET_OK; pPmObj_t r_pflt; float val; val = simple_atof(tres_pm_io.in); //val = (float) strtod(tres_pm_io.in, NULL); retv = float_new(val, &r_pflt); NATIVE_SET_TOS(r_pflt); return retv; }
/*----------------------------------------------------------------------------*/ PmReturn_t tres_pm_state_pop(pPmFrame_t *ppframe) { PmReturn_t retv = PM_RET_OK; pPmObj_t r_pflt; pPmObj_t pa; float fval; int32_t ival; int pop_retv; /* Raise TypeError if wrong number of args */ pa = NATIVE_GET_LOCAL(0); if(NATIVE_GET_NUM_ARGS() != 1) { PM_RAISE(retv, PM_RET_EX_TYPE); return retv; } switch (OBJ_GET_TYPE(pa)) { //case OBJ_TYPE_STR: // ptr = (char const *)&(((pPmString_t)pa)->val); // // TODO: unimplemented // break; case OBJ_TYPE_INT: pop_retv = pop_int(&ival); if(pop_retv != TRES_ERR_NONE) { ival = ((pPmInt_t) pa)->val; } retv = int_new(ival, &r_pflt); break; case OBJ_TYPE_FLT: pop_retv = pop_float(&fval); if(pop_retv != TRES_ERR_NONE) { fval = ((pPmFloat_t) pa)->val; } retv = float_new(fval, &r_pflt); break; default: /* Raise TypeError */ PM_RAISE(retv, PM_RET_EX_TYPE); } NATIVE_SET_TOS(r_pflt); return retv; }
/* Unfortunate specialization for floating-point modulus. */ void kitten_mod(Boxed stack, Boxed definitions) { Boxed unpromoted_b = pop(stack); Boxed unpromoted_a = pop(stack); Boxed a; Boxed b; int compatible_types = boxed_promote(unpromoted_a, unpromoted_b, &a, &b); assert(compatible_types); assert(is_numeric(a) && is_numeric(b)); switch (boxed_type(a)) { case FLOAT: push(stack, float_new(fmod(float_unbox(a), float_unbox(b)))); break; case INTEGER: push(stack, integer_new(integer_unbox(a) % integer_unbox(b))); break; default: break; } }
/* Make a deeper copy of a boxed reference. References within quotations are cloned using boxed_copy() rather than boxed_clone(). */ Boxed boxed_clone(Boxed reference) { trace("boxed_clone(%p)\n", reference); if (!reference) return NULL; switch (boxed_type(reference)) { case FLOAT: return float_new(float_value(reference)); case INTEGER: return integer_new(integer_value(reference)); case QUOTATION: { Boxed result = quotation_new(0); quotation_append(result, reference); return result; } case WORD: return word_new(word_value(reference)); } return NULL; }
void cm_float_sin(unsigned argc) { float_new(0, sinl(FLOAT(MC_FRAME_RECVR)->val)); }
PmReturn_t float_op(pPmObj_t px, pPmObj_t py, pPmObj_t *r_pn, int8_t op) { float x; float y; float r; PmReturn_t retval; /* Raise TypeError if args aren't ints or floats */ if (((OBJ_GET_TYPE(px) != OBJ_TYPE_INT) && (OBJ_GET_TYPE(px) != OBJ_TYPE_FLT)) || ((OBJ_GET_TYPE(py) != OBJ_TYPE_INT) && (OBJ_GET_TYPE(py) != OBJ_TYPE_FLT))) { PM_RAISE(retval, PM_RET_EX_TYPE); return retval; } /* Get the values as floats */ if (OBJ_GET_TYPE(px) == OBJ_TYPE_INT) { x = (float)((pPmInt_t)px)->val; } else { x = ((pPmFloat_t) px)->val; } if (OBJ_GET_TYPE(py) == OBJ_TYPE_INT) { y = (float)((pPmInt_t)py)->val; } else { y = ((pPmFloat_t) py)->val; } /* Raise ZeroDivisionError if denominator is zero */ if ((y == 0.0) && ((op == '/') || (op == '%'))) { PM_RAISE(retval, PM_RET_EX_ZDIV); return retval; } /* Calculate x raised to y */ switch (op) { /* *INDENT-OFF* */ case '+': r = x + y; break; case '-': r = x - y; break; case '*': r = x * y; break; case '/': r = x / y; break; case '%': r = fmodf(x, y); break; case 'P': r = powf(x, y); break; default: r = 0.0; break; /* *INDENT-ON* */ } retval = float_new(r, r_pn); return retval; }
VALUE float_divide(VALUE recv, VALUE arg) { return float_new(FLOAT(recv)->num / num2float(arg)); }
VALUE float_pow(VALUE recv, VALUE arg) { return float_new(powf(FLOAT(recv)->num, num2float(arg))); }
VALUE float_subtract(VALUE recv, VALUE arg) { return float_new(FLOAT(recv)->num - num2float(arg)); }
VALUE float_addition(VALUE recv, VALUE arg) { return float_new(FLOAT(recv)->num + num2float(arg)); }
VALUE float_multiply(VALUE recv, VALUE arg) { return float_new(FLOAT(recv)->num * num2float(arg)); }
VALUE float_s_new(VALUE recv, float num) { return float_new(num); }
void cm_float_cos(unsigned argc) { float_new(0, cosl(FLOAT(MC_FRAME_RECVR)->val)); }
PmReturn_t float_negative(pPmObj_t pf, pPmObj_t *r_pf) { /* Create new int obj */ return float_new(-((pPmFloat_t) pf)->val, r_pf); }
void cm_float_exp(unsigned argc) { float_new(0, expl(FLOAT(MC_FRAME_RECVR)->val)); }