コード例 #1
0
ファイル: s-mold.c プロジェクト: draegtun/ren-c
static void Mold_Object(const REBVAL *value, REB_MOLD *mold)
{
	REBSER *wser;
	REBVAL *words;
	REBVAL *vals; // first value is context
	REBCNT n;

	assert(VAL_OBJ_FRAME(value));

	wser = VAL_OBJ_WORDS(value);
//	if (wser < 1000)
//		Dump_Block_Raw(VAL_OBJ_FRAME(value), 0, 1);
	words = BLK_HEAD(wser);

	vals  = VAL_OBJ_VALUES(value); // first value is context

	Pre_Mold(value, mold);

	Append_Byte(mold->series, '[');

	// Prevent infinite looping:
	if (Find_Same_Block(MOLD_LOOP, value) > 0) {
		Append_Unencoded(mold->series, "...]");
		return;
	}
	Append_Value(MOLD_LOOP, value);

	mold->indent++;
	for (n = 1; n < SERIES_TAIL(wser); n++) {
		if (
			!VAL_GET_OPT(words+n, OPTS_HIDE) &&
			((VAL_TYPE(vals+n) > REB_NONE) || !GET_MOPT(mold, MOPT_NO_NONE))
		){
			New_Indented_Line(mold);
			Append_UTF8(mold->series, Get_Sym_Name(VAL_WORD_SYM(words+n)), -1);
			//Print("Slot: %s", Get_Sym_Name(VAL_WORD_SYM(words+n)));
			Append_Unencoded(mold->series, ": ");
			if (IS_WORD(vals+n) && !GET_MOPT(mold, MOPT_MOLD_ALL)) Append_Byte(mold->series, '\'');
			Mold_Value(mold, vals+n, TRUE);
		}
	}
	mold->indent--;
	New_Indented_Line(mold);
	Append_Byte(mold->series, ']');

	End_Mold(mold);
	Remove_Last(MOLD_LOOP);
}
コード例 #2
0
ファイル: s-mold.c プロジェクト: draegtun/ren-c
*/  void New_Indented_Line(REB_MOLD *mold)
/*
**		Create a newline with auto-indent on next line if needed.
**
***********************************************************************/
{
	REBINT n;
	REBUNI *cp = 0;

	// Check output string has content already but no terminator:
	if (mold->series->tail) {
		cp = UNI_LAST(mold->series);
		if (*cp == ' ' || *cp == '\t') *cp = '\n';
		else cp = 0;
	}

	// Add terminator:
	if (!cp) Append_Byte(mold->series, '\n');

	// Add proper indentation:
	if (!GET_MOPT(mold, MOPT_INDENT)) {
		for (n = 0; n < mold->indent; n++)
			Append_Unencoded(mold->series, "    ");
	}
}
コード例 #3
0
ファイル: t-bitset.c プロジェクト: kjanz1899/ren-c
//
//  Mold_Bitset: C
//
void Mold_Bitset(const REBVAL *value, REB_MOLD *mold)
{
    REBSER *ser = VAL_SERIES(value);

    if (BITS_NOT(ser)) Append_Unencoded(mold->series, "[not bits ");
    Mold_Binary(value, mold);
    if (BITS_NOT(ser)) Append_Codepoint_Raw(mold->series, ']');
}
コード例 #4
0
ファイル: s-mold.c プロジェクト: draegtun/ren-c
static void Mold_Block_Series(REB_MOLD *mold, REBSER *series, REBCNT index, const char *sep)
{
	REBSER *out = mold->series;
	REBOOL line_flag = FALSE; // newline was part of block
	REBOOL had_lines = FALSE;
	REBVAL *value = BLK_SKIP(series, index);

	if (!sep) sep = "[]";

	if (IS_END(value)) {
		Append_Unencoded(out, sep);
		return;
	}

	// Recursion check: (variation of: Find_Same_Block(MOLD_LOOP, value))
	for (value = BLK_HEAD(MOLD_LOOP); NOT_END(value); value++) {
		if (VAL_SERIES(value) == series) {
			Emit(mold, "C...C", sep[0], sep[1]);
			return;
		}
	}
	value = Alloc_Tail_Blk(MOLD_LOOP);
	Set_Block(value, series);

	if (sep[1]) {
		Append_Byte(out, sep[0]);
		mold->indent++;
	}
//	else out->tail--;  // why?????

	value = BLK_SKIP(series, index);
	while (NOT_END(value)) {
		if (VAL_GET_LINE(value)) {
			if (sep[1] || line_flag) New_Indented_Line(mold);
			had_lines = TRUE;
		}
		line_flag = TRUE;
		Mold_Value(mold, value, TRUE);
		value++;
		if (NOT_END(value))
			Append_Byte(out, (sep[0] == '/') ? '/' : ' ');
	}

	if (sep[1]) {
		mold->indent--;
		if (VAL_GET_LINE(value) || had_lines) New_Indented_Line(mold);
		Append_Byte(out, sep[1]);
	}

	Remove_Last(MOLD_LOOP);
}
コード例 #5
0
ファイル: s-mold.c プロジェクト: draegtun/ren-c
static void Mold_Simple_Block(REB_MOLD *mold, REBVAL *block, REBCNT len)
{
	// Simple molder for error locations. Series must be valid.
	// Max length in chars must be provided.
	REBCNT start = SERIES_TAIL(mold->series);

	while (NOT_END(block)) {
		if ((SERIES_TAIL(mold->series) - start) > len) break;
		Mold_Value(mold, block, TRUE);
		block++;
		if (NOT_END(block)) Append_Byte(mold->series, ' ');
	}

	// If it's too large, truncate it:
	if ((SERIES_TAIL(mold->series) - start) > len) {
		SERIES_TAIL(mold->series) = start + len;
		Append_Unencoded(mold->series, "...");
	}
}
コード例 #6
0
ファイル: s-mold.c プロジェクト: draegtun/ren-c
*/	REBSER *Mold_Print_Value(const REBVAL *value, REBCNT limit, REBFLG mold)
/*
**		Basis function for print.  Can do a form or a mold based
**		on the mold flag setting.  Can limit string output to a
**		specified size to prevent long console garbage output.
**
***********************************************************************/
{
	REB_MOLD mo;
	CLEARS(&mo);
	Reset_Mold(&mo);

	Mold_Value(&mo, value, mold);

	if (limit != 0 && STR_LEN(mo.series) > limit) {
		SERIES_TAIL(mo.series) = limit;
		Append_Unencoded(mo.series, "..."); // adds a null at the tail
	}

	return mo.series;
}
コード例 #7
0
ファイル: s-mold.c プロジェクト: draegtun/ren-c
static void Form_Object(const REBVAL *value, REB_MOLD *mold)
{
	REBSER *wser = VAL_OBJ_WORDS(value);
	REBVAL *words = BLK_HEAD(wser);
	REBVAL *vals  = VAL_OBJ_VALUES(value); // first value is context
	REBCNT n;

	// Prevent endless mold loop:
	if (Find_Same_Block(MOLD_LOOP, value) > 0) {
		Append_Unencoded(mold->series, "...]");
		return;
	}
	Append_Value(MOLD_LOOP, value);

	// Mold all words and their values:
	for (n = 1; n < SERIES_TAIL(wser); n++) {
		if (!VAL_GET_OPT(words+n, OPTS_HIDE))
			Emit(mold, "N: V\n", VAL_WORD_SYM(words+n), vals+n);
	}
	Remove_Last(mold->series);
	Remove_Last(MOLD_LOOP);
}
コード例 #8
0
ファイル: s-mold.c プロジェクト: draegtun/ren-c
static void Mold_Map(const REBVAL *value, REB_MOLD *mold, REBFLG molded)
{
	REBSER *mapser = VAL_SERIES(value);
	REBVAL *val;

	// Prevent endless mold loop:
	if (Find_Same_Block(MOLD_LOOP, value) > 0) {
		Append_Unencoded(mold->series, "...]");
		return;
	}
	Append_Value(MOLD_LOOP, value);

	if (molded) {
		Pre_Mold(value, mold);
		Append_Byte(mold->series, '[');
	}

	// Mold all non-none entries
	mold->indent++;
	for (val = BLK_HEAD(mapser); NOT_END(val) && NOT_END(val+1); val += 2) {
		if (!IS_NONE(val+1)) {
			if (molded) New_Indented_Line(mold);
			Emit(mold, "V V", val, val+1);
			if (!molded) Append_Byte(mold->series, '\n');
		}
	}
	mold->indent--;

	if (molded) {
		New_Indented_Line(mold);
		Append_Byte(mold->series, ']');
	}

	End_Mold(mold);
	Remove_Last(MOLD_LOOP);
}
コード例 #9
0
ファイル: s-mold.c プロジェクト: draegtun/ren-c
*/	void Mold_Binary(const 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_Unencoded(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);
}
コード例 #10
0
ファイル: t-date.c プロジェクト: mbk/ren-c
*/	void Emit_Date(REB_MOLD *mold, const REBVAL *value_orig)
/*
***********************************************************************/
{
	REBYTE buf[64];
	REBYTE *bp = &buf[0];
	REBINT tz;
	REBYTE dash = GET_MOPT(mold, MOPT_SLASH_DATE) ? '/' : '-';

	// We don't want to modify the incoming date value we are molding,
	// so we make a copy that we can tweak during the emit process

	REBVAL value_buffer = *value_orig;
	REBVAL *value = &value_buffer;

	if (
		VAL_MONTH(value) == 0
		|| VAL_MONTH(value) > 12
		|| VAL_DAY(value) == 0
		|| VAL_DAY(value) > 31
	) {
		Append_Unencoded(mold->series, "?date?");
		return;
	}

	if (VAL_TIME(value) != NO_TIME) Adjust_Date_Zone(value, FALSE);

//	Punctuation[GET_MOPT(mold, MOPT_COMMA_PT) ? PUNCT_COMMA : PUNCT_DOT]

	bp = Form_Int(bp, (REBINT)VAL_DAY(value));
	*bp++ = dash;
	memcpy(bp, Month_Names[VAL_MONTH(value)-1], 3);
	bp += 3;
	*bp++ = dash;
	bp = Form_Int_Pad(bp, (REBINT)VAL_YEAR(value), 6, -4, '0');
	*bp = 0;

	Append_Unencoded(mold->series, s_cast(buf));

	if (VAL_TIME(value) != NO_TIME) {

		Append_Byte(mold->series, '/');
		Emit_Time(mold, value);

		if (VAL_ZONE(value) != 0) {

			bp = &buf[0];
			tz = VAL_ZONE(value);
			if (tz < 0) {
				*bp++ = '-';
				tz = -tz;
			}
			else
				*bp++ = '+';

			bp = Form_Int(bp, tz/4);
			*bp++ = ':';
			bp = Form_Int_Pad(bp, (tz&3) * 15, 2, 2, '0');
			*bp = 0;

			Append_Unencoded(mold->series, s_cast(buf));
		}
	}
}
コード例 #11
0
ファイル: s-mold.c プロジェクト: draegtun/ren-c
*/  void Mold_Value(REB_MOLD *mold, const REBVAL *value, REBFLG molded)
/*
**		Mold or form any value to string series tail.
**
***********************************************************************/
{
	REBYTE buf[60];
	REBINT len;
	REBSER *ser = mold->series;

	CHECK_C_STACK_OVERFLOW(&len);

	assert(SERIES_WIDE(mold->series) == sizeof(REBUNI));
	assert(ser);

	// Special handling of string series: {
	if (ANY_STR(value) && !IS_TAG(value)) {

		// Forming a string:
		if (!molded) {
			Insert_String(ser, -1, VAL_SERIES(value), VAL_INDEX(value), VAL_LEN(value), 0);
			return;
		}

		// Special format for ALL string series when not at head:
		if (GET_MOPT(mold, MOPT_MOLD_ALL) && VAL_INDEX(value) != 0) {
			Mold_All_String(value, mold);
			return;
		}
	}

	switch (VAL_TYPE(value)) {
	case REB_NONE:
		Emit(mold, "+N", SYM_NONE);
		break;

	case REB_LOGIC:
//		if (!molded || !VAL_LOGIC_WORDS(value) || !GET_MOPT(mold, MOPT_MOLD_ALL))
			Emit(mold, "+N", VAL_LOGIC(value) ? SYM_TRUE : SYM_FALSE);
//		else
//			Mold_Logic(mold, value);
		break;

	case REB_INTEGER:
		len = Emit_Integer(buf, VAL_INT64(value));
		goto append;

	case REB_DECIMAL:
	case REB_PERCENT:
		len = Emit_Decimal(buf, VAL_DECIMAL(value), IS_PERCENT(value)?DEC_MOLD_PERCENT:0,
			Punctuation[GET_MOPT(mold, MOPT_COMMA_PT) ? PUNCT_COMMA : PUNCT_DOT], mold->digits);
		goto append;

	case REB_MONEY:
		len = Emit_Money(value, buf, mold->opts);
		goto append;

	case REB_CHAR:
		Mold_Uni_Char(ser, VAL_CHAR(value), (REBOOL)molded, (REBOOL)GET_MOPT(mold, MOPT_MOLD_ALL));
		break;

	case REB_PAIR:
		len = Emit_Decimal(buf, VAL_PAIR_X(value), DEC_MOLD_MINIMAL, Punctuation[PUNCT_DOT], mold->digits/2);
		Append_Unencoded_Len(ser, s_cast(buf), len);
		Append_Byte(ser, 'x');
		len = Emit_Decimal(buf, VAL_PAIR_Y(value), DEC_MOLD_MINIMAL, Punctuation[PUNCT_DOT], mold->digits/2);
		Append_Unencoded_Len(ser, s_cast(buf), len);
		//Emit(mold, "IxI", VAL_PAIR_X(value), VAL_PAIR_Y(value));
		break;

	case REB_TUPLE:
		len = Emit_Tuple(value, buf);
		goto append;

	case REB_TIME:
		//len = Emit_Time(value, buf, Punctuation[GET_MOPT(mold, MOPT_COMMA_PT) ? PUNCT_COMMA : PUNCT_DOT]);
		Emit_Time(mold, value);
		break;

	case REB_DATE:
		Emit_Date(mold, value);
		break;

	case REB_STRING:
		// FORM happens in top section.
		Mold_String_Series(value, mold);
		break;

	case REB_BINARY:
		if (GET_MOPT(mold, MOPT_MOLD_ALL) && VAL_INDEX(value) != 0) {
			Mold_All_String(value, mold);
			return;
		}
		Mold_Binary(value, mold);
		break;

	case REB_FILE:
		if (VAL_LEN(value) == 0) {
			Append_Unencoded(ser, "%\"\"");
			break;
		}
		Mold_File(value, mold);
		break;

	case REB_EMAIL:
	case REB_URL:
		Mold_Url(value, mold);
		break;

	case REB_TAG:
		if (GET_MOPT(mold, MOPT_MOLD_ALL) && VAL_INDEX(value) != 0) {
			Mold_All_String(value, mold);
			return;
		}
		Mold_Tag(value, mold);
		break;

//		Mold_Issue(value, mold);
//		break;

	case REB_BITSET:
		Pre_Mold(value, mold); // #[bitset! or make bitset!
		Mold_Bitset(value, mold);
		End_Mold(mold);
		break;

	case REB_IMAGE:
		Pre_Mold(value, mold);
		if (!GET_MOPT(mold, MOPT_MOLD_ALL)) {
			Append_Byte(ser, '[');
			Mold_Image_Data(value, mold);
			Append_Byte(ser, ']');
			End_Mold(mold);
		}
		else {
			REBVAL val = *value;
			VAL_INDEX(&val) = 0; // mold all of it
			Mold_Image_Data(&val, mold);
			Post_Mold(value, mold);
		}
		break;

	case REB_BLOCK:
	case REB_PAREN:
		if (!molded)
			Form_Block_Series(VAL_SERIES(value), VAL_INDEX(value), mold, 0);
		else
			Mold_Block(value, mold);
		break;

	case REB_PATH:
	case REB_SET_PATH:
	case REB_GET_PATH:
	case REB_LIT_PATH:
		Mold_Block(value, mold);
		break;

	case REB_VECTOR:
		Mold_Vector(value, mold, molded);
		break;

	case REB_DATATYPE:
		if (!molded)
			Emit(mold, "N", VAL_DATATYPE(value) + 1);
		else
			Emit(mold, "+DN", SYM_DATATYPE_TYPE, VAL_DATATYPE(value) + 1);
		break;

	case REB_TYPESET:
		Mold_Typeset(value, mold, molded);
		break;

	case REB_WORD:
		// This is a high frequency function, so it is optimized.
		Append_UTF8(ser, Get_Sym_Name(VAL_WORD_SYM(value)), -1);
		break;

	case REB_SET_WORD:
		Emit(mold, "W:", value);
		break;

	case REB_GET_WORD:
		Emit(mold, ":W", value);
		break;

	case REB_LIT_WORD:
		Emit(mold, "\'W", value);
		break;

	case REB_REFINEMENT:
		Emit(mold, "/W", value);
		break;

	case REB_ISSUE:
		Emit(mold, "#W", value);
		break;

	case REB_CLOSURE:
	case REB_FUNCTION:
	case REB_NATIVE:
	case REB_ACTION:
	case REB_COMMAND:
		Mold_Function(value, mold);
		break;

	case REB_OBJECT:
	case REB_MODULE:
	case REB_PORT:
		if (!molded) Form_Object(value, mold);
		else Mold_Object(value, mold);
		break;

	case REB_TASK:
		Mold_Object(value, mold); //// | (1<<MOPT_NO_NONE));
		break;

	case REB_ERROR:
		Mold_Error(value, mold, molded);
		break;

	case REB_MAP:
		Mold_Map(value, mold, molded);
		break;

	case REB_GOB:
	{
		REBSER *blk;
		Pre_Mold(value, mold);
		blk = Gob_To_Block(VAL_GOB(value));
		Mold_Block_Series(mold, blk, 0, 0);
		End_Mold(mold);
	}
		break;


	case REB_EVENT:
		Mold_Event(value, mold);
		break;

	case REB_STRUCT:
	{
		REBSER *blk;
		Pre_Mold(value, mold);
		blk = Struct_To_Block(&VAL_STRUCT(value));
		Mold_Block_Series(mold, blk, 0, 0);
		End_Mold(mold);
	}
		break;

	case REB_ROUTINE:
		Pre_Mold(value, mold);
		Mold_Block_Series(mold, VAL_ROUTINE_SPEC(value), 0, NULL);
		End_Mold(mold);
		break;
	case REB_LIBRARY:
		Pre_Mold(value, mold);

		DS_PUSH_NONE;
		*DS_TOP = *(REBVAL*)SERIES_DATA(VAL_LIB_SPEC(value));
		Mold_File(DS_TOP, mold);
		DS_DROP;

		End_Mold(mold);
		break;
	case REB_CALLBACK:
		Pre_Mold(value, mold);
		Mold_Block_Series(mold, VAL_ROUTINE_SPEC(value), 0, NULL);
		End_Mold(mold);
		break;
	case REB_REBCODE:
	case REB_OP:
	case REB_FRAME:
	case REB_HANDLE:
	case REB_UTYPE:
		// Value has no printable form, so just print its name.
		if (!molded) Emit(mold, "?T?", value);
		else Emit(mold, "+T", value);
		break;

	case REB_END:
	case REB_UNSET:
		if (molded) Emit(mold, "+T", value);
		break;

	default:
		assert(FALSE);
		Panic_Core(RP_DATATYPE+5, VAL_TYPE(value));
	}
	return;

append:
	Append_Unencoded_Len(ser, s_cast(buf), len);

}
コード例 #12
0
ファイル: s-mold.c プロジェクト: draegtun/ren-c
*/  REBSER *Emit(REB_MOLD *mold, const char *fmt, ...)
/*
***********************************************************************/
{
	va_list args;
	REBYTE ender = 0;
	REBSER *series = mold->series;

	assert(SERIES_WIDE(series) == 2);

	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_Unencoded(series, va_arg(args, const char *));
			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_Unencoded(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;
}
コード例 #13
0
ファイル: s-mold.c プロジェクト: draegtun/ren-c
static void Mold_Block(const REBVAL *value, REB_MOLD *mold)
{
	const char *sep;
	REBOOL all = GET_MOPT(mold, MOPT_MOLD_ALL);
	REBSER *series = mold->series;
	REBFLG over = FALSE;

	if (SERIES_WIDE(VAL_SERIES(value)) == 0) {
		assert(FALSE);
		Panic_Core(RP_BAD_WIDTH, sizeof(REBVAL), 0, VAL_TYPE(value));
	}

	// Optimize when no index needed:
	if (VAL_INDEX(value) == 0 && !IS_MAP(value)) // && (VAL_TYPE(value) <= REB_LIT_PATH))
		all = FALSE;

	// If out of range, do not cause error to avoid error looping.
	if (VAL_INDEX(value) >= VAL_TAIL(value)) over = TRUE; // Force it into []

	if (all || (over && !IS_BLOCK(value) && !IS_PAREN(value))) {
		SET_FLAG(mold->opts, MOPT_MOLD_ALL);
		Pre_Mold(value, mold); // #[block! part
		//if (over) Append_Unencoded(mold->series, "[]");
		//else
		Mold_Block_Series(mold, VAL_SERIES(value), 0, 0);
		Post_Mold(value, mold);
	}
	else
	{
		switch(VAL_TYPE(value)) {

		case REB_MAP:
			Pre_Mold(value, mold);
			sep = 0;

		case REB_BLOCK:
			if (GET_MOPT(mold, MOPT_ONLY)) {
				CLR_FLAG(mold->opts, MOPT_ONLY); // only top level
				sep = "\000\000";
			}
			else sep = 0;
			break;

		case REB_PAREN:
			sep = "()";
			break;

		case REB_GET_PATH:
			series = Append_Byte(series, ':');
			sep = "/";
			break;

		case REB_LIT_PATH:
			series = Append_Byte(series, '\'');
			/* fall through */
		case REB_PATH:
		case REB_SET_PATH:
			sep = "/";
			break;
		default:
			sep = NULL;
		}

		if (over) Append_Unencoded(mold->series, sep ? sep : "[]");
		else Mold_Block_Series(mold, VAL_SERIES(value), VAL_INDEX(value), sep);

		if (VAL_TYPE(value) == REB_SET_PATH)
			Append_Byte(series, ':');
	}
}
コード例 #14
0
ファイル: s-mold.c プロジェクト: draegtun/ren-c
static void Mold_String_Series(const REBVAL *value, REB_MOLD *mold)
{
	REBCNT len = VAL_LEN(value);
	REBSER *ser = VAL_SERIES(value);
	REBCNT idx = VAL_INDEX(value);
	REBYTE *bp;
	REBUNI *up;
	REBUNI *dp;
	REBOOL uni = !BYTE_SIZE(ser);
	REBCNT n;
	REBUNI c;

	REB_STRF sf;
	CLEARS(&sf);

	// Empty string:
	if (idx >= VAL_TAIL(value)) {
		Append_Unencoded(mold->series, "\"\"");  //Trap_DEAD_END(RE_PAST_END);
		return;
	}

	Sniff_String(ser, idx, &sf);
	if (!GET_MOPT(mold, MOPT_ANSI_ONLY)) sf.paren = 0;

	// Source can be 8 or 16 bits:
	if (uni) up = UNI_HEAD(ser);
	else bp = STR_HEAD(ser);

	// If it is a short quoted string, emit it as "string":
	if (len <= MAX_QUOTED_STR && sf.quote == 0 && sf.newline < 3) {

		dp = Prep_Uni_Series(mold, len + sf.newline + sf.escape + sf.paren + sf.chr1e + 2);

		*dp++ = '"';

		for (n = idx; n < VAL_TAIL(value); n++) {
			c = uni ? up[n] : cast(REBUNI, bp[n]);
			dp = Emit_Uni_Char(dp, c, (REBOOL)GET_MOPT(mold, MOPT_ANSI_ONLY)); // parened
		}

		*dp++ = '"';
		*dp = 0;
		return;
	}

	// It is a braced string, emit it as {string}:
	if (!sf.malign) sf.brace_in = sf.brace_out = 0;

	dp = Prep_Uni_Series(mold, len + sf.brace_in + sf.brace_out + sf.escape + sf.paren + sf.chr1e + 2);

	*dp++ = '{';

	for (n = idx; n < VAL_TAIL(value); n++) {

		c = uni ? up[n] : cast(REBUNI, bp[n]);
		switch (c) {
		case '{':
		case '}':
			if (sf.malign) {
				*dp++ = '^';
				*dp++ = c;
				break;
			}
		case '\n':
		case '"':
			*dp++ = c;
			break;
		default:
			dp = Emit_Uni_Char(dp, c, (REBOOL)GET_MOPT(mold, MOPT_ANSI_ONLY)); // parened
		}
	}

	*dp++ = '}';
	*dp = 0;
}
コード例 #15
0
ファイル: t-vector.c プロジェクト: rgchris/ren-c
//
//  Mold_Vector: C
//
void Mold_Vector(const REBVAL *value, REB_MOLD *mold, REBOOL molded)
{
    REBSER *vect = VAL_SERIES(value);
    REBYTE *data = SER_DATA_RAW(vect);
    REBCNT bits  = VECT_TYPE(vect);
//  REBCNT dims  = vect->size >> 8;
    REBCNT len;
    REBCNT n;
    REBCNT c;
    union {REBU64 i; REBDEC d;} v;
    REBYTE buf[32];
    REBYTE l;

    if (GET_MOPT(mold, MOPT_MOLD_ALL)) {
        len = VAL_LEN_HEAD(value);
        n = 0;
    } else {
        len = VAL_LEN_AT(value);
        n = VAL_INDEX(value);
    }

    if (molded) {
        enum Reb_Kind kind = (bits >= VTSF08) ? REB_DECIMAL : REB_INTEGER;
        Pre_Mold(value, mold);
        if (!GET_MOPT(mold, MOPT_MOLD_ALL))
            Append_Codepoint_Raw(mold->series, '[');
        if (bits >= VTUI08 && bits <= VTUI64)
            Append_Unencoded(mold->series, "unsigned ");
        Emit(
            mold,
            "N I I [",
            Canon(SYM_FROM_KIND(kind)),
            bit_sizes[bits & 3],
            len
        );
        if (len)
            New_Indented_Line(mold);
    }

    c = 0;
    for (; n < SER_LEN(vect); n++) {
        v.i = get_vect(bits, data, n);
        if (bits < VTSF08) {
            l = Emit_Integer(buf, v.i);
        } else {
            l = Emit_Decimal(buf, v.d, 0, '.', mold->digits);
        }
        Append_Unencoded_Len(mold->series, s_cast(buf), l);

        if ((++c > 7) && (n + 1 < SER_LEN(vect))) {
            New_Indented_Line(mold);
            c = 0;
        }
        else
            Append_Codepoint_Raw(mold->series, ' ');
    }

    if (len) {
        //
        // remove final space (overwritten with terminator)
        //
        TERM_UNI_LEN(mold->series, UNI_LEN(mold->series) - 1);
    }

    if (molded) {
        if (len) New_Indented_Line(mold);
        Append_Codepoint_Raw(mold->series, ']');
        if (!GET_MOPT(mold, MOPT_MOLD_ALL)) {
            Append_Codepoint_Raw(mold->series, ']');
        }
        else {
            Post_Mold(value, mold);
        }
    }
}