changeset 129:010eb8f0e18d

further work on dmd test suite
author korDen
date Sun, 05 Sep 2010 15:32:22 +0400
parents e6e542f37b94
children 60bb0fe4563e
files dmd/CastExp.d dmd/ComplexExp.d dmd/CondExp.d dmd/DebugCondition.d dmd/DebugSymbol.d dmd/Declaration.d dmd/DotExp.d dmd/DotTypeExp.d dmd/Dsymbol.d dmd/IndexExp.d dmd/Module.d dmd/Param.d dmd/RealExp.d dmd/Scope.d dmd/StringExp.d dmd/StructDeclaration.d dmd/SymOffExp.d dmd/TypeAArray.d dmd/TypeFunction.d dmd/TypeInfoFunctionDeclaration.d dmd/Util.d dmd/VersionSymbol.d dmd/WithScopeSymbol.d dmd/WithStatement.d dmd/condition/util/findCondition.d dmd/expression/Util.d
diffstat 26 files changed, 517 insertions(+), 133 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/CastExp.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/CastExp.d	Sun Sep 05 15:32:22 2010 +0400
@@ -2,6 +2,7 @@
 
 import dmd.common;
 import dmd.Expression;
+import dmd.GlobalExpressions;
 import dmd.TY;
 import dmd.TypeStruct;
 import dmd.ErrorExp;
@@ -365,7 +366,22 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		Expression e;
+		Expression e1;
+
+version (LOG) {
+		printf("CastExp.interpret() %.*s\n", toChars());
+}
+		e1 = this.e1.interpret(istate);
+		if (e1 is EXP_CANT_INTERPRET)
+			goto Lcant;
+		return Cast(type, to, e1);
+
+	Lcant:
+version (LOG) {
+		printf("CastExp.interpret() %.*s CANT\n", toChars());
+}
+		return EXP_CANT_INTERPRET;
 	}
 
 	override bool checkSideEffect(int flag)
--- a/dmd/ComplexExp.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/ComplexExp.d	Sun Sep 05 15:32:22 2010 +0400
@@ -14,6 +14,7 @@
 import dmd.TY;
 import dmd.Port;
 import dmd.Complex;
+import dmd.expression.Util;
 
 import dmd.backend.dt_t;
 import dmd.backend.elem;
@@ -118,10 +119,15 @@
 
 	override void toMangleBuffer(OutBuffer buf)
 	{
-		assert(false);
+		buf.writeByte('c');
+		real r = toReal();
+		realToMangleBuffer(buf, r);
+		buf.writeByte('c');	// separate the two
+		r = toImaginary();
+		realToMangleBuffer(buf, r);
 	}
+	
 version (_DH) {
-
 	OutBuffer hexp;
 }
 
--- a/dmd/CondExp.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/CondExp.d	Sun Sep 05 15:32:22 2010 +0400
@@ -6,6 +6,7 @@
 import dmd.PtrExp;
 import dmd.MATCH;
 import dmd.Expression;
+import dmd.GlobalExpressions;
 import dmd.Scope;
 import dmd.InterState;
 import dmd.OutBuffer;
@@ -161,7 +162,20 @@
 	
     override Expression interpret(InterState istate)
 	{
-		assert(false);
+version (LOG) {
+		printf("CondExp.interpret() %.*s\n", toChars());
+}
+		Expression e = econd.interpret(istate);
+		if (e !is EXP_CANT_INTERPRET)
+		{
+			if (e.isBool(true))
+				e = e1.interpret(istate);
+			else if (e.isBool(false))
+				e = e2.interpret(istate);
+			else
+				e = EXP_CANT_INTERPRET;
+		}
+		return e;
 	}
 
     override void checkEscape()
--- a/dmd/DebugCondition.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/DebugCondition.d	Sun Sep 05 15:32:22 2010 +0400
@@ -52,9 +52,9 @@
 				else
 				{	
 					if (!mod.debugidsNot)
-						mod.debugidsNot = new Array();
+						mod.debugidsNot = new Vector!string();
 
-					mod.debugidsNot.push(cast(void*)new String(ident.toChars()));
+					mod.debugidsNot.push(ident.toChars());
 				}
 			}
 			else if (level <= global.params.debuglevel || level <= mod.debuglevel)
--- a/dmd/DebugSymbol.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/DebugSymbol.d	Sun Sep 05 15:32:22 2010 +0400
@@ -6,45 +6,91 @@
 import dmd.Loc;
 import dmd.Scope;
 import dmd.ScopeDsymbol;
+import dmd.Module;
 import dmd.HdrGenState;
+import dmd.Array;
 import dmd.OutBuffer;
 
