Example #1
0
File: s-mold.c Project: Oldes/r3
STOID Mold_Object(REBVAL *value, REB_MOLD *mold)
{
	REBSER *wser;
	REBVAL *words;
	REBVAL *vals; // first value is context
	REBCNT n;
	REBOOL indented = !GET_MOPT(mold, MOPT_INDENT);

	ASSERT(VAL_OBJ_FRAME(value), RP_NO_OBJECT_FRAME);

	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_Bytes(mold->series, "...]");
		return;
	}
	Append_Val(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))
		){
			if(indented)
				New_Indented_Line(mold);
			else if (n > 1)
				Append_Byte(mold->series, ' ');

			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_Bytes(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--;
	if (indented) New_Indented_Line(mold);
	Append_Byte(mold->series, ']');

	End_Mold(mold);
	Remove_Last(MOLD_LOOP);
}
Example #2
0
STOID Form_Object(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_Bytes(mold->series, "...]");
		return;
	}
	Append_Val(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);
}
Example #3
0
STOID Mold_Block_Series(REB_MOLD *mold, REBSER *series, REBCNT index, REBYTE *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_Bytes(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 = Append_Value(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);
}
Example #4
0
STOID Mold_Map(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_Bytes(mold->series, "...]");
		return;
	}
	Append_Val(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);
}
Example #5
0
*/	static REBINT Add_Arg(REBDIA *dia, REBVAL *value)
/*
**		Add an actual argument to the output block.
**
**		Note that the argument may be out sequence with the formal
**		arguments so we must scan for a slot that matches.
**
**		Returns:
**		  1: arg matches a formal arg and has been stored
**		  0: no arg of that type was found
**		 -N: error (type block contains a bad value)
**
***********************************************************************/
{
	REBINT type = 0;
	REBINT accept = 0;
	REBVAL *fargs;
	REBINT fargi;
	REBVAL *outp;
	REBINT rept = 0;

	outp = BLK_SKIP(dia->out, dia->outi);

	// Scan all formal args, looking for one that matches given value:
	for (fargi = dia->fargi;; fargi++) {

		//Debug_Fmt("Add_Arg fargi: %d outi: %d", fargi, outi);
		
		if (IS_END(fargs = BLK_SKIP(dia->fargs, fargi))) return 0;

again:
		// Formal arg can be a word (type or refinement), datatype, or * (repeater):
		if (IS_WORD(fargs)) {

			// If word is a datatype name:
			type = VAL_WORD_CANON(fargs);
			if (type < REB_MAX) {
				type--;	// the type id
			}
			else if (type == SYM__P) {
				// repeat: * integer!
				rept = 1;
				fargs++;
				goto again;
			}
			else {
				// typeset or refinement
				REBVAL *temp;

				type = -1;

				// Is it a refinement word?
				if (IS_WORD(value) && VAL_WORD_CANON(fargs) == VAL_WORD_CANON(value)) {
					accept = 4;
				}
				// Is it a typeset?
				else if (NZ(temp = Get_Var_No_Trap(fargs)) && IS_TYPESET(temp)) {
					if (TYPE_CHECK(temp, VAL_TYPE(value))) accept = 1;
				}
				else if (!IS_WORD(value)) return 0; // do not search past a refinement
				//else return -REB_DIALECT_BAD_SPEC;
			}
		}
		// It's been reduced and is an actual datatype or typeset:
		else if (IS_DATATYPE(fargs)) {
			type = VAL_DATATYPE(fargs);
		}
		else if (IS_TYPESET(fargs)) {
			if (TYPE_CHECK(fargs, VAL_TYPE(value))) accept = 1;
		} else
			return -REB_DIALECT_BAD_SPEC;

		// Make room for it in the output block:
		if (IS_END(outp))
			outp = Append_Value(dia->out);
		else if (!IS_NONE(outp)) {
			// There's already an arg in this slot, so skip it...
			if (dia->cmd > 1) outp++;	
			if (!rept) continue; // see if there's another farg that will work for it
			// Look for first empty slot:
			while (NOT_END(outp) && !IS_NONE(outp)) outp++;
			if (IS_END(outp)) outp = Append_Value(dia->out);
		}

		// The datatype was correct from above!
		if (accept) break;

		//Debug_Fmt("want: %d got: %d rept: %d", type, VAL_TYPE(value), rept);

		// Direct match to datatype or to integer/decimal coersions:
		if (type == (REBINT)VAL_TYPE(value)) {
			accept = 1;
			break;
		}
		else if (type == REB_INTEGER && IS_DECIMAL(value)) {
			accept = 2;
			break;
		}
		else if (type == REB_DECIMAL && IS_INTEGER(value)) {
			accept = 3;
			break;
		}

		dia->missed++;				// for debugging

		// Repeat did not match, so stop repeating and remove unused output slot:
		if (rept) {
			Remove_Last(dia->out);
			outp--;
			rept = 0;
			continue;
		}

		if (dia->cmd > 1) outp++;	// skip output slot (for non-default values)
	}

	// Process the result:
	switch (accept) {

	case 1:
		*outp = *value;
		break;

	case 2:
		SET_INTEGER(outp, (REBI64)VAL_DECIMAL(value));
		break;

	case 3:
		SET_DECIMAL(outp, (REBDEC)VAL_INT64(value));
		break;

	case 4:	// refinement:
		dia->fargi = fargs - BLK_HEAD(dia->fargs) + 1;
		dia->outi = outp - BLK_HEAD(dia->out) + 1;
		*outp = *value;
		return 1;

	case 0:
		return 0;
	}

	// Optimization: arg was in correct order:
	if (!rept && fargi == (signed)(dia->fargi)) {
		dia->fargi++;
		dia->outi++;
	}

	return 1;
}