Mercurial > projects > ddmd
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; } /**************************************