+import dmd.condition.util.findCondition;
+
+/* DebugSymbol's happen for statements like:
+ *	debug = identifier;
+ *	debug = integer;
+ */
 class DebugSymbol : Dsymbol
 {
     uint level;
 
     this(Loc loc, Identifier ident)
 	{
-		assert(false);
+		super(ident);
+		this.loc = loc;
 	}
 
     this(Loc loc, uint level)
 	{
-		assert(false);
+		this.level = level;
+		this.loc = loc;
 	}
 
     override Dsymbol syntaxCopy(Dsymbol s)
 	{
-		assert(false);
+		assert(!s);
+		DebugSymbol ds = new DebugSymbol(loc, ident);
+		ds.level = level;
+		return ds;
 	}
 
-    override bool addMember(Scope sc, ScopeDsymbol s, bool memnum)
+    override bool addMember(Scope sc, ScopeDsymbol sd, bool memnum)
 	{
-		assert(false);
+		//printf("DebugSymbol.addMember('%s') %s\n", sd.toChars(), toChars());
+		Module m;
+
+		// Do not add the member to the symbol table,
+		// just make sure subsequent debug declarations work.
+		m = sd.isModule();
+		if (ident)
+		{
+			if (!m)
+				error("declaration must be at module level");
+			else
+			{
+				if (findCondition(m.debugidsNot, ident))
+					error("defined after use");
+				if (!m.debugids)
+					m.debugids = new Vector!string();
+				m.debugids.push(ident.toChars());	///
+			}
+		}
+		else
+		{
+			if (!m)
+				error("level declaration must be at module level");
+			else
+				m.debuglevel = level;
+		}
+		
+		return false;
 	}
 	
     override void semantic(Scope sc)
 	{
-		assert(false);
+		//printf("DebugSymbol.semantic() %s\n", toChars());
 	}
 	
     override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
-		assert(false);
+		buf.writestring("debug = ");
+		if (ident)
+			buf.writestring(ident.toChars());
+		else
+			buf.printf("%u", level);
+		buf.writestring(";");
+		buf.writenl();
 	}
 	
     override string kind()
 	{
-		assert(false);
+		return "debug";
 	}
 }
--- a/dmd/Declaration.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/Declaration.d	Sun Sep 05 15:32:22 2010 +0400
@@ -252,7 +252,6 @@
 }
 
 			case LINK.LINKdefault:
-				assert(false);
 				error("forward declaration");
 				return ident.toChars();
 
--- a/dmd/DotExp.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/DotExp.d	Sun Sep 05 15:32:22 2010 +0400
@@ -4,6 +4,9 @@
 import dmd.Expression;
 import dmd.Loc;
 import dmd.Scope;
+import dmd.ScopeExp;
+import dmd.TemplateDeclaration;
+import dmd.DotTemplateExp;
 import dmd.BinExp;
 import dmd.TOK;
 
@@ -11,13 +14,31 @@
 {
 	this(Loc loc, Expression e1, Expression e2)
 	{
-		assert(false);
-		super(loc, TOK.init, 0, e1, e2);
+		super(loc, TOKdotexp, DotExp.sizeof, e1, e2);
 	}
 
 	override Expression semantic(Scope sc)
 	{
-		assert(false);
+version (LOGSEMANTIC) {
+		printf("DotExp.semantic('%s')\n", toChars());
+		if (type) printf("\ttype = %s\n", type.toChars());
+}
+		e1 = e1.semantic(sc);
+		e2 = e2.semantic(sc);
+		if (e2.op == TOKimport)
+		{
+			ScopeExp se = cast(ScopeExp)e2;
+			TemplateDeclaration td = se.sds.isTemplateDeclaration();
+			if (td)
+			{   
+				Expression e = new DotTemplateExp(loc, e1, td);
+				e = e.semantic(sc);
+				return e;
+			}
+		}
+		if (!type)
+			type = e2.type;
+		return this;
 	}
 }
 
--- a/dmd/DotTypeExp.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/DotTypeExp.d	Sun Sep 05 15:32:22 2010 +0400
@@ -14,6 +14,8 @@
 import dmd.PREC;
 import dmd.expression.Util;
 
+import dmd.backend.Util;
+
 class DotTypeExp : UnaExp
 {
 	Dsymbol sym;
@@ -43,7 +45,13 @@
 
 	override elem* toElem(IRState* irs)
 	{
-		assert(false);
+		// Just a pass-thru to e1
+		elem *e;
+
+		//printf("DotTypeExp.toElem() %s\n", toChars());
+		e = e1.toElem(irs);
+		el_setLoc(e,loc);
+		return e;
 	}
 }
 
--- a/dmd/Dsymbol.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/Dsymbol.d	Sun Sep 05 15:32:22 2010 +0400
@@ -579,7 +579,7 @@
 	
     AggregateDeclaration isThis()	// is a 'this' required to access the member
 	{
-		assert(false);
+		return null;
 	}
 	
     ClassDeclaration isClassMember()	// are we a member of a class?
--- a/dmd/IndexExp.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/IndexExp.d	Sun Sep 05 15:32:22 2010 +0400
@@ -13,6 +13,7 @@
 import dmd.ScopeDsymbol;
 import dmd.TY;
 import dmd.ArrayScopeSymbol;
+import dmd.PREC;
 import dmd.TypeNext;
 import dmd.TypeSArray;
 import dmd.TypeAArray;
@@ -35,6 +36,7 @@
 import dmd.expression.util.arrayTypeCompatible;
 import dmd.expression.Util;
 import dmd.expression.Index;
+import dmd.expression.ArrayLength;
 
 import dmd.backend.Symbol;
 import dmd.backend.Util;
