예제 #1
0
파일: t-block.c 프로젝트: 51weekend/r3
*/	REBINT PD_Block(REBPVS *pvs)
/*
***********************************************************************/
{
	REBINT n = 0;

	/* Issues!!!
		a/1.3
		a/not-found: 10 error or append?
		a/not-followed: 10 error or append?
	*/

	if (IS_INTEGER(pvs->select)) {
		n = Int32(pvs->select) + VAL_INDEX(pvs->value) - 1;
	}
	else if (IS_WORD(pvs->select)) {
		n = Find_Word(VAL_SERIES(pvs->value), VAL_INDEX(pvs->value), VAL_WORD_CANON(pvs->select));
		if (n != NOT_FOUND) n++;
	}
	else {
		// other values:
		n = Find_Block_Simple(VAL_SERIES(pvs->value), VAL_INDEX(pvs->value), pvs->select) + 1;
	}

	if (n < 0 || (REBCNT)n >= VAL_TAIL(pvs->value)) {
		if (pvs->setval) return PE_BAD_SELECT;
		return PE_NONE;
	}

	if (pvs->setval) TRAP_PROTECT(VAL_SERIES(pvs->value));
	pvs->value = VAL_BLK_SKIP(pvs->value, n);
	// if valset - check PROTECT on block
	//if (NOT_END(pvs->path+1)) Next_Path(pvs); return PE_OK;
	return PE_SET;
}
예제 #2
0
*/	REBINT PD_String(REBPVS *pvs)
/*
***********************************************************************/
{
	REBVAL *data = pvs->value;
	REBVAL *val = pvs->setval;
	REBINT n = 0;
	REBCNT i;
	REBINT c;
	REBSER *ser = VAL_SERIES(data);

	if (IS_INTEGER(pvs->select)) {
		n = Int32(pvs->select) + VAL_INDEX(data) - 1;
	}
	else return PE_BAD_SELECT;

	if (val == 0) {
		if (n < 0 || (REBCNT)n >= SERIES_TAIL(ser)) return PE_NONE;
		if (IS_BINARY(data)) {
			SET_INTEGER(pvs->store, *BIN_SKIP(ser, n));
		} else {
			SET_CHAR(pvs->store, GET_ANY_CHAR(ser, n));
		}
		return PE_USE;
	}

	if (n < 0 || (REBCNT)n >= SERIES_TAIL(ser)) return PE_BAD_RANGE;

	if (IS_CHAR(val)) {
		c = VAL_CHAR(val);
		if (c > MAX_CHAR) return PE_BAD_SET;
	}
	else if (IS_INTEGER(val)) {
		c = Int32(val);
		if (c > MAX_CHAR || c < 0) return PE_BAD_SET;
		if (IS_BINARY(data)) { // special case for binary
			if (c > 0xff) Trap_Range(val);
			BIN_HEAD(ser)[n] = (REBYTE)c;
			return PE_OK;
		}
	}
	else if (ANY_BINSTR(val)) {
		i = VAL_INDEX(val);
		if (i >= VAL_TAIL(val)) return PE_BAD_SET;
		c = GET_ANY_CHAR(VAL_SERIES(val), i);
	}
	else
		return PE_BAD_SELECT;

	TRAP_PROTECT(ser);

	if (BYTE_SIZE(ser) && c > 0xff) Widen_String(ser);
	SET_ANY_CHAR(ser, n, c);

	return PE_OK;
}
예제 #3
0
//
//  PD_Map: C
//
REBINT PD_Map(REBPVS *pvs)
{
    REBVAL *data = pvs->value;
    REBVAL *val = 0;
    REBINT n = 0;

    if (IS_END(pvs->path+1)) val = pvs->setval;
    if (IS_NONE(pvs->select)) return PE_NONE;

    if (!ANY_WORD(pvs->select) && !ANY_BINSTR(pvs->select) &&
        !IS_INTEGER(pvs->select) && !IS_CHAR(pvs->select))
        return PE_BAD_SELECT;

    n = Find_Entry(VAL_SERIES(data), pvs->select, val);

    if (!n) return PE_NONE;

    TRAP_PROTECT(VAL_SERIES(data));
    pvs->value = VAL_BLK_SKIP(data, ((n-1)*2)+1);
    return PE_OK;
}
예제 #4
0
*/	REBINT Do_Series_Action(REBCNT action, REBVAL *value, REBVAL *arg)
/*
**		Common series functions.
**
***********************************************************************/
{
	REBINT	index;
	REBINT	tail;
	REBINT	len = 0;

	// Common setup code for all actions:
	if (action != A_MAKE && action != A_TO) {
		index = (REBINT)VAL_INDEX(value);
		tail  = (REBINT)VAL_TAIL(value);
	} else return -1;

	switch (action) {

	//-- Navigation:

	case A_HEAD:
		VAL_INDEX(value) = 0;
		break;

	case A_TAIL:
		VAL_INDEX(value) = (REBCNT)tail;
		break;

	case A_HEADQ:
		DECIDE(index == 0);

	case A_TAILQ:
		DECIDE(index >= tail);

	case A_PASTQ:
		DECIDE(index > tail);

	case A_NEXT:
		if (index < tail) VAL_INDEX(value)++;
		break;

	case A_BACK:
		if (index > 0) VAL_INDEX(value)--;
		break;

	case A_SKIP:
	case A_AT:
		len = Get_Num_Arg(arg);
		{
			REBI64 i = (REBI64)index + (REBI64)len;
			if (action == A_SKIP) {
				if (IS_LOGIC(arg)) i--;
			} else { // A_AT
				if (len > 0) i--;
			}
			if (i > (REBI64)tail) i = (REBI64)tail;
			else if (i < 0) i = 0;
			VAL_INDEX(value) = (REBCNT)i;
		}
		break;
/*
	case A_ATZ:
		len = Get_Num_Arg(arg);
		{
			REBI64 idx = Add_Max(0, index, len, MAX_I32);
			if (idx < 0) idx = 0;
			VAL_INDEX(value) = (REBCNT)idx;
		}
		break;
*/
	case A_INDEXQ:
		SET_INTEGER(DS_RETURN, ((REBI64)index) + 1);
		return R_RET;

	case A_LENGTHQ:
		SET_INTEGER(DS_RETURN, tail > index ? tail - index : 0);
		return R_RET;

	case A_REMOVE:
		// /PART length
		TRAP_PROTECT(VAL_SERIES(value));
		len = DS_REF(2) ? Partial(value, 0, DS_ARG(3), 0) : 1;
		index = (REBINT)VAL_INDEX(value);
		if (index < tail && len != 0)
			Remove_Series(VAL_SERIES(value), VAL_INDEX(value), len);
		break;

	case A_ADD:			// Join_Strings(value, arg);
	case A_SUBTRACT:	// "test this" - 10
	case A_MULTIPLY:	// "t" * 4 = "tttt"
	case A_DIVIDE:
	case A_REMAINDER:
	case A_POWER:
	case A_ODDQ:
	case A_EVENQ:
	case A_ABSOLUTE:
		Trap_Action(VAL_TYPE(value), action);

	default:
		return -1;
	}

	DS_RET_VALUE(value);
	return R_RET;

is_false:
	return R_FALSE;

is_true:
	return R_TRUE;
}