view dmd/RealExp.d @ 144:ea6325d0edd9

+ RealExp.toCBuffer
author Eldar Insafutdinov <e.insafutdinov@gmail.com>
date Tue, 14 Sep 2010 22:39:29 +0100
parents 010eb8f0e18d
children fe2e1b93e88f
line wrap: on
line source

module dmd.RealExp;

import dmd.common;
import dmd.Complex;
import dmd.Expression;
import dmd.backend.elem;
import dmd.InterState;
import dmd.Type;
import dmd.OutBuffer;
import dmd.Loc;
import dmd.TOK;
import dmd.Scope;
import dmd.IRState;
import dmd.Type;
import dmd.HdrGenState;
import dmd.Port;
import dmd.TY;

import dmd.expression.Util;

import dmd.backend.dt_t;
import dmd.backend.Util;
import dmd.backend.TYM;
import dmd.backend.mTY;

import std.stdio;

class RealExp : Expression
{
	real value;

	this(Loc loc, real value, Type type)
	{
		super(loc, TOK.TOKfloat64, RealExp.sizeof);
		//printf("RealExp.RealExp(%Lg)\n", value);
		this.value = value;
		this.type = type;
	}

	override bool equals(Object o)
	{
		if (this is o)
			return true;
		
		Expression e = cast(Expression)o;
		if (e.op == TOKfloat64) {
			RealExp ne = cast(RealExp)e;
			if (type.toHeadMutable().equals(ne.type.toHeadMutable())) {
				if (RealEquals(value, ne.value)) {
					return true;
				}
			}
		}
		
		return 0;
	}

	override Expression semantic(Scope sc)
	{
		if (!type)
			type = Type.tfloat64;
		else
			type = type.semantic(loc, sc);
		return this;
	}

	override Expression interpret(InterState istate)
	{
		assert(false);
	}

	override string toChars()
	{
		assert(false);
	}

	override ulong toInteger()
	{
		assert(false);
	}

	override ulong toUInteger()
	{
		assert(false);
	}

	override real toReal()
	{
		return type.isreal() ? value : 0;
	}

	override real toImaginary()
	{
		return type.isreal() ? 0 : value;
	}

	override Complex!(real) toComplex()
	{
		return Complex!(real)(toReal(), toImaginary());
	}

	override Expression castTo(Scope sc, Type t)
	{
		Expression e = this;
		if (type != t)
		{
			if ((type.isreal() && t.isreal()) ||
				(type.isimaginary() && t.isimaginary())
			   )
			{   
				e = copy();
				e.type = t;
			}
			else
				e = Expression.castTo(sc, t);
		}
		return e;
	}

	override int isConst()
	{
		return 1;
	}

	override bool isBool(bool result)
	{
		return result ? (value != 0) : (value == 0);
	}

	override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
	{
	    floatToBuffer(buf, type, value);
	}

	override void toMangleBuffer(OutBuffer buf)
	{
		buf.writeByte('e');
		realToMangleBuffer(buf, value);
	}

	override elem* toElem(IRState* irs)
	{
		eve c;
		tym_t ty;

		//printf("RealExp.toElem(%p) %s\n", this, toChars());
		///memset(&c, 0, sizeof(c));
		ty = type.toBasetype().totym();
		switch (tybasic(ty))
		{
			case TYfloat:
			case TYifloat:
				c.Vfloat = value;
				if (Port.isSignallingNan(value)) {
					std.stdio.writeln("signalling float");
					(cast(uint*)&c.Vfloat)[0] &= 0xFFBFFFFFL;
				}
				break;

			case TYdouble:
			case TYidouble:
				c.Vdouble = value;	// unfortunately, this converts SNAN to QNAN
				if (Port.isSignallingNan(value)) {
					std.stdio.writeln("signalling double");
					// Put SNAN back
					(cast(uint*)&c.Vdouble)[1] &= 0xFFF7FFFFL;
				}
				break;

			case TYldouble:
			case TYildouble:
				c.Vldouble = value;
				break;

			default:
				print();
				///type.print();
				///type.toBasetype().print();
	    	    printf("ty = %d, tym = %lx\n", type.ty, ty);
				assert(0);
		}
		return el_const(ty, &c);
	}
	
	static private char[6] zeropad;

	override dt_t** toDt(dt_t** pdt)
	{
		float fvalue;
		double dvalue;
		real evalue;

		//printf("RealExp.toDt(%Lg)\n", value);
		switch (type.toBasetype().ty)
		{
			case Tfloat32:
			case Timaginary32:
				fvalue = value;
				pdt = dtnbytes(pdt,4,cast(char*)&fvalue);
				break;

			case Tfloat64:
			case Timaginary64:
				dvalue = value;
				pdt = dtnbytes(pdt,8,cast(char*)&dvalue);
				break;

			case Tfloat80:
			case Timaginary80:
				evalue = value;
				pdt = dtnbytes(pdt,REALSIZE - REALPAD,cast(char*)&evalue);
				pdt = dtnbytes(pdt,REALPAD,zeropad.ptr);
				assert(REALPAD <= zeropad.sizeof);
				break;

			default:
				writef("%s\n", toChars());
				///type.print();
				assert(0);
				break;
		}
		return pdt;
	}
}