@@ -188,7 +190,7 @@
 
 	override int isLvalue()
 	{
-		assert(false);
+		return true;
 	}
 
 	override Expression toLvalue(Scope sc, Expression e)
@@ -213,7 +215,10 @@
 
 	override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
-		assert(false);
+		expToCBuffer(buf, hgs, e1, PREC.PREC_primary);
+		buf.writeByte('[');
+		expToCBuffer(buf, hgs, e2, PREC.PREC_assign);
+		buf.writeByte(']');
 	}
 
 	override Expression optimize(int result)
@@ -246,7 +251,35 @@
 
 	override Expression interpret(InterState istate)
 	{
-		assert(false);
+		Expression e;
+		Expression e1;
+		Expression e2;
+
+	version (LOG) {
+		printf("IndexExp.interpret() %s\n", toChars());
+	}
+		e1 = this.e1.interpret(istate);
+		if (e1 is EXP_CANT_INTERPRET)
+			goto Lcant;
+
+		if (e1.op == TOKstring || e1.op == TOKarrayliteral)
+		{
+			/* Set the $ variable
+			 */
+			e = ArrayLength(Type.tsize_t, e1);
+			if (e is EXP_CANT_INTERPRET)
+				goto Lcant;
+			if (lengthVar)
+				lengthVar.value = e;
+		}
+
+		e2 = this.e2.interpret(istate);
+		if (e2 is EXP_CANT_INTERPRET)
+			goto Lcant;
+		return Index(type, e1, e2);
+
+	Lcant:
+		return EXP_CANT_INTERPRET;
 	}
 
 	override Expression doInline(InlineDoState ids)
--- a/dmd/Module.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/Module.d	Sun Sep 05 15:32:22 2010 +0400
@@ -223,8 +223,8 @@
     ModuleInfoDeclaration vmoduleinfo;
 
     uint debuglevel;	// debug level
-    Array debugids;		// debug identifiers
-    Array debugidsNot;		// forward referenced debug identifiers
+    Vector!string debugids;		// debug identifiers
+    Vector!string debugidsNot;		// forward referenced debug identifiers
 
     uint versionlevel;	// version level
     Array versionids;		// version identifiers
@@ -297,7 +297,7 @@
 		symfile = new File(symfilename);
 	}
 
