1.1 --- a/jitcraft/Scanner.cpp Tue Jun 26 00:58:55 2012 -0700
1.2 +++ b/jitcraft/Scanner.cpp Wed Jun 27 02:21:56 2012 -0700
1.3 @@ -86,21 +86,115 @@
1.4 return false;
1.5 }
1.6
1.7 +static inline bool
1.8 +IsDigit(char c)
1.9 +{
1.10 + return c >= '0' && c <= '9';
1.11 +}
1.12 +
1.13 +// Based off the logic in sc2.c's ftoi()...
1.14 +double
1.15 +Scanner::ParseDouble(const char *string)
1.16 +{
1.17 + const char *ptr = string;
1.18 +
1.19 + double number = 0.0;
1.20 + while (IsDigit(*ptr)) {
1.21 + number = (number * 10) + (*ptr - '0');
1.22 + ptr++;
1.23 + }
1.24 +
1.25 + assert(*ptr == '.');
1.26 + ptr++;
1.27 +
1.28 + double fraction = 0.0;
1.29 + double multiplier = 1.0;
1.30 + while (IsDigit(*ptr)) {
1.31 + fraction = (fraction * 10) + (*ptr - '0');
1.32 + multiplier = multiplier / 10.0;
1.33 + ptr++;
1.34 + }
1.35 +
1.36 + number += fraction * multiplier;
1.37 +
1.38 + if (*ptr++ == 'e') {
1.39 + int sign = 1;
1.40 + if (*ptr == '-') {
1.41 + sign = -1;
1.42 + ptr++;
1.43 + }
1.44 +
1.45 + int exponent = 0;
1.46 + while (IsDigit(*ptr)) {
1.47 + exponent = (exponent * 10) + (*ptr - '0');
1.48 + ptr++;
1.49 + }
1.50 +
1.51 + multiplier = pow(10.0, exponent * sign);
1.52 + number *= multiplier;
1.53 + }
1.54 +
1.55 + return number;
1.56 +}
1.57 +
1.58 TokenKind
1.59 -Scanner::integerLiteral(char first)
1.60 +Scanner::numberLiteral(char first)
1.61 {
1.62 literal_ = first;
1.63
1.64 + char c;
1.65 for (;;) {
1.66 - char c = getChar();
1.67 - if (c < '0' || c > '9') {
1.68 - putChar(c);
1.69 + c = getChar();
1.70 + if (!IsDigit(c))
1.71 break;
1.72 - }
1.73 literal_ += c;
1.74 }
1.75
1.76 - return TOK_INTEGER_LITERAL;
1.77 + if (c != '.') {
1.78 + putChar(c);
1.79 + return TOK_INTEGER_LITERAL;
1.80 + }
1.81 + literal_ += c;
1.82 +
1.83 + c = getChar();
1.84 + if (!IsDigit(c)) {
1.85 + assert(false);
1.86 + return TOK_ERROR;
1.87 + }
1.88 + literal_ += c;
1.89 +
1.90 + for (;;) {
1.91 + c = getChar();
1.92 + if (!IsDigit(c))
1.93 + break;
1.94 + literal_ += c;
1.95 + }
1.96 +
1.97 + if (c != 'e') {
1.98 + putChar(c);
1.99 + } else {
1.100 + literal_ += c;
1.101 + c = getChar();
1.102 + if (c == '-') {
1.103 + literal_ += c;
1.104 + c = getChar();
1.105 + }
1.106 + if (!IsDigit(c)) {
1.107 + assert(false);
1.108 + return TOK_ERROR;
1.109 + }
1.110 + literal_ += c;
1.111 + for (;;) {
1.112 + c = getChar();
1.113 + if (!IsDigit(c)) {
1.114 + putChar(c);
1.115 + break;
1.116 + }
1.117 + literal_ += c;
1.118 + }
1.119 + }
1.120 +
1.121 + return TOK_FLOAT_LITERAL;
1.122 }
1.123
1.124 TokenKind
1.125 @@ -108,10 +202,12 @@
1.126 {
1.127 literal_ = first;
1.128
1.129 + char c;
1.130 for (;;) {
1.131 - char c = getChar();
1.132 + c = getChar();
1.133 if (!isascii(c) || (!isalnum(c) && c != '_')) {
1.134 - putChar(c);
1.135 + if (c != ':')
1.136 + putChar(c);
1.137 break;
1.138 }
1.139 literal_ += c;
1.140 @@ -129,7 +225,7 @@
1.141 return TOK_ELSE;
1.142 if (literal_ == "enum")
1.143 return TOK_ENUM;
1.144 - return TOK_NAME;
1.145 + return (c == ':') ? TOK_LABEL : TOK_NAME;
1.146 }
1.147
1.148 TokenKind
1.149 @@ -218,9 +314,10 @@
1.150
1.151 default:
1.152 if (c >= '0' && c <= '9')
1.153 - return integerLiteral(c);
1.154 + return numberLiteral(c);
1.155 if (c == '_' || (isascii(c) && isalpha(c)))
1.156 return identifier(c);
1.157 + assert(false);
1.158 return TOK_ERROR;
1.159 }
1.160 }