changeset 8:d42cd5917df4

wysiwyg strings, alias this, templates, TypeSlice implementation
author dkoroskin <>
date Mon, 14 Dec 2009 17:43:43 +0300
parents 89cc05dbdae1
children 661073dd5661
files dmd/AliasThis.d dmd/InExp.d dmd/Lexer.d dmd/TemplateDeclaration.d dmd/TypeSlice.d
diffstat 5 files changed, 270 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/AliasThis.d	Mon Dec 14 14:50:03 2009 +0300
+++ b/dmd/AliasThis.d	Mon Dec 14 17:43:43 2009 +0300
@@ -6,6 +6,7 @@
 import dmd.Scope;
 import dmd.OutBuffer;
 import dmd.HdrGenState;
+import dmd.AggregateDeclaration;
 
 class AliasThis : Dsymbol
 {
@@ -14,17 +15,38 @@
 
     this(Loc loc, Identifier ident)
 	{
-		assert(false);
+		super(null);		// it's anonymous (no identifier)
+		this.loc = loc;
+		this.ident = ident;
 	}
 
-    Dsymbol syntaxCopy(Dsymbol)
+    Dsymbol syntaxCopy(Dsymbol s)
 	{
-		assert(false);
+		assert(!s);
+		/* Since there is no semantic information stored here,
+		 * we don't need to copy it.
+		 */
+		return this;
 	}
 	
     void semantic(Scope sc)
 	{
-		assert(false);
+		Dsymbol parent = sc.parent;
+		if (parent)
+			parent = parent.pastMixin();
+		AggregateDeclaration ad = null;
+		if (parent)
+			ad = parent.isAggregateDeclaration();
+		if (ad)
+		{
+			if (ad.aliasthis)
+				error("there can be only one alias this");
+			assert(ad.members);
+			Dsymbol s = ad.search(loc, ident, 0);
+			ad.aliasthis = s;
+		}
+		else
+			error("alias this can only appear in struct or class declaration, not %s", parent ? parent.toChars() : "nowhere");
 	}
 	
     string kind()
--- a/dmd/InExp.d	Mon Dec 14 14:50:03 2009 +0300
+++ b/dmd/InExp.d	Mon Dec 14 17:43:43 2009 +0300
@@ -6,7 +6,12 @@
 import dmd.Scope;
 import dmd.IRState;
 import dmd.BinExp;
-import dmd.TOK;
+import dmd.TOK;
+import dmd.Type;
+import dmd.TY;
+import dmd.TypeAArray;
+
+import dmd.expression.util.arrayTypeCompatible;
 
 import dmd.backend.elem;
 
@@ -14,18 +19,47 @@
 {
 	this(Loc loc, Expression e1, Expression e2)
 	{
-		assert(false);
-		super(loc, TOK.init, 0, e1, e2);
+		super(loc, TOKin, InExp.sizeof, e1, e2);
 	}
 
 	Expression semantic(Scope sc)
 	{
-		assert(false);
+		if (type)
+			return this;
+
+		super.semanticp(sc);
+
+		Expression e = op_overload(sc);
+		if (e)
+			return e;
+
+		//type = Type.tboolean;
+		Type t2b = e2.type.toBasetype();
+		if (t2b.ty != TY.Taarray)
+		{
+			error("rvalue of in expression must be an associative array, not %s", e2.type.toChars());
+			type = Type.terror;
+		}
+		else
+		{
+			TypeAArray ta = cast(TypeAArray)t2b;
+
+			// Special handling for array keys
+			if (!arrayTypeCompatible(e1.loc, e1.type, ta.index))
+			{
+				// Convert key to type of key
+				e1 = e1.implicitCastTo(sc, ta.index);
+			}
+
+			// Return type is pointer to value
+			type = ta.nextOf().pointerTo();
+		}
+		return this;
 	}
 
 	int isBit()
 	{
-		assert(false);
+		return 0;
 	}
 
 	Identifier opId()
--- a/dmd/Lexer.d	Mon Dec 14 14:50:03 2009 +0300
+++ b/dmd/Lexer.d	Mon Dec 14 17:43:43 2009 +0300
@@ -1561,6 +1561,64 @@
 
     TOK wysiwygStringConstant(Token* t, int tc)
 	{
+		uint c;
+		Loc start = loc;
+
+		p++;
+		stringbuffer.reset();
+		while (true)
+		{
+			c = *p++;
+			switch (c)
+			{
+				case '\n':
+					loc.linnum++;
+					break;
+
+				case '\r':
+					if (*p == '\n')
+						continue;	// ignore
+					c = '\n';	// treat EndOfLine as \n character
+					loc.linnum++;
+					break;
+
+				case 0:
+				case 0x1A:
+					error("unterminated string constant starting at %s", start.toChars());
+					t.ustring = "".ptr;
+					t.len = 0;
+					t.postfix = 0;
+					return TOKstring;
+
+				case '"':
+				case '`':
+					if (c == tc)
+					{
+						t.len = stringbuffer.offset;
+						stringbuffer.writeByte(0);
+						char* tmp = cast(char*)GC.malloc(stringbuffer.offset);
+						memcpy(tmp, stringbuffer.data, stringbuffer.offset);
+						t.ustring = tmp;
+						stringPostfix(t);
+						return TOKstring;
+					}
+					break;
+
+				default:
+					if (c & 0x80)
+					{   p--;
+						uint u = decodeUTF();
+						p++;
+						if (u == PS || u == LS)
+							loc.linnum++;
+						stringbuffer.writeUTF8(u);
+						continue;
+					}
+					break;
+			}
+			stringbuffer.writeByte(c);
+		}
+		
 		assert(false);
 	}
 
@@ -1575,9 +1633,59 @@
 		assert(false);
 	}
 
+	/**************************************
+	 * Lex delimited strings:
+	 *	q{ foo(xxx) } // " foo(xxx) "
+	 *	q{foo(}       // "foo("
+	 *	q{{foo}"}"}   // "{foo}"}""
+	 * Input:
+	 *	p is on the q
+	 */
     TOK tokenStringConstant(Token* t)
 	{
-		assert(false);
+		uint nest = 1;
+		Loc start = loc;
+		ubyte* pstart = ++p;
+
+		while (true)
+		{	
+			Token tok;
+
+			scan(&tok);
+			switch (tok.value)
+			{
+				case TOKlcurly:
+					nest++;
+					continue;
+
+				case TOKrcurly:
+					if (--nest == 0)
+						goto Ldone;
+					continue;
+
+				case TOKeof:
+					goto Lerror;
+
+				default:
+					continue;
+			}
+		}
+
+	Ldone:
+		t.len = p - 1 - pstart;
+		char* tmp = cast(char*)GC.malloc(t.len + 1);
+		memcpy(tmp, pstart, t.len);
+		tmp[t.len] = 0;
+		t.ustring = tmp;
+		stringPostfix(t);
+		return TOKstring;
+
+	Lerror:
+		error("unterminated token string constant starting at %s", start.toChars());
+		t.ustring = "".ptr;
+		t.len = 0;
+		t.postfix = 0;
+		return TOKstring;
 	}
 }
     TOK escapeStringConstant(Token* t, int wide)