-    static Module load(Loc loc, Identifiers packages, Identifier ident)
+    static Module load(Loc loc, Vector!Identifier packages, Identifier ident)
 	{
 		Module m;
 		string filename;
@@ -311,7 +311,8 @@
 		filename = ident.toChars();
 		if (packages && packages.dim)
 		{
-			scope buf = new OutBuffer();
+			scope OutBuffer buf = new OutBuffer();
+			int i;
 
 			foreach (pid; packages)
 			{   
--- a/dmd/Param.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/Param.d	Sun Sep 05 15:32:22 2010 +0400
@@ -65,7 +65,7 @@
 	string xfilename;	// write JSON file to xfilename
 
     uint debuglevel;	// debug level
-    Array debugids;		// debug identifiers
+    Vector!string debugids;		// debug identifiers
 
     uint versionlevel;	// version level
     Array versionids;		// version identifiers
--- a/dmd/RealExp.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/RealExp.d	Sun Sep 05 15:32:22 2010 +0400
@@ -1,6 +1,7 @@
 module dmd.RealExp;
 
 import dmd.common;
+import dmd.Complex;
 import dmd.Expression;
 import dmd.backend.elem;
 import dmd.InterState;
@@ -15,13 +16,13 @@
 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 dmd.Complex;
-
 import std.stdio;
 
 class RealExp : Expression
@@ -38,7 +39,20 @@
 
 	override bool equals(Object o)
 	{
-		assert(false);
+		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)
@@ -120,7 +134,8 @@
 
 	override void toMangleBuffer(OutBuffer buf)
 	{
-		assert(false);
+		buf.writeByte('e');
+		realToMangleBuffer(buf, value);
 	}
 
 	override elem* toElem(IRState* irs)
--- a/dmd/Scope.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/Scope.d	Sun Sep 05 15:32:22 2010 +0400
@@ -171,13 +171,7 @@
 	
 	Scope clone()
 	{
-		// similar code is used in Type.clone()
-		// TODO: move to Util or something...
-		size_t size = __traits(classInstanceSize, typeof(this));
-		void* mem = GC.malloc(size);
-		memcpy(mem, cast(void*)this, size);
-		
-		return cast(typeof(this))mem;
+		return cloneThis(this);
 	}
 
     Scope push()
--- a/dmd/StringExp.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/StringExp.d	Sun Sep 05 15:32:22 2010 +0400
@@ -108,7 +108,7 @@
 				case 'd':
 					for (u = 0; u < len;)
 					{
-						p = utf_decodeChar(cast(string)string_[0..len], &u, &c);
+						p = utf_decodeChar((cast(char*)string_)[0..len], &u, &c);
 						if (p !is null)
 						{	
 							error("%s", p);
@@ -132,7 +132,7 @@
 				case 'w':
 					for (u = 0; u < len;)
 					{
-						p = utf_decodeChar(cast(string)string_[0..len], &u, &c);
+						p = utf_decodeChar((cast(char*)string_)[0..len], &u, &c);
 						if (p !is null)
 						{	
 							error("%s", p);
@@ -191,7 +191,7 @@
 		case 1:
 			for (size_t u = 0; u < len;)
 			{
-				p = utf_decodeChar(cast(string)string_[0..len], &u, &c);
+				p = utf_decodeChar((cast(char*)string_)[0..len], &u, &c);
 				if (p)
 				{   
 					error("%s", p);
@@ -205,7 +205,7 @@
 		case 2:
 			for (size_t u = 0; u < len;)
 			{
-				p = utf_decodeWchar(cast(wstring)string_[0..len], &u, &c);
+				p = utf_decodeWchar((cast(wchar*)string_)[0..len], &u, &c);
 				if (p)
 				{   error("%s", p);
 					break;
@@ -446,7 +446,7 @@
 					for (size_t u = 0; u < len;)
 					{	
 						dchar c;
-						string p = utf_decodeChar(cast(string)se.string_[0..len], &u, &c);
+						string p = utf_decodeChar((cast(char*)se.string_)[0..len], &u, &c);
 						if (p !is null)
 							error("%s", p);
 						else
@@ -460,7 +460,7 @@
 					for (size_t u = 0; u < len;)
 					{	
 						dchar c;
-						string p = utf_decodeChar(cast(string)se.string_[0..len], &u, &c);
+						string p = utf_decodeChar((cast(char*)se.string_)[0..len], &u, &c);
 						if (p !is null)
 							error("%s", p);
 						buffer.write4(c);
@@ -473,7 +473,7 @@
 					for (size_t u = 0; u < len;)
 					{	
 						dchar c;
-						string p = utf_decodeWchar(cast(wstring)se.string_[0..len], &u, &c);
+						string p = utf_decodeWchar((cast(wchar*)se.string_)[0..len], &u, &c);
 						if (p)
 							error("%s", p);
 						else
@@ -487,7 +487,7 @@
 					for (size_t u = 0; u < len;)
 					{	
 						dchar c;
-						string p = utf_decodeWchar(cast(wstring)se.string_[0..len], &u, &c);
+						string p = utf_decodeWchar((cast(wchar*)se.string_)[0..len], &u, &c);
 						if (p)
 							error("%s", p);
 						buffer.write4(c);
@@ -733,7 +733,7 @@
 		    m = 'w';
 		    for (u = 0; u < len; )
 		    {
-			p = utf_decodeWchar(cast(wstring)string_[0..len], &u, &c);
+			p = utf_decodeWchar((cast(wchar*)string_)[0..len], &u, &c);
 			if (p)
 			    error("%s", p);
 			else
--- a/dmd/StructDeclaration.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/StructDeclaration.d	Sun Sep 05 15:32:22 2010 +0400
@@ -61,6 +61,8 @@
 import dmd.backend.FL;
 import dmd.backend.glue;
 
+import std.stdio;
+
 class StructDeclaration : AggregateDeclaration
 {
     bool zeroInit;		// true if initialize with 0 fill
@@ -203,23 +205,33 @@
 		int members_dim = members.dim;
 		foreach(Dsymbol s; members)
 		{
-		s.semantic(sc2);
-		if (isUnionDeclaration())
-			sc2.offset = 0;
+			s.semantic(sc2);
+			if (isUnionDeclaration())
+				sc2.offset = 0;
 static if (false) {
-		if (sizeok == 2)
-		{   //printf("forward reference\n");
-			break;
-		}
+			if (sizeok == 2)
+			{   //printf("forward reference\n");
+				break;
+			}
 }
-		Type t;
-		if (s.isDeclaration() &&
-			(t = s.isDeclaration().type) !is null &&
-			t.toBasetype().ty == TY.Tstruct)
-		{   StructDeclaration sd = cast(StructDeclaration)t.toDsymbol(sc);
-			if (sd.isnested)
-			error("inner struct %s cannot be a field", sd.toChars());
-		}
+			if (auto d = s.isDeclaration())
+			{   
+				if (auto t = d.type) {
+					if (t.toBasetype().ty == TY.Tstruct) {
+						auto ad = t.toDsymbol(sc).isThis();
+						/*
+						StructDeclaration sd = cast(StructDeclaration)foo;
+						if (foo && !sd) {
+							writeln(t.classin);
+							writeln(foo.classinfo.name);
+							assert(false);
+						}
+						*/
+						if (ad && ad.isnested)
+							error("inner struct %s cannot be a field", ad.toChars());
+					}
+				}
+			}
 		}
 
 		/* The TypeInfo_Struct is expecting an opEquals and opCmp with
@@ -231,22 +243,22 @@
 
 		TypeFunction tfeqptr;
 		{
-		auto arguments = new Arguments;
-		auto arg = new Argument(STC.STCin, handle, Id.p, null);
+			Arguments arguments = new Arguments;
+			Argument arg = new Argument(STC.STCin, handle, Id.p, null);
 
-		arguments.push(arg);
-		tfeqptr = new TypeFunction(arguments, Type.tint32, 0, LINK.LINKd);
-		tfeqptr = cast(TypeFunction)tfeqptr.semantic(Loc(0), sc);
+			arguments.push(arg);
+			tfeqptr = new TypeFunction(arguments, Type.tint32, 0, LINK.LINKd);
+			tfeqptr = cast(TypeFunction)tfeqptr.semantic(Loc(0), sc);
 		}
 
 		TypeFunction tfeq;
 		{
-		auto arguments = new Arguments;
-		auto arg = new Argument(STC.STCin, type, null, null);
+			Arguments arguments = new Arguments;
+			Argument arg = new Argument(STC.STCin, type, null, null);
 
-		arguments.push(arg);
-		tfeq = new TypeFunction(arguments, Type.tint32, 0, LINK.LINKd);
-		tfeq = cast(TypeFunction)tfeq.semantic(Loc(0), sc);
+			arguments.push(arg);
+			tfeq = new TypeFunction(arguments, Type.tint32, 0, LINK.LINKd);
+			tfeq = cast(TypeFunction)tfeq.semantic(Loc(0), sc);
 		}
 
 		Identifier id = Id.eq;
@@ -437,8 +449,8 @@
 
 		FuncDeclaration fop = null;
 
-		auto param = new Argument(STC.STCnodtor, type, Id.p, null);
-		auto fparams = new Arguments;
+		Argument param = new Argument(STC.STCnodtor, type, Id.p, null);
+		Arguments fparams = new Arguments;
 		fparams.push(param);
 		Type ftype = new TypeFunction(fparams, handle, false, LINK.LINKd);
 version (STRUCTTHISREF) {
@@ -650,41 +662,41 @@
 		 */
 		if (postblit)
 		{
-		//printf("generating cpctor\n");
+			//printf("generating cpctor\n");
 
-		auto param = new Argument(STC.STCref, type, Id.p, null);
-		auto fparams = new Arguments;
-		fparams.push(param);
-		Type ftype = new TypeFunction(fparams, Type.tvoid, false, LINK.LINKd);
+			Argument param = new Argument(STC.STCref, type, Id.p, null);
+			Arguments fparams = new Arguments;
+			fparams.push(param);
+			Type ftype = new TypeFunction(fparams, Type.tvoid, false, LINK.LINKd);
 
-		fcp = new FuncDeclaration(Loc(0), Loc(0), Id.cpctor, STC.STCundefined, ftype);
+			fcp = new FuncDeclaration(Loc(0), Loc(0), Id.cpctor, STC.STCundefined, ftype);
 
-		// Build *this = p;
-		Expression e = new ThisExp(Loc(0));
+			// Build *this = p;
+			Expression e = new ThisExp(Loc(0));
 version (STRUCTTHISREF) {
 } else {
-		e = new PtrExp(Loc(0), e);
+			e = new PtrExp(Loc(0), e);
 }
-		auto ea = new AssignExp(Loc(0), e, new IdentifierExp(Loc(0), Id.p));
-		ea.op = TOK.TOKblit;
-		Statement s = new ExpStatement(Loc(0), ea);
+			AssignExp ea = new AssignExp(Loc(0), e, new IdentifierExp(Loc(0), Id.p));
+			ea.op = TOK.TOKblit;
+			Statement s = new ExpStatement(Loc(0), ea);
 
-		// Build postBlit();
-		e = new VarExp(Loc(0), postblit, 0);
-		e = new CallExp(Loc(0), e);
+			// Build postBlit();
+			e = new VarExp(Loc(0), postblit, 0);
+			e = new CallExp(Loc(0), e);
 
-		s = new CompoundStatement(Loc(0), s, new ExpStatement(Loc(0), e));
-		fcp.fbody = s;
+			s = new CompoundStatement(Loc(0), s, new ExpStatement(Loc(0), e));
+			fcp.fbody = s;
 
-		members.push(fcp);
+			members.push(fcp);
 
-		sc = sc.push();
-		sc.stc = STC.STCundefined;
-		sc.linkage = LINK.LINKd;
+			sc = sc.push();
+			sc.stc = STC.STCundefined;
+			sc.linkage = LINK.LINKd;
 
-		fcp.semantic(sc);
+			fcp.semantic(sc);
 
-		sc.pop();
+			sc.pop();
 		}
 
 		return fcp;
--- a/dmd/SymOffExp.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/SymOffExp.d	Sun Sep 05 15:32:22 2010 +0400
@@ -75,7 +75,7 @@
 
 	override bool isBool(bool result)
 	{
-		assert(false);
+		return result;
 	}
 
 	override Expression doInline(InlineDoState ids)
--- a/dmd/TypeAArray.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/TypeAArray.d	Sun Sep 05 15:32:22 2010 +0400
@@ -357,12 +357,12 @@
 	
     override bool isZeroInit(Loc loc)
 	{
-		assert(false);
+		return true;
 	}
 	
     override bool checkBoolean()
 	{
-		assert(false);
+		return true;
 	}
 	
     override TypeInfoDeclaration getTypeInfoDeclaration()
--- a/dmd/TypeFunction.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/TypeFunction.d	Sun Sep 05 15:32:22 2010 +0400
@@ -15,6 +15,7 @@
 import dmd.PROT;
 import dmd.TypeIdentifier;
 import dmd.TemplateParameter;
+import dmd.TypeInfoFunctionDeclaration;
 import dmd.Tuple;
 import dmd.Type;
 import dmd.Loc;
@@ -42,6 +43,8 @@
 import core.stdc.stdlib;
 import core.stdc.string;
 
+import std.stdio;
+
 class TypeFunction : TypeNext
 {
     // .next is the return type
@@ -103,11 +106,10 @@
 		if (parameters)
 		{
 			t.parameters = parameters.copy();
-			for (size_t i = 0; i < parameters.dim; i++)
+			foreach (arg; parameters)
 			{   
-				Argument arg = cast(Argument)parameters.data[i];
 				Argument cpy = arg.clone();
-				t.parameters.data[i] = cast(void*)cpy;
+				t.parameters[i] = cpy;
 			}
 		}
 
@@ -116,7 +118,7 @@
 
 	TypeFunction clone()
 	{
-		assert(this.classinfo == TypeFunction.classinfo);
+		assert(this.classinfo is TypeFunction.classinfo);
 		return cloneTo(new TypeFunction(null, next, varargs, linkage));
 	}
 }
@@ -135,7 +137,7 @@
 		 * as semantic() will get called again on this.
 		 */
 
-		TypeFunction tf = cast(TypeFunction)clone();
+		TypeFunction tf = cloneThis(this);
 
 		if (sc.stc & STC.STCpure)
 			tf.ispure = true;
@@ -151,20 +153,23 @@
 version(SARRAYVALUE) {} else
 {
 			if (tf.next.toBasetype().ty == TY.Tsarray)
-			{   error(loc, "functions cannot return static array %s", tf.next.toChars());
+			{   
+				error(loc, "functions cannot return static array %s", tf.next.toChars());
 				tf.next = Type.terror;
 			}
 }
 			if (tf.next.toBasetype().ty == TY.Tfunction)
-			{   error(loc, "functions cannot return a function");
+			{   
+				error(loc, "functions cannot return a function");
 				tf.next = Type.terror;
 			}
 			if (tf.next.toBasetype().ty == TY.Ttuple)
-			{   error(loc, "functions cannot return a tuple");
+			{   
+				error(loc, "functions cannot return a tuple");
 				tf.next = Type.terror;
 			}
 			if (tf.next.isauto() && !(sc.flags & SCOPE.SCOPEctor))
-			error(loc, "functions cannot return scope %s", tf.next.toChars());
+				error(loc, "functions cannot return scope %s", tf.next.toChars());
 		}
 
 		if (tf.parameters)
@@ -498,7 +503,7 @@
 	
     override TypeInfoDeclaration getTypeInfoDeclaration()
 	{
-		assert(false);
+		return new TypeInfoFunctionDeclaration(this);
 	}
 	
     override Type reliesOnTident()
--- a/dmd/TypeInfoFunctionDeclaration.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/TypeInfoFunctionDeclaration.d	Sun Sep 05 15:32:22 2010 +0400
@@ -3,7 +3,12 @@
 import dmd.common;
 import dmd.Type;
 import dmd.TypeInfoDeclaration;
+import dmd.TypeFunction;
+import dmd.TY;
+
 import dmd.backend.dt_t;
+import dmd.backend.Util;
+import dmd.backend.TYM;
 
 class TypeInfoFunctionDeclaration : TypeInfoDeclaration
 {
@@ -15,7 +20,16 @@
 
 	override void toDt(dt_t** pdt)
 	{
-		assert(false);
+		//printf("TypeInfoFunctionDeclaration.toDt()\n");
+		dtxoff(pdt, Type.typeinfofunction.toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Function
+		dtdword(pdt, 0);			    // monitor
+
+		assert(tinfo.ty == Tfunction);
+
+		TypeFunction tc = cast(TypeFunction)tinfo;
+
+		tc.next.getTypeInfo(null);
+		dtxoff(pdt, tc.next.vtinfo.toSymbol(), 0, TYnptr); // TypeInfo for function return value
 	}
 }
 
--- a/dmd/Util.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/Util.d	Sun Sep 05 15:32:22 2010 +0400
@@ -14,6 +14,9 @@
 import std.process : getenv;
 import std.c.string;
 import std.stdio : writef, writefln, write;
+
+import core.memory;
+
 version (Windows)
 {
     import std.c.process : spawnl, spawnlp;
@@ -99,6 +102,17 @@
     global.errors++;
 }
 
+T cloneThis(T)(T ptr)
+{
+	// similar code is used in Type.clone()
+	// TODO: move to Util or something...
+	size_t size = __traits(classInstanceSize, T);
+	void* mem = GC.malloc(size);
+	memcpy(mem, cast(void*)ptr, size);
+	
+	return cast(T)mem;
+}
+
 char* strupr(char* s)
 {
     char* t = s;
--- a/dmd/VersionSymbol.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/VersionSymbol.d	Sun Sep 05 15:32:22 2010 +0400
@@ -13,14 +13,14 @@
 import dmd.String;
 import dmd.OutBuffer;
 
+/* VersionSymbol's happen for statements like:
+ *	version = identifier;
+ *	version = integer;
+ */
 class VersionSymbol : Dsymbol
 {
     uint level;
 
-	/* VersionSymbol's happen for statements like:
-	 *	version = identifier;
-	 *	version = integer;
-	 */
     this(Loc loc, Identifier ident)
 	{
 		super(ident);
@@ -37,7 +37,10 @@
 	
     override Dsymbol syntaxCopy(Dsymbol s)
 	{
-		assert(false);
+		assert(!s);
+		VersionSymbol ds = new VersionSymbol(loc, ident);
+		ds.level = level;
+		return ds;
 	}
 	
     override bool addMember(Scope sc, ScopeDsymbol s, bool memnum)
@@ -78,11 +81,17 @@
 	
     override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
 	{
-		assert(false);
+		buf.writestring("version = ");
+		if (ident)
+			buf.writestring(ident.toChars());
+		else
+			buf.printf("%u", level);
+		buf.writestring(";");
+		buf.writenl();
 	}
 	
     override string kind()
 	{
-		assert(false);
+		return "version";
 	}
 }
--- a/dmd/WithScopeSymbol.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/WithScopeSymbol.d	Sun Sep 05 15:32:22 2010 +0400
@@ -13,12 +13,13 @@
 
     this(WithStatement withstate)
 	{
-		assert(false);
+		this.withstate = withstate;
 	}
 	
     override Dsymbol search(Loc loc, Identifier ident, int flags)
 	{
-		assert(false);
+		// Acts as proxy to the with class declaration
+		return withstate.exp.type.toDsymbol(null).search(loc, ident, 0);
 	}
 
     override WithScopeSymbol isWithScopeSymbol() { return this; }
--- a/dmd/WithStatement.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/WithStatement.d	Sun Sep 05 15:32:22 2010 +0400
@@ -6,12 +6,29 @@
 import dmd.VarDeclaration;
 import dmd.Loc;
 import dmd.OutBuffer;
+import dmd.ScopeDsymbol;
+import dmd.TypeExp;
+import dmd.TOK;
+import dmd.Initializer;
+import dmd.ExpInitializer;
+import dmd.Id;
+import dmd.ScopeExp;
+import dmd.WithScopeSymbol;
+import dmd.TY;
+import dmd.Type;
 import dmd.HdrGenState;
 import dmd.InlineScanState;
 import dmd.IRState;
 import dmd.Scope;
 import dmd.BE;
 
+import dmd.backend.Symbol;
+import dmd.backend.block;
+import dmd.backend.Blockx;
+import dmd.backend.elem;
+import dmd.backend.Util;
+import dmd.backend.OPER;
+
 class WithStatement : Statement
 {
     Expression exp;
@@ -28,12 +45,74 @@
 	
     override Statement syntaxCopy()
 	{
-		assert(false);
+		WithStatement s = new WithStatement(loc, exp.syntaxCopy(), body_ ? body_.syntaxCopy() : null);
+		return s;
 	}
 	
     override Statement semantic(Scope sc)
 	{
-		assert(false);
+		ScopeDsymbol sym;
+		Initializer init;
+
+		//printf("WithStatement.semantic()\n");
+		exp = exp.semantic(sc);
+		exp = resolveProperties(sc, exp);
+		if (exp.op == TOKimport)
+		{	
+			ScopeExp es = cast(ScopeExp)exp;
+
+			sym = es.sds;
+		}
+		else if (exp.op == TOKtype)
+		{	
+			TypeExp es = cast(TypeExp)exp;
+
+			sym = es.type.toDsymbol(sc).isScopeDsymbol();
+			if (!sym)
+			{   
+				error("%s has no members", es.toChars());
+				body_ = body_.semantic(sc);
+				return this;
+			}
+		}
+		else
+		{	
+			Type t = exp.type;
+
+			assert(t);
+			t = t.toBasetype();
+			if (t.isClassHandle())
+			{
+				init = new ExpInitializer(loc, exp);
+				wthis = new VarDeclaration(loc, exp.type, Id.withSym, init);
+				wthis.semantic(sc);
+
+				sym = new WithScopeSymbol(this);
+				sym.parent = sc.scopesym;
+			}
+			else if (t.ty == Tstruct)
+			{
+				Expression e = exp.addressOf(sc);
+				init = new ExpInitializer(loc, e);
+				wthis = new VarDeclaration(loc, e.type, Id.withSym, init);
+				wthis.semantic(sc);
+				sym = new WithScopeSymbol(this);
+				sym.parent = sc.scopesym;
+			}
+			else
+			{   
+				error("with expressions must be class objects, not '%s'", exp.type.toChars());
+				return null;
+			}
+		}
+		sc = sc.push(sym);
+
+		if (body_)
+			body_ = body_.semantic(sc);
+
+		sc.pop();
+
+		return this;
 	}
 	
     override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
@@ -48,7 +127,14 @@
 	
     override BE blockExit()
 	{
-		assert(false);
+		BE result = BEnone;
+		if (exp.canThrow())
+			result = BEthrow;
+		if (body_)
+			result |= body_.blockExit();
+		else
+			result |= BEfallthru;
+		return result;
 	}
 
     override Statement inlineScan(InlineScanState* iss)
@@ -58,6 +144,34 @@
 
     override void toIR(IRState* irs)
 	{
-		assert(false);
+		Symbol* sp;
+		elem* e;
+		elem* ei;
+		ExpInitializer ie;
+		Blockx* blx = irs.blx;
+
+		//printf("WithStatement.toIR()\n");
+		if (exp.op == TOKimport || exp.op == TOKtype)
+		{
+		}
+		else
+		{
+			// Declare with handle
+			sp = wthis.toSymbol();
+			symbol_add(sp);
+
+			// Perform initialization of with handle
+			ie = wthis.init.isExpInitializer();
+			assert(ie);
+			ei = ie.exp.toElem(irs);
+			e = el_var(sp);
+			e = el_bin(OPeq,e.Ety, e, ei);
+			elem_setLoc(e, loc);
+			incUsage(irs, loc);
+			block_appendexp(blx.curblock,e);
+		}
+		// Execute with block
+		if (body_)
+			body_.toIR(irs);
 	}
 }
--- a/dmd/condition/util/findCondition.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/condition/util/findCondition.d	Sun Sep 05 15:32:22 2010 +0400
@@ -5,15 +5,15 @@
 import dmd.Array;
 import dmd.Identifier;
 
-bool findCondition(Array ids, Identifier ident)
+bool findCondition(Vector!string ids, Identifier ident)
 {
     if (ids)
     {
 		for (int i = 0; i < ids.dim; i++)
 		{
-			String id = cast(String)ids.data[i];
+			string id = ids[i];
 
-			if (id.str == ident.toChars()) {
+			if (id == ident.toChars()) {
 				return true;
 			}
 		}
--- a/dmd/expression/Util.d	Sat Sep 04 01:33:05 2010 +0100
+++ b/dmd/expression/Util.d	Sun Sep 05 15:32:22 2010 +0400
@@ -67,6 +67,8 @@
 
 import std.stdio : writef;
 
+import core.stdc.math;
+import core.stdc.string;
 
 /***********************************
  * Utility to build a function call out of this reference and argument.
@@ -952,11 +954,11 @@
 
 	/* Create the TypeTuple corresponding to the types of args[]
 	 */
-	auto args = new Arguments;
+	Arguments args = new Arguments;
 	args.setDim(dim);
 	for (size_t i = 0; i < dim; i++)
 	{	
-		auto arg = new Argument(STCin, exps[i].type, null, null);
+		Argument arg = new Argument(STCin, exps[i].type, null, null);
 		args[i] = arg;
 	}
 	TypeTuple tup = new TypeTuple(args);
@@ -1284,14 +1286,14 @@
 		if (u == arguments.dim)
 			return;
 
-		auto arg = arguments[u];
+		Argument arg = arguments[u];
 		if (!arg.type)
 			break;
     }
 
     AggregateDeclaration ad;
 
-    auto arg = arguments[0];
+    Argument arg = arguments[0];
     Type taggr = aggr.type;
     if (!taggr)
 		return;
@@ -1465,7 +1467,7 @@
 
     for (size_t u = 0; u < nparams; u++)
     {
-		auto arg = arguments[u];
+		Argument arg = arguments[u];
 		Argument param = Argument.getNth(tf.parameters, u);
 		if (arg.type)
 		{   
@@ -1558,4 +1560,64 @@
 			}
 		}
     }
+}
+
+void realToMangleBuffer(OutBuffer buf, real value)
+{
+    /* Rely on %A to get portable mangling.
+     * Must munge result to get only identifier characters.
+     *
+     * Possible values from %A	=> mangled result
+     * NAN			=> NAN
+     * -INF			=> NINF
+     * INF			=> INF
+     * -0X1.1BC18BA997B95P+79	=> N11BC18BA997B95P79
+     * 0X1.9P+2			=> 19P2
+     */
+
+    if (isnan(value))
+		buf.writestring("NAN");	// no -NAN bugs
+    else
+    {
+		char buffer[32];
+		int n = sprintf(buffer.ptr, "%LA", value);
+		assert(n > 0 && n < buffer.sizeof);
+		for (int i = 0; i < n; i++)
+		{   char c = buffer[i];
+
+			switch (c)
+			{
+			case '-':
+				buf.writeByte('N');
+				break;
+
+			case '+':
+			case 'X':
+			case '.':
+				break;
+
+			case '0':
+				if (i < 2)
+				break;		// skip leading 0X
+			default:
+				buf.writeByte(c);
+				break;
+			}
+		}
+    }
+}
+
+/********************************
+ * Test to see if two reals are the same.
+ * Regard NaN's as equivalent.
+ * Regard +0 and -0 as different.
+ */
+
+int RealEquals(real x1, real x2)
+{
+    return (isnan(x1) && isnan(x2)) || 
+		/* In some cases, the REALPAD bytes get garbage in them,
+		 * so be sure and ignore them.
+		 */
+		memcmp(&x1, &x2, REALSIZE - REALPAD) == 0;
 }
\ No newline at end of file