changeset 123:9e39c7de8438

Make dmd test suite compile
author korDen
date Fri, 03 Sep 2010 20:46:58 +0400
parents c77e9f4f1793
children 731ab26f07bf
files dmd/AddAssignExp.d dmd/AddExp.d dmd/AndAssignExp.d dmd/AndExp.d dmd/ArrayLiteralExp.d dmd/BinExp.d dmd/CastExp.d dmd/ComExp.d dmd/Complex.d dmd/ComplexExp.d dmd/CompoundStatement.d dmd/CondExp.d dmd/DeclarationExp.d dmd/DeleteDeclaration.d dmd/DivAssignExp.d dmd/DivExp.d dmd/DotVarExp.d dmd/ForStatement.d dmd/FuncExp.d dmd/GotoCaseStatement.d dmd/IndexExp.d dmd/InterfaceDeclaration.d dmd/MinAssignExp.d dmd/MinExp.d dmd/ModAssignExp.d dmd/ModExp.d dmd/MulAssignExp.d dmd/MulExp.d dmd/NegExp.d dmd/NewAnonClassExp.d dmd/NewDeclaration.d dmd/NewExp.d dmd/NullExp.d dmd/OrAssignExp.d dmd/OrExp.d dmd/Parser.d dmd/RealExp.d dmd/Statement.d dmd/StructLiteralExp.d dmd/ThisExp.d dmd/TypeFunction.d dmd/UAddExp.d dmd/UnrolledLoopStatement.d dmd/Util.d dmd/WhileStatement.d dmd/XorAssignExp.d dmd/XorExp.d
diffstat 47 files changed, 817 insertions(+), 137 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/AddAssignExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/AddAssignExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -153,14 +153,7 @@
 	
     override Expression buildArrayLoop(Arguments fparams)
 	{
-		/* Evaluate assign expressions right to left		
-		 */								
-		Expression ex2 = e2.buildArrayLoop(fparams);		
-		Expression ex1 = e1.buildArrayLoop(fparams);		
-		Argument param = cast(Argument)fparams.data[0];		
-		param.storageClass = STCundefined;					
-		Expression e = new AddAssignExp(Loc(0), ex1, ex2);		
-		return e;							
+		return AssignExp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
     override Identifier opId()    /* For operator overloading */
--- a/dmd/AddExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/AddExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -124,12 +124,7 @@
 
 	override Expression buildArrayLoop(Arguments fparams)
 	{
-		/* Evaluate assign expressions left to right		
-		 */								
-		Expression ex1 = e1.buildArrayLoop(fparams);		
-		Expression ex2 = e2.buildArrayLoop(fparams);		
-		Expression e = new AddExp(Loc(0), ex1, ex2);			
-		return e;							
+		return Exp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
 	override bool isCommutative()
--- a/dmd/AndAssignExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/AndAssignExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -41,7 +41,7 @@
 	
     override Expression buildArrayLoop(Arguments fparams)
 	{
-		assert(false);
+		return AssignExp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
     override Identifier opId()    /* For operator overloading */
--- a/dmd/AndExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/AndExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -85,12 +85,7 @@
 
 	override Expression buildArrayLoop(Arguments fparams)
 	{
-		/* Evaluate assign expressions left to right		
-		 */								
-		Expression ex1 = e1.buildArrayLoop(fparams);		
-		Expression ex2 = e2.buildArrayLoop(fparams);		
-		Expression e = new AndExp(Loc(0), ex1, ex2);			
-		return e;							
+		return Exp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
 	override IntRange getIntRange()
--- a/dmd/ArrayLiteralExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/ArrayLiteralExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -16,6 +16,7 @@
 import dmd.HdrGenState;
 import dmd.backend.dt_t;
 import dmd.InlineScanState;
+import dmd.GlobalExpressions;
 import dmd.Array;
 import dmd.ArrayTypes;
 import dmd.TOK;
@@ -238,7 +239,56 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		Expressions expsx = null;
+
+version (LOG) {
+		printf("ArrayLiteralExp.interpret() %.*s\n", toChars());
+}
+		if (elements)
+		{
+			foreach (size_t i, Expression e; elements)
+			{   
+				Expression ex;
+
+				ex = e.interpret(istate);
+				if (ex is EXP_CANT_INTERPRET)
+				{   
+					delete expsx;
+					return EXP_CANT_INTERPRET;
+				}
+
+				/* If any changes, do Copy On Write
+				 */
+				if (ex != e)
+				{
+					if (!expsx)
+					{
+						expsx = new Expressions();
+						expsx.setDim(elements.dim);
+						for (size_t j = 0; j < elements.dim; j++)
+						{
+							expsx[j] = elements[j];
+						}
+					}
+					expsx[i] = ex;
+				}
+			}
+		}
+		if (elements && expsx)
+		{
+			expandTuples(expsx);
+			if (expsx.dim != elements.dim)
+			{   
+				delete expsx;
+				return EXP_CANT_INTERPRET;
+			}
+			
+			ArrayLiteralExp ae = new ArrayLiteralExp(loc, expsx);
+			ae.type = type;
+			
+			return ae;
+		}
+		return this;
 	}
 
 	override MATCH implicitConvTo(Type t)
--- a/dmd/BinExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/BinExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -672,7 +672,8 @@
 
     void scanForNestedRef(Scope sc)
 	{
-		assert(false);
+		e1.scanForNestedRef(sc);
+		e2.scanForNestedRef(sc);
 	}
 
 	Expression interpretCommon(InterState istate, Expression function(Type, Expression, Expression) fp)
@@ -1959,6 +1960,8 @@
 					case TOK.TOKleg:
 					case TOK.TOKue:
 						break;
+					default:
+						break;	///
 				}
 
 				return e;
@@ -2008,6 +2011,15 @@
 
 		return e;
 	}
+	final void AssignExp_buildArrayIdent(OutBuffer buf, Expressions arguments, string Str)
+	{							
+		/* Evaluate assign expressions right to left	
+		 */							
+		e2.buildArrayIdent(buf, arguments);		
+		e1.buildArrayIdent(buf, arguments);		
+		buf.writestring(Str);				
+		buf.writestring("ass");				
+	}
 	
 	final void Exp_buildArrayIdent(OutBuffer buf, Expressions arguments, string Str)
 	{									
@@ -2018,13 +2030,25 @@
 		buf.writestring(Str);						
 	}
 	
-	final void AssignExp_buildArrayIdent(OutBuffer buf, Expressions arguments, string Str)
-	{							
-		/* Evaluate assign expressions right to left	
-		 */							
-		e2.buildArrayIdent(buf, arguments);		
-		e1.buildArrayIdent(buf, arguments);		
-		buf.writestring(Str);				
-		buf.writestring("ass");				
+	final Expression AssignExp_buildArrayLoop(AssignExpType)(Arguments fparams)// if (is (AssignExpType : AssignExp))
+	{
+		/* Evaluate assign expressions right to left
+		 */
+		Expression ex2 = e2.buildArrayLoop(fparams);
+		Expression ex1 = e1.buildArrayLoop(fparams);
+		Argument param = cast(Argument)fparams.data[0];
+		param.storageClass = STCundefined;
+		Expression e = new AssignExpType(Loc(0), ex1, ex2);
+		return e;
 	}
-}
+	
+	final Expression Exp_buildArrayLoop(ExpType)(Arguments fparams) if (is (ExpType : BinExp))
+	{
+		/* Evaluate assign expressions left to right
+		 */
+		Expression ex1 = e1.buildArrayLoop(fparams);
+		Expression ex2 = e2.buildArrayLoop(fparams);
+		Expression e = new ExpType(Loc(0), ex1, ex2);
+		return e;
+	}
+}
\ No newline at end of file
--- a/dmd/CastExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/CastExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -370,7 +370,14 @@
 
 	override bool checkSideEffect(int flag)
 	{
-		assert(false);
+		/* if not:
+		 *  cast(void)
+		 *  cast(classtype)func()
+		 */
+		if (!to.equals(Type.tvoid) && !(to.ty == Tclass && e1.op == TOKcall && e1.type.ty == Tclass))
+			return Expression.checkSideEffect(flag);
+			
+		return true;
 	}
 
 	override void checkEscape()