--- a/dmd/TemplateDeclaration.d	Mon Dec 14 14:50:03 2009 +0300
+++ b/dmd/TemplateDeclaration.d	Mon Dec 14 17:43:43 2009 +0300
@@ -246,9 +246,55 @@
 		 */
 	}
 
+	/**********************************
+	 * Overload existing TemplateDeclaration 'this' with the new one 's'.
+	 * Return !=0 if successful; i.e. no conflict.
+	 */
     bool overloadInsert(Dsymbol s)
 	{
-		assert(false);
+		TemplateDeclaration f;
+
+	version (LOG) {
+		printf("TemplateDeclaration.overloadInsert('%s')\n", s.toChars());
+	}
+		f = s.isTemplateDeclaration();
+		if (!f)
+			return false;
+
+		for (TemplateDeclaration f2 = this; f2; f2 = f2.overnext)
+		{
+	static if (false) {
+		// Conflict if TemplateParameter's match
+		// Will get caught anyway later with TemplateInstance, but
+		// should check it now.
+		if (f.parameters.dim != f2.parameters.dim)
+			goto Lcontinue;
+
+		for (int i = 0; i < f.parameters.dim; i++)
+		{   
+			TemplateParameter p1 = cast(TemplateParameter)f.parameters.data[i];
+			TemplateParameter p2 = cast(TemplateParameter)f2.parameters.data[i];
+
+			if (!p1.overloadMatch(p2))
+				goto Lcontinue;
+		}
+
+	version (LOG) {
+		printf("\tfalse: conflict\n");
+	}
+		return false;
+
+		 Lcontinue:
+		;
+	}
+		}
+
+		f.overroot = this;
+		///*pf = f;
+	version (LOG) {
+		printf("\ttrue: no conflict\n");
+	}
+		return true;
 	}
 
     void toCBuffer(OutBuffer buf, HdrGenState* hgs)
--- a/dmd/TypeSlice.d	Mon Dec 14 14:50:03 2009 +0300
+++ b/dmd/TypeSlice.d	Mon Dec 14 17:43:43 2009 +0300
@@ -10,6 +10,12 @@
 import dmd.OutBuffer;
 import dmd.HdrGenState;
 import dmd.TY;
+import dmd.TypeTuple;
+import dmd.WANT;
+import dmd.ArrayTypes;
+import dmd.Argument;
+
+import dmd.type.Util;
 
 class TypeSlice : TypeNext
 {
@@ -18,8 +24,10 @@
 
     this(Type next, Expression lwr, Expression upr)
 	{
-		super(TY.init, null);
-		assert(false);
+		super(TY.Tslice, next);
+		//printf("TypeSlice[%s .. %s]\n", lwr.toChars(), upr.toChars());
+		this.lwr = lwr;
+		this.upr = upr;
 	}
 	
 version (DumbClone) {
@@ -32,12 +40,49 @@
 	
     Type syntaxCopy()
 	{
-		assert(false);
+		Type t = new TypeSlice(next.syntaxCopy(), lwr.syntaxCopy(), upr.syntaxCopy());
+		t.mod = mod;
+		return t;
 	}
 	
     Type semantic(Loc loc, Scope sc)
 	{
-		assert(false);
+		//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;
+		}
+
+		Arguments args = new Arguments;
+		args.reserve(cast(size_t)(i2 - i1));
+		for (size_t i = cast(size_t)i1; i < cast(size_t)i2; i++)
+		{	
+			Argument arg = cast(Argument)tt.arguments.data[i];
+			args.push(cast(void*)arg);
+		}
+
+		return new TypeTuple(args);
 	}
 	
     void resolve(Loc loc, Scope sc, Expression* pe, Type* pt, Dsymbol* ps)