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