package migl.lisp.operator;

import migl.lisp.LispElement;
import migl.lisp.LispError;
import migl.lisp.LispEval;
import migl.util.ConsList;

public class MathOperator implements LispOperator {

	@Override
	public LispElement apply(LispEval eval, String operator, ConsList<Object> lisp) throws LispError {
		if(lisp.size() != 1) {
			throw new LispError(LispError.ERR_NUM_ARG);
		}
		LispElement elt = eval.getElement(lisp.car());
		switch(operator) {
			case "cbrt":
				return LispElement.generate(Math.cbrt(elt.toNumber()));
			case "ceil":
				return LispElement.generate(Math.ceil(elt.toNumber()));
			case "floor":
				return LispElement.generate(Math.floor(elt.toNumber()));
			case "log10":
				return LispElement.generate(Math.log10(elt.toNumber()));
			case "cos":
				return LispElement.generate(Math.cos(elt.toNumber()));
			case "rint":
				return LispElement.generate(Math.rint(elt.toNumber()));
			case "round":
				return LispElement.generate(Math.round(elt.toNumber()));
			case "signum":
				return LispElement.generate(Math.signum(elt.toNumber()));
			default:
				throw new LispError(operator + LispError.ERR_UNKNOW);
		}
	}

}
