*/ void Reset_Mold(REB_MOLD *mold) /* ***********************************************************************/ { REBSER *buf = BUF_MOLD; REBINT len; if (!buf) Crash(RP_NO_BUFFER); if (SERIES_REST(buf) > MAX_COMMON) Shrink_Series(buf, MIN_COMMON); BLK_RESET(MOLD_LOOP); RESET_SERIES(buf); mold->series = buf; // This is not needed every time, but w/o a functional way to set the option, // it must be done like this and each time. if (GET_MOPT(mold, MOPT_MOLD_ALL)) len = MAX_DIGITS; else { len = Get_System_Int(SYS_OPTIONS, OPTIONS_DECIMAL_DIGITS, MAX_DIGITS); if (len > MAX_DIGITS) len = MAX_DIGITS; else if (len < 0) len = 0; } mold->digits = len; }
*/ void Reset_Mold(REB_MOLD *mold) /* ***********************************************************************/ { REBSER *buf = BUF_MOLD; REBINT len; if (!buf) Panic(RP_NO_BUFFER); if (SERIES_REST(buf) > MAX_COMMON) Shrink_Series(buf, MIN_COMMON); BLK_RESET(MOLD_LOOP); RESET_SERIES(buf); mold->series = buf; // This is not needed every time, but w/o a functional way to set the option, // it must be done like this and each time. if (GET_MOPT(mold, MOPT_MOLD_ALL)) len = MAX_DIGITS; else { // !!! It may be necessary to mold out values before the options // block is loaded, and this 'Get_System_Int' is a bottleneck which // crashes that in early debugging. BOOT_ERRORS is sufficient. if (PG_Boot_Phase >= BOOT_ERRORS) len = Get_System_Int(SYS_OPTIONS, OPTIONS_DECIMAL_DIGITS, MAX_DIGITS); else len = MAX_DIGITS; if (len > MAX_DIGITS) len = MAX_DIGITS; else if (len < 0) len = 0; } mold->digits = len; }
*/ void Mold_Binary(REBVAL *value, REB_MOLD *mold) /* ***********************************************************************/ { REBCNT len = VAL_LEN(value); REBSER *out; switch (Get_System_Int(SYS_OPTIONS, OPTIONS_BINARY_BASE, 16)) { default: case 16: out = Encode_Base16(value, 0, len > 32); break; case 64: Append_Bytes(mold->series, "64"); out = Encode_Base64(value, 0, len > 64); break; case 2: Append_Byte(mold->series, '2'); out = Encode_Base2(value, 0, len > 8); break; } Emit(mold, "#{E}", out); }
*/ REBINT Emit_Decimal(REBYTE *cp, REBDEC d, REBFLG percent, REBYTE point, REBINT digits) /* ***********************************************************************/ { REBYTE out[MAX_NUMCHR]; REBINT len; REBINT n; REBINT i; REBI64 sig; REBINT pt; REBFLG neg; REBYTE *start = cp; *cp = out[0] = 0; // Deal with 0 as special case: if (d == 0.0 || d == -0.0) { *cp++ = '0'; if (!percent) { *cp++ = '.'; *cp++ = '0'; } } else { if (percent) d *= 100.0; if (NZ(neg = (d < 0))) d = -d; if (Convert_Decimal(d, &sig, &pt)) { // Not exp format. len = Form_Integer(out, sig) - out; if (neg) *cp++ = '-'; // Trim un-needed trailing zeros: for (len--; len > 0 && len >= pt; len--) { if (out[len] == '0') out[len] = 0; else break; } // Leading zero, as in 0.1 if (pt <= 0) *cp++ = '0'; // Other leading digits: for (n = 0; out[n] && n < pt; n++) *cp++ = out[n]; if (!percent || n <= len) { // Decimal point: *cp++ = point; // Zeros before first significant digit: for (i = 0; i > pt; i--) *cp++ = '0'; // All remaining digits: for (; n <= len; n++) *cp++ = out[n]; // Force extra zero in 1.0 cases: if (cp[-1] == point) *cp++ = '0'; } } else { REBYTE *pp; // Requires exp format: if (percent) Trap0(RE_OVERFLOW); len = Get_System_Int(SYS_OPTIONS, OPTIONS_DECIMAL_DIGITS, MAX_DIGITS); if (len > MAX_DIGITS) len = MAX_DIGITS; gcvt(d, len, cp); // returns 1.2e123 (also 1e123) pp = strchr(cp, '.'); if (pp && (pp[1] == 'e' || pp[1] == 'E')) { memcpy(pp, pp+1, strlen(pp)); } if (point != '.' && pp) { cp = strchr(cp, '.'); if (cp) *cp = point; } cp = start + LEN_BYTES(start); } } if (percent) *cp++ = '%'; *cp = 0; return cp - start; }