1.1 --- a/jitcraft/Scanner.cpp Sun Jul 01 11:25:36 2012 -0700
1.2 +++ b/jitcraft/Scanner.cpp Sun Jul 01 14:52:57 2012 -0700
1.3 @@ -137,6 +137,114 @@
1.4 return number;
1.5 }
1.6
1.7 +static inline bool
1.8 +IsHexDigit(char c)
1.9 +{
1.10 + return IsDigit(c) ||
1.11 + (c >= 'a' && c <= 'f') ||
1.12 + (c >= 'A' && c <= 'F');
1.13 +}
1.14 +
1.15 +// Based on the logic for litchar() in sc2.c.
1.16 +int
1.17 +Scanner::readEscapeCode()
1.18 +{
1.19 + char c = getChar();
1.20 + if (c == '\\')
1.21 + return c;
1.22 +
1.23 + switch (c) {
1.24 + case 'a':
1.25 + return '\a';
1.26 + case 'b':
1.27 + return '\b';
1.28 + case 'e':
1.29 + return 27; // Apparently \e is non-standard.
1.30 + case 'f':
1.31 + return '\f';
1.32 + case 'n':
1.33 + return '\n';
1.34 + case 'r':
1.35 + return '\r';
1.36 + case 't':
1.37 + return '\t';
1.38 + case '\v':
1.39 + return '\v';
1.40 +
1.41 + case 'x':
1.42 + {
1.43 + unsigned digits = 0;
1.44 + char r = 0;
1.45 +
1.46 + c = getChar();
1.47 + while (IsHexDigit(c) && digits < 2) {
1.48 + if (IsDigit(c))
1.49 + c = (c << 4) + (c - '0');
1.50 + else
1.51 + c = (c << 4) + (tolower(c) - 'a' + 10);
1.52 + digits++;
1.53 + c = getChar();
1.54 + }
1.55 +
1.56 + // Swallow a trailing ';'
1.57 + if (c != ';')
1.58 + putChar(c);
1.59 +
1.60 + return r;
1.61 + }
1.62 +
1.63 + case '\'':
1.64 + case '\"':
1.65 + case '%':
1.66 + return c;
1.67 +
1.68 + default:
1.69 + {
1.70 + if (IsDigit(c)) {
1.71 + // \ddd
1.72 + char r = 0;
1.73 + while (IsDigit(c)) {
1.74 + r = r * 10 + (c - '0');
1.75 + c = getChar();
1.76 + }
1.77 +
1.78 + // Swallow a trailing ;
1.79 + if (c != ';')
1.80 + putChar(c);
1.81 +
1.82 + return r;
1.83 + }
1.84 + assert(false);
1.85 + return INT_MAX;
1.86 + }
1.87 + }
1.88 +}
1.89 +
1.90 +TokenKind
1.91 +Scanner::stringLiteral()
1.92 +{
1.93 + literal_.clear();
1.94 +
1.95 + for (;;) {
1.96 + char c = getChar();
1.97 + if (c == '\"')
1.98 + break;
1.99 + if (c == '\r' || c == '\n' || c == '\0') {
1.100 + assert(false);
1.101 + return TOK_ERROR;
1.102 + }
1.103 + if (c == '\\') {
1.104 + int code = readEscapeCode();
1.105 + if (code == INT_MAX)
1.106 + return TOK_ERROR;
1.107 + c = char(code);
1.108 + }
1.109 + literal_ += c;
1.110 + }
1.111 +
1.112 + return TOK_STRING_LITERAL;
1.113 +}
1.114 +
1.115 TokenKind
1.116 Scanner::numberLiteral(char first)
1.117 {
1.118 @@ -335,6 +443,9 @@
1.119 case '\n':
1.120 break;
1.121
1.122 + case '"':
1.123 + return stringLiteral();
1.124 +
1.125 default:
1.126 if (c >= '0' && c <= '9')
1.127 return numberLiteral(c);