diff -r f43e399ab622 -r 633176823669 jitcraft/Scanner.cpp --- a/jitcraft/Scanner.cpp Tue Jun 26 00:58:55 2012 -0700 +++ b/jitcraft/Scanner.cpp Wed Jun 27 02:21:56 2012 -0700 @@ -86,21 +86,115 @@ return false; } +static inline bool +IsDigit(char c) +{ + return c >= '0' && c <= '9'; +} + +// Based off the logic in sc2.c's ftoi()... +double +Scanner::ParseDouble(const char *string) +{ + const char *ptr = string; + + double number = 0.0; + while (IsDigit(*ptr)) { + number = (number * 10) + (*ptr - '0'); + ptr++; + } + + assert(*ptr == '.'); + ptr++; + + double fraction = 0.0; + double multiplier = 1.0; + while (IsDigit(*ptr)) { + fraction = (fraction * 10) + (*ptr - '0'); + multiplier = multiplier / 10.0; + ptr++; + } + + number += fraction * multiplier; + + if (*ptr++ == 'e') { + int sign = 1; + if (*ptr == '-') { + sign = -1; + ptr++; + } + + int exponent = 0; + while (IsDigit(*ptr)) { + exponent = (exponent * 10) + (*ptr - '0'); + ptr++; + } + + multiplier = pow(10.0, exponent * sign); + number *= multiplier; + } + + return number; +} + TokenKind -Scanner::integerLiteral(char first) +Scanner::numberLiteral(char first) { literal_ = first; + char c; for (;;) { - char c = getChar(); - if (c < '0' || c > '9') { - putChar(c); + c = getChar(); + if (!IsDigit(c)) break; - } literal_ += c; } - return TOK_INTEGER_LITERAL; + if (c != '.') { + putChar(c); + return TOK_INTEGER_LITERAL; + } + literal_ += c; + + c = getChar(); + if (!IsDigit(c)) { + assert(false); + return TOK_ERROR; + } + literal_ += c; + + for (;;) { + c = getChar(); + if (!IsDigit(c)) + break; + literal_ += c; + } + + if (c != 'e') { + putChar(c); + } else { + literal_ += c; + c = getChar(); + if (c == '-') { + literal_ += c; + c = getChar(); + } + if (!IsDigit(c)) { + assert(false); + return TOK_ERROR; + } + literal_ += c; + for (;;) { + c = getChar(); + if (!IsDigit(c)) { + putChar(c); + break; + } + literal_ += c; + } + } + + return TOK_FLOAT_LITERAL; } TokenKind @@ -108,10 +202,12 @@ { literal_ = first; + char c; for (;;) { - char c = getChar(); + c = getChar(); if (!isascii(c) || (!isalnum(c) && c != '_')) { - putChar(c); + if (c != ':') + putChar(c); break; } literal_ += c; @@ -129,7 +225,7 @@ return TOK_ELSE; if (literal_ == "enum") return TOK_ENUM; - return TOK_NAME; + return (c == ':') ? TOK_LABEL : TOK_NAME; } TokenKind @@ -218,9 +314,10 @@ default: if (c >= '0' && c <= '9') - return integerLiteral(c); + return numberLiteral(c); if (c == '_' || (isascii(c) && isalpha(c))) return identifier(c); + assert(false); return TOK_ERROR; } }