/* Float object implementation */

/* XXX There should be overflow checks here, but it's hard to check
   for any kind of float exception without losing portability. */

#include <stdio.h>
#include <math.h>
#include <ctype.h>

#include "PROTO.h"
#include "object.h"
#include "floatobject.h"
#include "stringobject.h"
#include "objimpl.h"
#include "errors.h"

#ifndef THINK_C
extern double fmod PROTO((double, double));
extern double pow PROTO((double, double));
#endif

object *
newfloatobject(fval)
	double fval;
{
	/* For efficiency, this code is copied from newobject() */
	register floatobject *op = (floatobject *) malloc(sizeof(floatobject));
	if (op == NULL)
		return err_nomem();
	NEWREF(op);
	op->ob_type = &Floattype;
	op->ob_fval = fval;
	return (object *) op;
}

double
getfloatvalue(op)
	object *op;
{
	if (!is_floatobject(op)) {
		err_badarg();
		return -1;
	}
	else
		return ((floatobject *)op) -> ob_fval;
}

/* Methods */

static void
float_buf_repr(buf, v)
	char *buf;
	floatobject *v;
{
	register char *cp;
	/* Subroutine for float_repr and float_print.
	   We want float numbers to be recognizable as such,
	   i.e., they should contain a decimal point or an exponent.
	   However, %g may print the number as an integer;
	   in such cases, we append ".0" to the string. */
	sprintf(buf, "%.12g", v->ob_fval);
	cp = buf;
	if (*cp == '-')
		cp++;
	for (; *cp != '\0'; cp++) {
		/* Any non-digit means it's not an integer;
		   this takes care of NAN and INF as well. */
		if (!isdigit(*cp))
			break;
	}
	if (*cp == '\0') {
		*cp++ = '.';
		*cp++ = '0';
		*cp++ = '\0';
	}
}

static void
float_print(v, fp, flags)
	floatobject *v;
	FILE *fp;
	int flags;
{
	char buf[100];
	float_buf_repr(buf, v);
	fputs(buf, fp);
}

static object *
float_repr(v)
	floatobject *v;
{
	char buf[100];
	float_buf_repr(buf, v);
	return newstringobject(buf);
}

static int
float_compare(v, w)
	floatobject *v, *w;
{
	double i = v->ob_fval;
	double j = w->ob_fval;
	return (i < j) ? -1 : (i > j) ? 1 : 0;
}

static object *
float_add(v, w)
	floatobject *v;
	object *w;
{
	if (!is_floatobject(w)) {
		err_badarg();
		return NULL;
	}
	return newfloatobject(v->ob_fval + ((floatobject *)w) -> ob_fval);
}

static object *
float_sub(v, w)
	floatobject *v;
	object *w;
{
	if (!is_floatobject(w)) {
		err_badarg();
		return NULL;
	}
	return newfloatobject(v->ob_fval - ((floatobject *)w) -> ob_fval);
}

static object *
float_mul(v, w)
	floatobject *v;
	object *w;
{
	if (!is_floatobject(w)) {
		err_badarg();
		return NULL;
	}
	return newfloatobject(v->ob_fval * ((floatobject *)w) -> ob_fval);
}

static object *
float_div(v, w)
	floatobject *v;
	object *w;
{
	if (!is_floatobject(w)) {
		err_badarg();
		return NULL;
	}
	if (((floatobject *)w) -> ob_fval == 0) {
		err_setstr(ZeroDivisionError, "float division by zero");
		return NULL;
	}
	return newfloatobject(v->ob_fval / ((floatobject *)w) -> ob_fval);
}

static object *
float_rem(v, w)
	floatobject *v;
	object *w;
{
	double wx;
	if (!is_floatobject(w)) {
		err_badarg();
		return NULL;
	}
	wx = ((floatobject *)w) -> ob_fval;
	if (wx == 0.0) {
		err_setstr(ZeroDivisionError, "float division by zero");
		return NULL;
	}
	return newfloatobject(fmod(v->ob_fval, wx));
}

static object *
float_pow(v, w)
	floatobject *v;
	object *w;
{
	double iv, iw, ix;
	if (!is_floatobject(w)) {
		err_badarg();
		return NULL;
	}
	iv = v->ob_fval;
	iw = ((floatobject *)w)->ob_fval;
	if (iw == 0.0)
		return newfloatobject(1.0); /* x**0 is always 1, even 0**0 */
	errno = 0;
	ix = pow(iv, iw);
	if (errno != 0) {
		/* XXX could it be another type of error? */
		err_errno(OverflowError);
		return NULL;
	}
	return newfloatobject(ix);
}

static object *
float_neg(v)
	floatobject *v;
{
	return newfloatobject(-v->ob_fval);
}

static object *
float_pos(v)
	floatobject *v;
{
	return newfloatobject(v->ob_fval);
}

static number_methods float_as_number = {
	float_add,	/*tp_add*/
	float_sub,	/*tp_subtract*/
	float_mul,	/*tp_multiply*/
	float_div,	/*tp_divide*/
	float_rem,	/*tp_remainder*/
	float_pow,	/*tp_power*/
	float_neg,	/*tp_negate*/
	float_pos,	/*tp_plus*/
};

typeobject Floattype = {
	OB_HEAD_INIT(&Typetype)
	0,
	"float",
	sizeof(floatobject),
	0,
	free,			/*tp_dealloc*/
	float_print,		/*tp_print*/
	0,			/*tp_getattr*/
	0,			/*tp_setattr*/
	float_compare,		/*tp_compare*/
	float_repr,		/*tp_repr*/
	&float_as_number,	/*tp_as_number*/
	0,			/*tp_as_sequence*/
	0,			/*tp_as_mapping*/
};

/*
XXX This is not enough.  Need:
- automatic casts for mixed arithmetic (3.1 * 4)
- mixed comparisons (!)
- look at other uses of ints that could be extended to floats
*/
