Mercurial > projects > ddmd
view dmd/TypeAArray.d @ 0:10317f0c89a5
Initial commit
author | korDen |
---|---|
date | Sat, 24 Oct 2009 08:42:06 +0400 |
parents | |
children | 2cc604139636 |
line wrap: on
line source
module dmd.TypeAArray; import dmd.TypeArray; import dmd.MOD; import dmd.ArrayTypes; import dmd.TypeInfoDeclaration; import dmd.Expression; import dmd.Scope; import dmd.Loc; import dmd.Dsymbol; import dmd.Type; import dmd.TypeSArray; import dmd.OutBuffer; import dmd.HdrGenState; import dmd.Identifier; import dmd.MATCH; import dmd.TY; import dmd.Id; import dmd.CallExp; import dmd.IntegerExp; import dmd.FuncDeclaration; import dmd.VarExp; import dmd.TypeFunction; import dmd.NullExp; import dmd.Array; import dmd.backend.Symbol; import dmd.backend.TYPE; import dmd.backend.Util; import dmd.backend.SC; import dmd.backend.LIST; import dmd.backend.TYM; import dmd.backend.TF; import dmd.backend.mTYman; import core.stdc.stdio; import core.stdc.stdlib; class TypeAArray : TypeArray { Type index; // key type this(Type t, Type index) { super(Taarray, t); this.index = index; } Type syntaxCopy() { assert(false); } version (DumbClone) { } else { Type clone() { assert(false); } } ulong size(Loc loc) { return PTRSIZE /* * 2*/; } Type semantic(Loc loc, Scope sc) { //printf("TypeAArray::semantic() %s index.ty = %d\n", toChars(), index.ty); // Deal with the case where we thought the index was a type, but // in reality it was an expression. if (index.ty == Tident || index.ty == Tinstance || index.ty == Tsarray) { Expression e; Type t; Dsymbol s; index.resolve(loc, sc, &e, &t, &s); if (e) { // It was an expression - // Rewrite as a static array TypeSArray tsa = new TypeSArray(next, e); return tsa.semantic(loc,sc); } else if (t) index = t; else index.error(loc, "index is not a type or an expression"); } else index = index.semantic(loc,sc); if (index.nextOf() && !index.nextOf().isInvariant()) { index = index.constOf().mutableOf(); static if (false) { printf("index is %p %s\n", index, index.toChars()); index.check(); printf("index.mod = x%x\n", index.mod); printf("index.ito = x%x\n", index.ito); if (index.ito) { printf("index.ito.mod = x%x\n", index.ito.mod); printf("index.ito.ito = x%x\n", index.ito.ito); } } } switch (index.toBasetype().ty) { case Tbool: case Tfunction: case Tvoid: case Tnone: error(loc, "can't have associative array key of %s", index.toBasetype().toChars()); break; default: break; /// } next = next.semantic(loc,sc); transitive(); switch (next.toBasetype().ty) { case Tfunction: case Tnone: error(loc, "can't have associative array of %s", next.toChars()); break; default: break; /// } if (next.isauto()) error(loc, "cannot have array of auto %s", next.toChars()); return merge(); } void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps) { assert(false); } void toDecoBuffer(OutBuffer buf, int flag) { Type.toDecoBuffer(buf, flag); index.toDecoBuffer(buf); next.toDecoBuffer(buf, (flag & 0x100) ? MOD.MODundefined : mod); } void toCBuffer2(OutBuffer buf, HdrGenState* hgs, MOD mod) { assert(false); } Expression dotExp(Scope sc, Expression e, Identifier ident) { version (LOGDOTEXP) { printf("TypeAArray.dotExp(e = '%s', ident = '%s')\n", e.toChars(), ident.toChars()); } if (ident == Id.length) { Expression ec; FuncDeclaration fd; Expressions arguments; fd = FuncDeclaration.genCfunc(Type.tsize_t, Id.aaLen); ec = new VarExp(Loc(0), fd); arguments = new Expressions(); arguments.push(cast(void*)e); e = new CallExp(e.loc, ec, arguments); e.type = (cast(TypeFunction)fd.type).next; } else if (ident == Id.keys) { Expression ec; FuncDeclaration fd; Expressions arguments; int size = cast(int)index.size(e.loc); assert(size); fd = FuncDeclaration.genCfunc(Type.tindex, Id.aaKeys); ec = new VarExp(Loc(0), fd); arguments = new Expressions(); arguments.push(cast(void*)e); arguments.push(cast(void*)new IntegerExp(Loc(0), size, Type.tsize_t)); e = new CallExp(e.loc, ec, arguments); e.type = index.arrayOf(); } else if (ident == Id.values) { Expression ec; FuncDeclaration fd; Expressions arguments; fd = FuncDeclaration.genCfunc(Type.tindex, Id.aaValues); ec = new VarExp(Loc(0), fd); arguments = new Expressions(); arguments.push(cast(void*)e); size_t keysize = cast(size_t)index.size(e.loc); keysize = (keysize + PTRSIZE - 1) & ~(PTRSIZE - 1); arguments.push(cast(void*)new IntegerExp(Loc(0), keysize, Type.tsize_t)); arguments.push(cast(void*)new IntegerExp(Loc(0), next.size(e.loc), Type.tsize_t)); e = new CallExp(e.loc, ec, arguments); e.type = next.arrayOf(); } else if (ident == Id.rehash) { Expression ec; FuncDeclaration fd; Expressions arguments; fd = FuncDeclaration.genCfunc(Type.tint64, Id.aaRehash); ec = new VarExp(Loc(0), fd); arguments = new Expressions(); arguments.push(cast(void*)e.addressOf(sc)); arguments.push(cast(void*)index.getInternalTypeInfo(sc)); e = new CallExp(e.loc, ec, arguments); e.type = this; } else { e = Type.dotExp(sc, e, ident); } return e; } Expression defaultInit(Loc loc) { version (LOGDEFAULTINIT) { printf("TypeAArray.defaultInit() '%s'\n", toChars()); } Expression e = new NullExp(loc); e.type = this; return e; } MATCH deduceType(Scope sc, Type tparam, TemplateParameters parameters, Objects dedtypes) { assert(false); } bool isZeroInit(Loc loc) { assert(false); } bool checkBoolean() { assert(false); } TypeInfoDeclaration getTypeInfoDeclaration() { assert(false); } bool hasPointers() { return true; } MATCH implicitConvTo(Type to) { assert(false); } MATCH constConv(Type to) { assert(false); } version (CPP_MANGLE) { void toCppMangle(OutBuffer buf, CppMangleState* cms) { assert(false); } } // Back end /******************************************** * Determine the right symbol to look up * an associative array element. * Input: * flags 0 don't add value signature * 1 add value signature */ Symbol* aaGetSymbol(const(char)* func, int flags) in { assert(func); assert((flags & ~1) == 0); } out (result) { assert(result); } body { int sz; char* id; type* t; Symbol* s; int i; // Dumb linear symbol table - should use associative array! static Array sarray = null; //printf("aaGetSymbol(func = '%s', flags = %d, key = %p)\n", func, flags, key); static if (false) { scope OutBuffer buf = new OutBuffer(); key.toKeyBuffer(buf); sz = next.size(); // it's just data, so we only care about the size sz = (sz + 3) & ~3; // reduce proliferation of library routines id = cast(char*)alloca(3 + strlen(func) + buf.offset + sizeof(sz) * 3 + 1); buf.writeByte(0); if (flags & 1) sprintf(id, "_aa%s%s%d", func, buf.data, sz); else sprintf(id, "_aa%s%s", func, buf.data); } else { id = cast(char*)alloca(3 + strlen(func) + 1); sprintf(id, "_aa%s", func); } if (!sarray) sarray = new Array(); // See if symbol is already in sarray for (i = 0; i < sarray.dim; i++) { s = cast(Symbol*)sarray.data[i]; if (strcmp(id, s.Sident.ptr) == 0) return s; // use existing Symbol } // Create new Symbol s = symbol_calloc(id); slist_add(s); s.Sclass = SCextern; s.Ssymnum = -1; symbol_func(s); t = type_alloc(TYnfunc); t.Tflags = TFprototype | TFfixed; t.Tmangle = mTYman_c; t.Tparamtypes = null; t.Tnext = next.toCtype(); t.Tnext.Tcount++; t.Tcount++; s.Stype = t; sarray.push(s); // remember it return s; } type* toCtype() { assert(false); } }