Mercurial > projects > ddmd
view dmd/TypeSlice.d @ 187:b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
author | Abscissa |
---|---|
date | Tue, 07 Jun 2011 23:37:34 -0400 |
parents | e3afd1303184 |
children |
line wrap: on
line source
module dmd.TypeSlice; import dmd.common; import dmd.Type; import dmd.TypeNext; import dmd.MOD; import dmd.Expression; import dmd.Loc; import dmd.Scope; import dmd.Dsymbol; import dmd.OutBuffer; import dmd.HdrGenState; import dmd.TY; import dmd.TypeTuple; import dmd.WANT; import dmd.ArrayTypes; import dmd.Parameter; import dmd.SliceExp; import dmd.TupleDeclaration; import dmd.ScopeDsymbol; import dmd.ArrayScopeSymbol; import dmd.type.Util; import dmd.DDMDExtensions; class TypeSlice : TypeNext { mixin insertMemberExtension!(typeof(this)); Expression lwr; Expression upr; this(Type next, Expression lwr, Expression upr) { register(); super(TY.Tslice, next); //printf("TypeSlice[%s .. %s]\n", lwr.toChars(), upr.toChars()); this.lwr = lwr; this.upr = upr; } override Type syntaxCopy() { Type t = new TypeSlice(next.syntaxCopy(), lwr.syntaxCopy(), upr.syntaxCopy()); t.mod = mod; return t; } override Type semantic(Loc loc, Scope sc) { //printf("TypeSlice.semantic() %s\n", toChars()); next = next.semantic(loc, sc); transitive(); //printf("next: %s\n", next.toChars()); Type tbn = next.toBasetype(); if (tbn.ty != Ttuple) { error(loc, "can only slice tuple types, not %s", tbn.toChars()); return Type.terror; } TypeTuple tt = cast(TypeTuple)tbn; lwr = semanticLength(sc, tbn, lwr); lwr = lwr.optimize(WANTvalue); ulong i1 = lwr.toUInteger(); upr = semanticLength(sc, tbn, upr); upr = upr.optimize(WANTvalue); ulong i2 = upr.toUInteger(); if (!(i1 <= i2 && i2 <= tt.arguments.dim)) { error(loc, "slice [%ju..%ju] is out of range of [0..%u]", i1, i2, tt.arguments.dim); return Type.terror; } auto args = new Parameters; args.reserve(cast(size_t)(i2 - i1)); for (size_t i = cast(size_t)i1; i < cast(size_t)i2; i++) { auto arg = tt.arguments[i]; args.push(arg); } return new TypeTuple(args); } override void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps) { 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. */ auto objects = new Objects; objects.setDim(cast(uint)(i2 - i1)); for (size_t i = 0; i < objects.dim; i++) { objects[i] = td.objects[cast(size_t)i1 + i]; } auto tds = new TupleDeclaration(loc, td.ident, objects); *ps = tds; } else goto Ldefault; } else { Ldefault: Type.resolve(loc, sc, pe, pt, ps); } } override void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { assert(false); } }