Ejemplo n.º 1
0
static Expr* mul(Expr* args) {
	assert(args);

	double dbuf = 1.0;
	long long lbuf = 1;
	bool exact = true;

	while(scm_is_pair(args)) {
		Expr* cur = scm_car(args);
		if(scm_is_int(cur)) {
			lbuf *= scm_ival(cur);
			dbuf *= scm_ival(cur);
		} else if(scm_is_real(cur)) {
			exact = false;
			dbuf *= scm_rval(cur);
		} else {
			return scm_mk_error("Wrong type of argument to *");
		}
		args = scm_cdr(args);
	}

	if(args != EMPTY_LIST) {
		return scm_mk_error("args to * aren't a proper list");
	}


	return exact ? scm_mk_int(lbuf) : scm_mk_real(dbuf);
}
Ejemplo n.º 2
0
static Expr* sub(Expr* args) {
	assert(args);

	if(args == EMPTY_LIST) return scm_mk_error("no arguments passed to - (expected at least 1)");

	// unary case
	if(scm_cdr(args) == EMPTY_LIST) {
		Expr* v = scm_car(args);

		if(scm_is_int(v)) return scm_mk_int(-scm_ival(v));
		if(scm_is_real(v)) return scm_mk_int(-scm_rval(v));

		return scm_mk_error("wrong type of argument to -");
	}

	Expr* first = scm_car(args);
	if(!scm_is_num(first)) return scm_mk_error("wrong type of argument to -");

	bool exact = scm_is_int(first);
	double dbuf = exact ? scm_ival(first) : scm_rval(first);
	long long lbuf = exact ? scm_ival(first) : 0;

	args = scm_cdr(args);

	while(scm_is_pair(args)) {
		Expr* cur = scm_car(args);
		if(scm_is_int(cur)) {
			lbuf -= scm_ival(cur);
			dbuf -= scm_ival(cur);
		} else if(scm_is_real(cur)) {
			exact = false;
			dbuf -= scm_rval(cur);
		} else {
			return scm_mk_error("Wrong type of argument to +");
		}
		args = scm_cdr(args);
	}

	if(args != EMPTY_LIST) {
		return scm_mk_error("args to + aren't a proper list");
	}


	return exact ? scm_mk_int(lbuf) : scm_mk_real(dbuf);
}
Ejemplo n.º 3
0
static Expr* num_eq(Expr* args) {
	assert(args);

	if(args == EMPTY_LIST) return TRUE;

	Expr* cur = scm_car(args);
	checknum(cur);

	bool eq = true;
	bool exact = scm_is_int(cur);
	long long ex;
	double in;

	if(exact) {
		ex = scm_ival(cur);
		in = ex;
	} else {
		in = scm_rval(cur);
		ex = in;

		exact = ((double)ex) == in;
	}

	args = scm_cdr(args);

	while(scm_is_pair(args)) {
		cur = scm_car(args);
		checknum(cur);

		if(exact && scm_is_int(cur)) {
			if(ex != scm_ival(cur)) {
				eq = false;
				break;
			}
		} else if(exact) {
			if(in != scm_rval(cur)) {
				eq = false;
				break;
			}
		} else if(scm_is_real(cur)) {
			if(in != scm_rval(cur)) {
				eq = false;
				break;
			}
		} else {
			eq = false;
			break;
		}

		args = scm_cdr(args);
	}

	if(eq && args != EMPTY_LIST) return scm_mk_error("arguments to = aren't a proper list");

	return eq ? TRUE : FALSE;
}
Ejemplo n.º 4
0
static Expr* real(Expr* args) {
	assert(args);

	if(args == EMPTY_LIST) return scm_mk_error("No args passed to real? (expected 1)");

	Expr* fst = scm_car(args);
	Expr* rst = scm_cdr(args);

	if(rst != EMPTY_LIST) return scm_mk_error("Too many args passed to real? (expected 1)");

	return scm_is_real(fst) ? TRUE : FALSE;
}
Ejemplo n.º 5
0
static Expr* inexact(Expr* args) {
	assert(args);

	if(args == EMPTY_LIST) return scm_mk_error("No args passed to inexact? (expected 1)");

	Expr* fst = scm_car(args);
	Expr* rst = scm_cdr(args);

	if(rst != EMPTY_LIST) return scm_mk_error("Too many args passed to inexact? (expected 1)");
	if(number(args) != TRUE) return scm_mk_error("Argument to inexact? is not a number");

	return scm_is_real(fst) ? TRUE : FALSE;
}
Ejemplo n.º 6
0
static Expr* ex2in(Expr* args) {
	assert(args);

	if(scm_list_len(args) != 1) return scm_mk_error("exact->inexact expects 1 arg");

	Expr* fst = scm_car(args);

	if(scm_is_int(fst)) {
		Expr* toRet = scm_mk_real(scm_ival(fst));
		return toRet ? toRet : OOM;
	} else if(scm_is_real(fst)) {
		return fst;
	} else {
		return scm_mk_error("exact->inexact expects a number");
	}
}
Ejemplo n.º 7
0
PyObject *scm2py(SCM value)
{
	if (value == NULL)
		return NULL;
	if (value == SCM_UNSPECIFIED) {
		Py_INCREF(Py_None);
		return Py_None;
	}
	if (scm_is_exact_integer(value))
		return PyInt_FromLong(scm_to_long(value));
	if (scm_is_real(value))
		return PyFloat_FromDouble(scm_to_double(value));
	if (scm_is_bool(value)) {
		PyObject *result = scm_to_bool(value) ? Py_True : Py_False;
		Py_INCREF(result);
		return result;
	}
	if (value == SCM_EOL)
		return PyTuple_New(0);
	if (scm_is_string(value)) {
		size_t len = 0;
		char *s = scm_to_utf8_stringn(value, &len);
		PyObject *result = PyUnicode_FromStringAndSize(s, len);
		free(s);
		return result;
	}
	if (scm_is_pair(value)) {
		unsigned int len = scm_to_uint(scm_length(value));
		PyObject *result = PyTuple_New(len);
		scm_dynwind_begin(0);
		scm_dynwind_unwind_handler(
			(void (*)(void *))Py_DecRef, result, 0);
		unsigned int i;
		for (i = 0; i < len; i++) {
			PyObject *item = scm2py(scm_car(value));
			if (item == NULL) {
				scm_dynwind_end();
				Py_DECREF(result);
				return NULL;
			}
			PyTuple_SET_ITEM(result, i, item);
			value = scm_cdr(value);
		}
		scm_dynwind_end();
		return result;
	}
	if (scm_to_bool(scm_procedure_p(value))) {
		SCM ptr = scm_assq_ref(gsubr_alist, value);
		if (!scm_is_false(ptr)) {
			PyObject *result = scm_to_pointer(ptr);
			Py_INCREF(result);
			return result;
		}
		Procedure *result =
			(Procedure *)ProcedureType.tp_alloc(&ProcedureType, 0);
		if (result == NULL)
			return NULL;
		result->proc = value;
		return (PyObject *)result;
	}

	char *msg = scm_to_utf8_stringn(
		scm_simple_format(
			SCM_BOOL_F,
			scm_from_utf8_string(
				"Guile expression ~S doesn't have a "
				"corresponding Python value"),
			scm_list_1(value)), NULL);
	PyErr_SetString(PyExc_TypeError, msg);
	free(msg);
	return NULL;
}