--- a/dmd/ComExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/ComExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -13,6 +13,7 @@
 import dmd.ArrayTypes;
 import dmd.TOK;
 import dmd.TY;
+import dmd.Id;
 
 import dmd.backend.Util;
 import dmd.backend.OPER;
@@ -69,17 +70,20 @@
 
 	override void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		e1.buildArrayIdent(buf, arguments);
+		buf.writestring("Com");
 	}
 
 	override Expression buildArrayLoop(Arguments fparams)
 	{
-		assert(false);
+		Expression ex1 = e1.buildArrayLoop(fparams);
+		Expression e = new ComExp(Loc(0), ex1);
+		return e;
 	}
 
 	override Identifier opId()
 	{
-		assert(false);
+		return Id.com;
 	}
 
 	override elem* toElem(IRState* irs)
--- a/dmd/Complex.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/Complex.d	Fri Sep 03 20:46:58 2010 +0400
@@ -4,4 +4,6 @@
 {
 	T re;
 	T im;
+	
+	public static const Complex zero = Complex(0, 0);
 }
\ No newline at end of file
--- a/dmd/ComplexExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/ComplexExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -105,7 +105,10 @@
 
 	override bool isBool(bool result)
 	{
-		assert(false);
+		if (result)
+			return value != Complex!(real).zero;
+		else
+			return value == Complex!(real).zero;
 	}
 
 	override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
--- a/dmd/CompoundStatement.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/CompoundStatement.d	Fri Sep 03 20:46:58 2010 +0400
@@ -207,7 +207,13 @@
 	
     override bool usesEH()
 	{
-		assert(false);
+		foreach (Statement s; statements)
+		{	
+			if (s && s.usesEH())
+				return true;
+		}
+		
+		return false;
 	}
 	
     override BE blockExit()
--- a/dmd/CondExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/CondExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -3,6 +3,7 @@
 import dmd.common;
 import dmd.BinExp;
 import dmd.Loc;
+import dmd.PtrExp;
 import dmd.MATCH;
 import dmd.Expression;
 import dmd.Scope;
@@ -171,22 +172,39 @@
 
     override int isLvalue()
 	{
-		assert(false);
+		return e1.isLvalue() && e2.isLvalue();
 	}
 
-    override Expression toLvalue(Scope sc, Expression e)
+    override Expression toLvalue(Scope sc, Expression ex)
 	{
-		assert(false);
+		PtrExp e;
+
+		// convert (econd ? e1 : e2) to *(econd ? &e1 : &e2)
+		e = new PtrExp(loc, this, type);
+
+		e1 = e1.addressOf(sc);
+		//e1 = e1.toLvalue(sc, null);
+
+		e2 = e2.addressOf(sc);
+		//e2 = e2.toLvalue(sc, null);
+
+		typeCombine(sc);
+
+		type = e2.type;
+		return e;
 	}
 
     override Expression modifiableLvalue(Scope sc, Expression e)
 	{
-		assert(false);
+		error("conditional expression %s is not a modifiable lvalue", toChars());
+		return this;
 	}
 
     override Expression checkToBoolean()
 	{
-		assert(false);
+		e1 = e1.checkToBoolean();
+		e2 = e2.checkToBoolean();
+		return this;
 	}
 
     override bool checkSideEffect(int flag)
