コード例 #1
0
ファイル: d-dump.c プロジェクト: RamchandraApte/rebol
*/  void Dump_Stack(REBINT dsf, REBINT dsp)
/*
***********************************************************************/
{
	REBINT n;
	REBINT m;
	REBVAL *args;

	if (dsf == 0) {
		dsf = DSF;
		dsp = DSP;
	}

	m = dsp - dsf - DSF_SIZE;
	Debug_Fmt(BOOT_STR(RS_STACK, 1), dsp, Get_Word_Name(DSF_WORD(dsf)), m, Get_Type_Name(DSF_FUNC(dsf)));

	if (dsf > 0) {
		if (ANY_FUNC(DSF_FUNC(dsf))) {
			args = BLK_HEAD(VAL_FUNC_ARGS(DSF_FUNC(dsf)));
			m = SERIES_TAIL(VAL_FUNC_ARGS(DSF_FUNC(dsf)));
			for (n = 1; n < m; n++)
				Debug_Fmt("\t%s: %72r", Get_Word_Name(args+n), DSF_ARGS(dsf, n));
		}
		//Debug_Fmt(Str_Stack[2], PRIOR_DSF(dsf));
		if (PRIOR_DSF(dsf) > 0) Dump_Stack(PRIOR_DSF(dsf), dsf-1);
	}

	//for (n = 1; n <= 2; n++) {
	//	Debug_Fmt("  ARG%d: %s %r", n, Get_Type_Name(DSF_ARGS(dsf, n)), DSF_ARGS(dsf, n));
	//}
}
コード例 #2
0
ファイル: c-function.c プロジェクト: draegtun/ren-c
*/	REBFLG Make_Function(REBCNT type, REBVAL *value, REBVAL *def)
/*
***********************************************************************/
{
	REBVAL *spec;
	REBVAL *body;
	REBCNT len;

	if (
		!IS_BLOCK(def)
		|| (len = VAL_LEN(def)) < 2
		|| !IS_BLOCK(spec = VAL_BLK(def))
	) return FALSE;

	body = VAL_BLK_SKIP(def, 1);

	VAL_FUNC_SPEC(value) = VAL_SERIES(spec);
	VAL_FUNC_ARGS(value) = Check_Func_Spec(VAL_SERIES(spec));

	if (type != REB_COMMAND) {
		if (len != 2 || !IS_BLOCK(body)) return FALSE;
		VAL_FUNC_BODY(value) = VAL_SERIES(body);
	}
	else
		Make_Command(value, def);

	VAL_SET(value, type);

	if (type == REB_FUNCTION || type == REB_CLOSURE)
		Bind_Relative(VAL_FUNC_ARGS(value), VAL_FUNC_ARGS(value), VAL_FUNC_BODY(value));

	return TRUE;
}
コード例 #3
0
ファイル: c-function.c プロジェクト: RamchandraApte/rebol
*/	REBFLG Copy_Function(REBVAL *value, REBVAL *args)
/*
***********************************************************************/
{
	REBVAL *spec = VAL_BLK(args);
	REBVAL *body = VAL_BLK_SKIP(args, 1);

	if (IS_END(spec)) body = 0;
	else {
		// Spec given, must be block or *
		if (IS_BLOCK(spec)) {
			VAL_FUNC_SPEC(value) = VAL_SERIES(spec);
			VAL_FUNC_ARGS(value) = Check_Func_Spec(VAL_SERIES(spec));
		} else
			if (!IS_STAR(spec)) return FALSE;
	}

	if (body && !IS_END(body)) {
		if (!IS_FUNCTION(value) && !IS_CLOSURE(value)) return FALSE;
		// Body must be block:
		if (!IS_BLOCK(body)) return FALSE;
		VAL_FUNC_BODY(value) = VAL_SERIES(body);
	}
	// No body, use protytpe:
	else if (IS_FUNCTION(value) || IS_CLOSURE(value))
		VAL_FUNC_BODY(value) = Clone_Block(VAL_FUNC_BODY(value));

	// Rebind function words:
	if (IS_FUNCTION(value))
		Bind_Relative(VAL_FUNC_ARGS(value), VAL_FUNC_BODY(value), VAL_FUNC_BODY(value));

	return TRUE;
}
コード例 #4
0
ファイル: c-function.c プロジェクト: RamchandraApte/rebol
*/	REBFLG Make_Function(REBCNT type, REBVAL *value, REBVAL *def)
/*
***********************************************************************/
{
	REBVAL *spec;
	REBVAL *body;
	REBCNT len;

	if (
		!IS_BLOCK(def)
////		|| type < REB_CLOSURE // for now
		|| (len = VAL_LEN(def)) < 2
		|| !IS_BLOCK(spec = VAL_BLK(def))
	) return FALSE;

	body = VAL_BLK_SKIP(def, 1);

	//	Print("Make_Func"); //: %s spec %d", Get_Sym_Name(type+1), SERIES_TAIL(spec));
	VAL_FUNC_SPEC(value) = VAL_SERIES(spec);
	VAL_FUNC_ARGS(value) = Check_Func_Spec(VAL_SERIES(spec));

	if (type != REB_COMMAND) {
		if (len != 2 || !IS_BLOCK(body)) return FALSE;
		VAL_FUNC_BODY(value) = VAL_SERIES(body);
	}
	else
		Make_Command(value, def);

	VAL_SET(value, type);

	if (type == REB_FUNCTION)
		Bind_Relative(VAL_FUNC_ARGS(value), VAL_FUNC_BODY(value), VAL_FUNC_BODY(value));

	return TRUE;
}
コード例 #5
0
ファイル: t-function.c プロジェクト: 51weekend/r3
static REBOOL Same_Func(REBVAL *val, REBVAL *arg)
{
	if (VAL_TYPE(val) == VAL_TYPE(arg) &&
		VAL_FUNC_SPEC(val) == VAL_FUNC_SPEC(arg) &&
		VAL_FUNC_ARGS(val) == VAL_FUNC_ARGS(arg) &&
		VAL_FUNC_CODE(val) == VAL_FUNC_CODE(arg)) return TRUE;
	return FALSE;
}
コード例 #6
0
ファイル: c-function.c プロジェクト: RamchandraApte/rebol
*/	void Clone_Function(REBVAL *value, REBVAL *func)
/*
***********************************************************************/
{
	VAL_FUNC_SPEC(value) = VAL_FUNC_SPEC(func);
	VAL_FUNC_ARGS(value) = VAL_FUNC_ARGS(func);
	VAL_FUNC_BODY(value) = Clone_Block(VAL_FUNC_BODY(func));
}
コード例 #7
0
ファイル: c-function.c プロジェクト: draegtun/ren-c
*/	void Clone_Function(REBVAL *value, REBVAL *func)
/*
***********************************************************************/
{
	REBSER *src_frame = VAL_FUNC_ARGS(func);

	VAL_FUNC_SPEC(value) = VAL_FUNC_SPEC(func);
	VAL_FUNC_BODY(value) = Clone_Block(VAL_FUNC_BODY(func));
	VAL_FUNC_ARGS(value) = Copy_Block(src_frame, 0);
	// VAL_FUNC_BODY(value) = Clone_Block(VAL_FUNC_BODY(func));
	VAL_FUNC_BODY(value) = Copy_Block_Values(VAL_FUNC_BODY(func), 0, SERIES_TAIL(VAL_FUNC_BODY(func)), TS_CLONE);
	Rebind_Block(src_frame, VAL_FUNC_ARGS(value), BLK_HEAD(VAL_FUNC_BODY(value)), 0);
}
コード例 #8
0
ファイル: f-extension.c プロジェクト: MannyZhong/r3
*/	void Do_Command(REBVAL *value)
/*
**	Evaluates the arguments for a command function and creates
**	a resulting stack frame (struct or object) for command processing.
**
**	A command value consists of:
**		args - same as other funcs
**		spec - same as other funcs
**		body - [ext-obj func-index]
**
***********************************************************************/
{
	REBVAL *val = BLK_HEAD(VAL_FUNC_BODY(value));
	REBEXT *ext;
	REBCNT cmd;
	REBCNT argc;
	REBCNT n;
	RXIFRM frm;	// args stored here

	// All of these were checked above on definition:
	val = BLK_HEAD(VAL_FUNC_BODY(value));
	cmd = (int)VAL_INT64(val+1);
	ext = &Ext_List[VAL_I32(VAL_OBJ_VALUE(val, 1))]; // Handler

	// Copy args to command frame (array of args):
	RXA_COUNT(&frm) = argc = SERIES_TAIL(VAL_FUNC_ARGS(value))-1; // not self
	if (argc > 7) Trap0(RE_BAD_COMMAND);
	val = DS_ARG(1);
	for (n = 1; n <= argc; n++, val++) {
		RXA_TYPE(&frm, n) = Reb_To_RXT[VAL_TYPE(val)];
		frm.args[n] = Value_To_RXI(val);
	}

	// Call the command:
	n = ext->call(cmd, &frm, 0);
	val = DS_RETURN;
	switch (n) {
	case RXR_VALUE:
		RXI_To_Value(val, frm.args[1], RXA_TYPE(&frm, 1));
		break;
	case RXR_BLOCK:
		RXI_To_Block(&frm, val);
		break;
	case RXR_UNSET:
		SET_UNSET(val);
		break;
	case RXR_NONE:
		SET_NONE(val);
		break;
	case RXR_TRUE:
		SET_TRUE(val);
		break;
	case RXR_FALSE:
		SET_FALSE(val);
		break;
	case RXR_ERROR:
	default:
		SET_UNSET(val);
	}
}
コード例 #9
0
ファイル: c-function.c プロジェクト: draegtun/ren-c
*/	void Do_Routine(REBVAL *routine)
/*
 */
{
	//RL_Print("%s, %d\n", __func__, __LINE__);
	REBSER *args = Copy_Values(BLK_SKIP(DS_Series, DS_ARG_BASE + 1), SERIES_TAIL(VAL_FUNC_ARGS(routine)) - 1);
	Call_Routine(routine, args, DS_OUT);
}
コード例 #10
0
ファイル: c-function.c プロジェクト: RamchandraApte/rebol
*/	void Do_Closure(REBVAL *func)
/*
**		Do a closure by cloning its body and binding it to
**		a new frame of words/values.
**
**		This could be made faster by pre-binding the body,
**		then using Rebind_Block to rebind the words in it.
**
***********************************************************************/
{
	REBSER *body;
	REBSER *frame;
	REBVAL *result;
	REBVAL *ds;

	Eval_Functions++;
	//DISABLE_GC;

	// Clone the body of the function to allow rebinding to it:
	body = Clone_Block(VAL_FUNC_BODY(func));

	// Copy stack frame args as the closure object (one extra at head)
	frame = Copy_Values(BLK_SKIP(DS_Series, DS_ARG_BASE), SERIES_TAIL(VAL_FUNC_ARGS(func)));
	SET_FRAME(BLK_HEAD(frame), 0, VAL_FUNC_ARGS(func));

	// Rebind the body to the new context (deeply):
	//Rebind_Block(VAL_FUNC_ARGS(func), frame, body);
	Bind_Block(frame, BLK_HEAD(body), BIND_DEEP); // | BIND_NO_SELF);

	ds = DS_RETURN;
	SET_OBJECT(ds, body); // keep it GC safe
	result = Do_Blk(body, 0); // GC-OK - also, result returned on DS stack
	ds = DS_RETURN;

	if (IS_ERROR(result) && IS_RETURN(result)) {
		// Value below is kept safe from GC because no-allocation is
		// done between point of SET_THROW and here.
		if (VAL_ERR_VALUE(result))
			*ds = *VAL_ERR_VALUE(result);
		else
			SET_UNSET(ds);
	}
	else *ds = *result; // Set return value (atomic)
}
コード例 #11
0
ファイル: c-function.c プロジェクト: draegtun/ren-c
*/	void Make_Native(REBVAL *value, REBSER *spec, REBFUN func, REBINT type)
/*
***********************************************************************/
{
	//Print("Make_Native: %s spec %d", Get_Sym_Name(type+1), SERIES_TAIL(spec));
	VAL_FUNC_SPEC(value) = spec;
	VAL_FUNC_ARGS(value) = Check_Func_Spec(spec);
	VAL_FUNC_CODE(value) = func;
	VAL_SET(value, type);
}
コード例 #12
0
ファイル: c-frame.c プロジェクト: MannyZhong/r3
*/  void Bind_Stack_Block(REBSER *body, REBSER *block)
/*
***********************************************************************/
{
	REBINT dsf = DSF;

	// Find body (frame) on stack:
	while (body != VAL_WORD_FRAME(DSF_WORD(dsf))) {
		dsf = PRIOR_DSF(dsf);
		if (dsf <= 0) Trap0(RE_NOT_DEFINED);  // better message !!!!
	}

	if (IS_FUNCTION(DSF_FUNC(dsf))) {
		Bind_Relative(VAL_FUNC_ARGS(DSF_FUNC(dsf)), body, block);
	}
}
コード例 #13
0
ファイル: f-extension.c プロジェクト: MannyZhong/r3
*/	void Make_Command(REBVAL *value, REBVAL *def)
/*
**		Assumes prior function has already stored the spec and args
**		series. This function validates the body.
**
***********************************************************************/
{
	REBVAL *args = BLK_HEAD(VAL_FUNC_ARGS(value));
	REBCNT n;
	REBVAL *val = VAL_BLK_SKIP(def, 1);
	REBEXT *ext;

	if (
		VAL_LEN(def) != 3
		|| !(IS_MODULE(val) || IS_OBJECT(val))
		|| !IS_HANDLE(VAL_OBJ_VALUE(val, 1))
		|| !IS_INTEGER(val+1)
		|| VAL_INT64(val+1) > 0xffff
	) Trap1(RE_BAD_FUNC_DEF, def);

	val = VAL_OBJ_VALUE(val, 1);
	if (
		!(ext = &Ext_List[VAL_I32(val)])
		|| !(ext->call)
	) Trap1(RE_BAD_EXTENSION, def);

	// make command! [[arg-spec] handle cmd-index]
	VAL_FUNC_BODY(value) = Copy_Block_Len(VAL_SERIES(def), 1, 2);

	// Check for valid command arg datatypes:
	args++; // skip self
	n = 1;
	for (; NOT_END(args); args++, n++) {
		// If the typeset contains args that are not valid:
		// (3 is the default when no args given, for not END and UNSET)
		if (3 != ~VAL_TYPESET(args) && (VAL_TYPESET(args) & ~RXT_ALLOWED_TYPES))
			Trap1(RE_BAD_FUNC_ARG, args);
	}

	VAL_SET(value, REB_COMMAND);
}
コード例 #14
0
ファイル: c-frame.c プロジェクト: MannyZhong/r3
*/  void Bind_Stack_Word(REBSER *body, REBVAL *word)
/*
***********************************************************************/
{
	REBINT dsf = DSF;
	REBINT index;

	// Find body (frame) on stack:
	while (body != VAL_WORD_FRAME(DSF_WORD(dsf))) {
		dsf = PRIOR_DSF(dsf);
		if (dsf <= 0) Trap1(RE_NOT_IN_CONTEXT, word);
	}

	if (IS_FUNCTION(DSF_FUNC(dsf))) {
		index = Find_Arg_Index(VAL_FUNC_ARGS(DSF_FUNC(dsf)), VAL_WORD_SYM(word));
		if (!index) Trap1(RE_NOT_IN_CONTEXT, word);
		VAL_WORD_FRAME(word) = body;
		VAL_WORD_INDEX(word) = -index;
	} else
		Crash(9100); // !!!  function is not there!
}
コード例 #15
0
ファイル: c-frame.c プロジェクト: MannyZhong/r3
*/  void Bind_Frame(REBSER *obj)
/*
**      Clone a frame, knowing which types of values need to be
**		copied, deep copied, and rebound.
**
***********************************************************************/
{
	REBVAL *val;
	REBOOL funcs = FALSE;

	//DISABLE_GC;
	// Copy functions:
	for (val = BLK_SKIP(obj, 1); NOT_END(val); val++) {
		if (IS_FUNCTION(val)) {
			Clone_Function(val, val); 
			funcs = TRUE;
		}
		else if (IS_CLOSURE(val)) {
			funcs = TRUE;
		}
	}

	// Rebind all values:
	Bind_Block(obj, BLK_SKIP(obj, 1), BIND_DEEP | BIND_FUNC);

	if (funcs) {
		// Rebind functions:
		for (val = BLK_SKIP(obj, 1); NOT_END(val); val++) {
			if (IS_FUNCTION(val)) {
				Bind_Relative(VAL_FUNC_ARGS(val), VAL_FUNC_BODY(val), VAL_FUNC_BODY(val));
			}
			else if (IS_CLOSURE(val)) {
			}
		}
	}

	//ENABLE_GC;
}
コード例 #16
0
ファイル: f-extension.c プロジェクト: MannyZhong/r3
*/	void Do_Commands(REBSER *cmds, void *context)
/*
**		Evaluate a block of commands as efficiently as possible.
**		The arguments to each command must already be reduced or
**		use only variable lookup.
**
**		Returns the last evaluated value, if provided.
**
***********************************************************************/
{
	REBVAL *blk;
	REBCNT index = 0;
	REBVAL *set_word = 0;
	REBVAL *cmd_word;
	REBSER *words;
	REBVAL *args;
	REBVAL *val;
	REBVAL *func;
	RXIFRM frm;	// args stored here
	REBCNT n;
	REBEXT *ext;
	REBCEC *ctx;

	if ((ctx = context)) ctx->block = cmds;
	blk = BLK_HEAD(cmds);

	while (NOT_END(blk)) {

		// var: command result
		if IS_SET_WORD(blk) {
			set_word = blk++;
			index++;
		};

		// get command function
		if (IS_WORD(cmd_word = blk)) {
			// Optimized var fetch:
			n = VAL_WORD_INDEX(blk);
			if (n > 0) func = FRM_VALUES(VAL_WORD_FRAME(blk)) + n;
			else func = Get_Var(blk); // fallback
		} else func = blk;

		if (!IS_COMMAND(func)) Trap2(RE_EXPECT_VAL, Get_Type_Word(REB_COMMAND), blk);

		// Advance to next value
		blk++;
		if (ctx) ctx->index = index; // position of function
		index++;

		// get command arguments and body
		words = VAL_FUNC_WORDS(func);
		RXA_COUNT(&frm) = SERIES_TAIL(VAL_FUNC_ARGS(func))-1; // not self

		// collect each argument (arg list already validated on MAKE)
		n = 0;
		for (args = BLK_SKIP(words, 1); NOT_END(args); args++) {

			//Debug_Type(args);
			val = blk++;
			index++;
			if (IS_END(val)) Trap2(RE_NO_ARG, cmd_word, args);
			//Debug_Type(val);

			// actual arg is a word, lookup?
			if (VAL_TYPE(val) >= REB_WORD) {
				if (IS_WORD(val)) {
					if (IS_WORD(args)) val = Get_Var(val);
				}
				else if (IS_PATH(val)) {
					if (IS_WORD(args)) val = Get_Any_Var(val); // volatile value!
				}
				else if (IS_PAREN(val)) {
					val = Do_Blk(VAL_SERIES(val), 0); // volatile value!
				}
				// all others fall through
			}

			// check datatype
			if (!TYPE_CHECK(args, VAL_TYPE(val)))
				Trap3(RE_EXPECT_ARG, cmd_word, args, Of_Type(val));

			// put arg into command frame
			n++;
			RXA_TYPE(&frm, n) = Reb_To_RXT[VAL_TYPE(val)];
			frm.args[n] = Value_To_RXI(val);
		}

		// Call the command (also supports different extension modules):
		func  = BLK_HEAD(VAL_FUNC_BODY(func));
		n = (REBCNT)VAL_INT64(func + 1);
		ext = &Ext_List[VAL_I32(VAL_OBJ_VALUE(func, 1))]; // Handler
		n = ext->call(n, &frm, context);
		val = DS_RETURN;
		switch (n) {
		case RXR_VALUE:
			RXI_To_Value(val, frm.args[1], RXA_TYPE(&frm, 1));
			break;
		case RXR_BLOCK:
			RXI_To_Block(&frm, val);
			break;
		case RXR_UNSET:
			SET_UNSET(val);
			break;
		case RXR_NONE:
			SET_NONE(val);
			break;
		case RXR_TRUE:
			SET_TRUE(val);
			break;
		case RXR_FALSE:
			SET_FALSE(val);
			break;
		case RXR_ERROR:
		default:
			SET_UNSET(val);
		}

		if (set_word) {
			Set_Var(set_word, val);
			set_word = 0;
		}
	}
}