diff dmd/WithStatement.d @ 129:010eb8f0e18d

further work on dmd test suite
author korDen
date Sun, 05 Sep 2010 15:32:22 +0400
parents e28b18c23469
children e3afd1303184
line wrap: on
line diff
--- 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);
 	}
 }