STOID Mold_Typeset(REBVAL *value, REB_MOLD *mold, REBFLG molded) { REBINT n; if (molded) { Pre_Mold(value, mold); // #[typeset! or make typeset! Append_Byte(mold->series, '['); } // Convert bits to types (we can make this more efficient !!) for (n = 0; n < REB_MAX; n++) { if (TYPE_CHECK(value, n)) { Emit(mold, "+DN ", SYM_DATATYPE_TYPE, n + 1); } } Trim_Tail(mold->series, ' '); if (molded) { //Form_Typeset(value, mold & ~(1<<MOPT_MOLD_ALL)); Append_Byte(mold->series, ']'); End_Mold(mold); } }
*/ REBSER *Emit(REB_MOLD *mold, REBYTE *fmt, ...) /* ***********************************************************************/ { va_list args; REBYTE ender = 0; REBSER *series = mold->series; ASSERT2(SERIES_WIDE(series) ==2, 9997); va_start(args, fmt); for (; *fmt; fmt++) { switch (*fmt) { case 'W': // Word symbol Append_UTF8(series, Get_Word_Name(va_arg(args, REBVAL*)), -1); break; case 'V': // Value Mold_Value(mold, va_arg(args, REBVAL*), TRUE); break; case 'S': // String of bytes Append_Bytes(series, va_arg(args, REBYTE*)); break; case 'C': // Char Append_Byte(series, va_arg(args, REBCNT)); break; case 'E': // Series (byte or uni) { REBSER *src = va_arg(args, REBSER*); Insert_String(series, SERIES_TAIL(series), src, 0, SERIES_TAIL(src), 0); } break; case 'I': // Integer Append_Int(series, va_arg(args, REBINT)); break; case 'i': Append_Int_Pad(series, va_arg(args, REBINT), -9); Trim_Tail(mold->series, '0'); break; case '2': // 2 digit int (for time) Append_Int_Pad(series, va_arg(args, REBINT), 2); break; case 'T': // Type name Append_UTF8(series, Get_Type_Name(va_arg(args, REBVAL*)), -1); break; case 'N': // Symbol name Append_UTF8(series, Get_Sym_Name(va_arg(args, REBCNT)), -1); break; case '+': // Add #[ if mold/all if (GET_MOPT(mold, MOPT_MOLD_ALL)) { Append_Bytes(series, "#["); ender = ']'; } break; case 'D': // Datatype symbol: #[type if (ender) { Append_UTF8(series, Get_Sym_Name(va_arg(args, REBCNT)), -1); Append_Byte(series, ' '); } else va_arg(args, REBCNT); // ignore it break; case 'B': // Boot string Append_Boot_Str(series, va_arg(args, REBINT)); break; default: Append_Byte(series, *fmt); } } va_end(args); if (ender) Append_Byte(series, ender); return series; }
// // Emit: C // // This is a general "printf-style" utility function, which R3-Alpha used to // make some formatting tasks easier. It was not applied consistently, and // some callsites avoided using it because it would be ostensibly slower // than calling the functions directly. // void Emit(REB_MOLD *mo, const char *fmt, ...) { va_list va; va_start(va, fmt); REBYTE ender = '\0'; for (; *fmt; fmt++) { switch (*fmt) { case 'W': { // Word symbol const REBVAL *any_word = va_arg(va, const REBVAL*); Append_Spelling(mo->series, VAL_WORD_SPELLING(any_word)); break; } case 'V': // Value Mold_Value(mo, va_arg(va, const REBVAL*)); break; case 'S': // String of bytes Append_Ascii(mo->series, va_arg(va, const char *)); break; case 'C': // Char Append_Codepoint(mo->series, va_arg(va, uint32_t)); break; case 'I': // Integer Append_Int(mo->series, va_arg(va, REBINT)); break; case 'i': Append_Int_Pad(mo->series, va_arg(va, REBINT), -9); Trim_Tail(mo, '0'); break; case '2': // 2 digit int (for time) Append_Int_Pad(mo->series, va_arg(va, REBINT), 2); break; case 'T': { // Type name REBSTR *type_name = Get_Type_Name(va_arg(va, REBVAL*)); Append_Spelling(mo->series, type_name); break; } case 'N': { // Symbol name REBSTR *spelling = va_arg(va, REBSTR*); Append_Spelling(mo->series, spelling); break; } case '+': // Add #[ if mold/all if (GET_MOLD_FLAG(mo, MOLD_FLAG_ALL)) { Append_Ascii(mo->series, "#["); ender = ']'; } break; case 'D': // Datatype symbol: #[type if (ender != '\0') { REBSTR *canon = Canon(cast(REBSYM, va_arg(va, int))); Append_Spelling(mo->series, canon); Append_Codepoint(mo->series, ' '); } else va_arg(va, REBCNT); // ignore it break; default: Append_Codepoint(mo->series, *fmt); }