*/ 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; }
*/ 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; }
// // 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; }
*/ 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; }