Mercurial > projects > ddmd
diff 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 diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmd/TypeAArray.d Sat Oct 24 08:42:06 2009 +0400 @@ -0,0 +1,360 @@ +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); + } +} \ No newline at end of file