Miscellaneous module

Wang Renxin edited this page Mar 27, 2018 · 10 revisions

This page shows some miscellaneous function implementatins with MY-BASIC.

Add implementation functions. An ASSERT statement which evaluates an expression, and triggers an assertion if it results false, then terminates the execution; otherwise it continue executing:

static int _assert(struct mb_interpreter_t* s, void** l) {
	int result = MB_FUNC_OK;
	int_t val = 0;
	char* msg = 0;

	mb_check(mb_attempt_open_bracket(s, l));

	mb_check(mb_pop_int(s, l, &val));

	if(mb_has_arg(s, l)) {
		mb_check(mb_pop_string(s, l, &msg));
	}

	mb_check(mb_attempt_close_bracket(s, l));

	if(!val) {
		if(msg) {
			_printf("ASSERTION: %s.\n", msg);
		} else {
			_printf("ASSERTION.");
		}

		result = MB_FUNC_ERR;
	}

	return result;
}

An IIF statement which evaluates the first argument and returns the second argument if it results true, otherwise returns the third one. This is similar to ?: ternary operator in some other languages, as follow:

static int _iif(struct mb_interpreter_t* s, void** l) {
	int result = MB_FUNC_OK;
	mb_value_t arg;
	mb_value_t st;
	mb_value_t sf;
	bool_t cond = false;

	mb_assert(s && l);

	mb_check(mb_attempt_open_bracket(s, l));

	mb_check(mb_pop_value(s, l, &arg));
	mb_check(mb_pop_value(s, l, &st));
	mb_check(mb_pop_value(s, l, &sf));

	mb_check(mb_attempt_close_bracket(s, l));

	switch(arg.type) {
	case MB_DT_NIL:
		break;
	case MB_DT_INT:
		cond = !!arg.value.integer;

		break;
	default:
		cond = true;

		break;
	}

	if(cond) {
		mb_check(mb_push_value(s, l, st));
	} else {
		mb_check(mb_push_value(s, l, sf));
	}

	return result;
}

A SWAP statement which swaps the value of two variables as follow:

static int _swap(struct mb_interpreter_t* s, void** l) {
	int result = MB_FUNC_OK;
	void* v0 = 0;
	void* v1 = 0;
	mb_value_t val0;
	mb_value_t val1;

	mb_assert(s && l);

	mb_check(mb_attempt_open_bracket(s, l));

	mb_check(mb_get_var(s, l, &v0, true));
	mb_check(mb_get_var(s, l, &v1, true));

	mb_check(mb_attempt_close_bracket(s, l));

	mb_get_var_value(s, v0, &val0);
	mb_get_var_value(s, v1, &val1);
	mb_set_var_value(s, v0, val1);
	mb_set_var_value(s, v1, val0);

	return result;
}

A pair of MIN and MAX functions which evaluate arguments and return the minimum or maximum value:

static int _min(struct mb_interpreter_t* s, void** l) {
	int result = MB_FUNC_OK;
	real_t ret = (real_t)INT_MAX;
	real_t tmp = (real_t)0;

	mb_assert(s && l);

	mb_check(mb_attempt_open_bracket(s, l));

	while(mb_has_arg(s, l)) {
		mb_check(mb_pop_real(s, l, &tmp));
		if(tmp < ret)
			ret = tmp;
	}

	mb_check(mb_attempt_close_bracket(s, l));

	mb_check(mb_push_real(s, l, ret));

	return result;
}
static int _max(struct mb_interpreter_t* s, void** l) {
	int result = MB_FUNC_OK;
	real_t ret = (real_t)INT_MIN;
	real_t tmp = (real_t)0;

	mb_assert(s && l);

	mb_check(mb_attempt_open_bracket(s, l));

	while(mb_has_arg(s, l)) {
		mb_check(mb_pop_real(s, l, &tmp));
		if(tmp > ret)
			ret = tmp;
	}

	mb_check(mb_attempt_close_bracket(s, l));

	mb_check(mb_push_real(s, l, ret));

	return result;
}

Register them:

mb_register_func(bas, "ASSERT", _assert);
mb_register_func(bas, "IIF", _iif);
mb_register_func(bas, "SWAP", _swap);
mb_register_func(bas, "MIN", _min);
mb_register_func(bas, "MAX", _max);

See the BASIC usage as follow.

ASSERT statement:

assert(true, "t")
assert(false, "f")

IIF statement:

print iif(true, "succeed", "fail");
print iif(false, "fail", "succeed");
print iif(nil, "fail", "succeed");
print iif(0, "fail", "succeed");
print iif(1, "succeed", "fail");
print iif(0.1, "succeed", "fail");
print iif("", "succeed", "fail");

SWAP statement:

a = "hello"
b = "world"
swap(a, b)
print b, a;

MIN and MAX statements:

print min(1, 2, 3, 4);
print max(1, 2, 3, 4);
Clone this wiki locally
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.