diff dmd/Lexer.d @ 51:b7d29f613539

StaticAssertStatement.syntaxCopy IfStatement.syntaxCopy CompoundDeclarationStatement.syntaxCopy VoidInitializer.syntaxCopy TypeAArray.syntaxCopy TypeTypeof.syntaxCopy TypeAArray.resolve TypeSArray.deduceType TypeAArray.deduceType TypeAArray.implicitConvTo TemplateDeclaration.leastAsSpecialized TemplateTypeParameter.dummyArg TypeIdentifier.deduceType TemplateTypeParameter.syntaxCopy Lexer.hexStringConstant Lexer.delimitedStringConstant GotoDefaultStatement.ctor CaseRangeStatement.ctor Type.castMod StorageClassDeclaration.syntaxCopy TemplateDeclaration.syntaxCopy
author korDen
date Sat, 21 Aug 2010 11:17:42 +0400
parents 0aa7d1437ada
children ef02e2e203c2
line wrap: on
line diff
--- a/dmd/Lexer.d	Sat Aug 21 10:38:26 2010 +0400
+++ b/dmd/Lexer.d	Sat Aug 21 11:17:42 2010 +0400
@@ -1622,15 +1622,256 @@
 		assert(false);
 	}
 
+	/**************************************
+	 * Lex hex strings:
+	 *	x"0A ae 34FE BD"
+	 */
     TOK hexStringConstant(Token* t)
 	{
-		assert(false);
+		uint c;
+		Loc start = loc;
+		uint n = 0;
+		uint v;
+
+		p++;
+		stringbuffer.reset();
+		while (1)
+			{
+			c = *p++;
+			switch (c)
+			{
+				case ' ':
+				case '\t':
+				case '\v':
+				case '\f':
+					continue;			// skip white space
+
+				case '\r':
+					if (*p == '\n')
+						continue;			// ignore
+				// Treat isolated '\r' as if it were a '\n'
+				case '\n':
+					loc.linnum++;
+					continue;
+
+				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 '"':
+					if (n & 1)
+					{   
+						error("odd number (%d) of hex characters in hex string", n);
+						stringbuffer.writeByte(v);
+					}
+					t.len = stringbuffer.offset;
+					stringbuffer.writeByte(0);
+					void* mem = malloc(stringbuffer.offset);
+					memcpy(mem, stringbuffer.data, stringbuffer.offset);
+					t.ustring = cast(const(char)*)mem;
+					stringPostfix(t);
+					return TOKstring;
+
+			default:
+				if (c >= '0' && c <= '9')
+					c -= '0';
+				else if (c >= 'a' && c <= 'f')
+					c -= 'a' - 10;
+				else if (c >= 'A' && c <= 'F')
+					c -= 'A' - 10;
+				else if (c & 0x80)
+				{   p--;
+					uint u = decodeUTF();
+					p++;
+					if (u == PS || u == LS)
+					loc.linnum++;
+					else
+					error("non-hex character \\u%x", u);
+				}
+				else
+					error("non-hex character '%c'", c);
+				if (n & 1)
+				{   v = (v << 4) | c;
+					stringbuffer.writeByte(v);
+				}
+				else
+					v = c;
+				n++;
+				break;
+			}
+		}
 	}
 
 version (DMDV2) {
+	/**************************************
+	 * Lex delimited strings:
+	 *	q"(foo(xxx))"   // "foo(xxx)"
+	 *	q"[foo(]"       // "foo("
+	 *	q"/foo]/"       // "foo]"
+	 *	q"HERE
+	 *	foo
+	 *	HERE"		// "foo\n"
+	 * Input:
+	 *	p is on the "
+	 */
     TOK delimitedStringConstant(Token* t)
 	{
-		assert(false);
+		uint c;
+		Loc start = loc;
+		uint delimleft = 0;
+		uint delimright = 0;
+		uint nest = 1;
+		uint nestcount;
+		Identifier hereid = null;
+		uint blankrol = 0;
+		uint startline = 0;
+
+		p++;
+		stringbuffer.reset();
+		while (1)
+		{
+			c = *p++;
+			//printf("c = '%c'\n", c);
+			switch (c)
+			{
+				case '\n':
+					Lnextline:
+					loc.linnum++;
+					startline = 1;
+					if (blankrol)
+					{   blankrol = 0;
+						continue;
+					}
+					if (hereid)
+					{
+						stringbuffer.writeUTF8(c);
+						continue;
+					}
+					break;
+
+				case '\r':
+					if (*p == '\n')
+						continue;	// ignore
+					c = '\n';	// treat EndOfLine as \n character
+					goto Lnextline;
+
+				case 0:
+				case 0x1A:
+					goto Lerror;
+
+				default:
+					if (c & 0x80)
+					{   p--;
+						c = decodeUTF();
+						p++;
+						if (c == PS || c == LS)
+						goto Lnextline;
+					}
+					break;
+			}
+			if (delimleft == 0)
+			{   
+				delimleft = c;
+				nest = 1;
+				nestcount = 1;
+				if (c == '(')
+					delimright = ')';
+				else if (c == '{')
+					delimright = '}';
+				else if (c == '[')
+					delimright = ']';
+				else if (c == '<')
+					delimright = '>';
+				else if (isalpha(c) || c == '_' || (c >= 0x80 && isUniAlpha(c)))
+				{	
+					// Start of identifier; must be a heredoc
+					Token t2;
+					p--;
+					scan(&t2);		// read in heredoc identifier
+					if (t2.value != TOKidentifier)
+					{   
+						error("identifier expected for heredoc, not %s", t2.toChars());
+						delimright = c;
+					}
+					else
+					{   
+						hereid = t2.ident;
+						//printf("hereid = '%s'\n", hereid.toChars());
+						blankrol = 1;
+					}
+					nest = 0;
+				}
+				else
+				{	
+					delimright = c;
+					nest = 0;
+					if (isspace(c))
+						error("delimiter cannot be whitespace");
+				}
+			}
+			else
+			{
+				if (blankrol)
+				{	
+					error("heredoc rest of line should be blank");
+					blankrol = 0;
+					continue;
+				}
+				if (nest == 1)
+				{
+					if (c == delimleft)
+						nestcount++;
+					else if (c == delimright)
+					{   nestcount--;
+						if (nestcount == 0)
+						goto Ldone;
+					}
+				}
+				else if (c == delimright)
+					goto Ldone;
+				if (startline && isalpha(c) && hereid)
+				{	
+					Token t2;
+					ubyte* psave = p;
+					p--;
+					scan(&t2);		// read in possible heredoc identifier
+					//printf("endid = '%s'\n", t2.ident.toChars());
+					if (t2.value == TOKidentifier && t2.ident.equals(hereid))
+					{   
+						/* should check that rest of line is blank
+						 */
+						goto Ldone;
+					}
+					p = psave;
+				}
+				stringbuffer.writeUTF8(c);
+				startline = 0;
+			}
+		}
+
+	Ldone:
+		if (*p == '"')
+			p++;
+		else
+			error("delimited string must end in %c\"", delimright);
+		t.len = stringbuffer.offset;
+		stringbuffer.writeByte(0);
+		void* mem = malloc(stringbuffer.offset);
+		memcpy(mem, stringbuffer.data, stringbuffer.offset);
+		t.ustring = cast(const(char)*)mem;
+		stringPostfix(t);
+		return TOKstring;
+
+	Lerror:
+		error("unterminated string constant starting at %s", start.toChars());
+		t.ustring = "".ptr;
+		t.len = 0;
+		t.postfix = 0;
+		return TOKstring;
 	}
 
 	/**************************************