Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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);
    }
}