Beispiel #1
0
static REBSER *Trim_Object(REBSER *obj)
{
	REBVAL *val;
	REBINT cnt = 0;
	REBSER *nobj;
	REBVAL *nval;
	REBVAL *word;
	REBVAL *nwrd;

	word = FRM_WORDS(obj)+1;
	for (val = FRM_VALUES(obj)+1; NOT_END(val); val++, word++) {
		if (VAL_TYPE(val) > REB_NONE && !VAL_GET_OPT(word, OPTS_HIDE))
			cnt++;
	}

	nobj = Make_Frame(cnt);
	nval = FRM_VALUES(nobj)+1;
	word = FRM_WORDS(obj)+1;
	nwrd = FRM_WORDS(nobj)+1;
	for (val = FRM_VALUES(obj)+1; NOT_END(val); val++, word++) {
		if (VAL_TYPE(val) > REB_NONE && !VAL_GET_OPT(word, OPTS_HIDE)) {
			*nval++ = *val;
			*nwrd++ = *word;
		}
	}
	SET_END(nval);
	SET_END(nwrd);
	SERIES_TAIL(nobj) = cnt+1;
	SERIES_TAIL(FRM_WORD_SERIES(nobj)) = cnt+1;

	return nobj;
}
Beispiel #2
0
*/	static REBSER *Init_Loop(REBVAL *spec, REBVAL *body_blk, REBSER **fram)
/*
**		Initialize standard for loops (copy block, make frame, bind).
**		Spec: WORD or [WORD ...]
**
***********************************************************************/
{
	REBSER *frame;
	REBINT len;
	REBVAL *word;
	REBVAL *vals;
	REBSER *body;

	// For :WORD format, get the var's value:
	if (IS_GET_WORD(spec)) spec = Get_Var(spec);

	// Hand-make a FRAME (done for for speed):
	len = IS_BLOCK(spec) ? VAL_LEN(spec) : 1;
	if (len == 0) Trap_Arg(spec);
	frame = Make_Frame(len);
	SET_SELFLESS(frame);
	SERIES_TAIL(frame) = len+1;
	SERIES_TAIL(FRM_WORD_SERIES(frame)) = len+1;

	// Setup for loop:
	word = FRM_WORD(frame, 1); // skip SELF
	vals = BLK_SKIP(frame, 1);
	if (IS_BLOCK(spec)) spec = VAL_BLK_DATA(spec);

	// Optimally create the FOREACH frame:
	while (len-- > 0) {
		if (!IS_WORD(spec) && !IS_SET_WORD(spec)) {
			// Prevent inconsistent GC state:
			Free_Series(FRM_WORD_SERIES(frame));
			Free_Series(frame);
			Trap_Arg(spec);
		}
		VAL_SET(word, VAL_TYPE(spec));
		VAL_BIND_SYM(word) = VAL_WORD_SYM(spec);
		VAL_BIND_TYPESET(word) = ALL_64;
		word++;
		SET_NONE(vals);
		vals++;
		spec++;
	}
	SET_END(word);
	SET_END(vals);

	body = Clone_Block_Value(body_blk);
	Bind_Block(frame, BLK_HEAD(body), BIND_DEEP);

	*fram = frame;

	return body;
}
Beispiel #3
0
*/	static REBSER *Init_Loop(const REBVAL *spec, REBVAL *body_blk, REBSER **fram)
/*
**		Initialize standard for loops (copy block, make frame, bind).
**		Spec: WORD or [WORD ...]
**
***********************************************************************/
{
	REBSER *frame;
	REBINT len;
	REBVAL *word;
	REBVAL *vals;
	REBSER *body;

	// For :WORD format, get the var's value:
	if (IS_GET_WORD(spec)) spec = GET_VAR(spec);

	// Hand-make a FRAME (done for for speed):
	len = IS_BLOCK(spec) ? VAL_LEN(spec) : 1;
	if (len == 0) raise Error_Invalid_Arg(spec);
	frame = Make_Frame(len, FALSE);
	SERIES_TAIL(frame) = len+1;
	SERIES_TAIL(FRM_WORD_SERIES(frame)) = len+1;

	// Setup for loop:
	word = FRM_WORD(frame, 1); // skip SELF
	vals = BLK_SKIP(frame, 1);
	if (IS_BLOCK(spec)) spec = VAL_BLK_DATA(spec);

	// Optimally create the FOREACH frame:
	while (len-- > 0) {
		if (!IS_WORD(spec) && !IS_SET_WORD(spec)) {
			// Prevent inconsistent GC state:
			Free_Series(FRM_WORD_SERIES(frame));
			Free_Series(frame);
			raise Error_Invalid_Arg(spec);
		}
		Val_Init_Word_Typed(word, VAL_TYPE(spec), VAL_WORD_SYM(spec), ALL_64);
		word++;
		SET_NONE(vals);
		vals++;
		spec++;
	}
	SET_END(word);
	SET_END(vals);

	body = Copy_Array_At_Deep_Managed(
		VAL_SERIES(body_blk), VAL_INDEX(body_blk)
	);
	Bind_Values_Deep(BLK_HEAD(body), frame);

	*fram = frame;

	return body;
}
Beispiel #4
0
//
//  Map_To_Block: C
// 
// mapser = series of the map
// what: -1 - words, +1 - values, 0 -both
//
REBSER *Map_To_Block(REBSER *mapser, REBINT what)
{
    REBVAL *val;
    REBCNT cnt = 0;
    REBSER *blk;
    REBVAL *out;

    // Count number of set entries:
    for (val = BLK_HEAD(mapser); NOT_END(val) && NOT_END(val+1); val += 2) {
        if (!IS_NONE(val+1)) cnt++; // must have non-none value
    }

    // Copy entries to new block:
    blk = Make_Array(cnt * ((what == 0) ? 2 : 1));
    out = BLK_HEAD(blk);
    for (val = BLK_HEAD(mapser); NOT_END(val) && NOT_END(val+1); val += 2) {
        if (!IS_NONE(val+1)) {
            if (what <= 0) *out++ = val[0];
            if (what >= 0) *out++ = val[1];
        }
    }

    SET_END(out);
    blk->tail = out - BLK_HEAD(blk);
    return blk;
}
Beispiel #5
0
*/	REBVAL *Append_Event()
/*
**		Append an event to the end of the current event port queue.
**		Return a pointer to the event value.
**
**		Note: this function may be called from out of environment,
**		so do NOT extend the event queue here. If it does not have
**		space, return 0. (Should it overwrite or wrap???)
**
***********************************************************************/
{
	REBVAL *port;
	REBVAL *value;
	REBVAL *state;

	port = Get_System(SYS_PORTS, PORTS_SYSTEM);
	if (!IS_PORT(port)) return 0; // verify it is a port object

	// Get queue block:
	state = VAL_BLK_SKIP(port, STD_PORT_STATE);
	if (!IS_BLOCK(state)) return 0;

	// Append to tail if room:
	if (SERIES_FULL(VAL_SERIES(state))) Crash(RP_MAX_EVENTS);
	VAL_TAIL(state)++;
	value = VAL_BLK_TAIL(state);
	SET_END(value);
	value--;
	SET_NONE(value);

	//Dump_Series(VAL_SERIES(state), "state");
	//Print("Tail: %d %d", VAL_TAIL(state), nn++);

	return value;
}
Beispiel #6
0
*/	REBSER *Map_To_Object(REBSER *mapser)
/*
***********************************************************************/
{
	REBVAL *val;
	REBCNT cnt = 0;
	REBSER *frame;
	REBVAL *key;
	REBVAL *mval;

	// Count number of set entries:
	for (mval = BLK_HEAD(mapser); NOT_END(mval) && NOT_END(mval+1); mval += 2) {
		if (ANY_WORD(mval) && !IS_NONE(mval+1)) cnt++;
	}

	// See Make_Frame() - cannot use it directly because no Collect_Words
	frame = Make_Frame(cnt, TRUE);

	key = FRM_KEY(frame, 1);
	val  = FRM_VALUE(frame, 1);
	for (mval = BLK_HEAD(mapser); NOT_END(mval) && NOT_END(mval+1); mval += 2) {
		if (ANY_WORD(mval) && !IS_NONE(mval+1)) {
			// !!! Used to leave SET_WORD typed values here... but why?
			// (Objects did not make use of the set-word vs. other distinctions
			// that function specs did.)
			Val_Init_Typeset(
				key,
				// all types except END or UNSET
				~((FLAGIT_64(REB_END) | FLAGIT_64(REB_UNSET))),
				VAL_WORD_SYM(mval)
			);
			key++;
			*val++ = mval[1];
		}
	}

	SET_END(key);
	SET_END(val);
	FRM_KEYLIST(frame)->tail = frame->tail = cnt + 1;

	return frame;
}
Beispiel #7
0
*/	REBSER *Map_To_Object(REBSER *mapser)
/*
***********************************************************************/
{
	REBVAL *val;
	REBCNT cnt = 0;
	REBSER *frame;
	REBVAL *word;
	REBVAL *mval;

	// Count number of set entries:
	for (mval = BLK_HEAD(mapser); NOT_END(mval) && NOT_END(mval+1); mval += 2) {
		if (ANY_WORD(mval) && !IS_NONE(mval+1)) cnt++;
	}

	// See Make_Frame() - cannot use it directly because no Collect_Words
	frame = Make_Frame(cnt, TRUE);

	word = FRM_WORD(frame, 1);
	val  = FRM_VALUE(frame, 1);
	for (mval = BLK_HEAD(mapser); NOT_END(mval) && NOT_END(mval+1); mval += 2) {
		if (ANY_WORD(mval) && !IS_NONE(mval+1)) {
			Init_Unword(
				word,
				REB_SET_WORD,
				VAL_WORD_SYM(mval),
				// all types except END or UNSET
				~((TYPESET(REB_END) | TYPESET(REB_UNSET)))
			);
			word++;
			*val++ = mval[1];
		}
	}

	SET_END(word);
	SET_END(val);
	FRM_WORD_SERIES(frame)->tail = frame->tail = cnt + 1;

	return frame;
}
Beispiel #8
0
*/  REBSER *Create_Frame(REBSER *words, REBSER *spec)
/*
**      Create a new frame from a word list.
**      The values of the frame are initialized to NONE.
**
***********************************************************************/
{
	REBINT len = SERIES_TAIL(words);
	REBSER *frame = Make_Block(len);
	REBVAL *value = BLK_HEAD(frame);

	SET_FRAME(value, spec, words);

	SERIES_TAIL(frame) = len;
	for (value++, len--; len > 0; len--, value++) SET_NONE(value); // skip first value (self)
	SET_END(value);

	return frame;
}
Beispiel #9
0
//
//  Collect_Set_Words: C
// 
// Scan a block, collecting all of its SET words as a block.
//
REBARR *Collect_Set_Words(REBVAL *val)
{
    REBCNT count = 0;
    REBVAL *val2 = val;
    REBARR *array;

    for (; NOT_END(val); val++) if (IS_SET_WORD(val)) count++;
    val = val2;

    array = Make_Array(count);
    val2 = ARR_HEAD(array);
    for (; NOT_END(val); val++) {
        if (IS_SET_WORD(val))
            Val_Init_Word(val2++, REB_WORD, VAL_WORD_SYM(val));
    }
    SET_END(val2);
    SET_ARRAY_LEN(array, count);

    return array;
}
Beispiel #10
0
*/	REBSER *Collect_Set_Words(REBVAL *val)
/*
**		Scan a block, collecting all of its SET words as a block.
**
***********************************************************************/
{
	REBCNT cnt = 0;
	REBVAL *val2 = val;
	REBSER *ser;

	for (; NOT_END(val); val++) if (IS_SET_WORD(val)) cnt++;
	val = val2;

	ser = Make_Block(cnt);
	val2 = BLK_HEAD(ser);
	for (; NOT_END(val); val++) {
		if (IS_SET_WORD(val)) Init_Word(val2++, VAL_WORD_SYM(val));
	}
	SET_END(val2);
	SERIES_TAIL(ser) = cnt;

	return ser;
}
Beispiel #11
0
Datei: t-gob.c Projekt: xqlab/r3
*/	static REBSER *Pane_To_Block(REBGOB *gob, REBCNT index, REBINT len)
/*
**		Convert pane list of gob pointers to a block of GOB!s.
**
***********************************************************************/
{
    REBSER *ser;
    REBGOB **gp;
    REBVAL *val;

    if (len == -1 || (len + index) > GOB_TAIL(gob)) len = GOB_TAIL(gob) - index;
    if (len < 0) len = 0;

    ser = Make_Block(len);
    ser->tail = len;
    val = BLK_HEAD(ser);
    gp = GOB_HEAD(gob);
    for (; len > 0; len--, val++, gp++) {
        SET_GOB(val, *gp);
    }
    SET_END(val);

    return ser;
}