changeset 37:38a17310d587

TypeSlice::resolve() implemented
author korDen
date Sat, 21 Aug 2010 07:04:01 +0400
parents 3012e829306f
children 4caad35a6ceb
files dmd/TypeSlice.d
diffstat 1 files changed, 66 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/TypeSlice.d	Sat Aug 21 06:55:28 2010 +0400
+++ b/dmd/TypeSlice.d	Sat Aug 21 07:04:01 2010 +0400
@@ -14,6 +14,10 @@
 import dmd.WANT;
 import dmd.ArrayTypes;
 import dmd.Argument;
+import dmd.SliceExp;
+import dmd.TupleDeclaration;
+import dmd.ScopeDsymbol;
+import dmd.ArrayScopeSymbol;
 
 import dmd.type.Util;
 
@@ -87,7 +91,68 @@
 	
     void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps)
 	{
-		assert(false);
+		next.resolve(loc, sc, pe, pt, ps);
+		if (*pe)
+		{	// It's really a slice expression
+			Expression e;
+			e = new SliceExp(loc, *pe, lwr, upr);
+			*pe = e;
+		}
+		else if (*ps)
+		{	
+			Dsymbol s = *ps;
+			TupleDeclaration td = s.isTupleDeclaration();
+			if (td)
+			{
+				/* It's a slice of a TupleDeclaration
+				 */
+				ScopeDsymbol sym = new ArrayScopeSymbol(sc, td);
+				sym.parent = sc.scopesym;
+				sc = sc.push(sym);
+
+				lwr = lwr.semantic(sc);
+				lwr = lwr.optimize(WANTvalue);
+				ulong i1 = lwr.toUInteger();
+
+				upr = upr.semantic(sc);
+				upr = upr.optimize(WANTvalue);
+				ulong i2 = upr.toUInteger();
+
+				sc = sc.pop();
+
+				if (!(i1 <= i2 && i2 <= td.objects.dim))
+				{   
+					error(loc, "slice [%ju..%ju] is out of range of [0..%u]", i1, i2, td.objects.dim);
+					goto Ldefault;
+				}
+
+				if (i1 == 0 && i2 == td.objects.dim)
+				{
+					*ps = td;
+					return;
+				}
+
+				/* Create a new TupleDeclaration which
+				 * is a slice [i1..i2] out of the old one.
+				 */
+				Objects objects = new Objects;
+				objects.setDim(cast(uint)(i2 - i1));
+				for (size_t i = 0; i < objects.dim; i++)
+				{
+					objects.data[i] = td.objects.data[cast(size_t)i1 + i];
+				}
+
+				TupleDeclaration tds = new TupleDeclaration(loc, td.ident, objects);
+				*ps = tds;
+			}
+			else
+				goto Ldefault;
+		}
+		else
+		{
+Ldefault:
+			Type.resolve(loc, sc, pe, pt, ps);
+		}
 	}
 	
     void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod)