示例#1
0
文件: coerce.c 项目: krunen/MoarVM
MVMnum64 MVM_coerce_s_n(MVMThreadContext *tc, MVMString *s) {
    char     *enc = MVM_string_ascii_encode(tc, s, NULL);
    MVMnum64  n;
    if (strcmp(enc, "NaN") == 0)
        n = MVM_num_nan(tc);
    else if (strcmp(enc, "Inf") == 0)
        n = MVM_num_posinf(tc);
    else if (strcmp(enc, "+Inf") == 0)
        n = MVM_num_posinf(tc);
    else if (strcmp(enc, "-Inf") == 0)
        n = MVM_num_neginf(tc);
    else
        n = atof(enc);
    MVM_free(enc);
    return n;
}
示例#2
0
文件: coerce.c 项目: niner/MoarVM
MVMString * MVM_coerce_n_s(MVMThreadContext *tc, MVMnum64 n) {
    if (n == MVM_num_posinf(tc)) {
        return MVM_string_ascii_decode_nt(tc, tc->instance->VMString, "Inf");
    }
    else if (n == MVM_num_neginf(tc)) {
        return MVM_string_ascii_decode_nt(tc, tc->instance->VMString, "-Inf");
    }
    else if (n != n) {
        return MVM_string_ascii_decode_nt(tc, tc->instance->VMString, "NaN");
    }
    else {
        char buf[64];
        int i;
        if (snprintf(buf, 64, "%.15g", n) < 0)
            MVM_exception_throw_adhoc(tc, "Could not stringify number");
        if (strstr(buf, ".")) {
            MVMint64 is_not_scientific = !strstr(buf, "e");
            i = strlen(buf);
            while (i > 1 && ((buf[--i] == '0'  && is_not_scientific) || buf[i] == ' '))
                buf[i] = '\0';
            if (buf[i] == '.')
                buf[i] = '\0';
        }
        return MVM_string_ascii_decode(tc, tc->instance->VMString, buf, strlen(buf));
    }
}
示例#3
0
static double parse_simple_number(MVMThreadContext *tc, MVMCodepointIter *ci, MVMCodepoint *cp, MVMString *s) {
    double sign;
    /* Handle NaN here, to make later parsing simpler */

    if (match_word(tc, ci, cp, "NaN", s)) {
        return MVM_num_nan(tc);
    }

    sign = parse_sign(tc, ci, cp);

    if (match_word(tc, ci, cp, "Inf", s)) {
        return sign * MVM_num_posinf(tc);
    }
    else if (*cp == ':') {
        int radix;
        double body;
        get_cp(tc, ci, cp);
        radix = (int) parse_int_frac_exp(tc, ci, cp, s, 10, 0);
        if (*cp == '<') {
            get_cp(tc, ci, cp);
            body = parse_int_frac_exp(tc, ci, cp, s, radix, 0);
            if (*cp == '>') { /* > */
                get_cp(tc, ci, cp);
                return sign * body;
            }
            parse_error(tc, s, "malformed ':radix<>' style radix number, expecting '>' after the body");
        }
        else if (*cp == 171) { /* « */
            get_cp(tc, ci, cp);
            body = parse_int_frac_exp(tc, ci, cp, s, radix, 0);
            if (*cp == 187) { /* » */
                get_cp(tc, ci, cp);
                return sign * body;
            }
            parse_error(tc, s, "malformed ':radix«»' style radix number, expecting '>' after the body");
        }
        else if (*cp == '[') {
            double result = 0;
            get_cp(tc, ci, cp);
            while (*cp != ']' && MVM_string_ci_has_more(tc, ci)) {
                double digit = parse_decimal_integer(tc, ci, cp, s);
                result = result * radix + digit;
                if (*cp == ',') {
                    get_cp(tc, ci, cp);
                }
            }
            if (*cp == ']') {
                get_cp(tc, ci, cp);
                return sign * result;
            }
            parse_error(tc, s, "malformed ':radix[]' style radix number, expecting ']' after the body");
        }
        parse_error(tc, s, "malformed ':radix' style number. Expected <, [ or « after ':radix'");
    }
    else if (*cp == '0') {
        int radix = 0;

        get_cp(tc, ci, cp);
        switch (*cp) {
        case 'b': radix =  2; break;
        case 'o': radix =  8; break;
        case 'd': radix = 10; break;
        case 'x': radix = 16; break;
        }
        if (radix) {
            get_cp(tc, ci, cp);
            if (*cp == '_') get_cp(tc, ci, cp);
            return sign * parse_int_frac_exp(tc, ci, cp, s, radix, 1);
        }
        return sign * parse_int_frac_exp(tc, ci, cp, s, 10, 1);
    }
    else {
        return sign * parse_int_frac_exp(tc, ci, cp, s, 10, 0);
    }
}