--- a/dmd/DeclarationExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/DeclarationExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -198,7 +198,8 @@
 
 	override void scanForNestedRef(Scope sc)
 	{
-		assert(false);
+		//printf("DeclarationExp.scanForNestedRef() %s\n", toChars());
+		declaration.parent = sc.parent;
 	}
 
 version (DMDV2) {
--- a/dmd/DeleteDeclaration.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/DeleteDeclaration.d	Fri Sep 03 20:46:58 2010 +0400
@@ -9,6 +9,13 @@
 import dmd.OutBuffer;
 import dmd.HdrGenState;
 import dmd.STC;
+import dmd.Id;
+import dmd.Argument;
+import dmd.ClassDeclaration;
+import dmd.TypeFunction;
+import dmd.Type;
+import dmd.LINK;
+import dmd.TY;
 
 class DeleteDeclaration : FuncDeclaration
 {
@@ -16,48 +23,87 @@
 
     this(Loc loc, Loc endloc, Arguments arguments)
 	{
-		assert(false);
-		super(loc, endloc, null, STC.init, null);
+		super(loc, endloc, Id.classDelete, STCstatic, null);
+		this.arguments = arguments;
 	}
 	
     override Dsymbol syntaxCopy(Dsymbol)
 	{
-		assert(false);
+		DeleteDeclaration f;
+
+		f = new DeleteDeclaration(loc, endloc, null);
+
+		FuncDeclaration.syntaxCopy(f);
+
+		f.arguments = Argument.arraySyntaxCopy(arguments);
+
+		return f;
 	}
 	
     override void semantic(Scope sc)
 	{
-		assert(false);
+		ClassDeclaration cd;
+
+		//printf("DeleteDeclaration.semantic()\n");
+
+		parent = sc.parent;
+		Dsymbol parent = toParent();
+		cd = parent.isClassDeclaration();
+		if (!cd && !parent.isStructDeclaration())
+		{
+			error("new allocators only are for class or struct definitions");
+		}
+		type = new TypeFunction(arguments, Type.tvoid, 0, LINKd);
+
+		type = type.semantic(loc, sc);
+		assert(type.ty == Tfunction);
+
+		// Check that there is only one argument of type void*
+		TypeFunction tf = cast(TypeFunction)type;
+		if (Argument.dim(tf.parameters) != 1)
+		{
+			error("one argument of type void* expected");
+		}
+		else
+		{
+			Argument a = Argument.getNth(tf.parameters, 0);
+			if (!a.type.equals(Type.tvoid.pointerTo()))
+				error("one argument of type void* expected, not %s", a.type.toChars());
+		}
+
+		FuncDeclaration.semantic(sc);
 	}
 	
     override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
-		assert(false);
+		buf.writestring("delete");
+		Argument.argsToCBuffer(buf, hgs, arguments, 0);
+		bodyToCBuffer(buf, hgs);
 	}
 	
     override string kind()
 	{
-		assert(false);
+		return "deallocator";
 	}
 
     override bool isDelete()
 	{
-		assert(false);
+		return true;
 	}
 	
     override bool isVirtual()
 	{
-		assert(false);
+		return false;
 	}
 	
     override bool addPreInvariant()
 	{
-		assert(false);
+		return false;
 	}
 	
     override bool addPostInvariant()
 	{
-		assert(false);
+		return false;
 	}
 	
 version (_DH) {
--- a/dmd/DivAssignExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/DivAssignExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -106,7 +106,7 @@
 	
     override Expression buildArrayLoop(Arguments fparams)
 	{
-		assert(false);
+		return AssignExp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
     override Identifier opId()    /* For operator overloading */
--- a/dmd/DivExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/DivExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -118,12 +118,7 @@
 
 	override Expression buildArrayLoop(Arguments fparams)
 	{
-		/* Evaluate assign expressions left to right		
-		 */								
-		Expression ex1 = e1.buildArrayLoop(fparams);		
-		Expression ex2 = e2.buildArrayLoop(fparams);		
-		Expression e = new DivExp(Loc(0), ex1, ex2);			
-		return e;							
+		return Exp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
 	override IntRange getIntRange()
--- a/dmd/DotVarExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/DotVarExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -225,7 +225,36 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		Expression e = EXP_CANT_INTERPRET;
+
+version (LOG) {
+		printf("DotVarExp.interpret() %.*s\n", toChars());
+}
+
+		Expression ex = e1.interpret(istate);
+		if (ex !is EXP_CANT_INTERPRET)
+		{
+			if (ex.op == TOKstructliteral)
+			{   
+				StructLiteralExp se = cast(StructLiteralExp)ex;
+				VarDeclaration v = var.isVarDeclaration();
+				if (v)
+				{	
+					e = se.getField(type, v.offset);
+					if (!e)
+						e = EXP_CANT_INTERPRET;
+					return e;
+				}
+			} else {
+				error("%s.%s is not yet implemented at compile time", ex.toChars(), var.toChars());
+			}
+		}
+
+version (LOG) {
+		if (e is EXP_CANT_INTERPRET)
+			printf("DotVarExp.interpret() %.*s = EXP_CANT_INTERPRET\n", toChars());
+}
+		return e;
 	}
 
 	override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
--- a/dmd/ForStatement.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/ForStatement.d	Fri Sep 03 20:46:58 2010 +0400
@@ -3,6 +3,7 @@
 import dmd.common;
 import dmd.Statement;
 import dmd.Expression;
+import dmd.GlobalExpressions;
 import dmd.Loc;
 import dmd.Scope;
 import dmd.InterState;
@@ -156,7 +157,79 @@
 	
     override Expression interpret(InterState istate)
 	{
-		assert(false);
+version (LOG) {
+		printf("ForStatement.interpret()\n");
+}
+		if (istate.start == this)
+			istate.start = null;
+		
+		Expression e;
+
+		if (init)
+		{
+			e = init.interpret(istate);
+			if (e is EXP_CANT_INTERPRET)
+				return e;
+			assert(!e);
+		}
+
+		if (istate.start)
+		{
+			e = body_ ? body_.interpret(istate) : null;
+			if (istate.start)
+				return null;
+			if (e is EXP_CANT_INTERPRET)
+				return e;
+			if (e is EXP_BREAK_INTERPRET)
+				return null;
+			if (e is EXP_CONTINUE_INTERPRET)
+				goto Lcontinue;
+			if (e)
+				return e;
+		}
+
+		while (true)
+		{
+			if (!condition)
+				goto Lhead;
+			e = condition.interpret(istate);
+			if (e is EXP_CANT_INTERPRET)
+				break;
+			if (!e.isConst())
+			{   
+				e = EXP_CANT_INTERPRET;
+				break;
+			}
+			if (e.isBool(true))
+			{
+			Lhead:
+				e = body_ ? body_.interpret(istate) : null;
+				if (e is EXP_CANT_INTERPRET)
+					break;
+				if (e is EXP_BREAK_INTERPRET)
+				{   
+					e = null;
+					break;
+				}
+				if (e && e !is EXP_CONTINUE_INTERPRET)
+					break;
+			Lcontinue:
+				if (increment)
+				{
+					e = increment.interpret(istate);
+					if (e is EXP_CANT_INTERPRET)
+						break;
+				}
+			}
+			else if (e.isBool(false))
+			{
+				e = null;
+				break;
+			}
+			else
+				assert(0);
+		}
+		return e;
 	}
 	
     override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
--- a/dmd/FuncExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/FuncExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -87,7 +87,8 @@
 
 	override void scanForNestedRef(Scope sc)
 	{
-		assert(false);
+		//printf("FuncExp.scanForNestedRef(%s)\n", toChars());
+		//fd.parent = sc.parent;
 	}
 
 	override string toChars()
@@ -122,7 +123,8 @@
 
 	override int inlineCost(InlineCostState* ics)
 	{
-		assert(false);
+		// Right now, this makes the function be output to the .obj file twice.
+		return COST_MAX;
 	}
 }
 
--- a/dmd/GotoCaseStatement.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/GotoCaseStatement.d	Fri Sep 03 20:46:58 2010 +0400
@@ -13,6 +13,11 @@
 import dmd.BE;
 import dmd.WANT;
 
+import dmd.backend.Util;
+import dmd.backend.block;
+import dmd.backend.BC;
+import dmd.backend.Blockx;
+
 class GotoCaseStatement : Statement
 {
     Expression exp;		// NULL, or which case to goto
@@ -75,6 +80,39 @@
 
     override void toIR(IRState* irs)
 	{
-		assert(false);
+		block* b;
+		Blockx* blx = irs.blx;
+		block* bdest = cs.cblock;
+
+		if (!bdest)
+		{
+			bdest = block_calloc(blx);
+			cs.cblock = bdest;
+		}
+
+		b = blx.curblock;
+
+		// The rest is equivalent to GotoStatement
+
+		// Adjust exception handler scope index if in different try blocks
+		if (b.Btry != bdest.Btry)
+		{
+			// Check that bdest is in an enclosing try block
+			for (block* bt = b.Btry; bt != bdest.Btry; bt = bt.Btry)
+			{
+				if (!bt)
+				{
+					//printf("b.Btry = %p, bdest.Btry = %p\n", b.Btry, bdest.Btry);
+					error("cannot goto into try block");
+					break;
+				}
+			}
+
+			//setScopeIndex(blx, b, bdest.Btry ? bdest.Btry.Bscope_index : -1);
+		}
+
+		list_append(&b.Bsucc,bdest);
+		incUsage(irs, loc);
+		block_next(blx, BC.BCgoto, null);
 	}
 }
--- a/dmd/IndexExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/IndexExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -288,7 +288,14 @@
 
 	override void scanForNestedRef(Scope sc)
 	{
-		assert(false);
+		e1.scanForNestedRef(sc);
+
+		if (lengthVar)
+		{	
+			//printf("lengthVar\n");
+			lengthVar.parent = sc.parent;
+		}
+		e2.scanForNestedRef(sc);
 	}
 
 	override elem* toElem(IRState* irs)
--- a/dmd/InterfaceDeclaration.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/InterfaceDeclaration.d	Fri Sep 03 20:46:58 2010 +0400
@@ -50,7 +50,15 @@
 	
     override Dsymbol syntaxCopy(Dsymbol s)
 	{
-		assert(false);
+		InterfaceDeclaration id;
+
+		if (s)
+			id = cast(InterfaceDeclaration)s;
+		else
+			id = new InterfaceDeclaration(loc, ident, null);
+
+		ClassDeclaration.syntaxCopy(id);
+		return id;
 	}
 	
     override void semantic(Scope sc)
--- a/dmd/MinAssignExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/MinAssignExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -81,7 +81,7 @@
 	
     override Expression buildArrayLoop(Arguments fparams)
 	{
-		assert(false);
+		return AssignExp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
     override Identifier opId()    /* For operator overloading */
--- a/dmd/MinExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/MinExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -150,12 +150,7 @@
 
 	override Expression buildArrayLoop(Arguments fparams)
 	{
-		/* Evaluate assign expressions left to right		
-		 */								
-		Expression ex1 = e1.buildArrayLoop(fparams);		
-		Expression ex2 = e2.buildArrayLoop(fparams);		
-		Expression e = new MinExp(Loc(0), ex1, ex2);			
-		return e;							
+		return Exp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
 	override Identifier opId()
--- a/dmd/ModAssignExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/ModAssignExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -38,12 +38,12 @@
 	
     override void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		AssignExp_buildArrayIdent(buf, arguments, "Mod");
 	}
 	
     override Expression buildArrayLoop(Arguments fparams)
 	{
-		assert(false);
+		return AssignExp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
     override Identifier opId()    /* For operator overloading */
--- a/dmd/ModExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/ModExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -85,12 +85,7 @@
 
 	override Expression buildArrayLoop(Arguments fparams)
 	{
-		/* Evaluate assign expressions left to right		
-		 */								
-		Expression ex1 = e1.buildArrayLoop(fparams);		
-		Expression ex2 = e2.buildArrayLoop(fparams);		
-		Expression e = new ModExp(Loc(0), ex1, ex2);			
-		return e;							
+		return Exp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
 	override Identifier opId()
--- a/dmd/MulAssignExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/MulAssignExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -98,7 +98,7 @@
 	
     override Expression buildArrayLoop(Arguments fparams)
 	{
-		assert(false);
+		return AssignExp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
     override Identifier opId()    /* For operator overloading */
--- a/dmd/MulExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/MulExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -123,12 +123,7 @@
 
 	override Expression buildArrayLoop(Arguments fparams)
 	{
-		/* Evaluate assign expressions left to right		
-		 */								
-		Expression ex1 = e1.buildArrayLoop(fparams);		
-		Expression ex2 = e2.buildArrayLoop(fparams);		
-		Expression e = new MulExp(Loc(0), ex1, ex2);			
-		return e;							
+		return Exp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
 	override bool isCommutative()
--- a/dmd/NegExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/NegExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -72,12 +72,15 @@
 
 	override void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		e1.buildArrayIdent(buf, arguments);
+		buf.writestring("Neg");
 	}
 
 	override Expression buildArrayLoop(Arguments fparams)
 	{
-		assert(false);
+		Expression ex1 = e1.buildArrayLoop(fparams);
+		Expression e = new NegExp(Loc(0), ex1);
+		return e;
 	}
 
 	override Identifier opId()
--- a/dmd/NewAnonClassExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/NewAnonClassExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -6,9 +6,14 @@
 import dmd.Loc;
 import dmd.Scope;
 import dmd.ClassDeclaration;
+import dmd.DeclarationExp;
+import dmd.NewExp;
+import dmd.CommaExp;
+import dmd.PREC;
 import dmd.HdrGenState;
 import dmd.ArrayTypes;
 import dmd.TOK;
+import dmd.expression.Util;
 
 class NewAnonClassExp : Expression
 {
@@ -21,33 +26,75 @@
 
 	this(Loc loc, Expression thisexp, Expressions newargs, ClassDeclaration cd, Expressions arguments)
 	{
-		assert(false);
-		super(loc, TOK.init, 0);
+		super(loc, TOKnewanonclass, NewAnonClassExp.sizeof);
+		this.thisexp = thisexp;
+		this.newargs = newargs;
+		this.cd = cd;
+		this.arguments = arguments;
 	}
 
 	override Expression syntaxCopy()
 	{
-		assert(false);
+		return new NewAnonClassExp(loc, 
+			thisexp ? thisexp.syntaxCopy() : null,
+			arraySyntaxCopy(newargs),
+			cast(ClassDeclaration)cd.syntaxCopy(null),
+			arraySyntaxCopy(arguments));
 	}
-
+	
 	override Expression semantic(Scope sc)
 	{
-		assert(false);
+version (LOGSEMANTIC) {
+		printf("NewAnonClassExp.semantic() %s\n", toChars());
+		//printf("thisexp = %p\n", thisexp);
+		//printf("type: %s\n", type.toChars());
+}
+
+		Expression d = new DeclarationExp(loc, cd);
+		d = d.semantic(sc);
+
+		Expression n = new NewExp(loc, thisexp, newargs, cd.type, arguments);
+
+		Expression c = new CommaExp(loc, d, n);
+		return c.semantic(sc);
 	}
 
 	override bool checkSideEffect(int flag)
 	{
-		assert(false);
+		return true;
 	}
 
-	void toCBuffer(OutBuffer buf, HdrGenState hgs)
+	void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
-		assert(false);
+		if (thisexp)
+		{	
+			expToCBuffer(buf, hgs, thisexp, PREC.PREC_primary);
+			buf.writeByte('.');
+		}
+		buf.writestring("new");
+		if (newargs && newargs.dim)
+		{
+			buf.writeByte('(');
+			argsToCBuffer(buf, newargs, hgs);
+			buf.writeByte(')');
+		}
+		buf.writestring(" class ");
+		if (arguments && arguments.dim)
+		{
+			buf.writeByte('(');
+			argsToCBuffer(buf, arguments, hgs);
+			buf.writeByte(')');
+		}
+		//buf.writestring(" { }");
+		if (cd)
+		{
+			cd.toCBuffer(buf, hgs);
+		}
 	}
 
 	override bool canThrow()
 	{
-		assert(false);
+		return true;
 	}
 }
 
--- a/dmd/NewDeclaration.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/NewDeclaration.d	Fri Sep 03 20:46:58 2010 +0400
@@ -5,10 +5,17 @@
 import dmd.Loc;
 import dmd.ArrayTypes;
 import dmd.Dsymbol;
+import dmd.Argument;
+import dmd.ClassDeclaration;
+import dmd.Type;
+import dmd.TypeFunction;
+import dmd.LINK;
+import dmd.TY;
 import dmd.Scope;
 import dmd.OutBuffer;
 import dmd.HdrGenState;
 import dmd.STC;
+import dmd.Id;
 
 class NewDeclaration : FuncDeclaration
 {
@@ -17,43 +24,85 @@
 
     this(Loc loc, Loc endloc, Arguments arguments, int varargs)
 	{
-		assert(false);
-		super(loc, loc, null, STC.init, null);
+		super(loc, endloc, Id.classNew, STCstatic, null);
+		this.arguments = arguments;
+		this.varargs = varargs;
 	}
 
     override Dsymbol syntaxCopy(Dsymbol)
 	{
-		assert(false);
+		NewDeclaration f;
+
+		f = new NewDeclaration(loc, endloc, null, varargs);
+
+		FuncDeclaration.syntaxCopy(f);
+
+		f.arguments = Argument.arraySyntaxCopy(arguments);
+
+		return f;
 	}
 
     override void semantic(Scope sc)
 	{
-		assert(false);
+		ClassDeclaration cd;
+		Type tret;
+
+		//printf("NewDeclaration.semantic()\n");
+
+		parent = sc.parent;
+		Dsymbol parent = toParent();
+		cd = parent.isClassDeclaration();
+		if (!cd && !parent.isStructDeclaration())
+		{
+			error("new allocators only are for class or struct definitions");
+		}
+		tret = Type.tvoid.pointerTo();
+		type = new TypeFunction(arguments, tret, varargs, LINKd);
+
+		type = type.semantic(loc, sc);
+		assert(type.ty == Tfunction);
+
+		// Check that there is at least one argument of type size_t
+		TypeFunction tf = cast(TypeFunction)type;
+		if (Argument.dim(tf.parameters) < 1)
+		{
+			error("at least one argument of type size_t expected");
+		}
+		else
+		{
+			Argument a = Argument.getNth(tf.parameters, 0);
+			if (!a.type.equals(Type.tsize_t))
+				error("first argument must be type size_t, not %s", a.type.toChars());
+		}
+
+		FuncDeclaration.semantic(sc);
 	}
 
     override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
-		assert(false);
+		buf.writestring("new");
+		Argument.argsToCBuffer(buf, hgs, arguments, varargs);
+		bodyToCBuffer(buf, hgs);
 	}
 
     override string kind()
 	{
-		assert(false);
+		return "allocator";
 	}
 
     override bool isVirtual()
 	{
-		assert(false);
+		return false;
 	}
 
     override bool addPreInvariant()
 	{
-		assert(false);
+		return false;
 	}
 
     override bool addPostInvariant()
 	{
-		assert(false);
+		return false;
 	}
 
     override NewDeclaration isNewDeclaration() { return this; }
--- a/dmd/NewExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/NewExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -720,7 +720,7 @@
 
 	override bool checkSideEffect(int flag)
 	{
-		assert(false);
+		return true;
 	}
 
 	override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
--- a/dmd/NullExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/NullExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -138,7 +138,7 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		return this;
 	}
 
 	override elem* toElem(IRState* irs)
--- a/dmd/OrAssignExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/OrAssignExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -36,12 +36,12 @@
 	
     override void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		AssignExp_buildArrayIdent(buf, arguments, "Or");
 	}
 	
     override Expression buildArrayLoop(Arguments fparams)
 	{
-		assert(false);
+		return AssignExp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
     override Identifier opId()    /* For operator overloading */
--- a/dmd/OrExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/OrExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -81,12 +81,12 @@
 
 	override void buildArrayIdent(OutBuffer buf, Expressions arguments)
 	{
-		assert(false);
+		Exp_buildArrayIdent(buf, arguments, "Or");
 	}
 
 	override Expression buildArrayLoop(Arguments fparams)
 	{
-		assert(false);
+		return Exp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
 	override MATCH implicitConvTo(Type t)
--- a/dmd/Parser.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/Parser.d	Fri Sep 03 20:46:58 2010 +0400
@@ -1718,14 +1718,44 @@
 		return f;
 	}
 	
+	/*****************************************
+	 * Parse a new definition:
+	 *	new(arguments) { body }
+	 * Current token is 'new'.
+	 */
     NewDeclaration parseNew()
 	{
-		assert(false);
+		NewDeclaration f;
+		scope Arguments arguments = new Arguments();
+		int varargs;
+		Loc loc = this.loc;
+
+		nextToken();
+		arguments = parseParameters(&varargs);
+		f = new NewDeclaration(loc, Loc(0), arguments, varargs);
+		parseContracts(f);
+		return f;
 	}
 	
+	/*****************************************
+	 * Parse a delete definition:
+	 *	delete(arguments) { body }
+	 * Current token is 'delete'.
+	 */
     DeleteDeclaration parseDelete()
 	{
-		assert(false);
+		DeleteDeclaration f;
+		scope Arguments arguments;
+		int varargs;
+		Loc loc = this.loc;
+
+		nextToken();
+		arguments = parseParameters(&varargs);
+		if (varargs)
+			error("... not allowed in delete function parameter list");
+		f = new DeleteDeclaration(loc, Loc(0), arguments);
+		parseContracts(f);
+		return f;
 	}
 	
     Arguments parseParameters(int* pvarargs)
--- a/dmd/RealExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/RealExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -110,7 +110,7 @@
 
 	override bool isBool(bool result)
 	{
-		assert(false);
+		return result ? (value != 0) : (value == 0);
 	}
 
 	override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
--- a/dmd/Statement.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/Statement.d	Fri Sep 03 20:46:58 2010 +0400
@@ -120,9 +120,11 @@
 		assert(false);
 	}
 	
+	// TRUE if statement uses exception handling
+	
     bool usesEH()
 	{
-		assert(false);
+		return false;
 	}
 	
     BE blockExit()
--- a/dmd/StructLiteralExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/StructLiteralExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -2,11 +2,13 @@
 
 import dmd.common;
 import dmd.Expression;
+import dmd.GlobalExpressions;
 import dmd.MOD;
 import dmd.TypeStruct;
 import dmd.TypeSArray;
 import dmd.expression.Util;
 import dmd.ErrorExp;
+import dmd.Array;
 import dmd.Dsymbol;
 import dmd.VarDeclaration;
 import dmd.StructDeclaration;
@@ -63,7 +65,7 @@
 
 	override Expression syntaxCopy()
 	{
-		assert(false);
+		return new StructLiteralExp(loc, sd, arraySyntaxCopy(elements));
 	}
 
 	override Expression semantic(Scope sc)
@@ -459,12 +461,163 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		Expressions expsx = null;
+
+version (LOG) {
+		printf("StructLiteralExp.interpret() %.*s\n", toChars());
+}
+		/* We don't know how to deal with overlapping fields
+		 */
+		if (sd.hasUnions)
+		{   
+			error("Unions with overlapping fields are not yet supported in CTFE");
+			return EXP_CANT_INTERPRET;
+		}
+
+		if (elements)
+		{
+			foreach (size_t i, Expression e; elements)
+			{   
+				if (!e)
+					continue;
+
+				Expression ex = e.interpret(istate);
+				if (ex is EXP_CANT_INTERPRET)
+				{   
+					delete expsx;
+					return EXP_CANT_INTERPRET;
+				}
+
+				/* If any changes, do Copy On Write
+				 */
+				if (ex != e)
+				{
+					if (!expsx)
+					{   
+						expsx = new Expressions();
+						expsx.setDim(elements.dim);
+						for (size_t j = 0; j < elements.dim; j++)
+						{
+							expsx[j] = elements[j];
+						}
+					}
+					expsx[i] = ex;
+				}
+			}
+		}
+		if (elements && expsx)
+		{
+			expandTuples(expsx);
+			if (expsx.dim != elements.dim)
+			{   
+				delete expsx;
+				return EXP_CANT_INTERPRET;
+			}
+			StructLiteralExp se = new StructLiteralExp(loc, sd, expsx);
+			se.type = type;
+			return se;
+		}
+		return this;
 	}
 
 	override dt_t** toDt(dt_t** pdt)
 	{
-		assert(false);
+		Array dts;
+		dt_t *dt;
+		dt_t *d;
+		uint offset;
+
+		//printf("StructLiteralExp.toDt() %s)\n", toChars());
+		dts.setDim(sd.fields.dim);
+		dts.zero();
+		assert(elements.dim <= sd.fields.dim);
+
+		foreach (uint i, Expression e; elements)
+		{
+			if (!e)
+				continue;
+
+			dt = null;
+			e.toDt(&dt);
+			dts.data[i] = dt;
+		}
+
+		offset = 0;
+		foreach (uint j, VarDeclaration v; sd.fields)
+		{
+			d = cast(dt_t*)dts.data[j];
+			if (!d)
+			{   // An instance specific initializer was not provided.
+				// Look to see if there's a default initializer from the
+				// struct definition
+				if (v.init)
+				{
+					d = v.init.toDt();
+				}
+				else if (v.offset >= offset)
+				{
+					uint k;
+					uint offset2 = v.offset + cast(uint)v.type.size();
+					// Make sure this field (v) does not overlap any explicitly
+					// initialized field.
+					for (k = j + 1; 1; k++)
+					{
+						if (k == dts.dim)		// didn't find any overlap
+						{
+							v.type.toDt(&d);
+							break;
+						}
+						VarDeclaration v2 = sd.fields[k];
+
+						if (v2.offset < offset2 && dts.data[k])
+							break;			// overlap
+					}
+				}
+			}
+			if (d)
+			{
+				if (v.offset < offset)
+					error("duplicate union initialization for %s", v.toChars());
+				else
+				{	
+					uint sz = dt_size(d);
+					uint vsz = cast(uint)v.type.size();
+					uint voffset = v.offset;
+					assert(sz <= vsz);
+
+					uint dim = 1;
+					for (Type vt = v.type.toBasetype(); vt.ty == Tsarray; vt = vt.nextOf().toBasetype())
+					{   
+						TypeSArray tsa = cast(TypeSArray)vt;
+						dim *= tsa.dim.toInteger();
+					}
+
+					for (size_t i = 0; i < dim; i++)
+					{
+						if (offset < voffset)
+							pdt = dtnzeros(pdt, voffset - offset);
+						if (!d)
+						{
+							if (v.init)
+								d = v.init.toDt();
+							else
+								v.type.toDt(&d);
+						}
+						pdt = dtcat(pdt, d);
+						d = null;
+						offset = voffset + sz;
+						voffset += vsz / dim;
+						if (sz == vsz)
+							break;
+					}
+				}
+			}
+		}
+		
+		if (offset < sd.structsize)
+			pdt = dtnzeros(pdt, sd.structsize - offset);
+
+		return pdt;
 	}
 
 version(DMDV2)
--- a/dmd/ThisExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/ThisExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -131,7 +131,8 @@
 
 	override void scanForNestedRef(Scope sc)
 	{
-		assert(false);
+		assert(var);
+		var.isVarDeclaration().checkNestedReference(sc, Loc(0));
 	}
 
 	override int inlineCost(InlineCostState* ics)
--- a/dmd/TypeFunction.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/TypeFunction.d	Fri Sep 03 20:46:58 2010 +0400
@@ -4,6 +4,7 @@
 import dmd.TypeNext;
 import dmd.TypeSArray;
 import dmd.TypeArray;
+import dmd.TemplateTupleParameter;
 import dmd.ArrayTypes;
 import dmd.LINK;
 import dmd.StructDeclaration;
@@ -12,6 +13,9 @@
 import dmd.STC;
 import dmd.MOD;
 import dmd.PROT;
+import dmd.TypeIdentifier;
+import dmd.TemplateParameter;
+import dmd.Tuple;
 import dmd.Type;
 import dmd.Loc;
 import dmd.Scope;
@@ -26,6 +30,7 @@
 import dmd.RET;
 import dmd.TY;
 import dmd.Util;
+import dmd.TemplateInstance : isTuple;
 
 import dmd.backend.TYPE;
 import dmd.backend.PARAM;
@@ -395,7 +400,100 @@
 	
     override MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes)
 	{
-		assert(false);
+		//printf("TypeFunction.deduceType()\n");
+		//printf("\tthis   = %d, ", ty); print();
+		//printf("\ttparam = %d, ", tparam.ty); tparam.print();
+
+		// Extra check that function characteristics must match
+		if (tparam && tparam.ty == Tfunction)
+		{
+			TypeFunction tp = cast(TypeFunction)tparam;
+			if (varargs != tp.varargs ||
+				linkage != tp.linkage)
+				return MATCHnomatch;
+
+			size_t nfargs = Argument.dim(this.parameters);
+			size_t nfparams = Argument.dim(tp.parameters);
+
+			/* See if tuple match
+			 */
+			if (nfparams > 0 && nfargs >= nfparams - 1)
+			{
+				/* See if 'A' of the template parameter matches 'A'
+				 * of the type of the last function parameter.
+				 */
+				Argument fparam = Argument.getNth(tp.parameters, nfparams - 1);
+				assert(fparam);
+				assert(fparam.type);
+				if (fparam.type.ty != Tident)
+					goto L1;
+				TypeIdentifier tid = cast(TypeIdentifier)fparam.type;
+				if (tid.idents.dim)
+					goto L1;
+
+				/* Look through parameters to find tuple matching tid.ident
+				 */
+				size_t tupi = 0;
+				for (; 1; tupi++)
+				{	
+					if (tupi == parameters.dim)
+						goto L1;
+					TemplateParameter t = parameters[tupi];
+					TemplateTupleParameter tup = t.isTemplateTupleParameter();
+					if (tup && tup.ident.equals(tid.ident))
+						break;
+				}
+
+				/* The types of the function arguments [nfparams - 1 .. nfargs]
+				 * now form the tuple argument.
+				 */
+				int tuple_dim = nfargs - (nfparams - 1);
+
+				/* See if existing tuple, and whether it matches or not
+				 */
+				Object o = dedtypes[tupi];
+				if (o)
+				{	
+					// Existing deduced argument must be a tuple, and must match
+					Tuple t = isTuple(o);
+					if (!t || t.objects.dim != tuple_dim)
+						return MATCHnomatch;
+					for (size_t i = 0; i < tuple_dim; i++)
+					{   
+						Argument arg = Argument.getNth(this.parameters, nfparams - 1 + i);
+						if (!arg.type.equals(t.objects[i]))
+							return MATCHnomatch;
+					}
+				}
+				else
+				{	// Create new tuple
+					Tuple t = new Tuple();
+					t.objects.setDim(tuple_dim);
+					for (size_t i = 0; i < tuple_dim; i++)
+					{   
+						Argument arg = Argument.getNth(this.parameters, nfparams - 1 + i);
+						t.objects[i] = arg.type;
+					}
+					dedtypes[tupi] = t;
+				}
+				nfparams--;	// don't consider the last parameter for type deduction
+				goto L2;
+			}
+
+			L1:
+			if (nfargs != nfparams)
+				return MATCHnomatch;
+			L2:
+			for (size_t i = 0; i < nfparams; i++)
+			{
+				Argument a = Argument.getNth(this.parameters, i);
+				Argument ap = Argument.getNth(tp.parameters, i);
+				if (a.storageClass != ap.storageClass ||
+					!a.type.deduceType(sc, ap.type, parameters, dedtypes))
+				return MATCHnomatch;
+			}
+		}
+		return Type.deduceType(sc, tparam, parameters, dedtypes);
 	}
 	
     override TypeInfoDeclaration getTypeInfoDeclaration()
--- a/dmd/UAddExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/UAddExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -7,6 +7,7 @@
 import dmd.Loc;
 import dmd.Scope;
 import dmd.TOK;
+import dmd.Id;
 
 class UAddExp : UnaExp
 {
@@ -35,6 +36,6 @@
 
 	override Identifier opId()
 	{
-		assert(false);
+		return Id.uadd;
 	}
 }
--- a/dmd/UnrolledLoopStatement.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/UnrolledLoopStatement.d	Fri Sep 03 20:46:58 2010 +0400
@@ -103,7 +103,18 @@
 
 	override int inlineCost(InlineCostState* ics)
 	{
-		assert(false);
+		int cost = 0;
+
+		foreach (Statement s; statements)
+		{	
+			if (s)
+			{
+				cost += s.inlineCost(ics);
+				if (cost >= COST_MAX)
+					break;
+			}
+		}
+		return cost;
 	}
 
 	override Expression doInline(InlineDoState ids)
@@ -113,7 +124,12 @@
 
 	override Statement inlineScan(InlineScanState* iss)
 	{
-		assert(false);
+		foreach (ref Statement s; statements)
+		{	
+			if (s)
+				s = s.inlineScan(iss);
+		}
+		return this;
 	}
 
 	override void toIR(IRState* irs)
--- a/dmd/Util.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/Util.d	Fri Sep 03 20:46:58 2010 +0400
@@ -75,7 +75,11 @@
 
 void warning(T...)(Loc loc, string format, T t)
 {
-	assert(false);
+	if (global.params.warnings && !global.gag)
+    {
+		write("warning - ");
+		error(loc, format, t);
+    }
 }
 
 void error(T...)(Loc loc, string format, T t)
--- a/dmd/WhileStatement.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/WhileStatement.d	Fri Sep 03 20:46:58 2010 +0400
@@ -48,7 +48,7 @@
 	
     override bool hasContinue()
 	{
-		assert(false);
+		return true;
 	}
 	
     override bool usesEH()
--- a/dmd/XorAssignExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/XorAssignExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -40,7 +40,7 @@
 	
     override Expression buildArrayLoop(Arguments fparams)
 	{
-		assert(false);
+		return AssignExp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
     override Identifier opId()    /* For operator overloading */
--- a/dmd/XorExp.d	Thu Sep 02 23:37:49 2010 +0100
+++ b/dmd/XorExp.d	Fri Sep 03 20:46:58 2010 +0400
@@ -83,12 +83,7 @@
 
 	override Expression buildArrayLoop(Arguments fparams)
 	{
-		/* Evaluate assign expressions left to right		
-		 */								
-		Expression ex1 = e1.buildArrayLoop(fparams);		
-		Expression ex2 = e2.buildArrayLoop(fparams);		
-		Expression e = new XorExp(Loc(0), ex1, ex2);			
-		return e;							
+		return Exp_buildArrayLoop!(typeof(this))(fparams);
 	}
 
 	override MATCH implicitConvTo(Type t)