Exemple #1
0
*/  void Post_Mold(REBVAL *value, REB_MOLD *mold)
/*
**		For series that has an index, add the index for mold/all.
**		Add closing block.
**
***********************************************************************/
{
	if (VAL_INDEX(value)) {
		Append_Byte(mold->series, ' ');
		Append_Int(mold->series, VAL_INDEX(value)+1);
	}
	if (GET_MOPT(mold, MOPT_MOLD_ALL)) Append_Byte(mold->series, ']');
}
Exemple #2
0
*/	static void Scan_Error(REBCNT errnum, SCAN_STATE *ss, REBCNT tkn, REBYTE *arg, REBCNT size, REBVAL *relax)
/*
**		Scanner error handler
**
***********************************************************************/
{
	ERROR_OBJ *error;
	REBSER *errs;
	REBYTE *name;
	REBYTE *cp;
	REBYTE *bp;
	REBSER *ser;
	REBCNT len = 0;

	ss->errors++;

	if (PG_Boot_Strs)
		name = BOOT_STR(RS_SCAN,tkn);
	else
		name = (REBYTE*)"boot";

	cp = ss->head_line;
    while (IS_LEX_SPACE(*cp)) cp++;	// skip indentation
	bp = cp;
	while (NOT_NEWLINE(*cp)) cp++, len++;

	//DISABLE_GC;
	errs = Make_Error(errnum, 0, 0, 0);
	error = (ERROR_OBJ *)FRM_VALUES(errs);
	ser = Make_Binary(len + 16);
	Append_Bytes(ser, "(line ");
	Append_Int(ser, ss->line_count);
	Append_Bytes(ser, ") ");
	Append_Series(ser, (REBYTE*)bp, len);
	Set_String(&error->nearest, ser);
	Set_String(&error->arg1, Copy_Bytes(name, -1));
	Set_String(&error->arg2, Copy_Bytes(arg, size));

	if (relax) {
		SET_ERROR(relax, errnum, errs);
		//ENABLE_GC;
		return;
	}

	Throw_Error(errs);	// ENABLE_GC implied
}
Exemple #3
0
STOID Mold_Error(REBVAL *value, REB_MOLD *mold, REBFLG molded)
{
	ERROR_OBJ *err;
	REBVAL *msg;  // Error message block

	// Protect against recursion. !!!!

	if (molded) {
		if (VAL_OBJ_FRAME(value) && VAL_ERR_NUM(value) >= RE_NOTE && VAL_ERR_OBJECT(value))
			Mold_Object(value, mold);
		else {
			// Happens if throw or return is molded.
			// make error! 0-3
			Pre_Mold(value, mold);
			Append_Int(mold->series, VAL_ERR_NUM(value));
			End_Mold(mold);
		}
		return;
	}

	// If it is an unprocessed BREAK, THROW, CONTINUE, RETURN:
	if (VAL_ERR_NUM(value) < RE_NOTE || !VAL_ERR_OBJECT(value)) {
		VAL_ERR_OBJECT(value) = Make_Error(VAL_ERR_NUM(value), value, 0, 0); // spoofs field
	}
	err = VAL_ERR_VALUES(value);

	// Form: ** <type> Error:
	Emit(mold, "** WB", &err->type, RS_ERRS+0);

	// Append: error message ARG1, ARG2, etc.
	msg = Find_Error_Info(err, 0);
	if (msg) {
		if (!IS_BLOCK(msg)) Mold_Value(mold, msg, 0);
		else {
			//start = DSP + 1;
			//Reduce_In_Frame(VAL_ERR_OBJECT(value), VAL_BLK_DATA(msg));
			//SERIES_TAIL(DS_Series) = DSP + 1;
			//Form_Block_Series(DS_Series, start, mold, 0);
			Form_Block_Series(VAL_SERIES(msg), 0, mold, VAL_ERR_OBJECT(value));
		}
	} else
		Append_Boot_Str(mold->series, RS_ERRS+1);

	Append_Byte(mold->series, '\n');

	// Form: ** Where: function
	value = &err->where;
	if (VAL_TYPE(value) > REB_NONE) {
		Append_Boot_Str(mold->series, RS_ERRS+2);
		Mold_Value(mold, value, 0);
		Append_Byte(mold->series, '\n');
	}

	// Form: ** Near: location
	value = &err->nearest;
	if (VAL_TYPE(value) > REB_NONE) {
		Append_Boot_Str(mold->series, RS_ERRS+3);
		if (IS_STRING(value)) // special case: source file line number
			Append_String(mold->series, VAL_SERIES(value), 0, VAL_TAIL(value));
		else if (IS_BLOCK(value))
			Mold_Simple_Block(mold, VAL_BLK_DATA(value), 60);
		Append_Byte(mold->series, '\n');
	}
}
Exemple #4
0
*/  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;
}
Exemple #5
0
//
//  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);
        }
Exemple #6
0
static void Mold_Error(const REBVAL *value, REB_MOLD *mold, REBFLG molded)
{
	ERROR_OBJ *err;
	REBVAL *msg;  // Error message block
	REBSER *frame;

	// Protect against recursion. !!!!

	if (molded) {
		if (VAL_OBJ_FRAME(value) && VAL_ERR_NUM(value) >= RE_NOTE && VAL_ERR_OBJECT(value))
			Mold_Object(value, mold);
		else {
			// Happens if throw or return is molded.
			// make error! 0-3
			Pre_Mold(value, mold);
			Append_Int(mold->series, VAL_ERR_NUM(value));
			End_Mold(mold);
		}
		return;
	}

	if (VAL_ERR_NUM(value) < RE_THROW_MAX) {
		// Though we generally do not make error objects for THROWN() errors,
		// we do make one here for the purposes of molding.
		frame = Make_Error(VAL_ERR_NUM(value), value, 0, 0);
		err = ERR_VALUES(frame);
	}
	else {
		frame = VAL_ERR_OBJECT(value);
		err = VAL_ERR_VALUES(value);
	}

	// Form: ** <type> Error:
	Emit(mold, "** WB", &err->type, RS_ERRS+0);

	// Append: error message ARG1, ARG2, etc.
	msg = Find_Error_Info(err, 0);
	if (msg) {
		if (!IS_BLOCK(msg)) Mold_Value(mold, msg, 0);
		else {
			//start = DSP + 1;
			//Reduce_In_Frame(frame, VAL_BLK_DATA(msg));
			//SERIES_TAIL(DS_Series) = DSP + 1;
			//Form_Block_Series(DS_Series, start, mold, 0);
			Form_Block_Series(VAL_SERIES(msg), 0, mold, frame);
		}
	} else
		Append_Boot_Str(mold->series, RS_ERRS+1);

	Append_Byte(mold->series, '\n');

	// Form: ** Where: function
	value = &err->where;
	if (VAL_TYPE(value) > REB_NONE) {
		Append_Boot_Str(mold->series, RS_ERRS+2);
		Mold_Value(mold, value, 0);
		Append_Byte(mold->series, '\n');
	}

	// Form: ** Near: location
	value = &err->nearest;
	if (VAL_TYPE(value) > REB_NONE) {
		Append_Boot_Str(mold->series, RS_ERRS+3);
		if (IS_STRING(value)) // special case: source file line number
			Append_String(mold->series, VAL_SERIES(value), 0, VAL_TAIL(value));
		else if (IS_BLOCK(value))
			Mold_Simple_Block(mold, VAL_BLK_DATA(value), 60);
		Append_Byte(mold->series, '\n');
	}
}