jitcraft/Scanner.cpp
changeset 25 23e8b3d8e4e6
parent 23 8a31742781c1
child 28 a9665857cfd5
     1.1 --- a/jitcraft/Scanner.cpp	Sun Jul 01 18:39:11 2012 -0700
     1.2 +++ b/jitcraft/Scanner.cpp	Mon Jul 02 01:24:57 2012 -0700
     1.3 @@ -18,6 +18,7 @@
     1.4  #include <assert.h>
     1.5  #include <ctype.h>
     1.6  #include "Scanner.h"
     1.7 +#include "Utility.h"
     1.8  
     1.9  using namespace jc;
    1.10  
    1.11 @@ -29,13 +30,17 @@
    1.12      NULL
    1.13  };
    1.14  
    1.15 -Scanner::Scanner(const char *stream, size_t length)
    1.16 -  : stream_(stream),
    1.17 +Scanner::Scanner(CompileContext &cc, const char *stream, size_t length)
    1.18 +  : cc_(cc),
    1.19 +    stream_(stream),
    1.20      length_(length),
    1.21      pushed_(false),
    1.22      saved_('\0'),
    1.23      pos_(stream_)
    1.24  {
    1.25 +    cur_.line = 0;
    1.26 +    cur_.col = 0;
    1.27 +    last_ = cur_;
    1.28  }
    1.29  
    1.30  char
    1.31 @@ -48,6 +53,7 @@
    1.32      }
    1.33      if (pos_ >= stream_ + length_)
    1.34          return '\0';
    1.35 +    last_.col = cur_.col++;
    1.36      return *pos_++;
    1.37  }
    1.38  
    1.39 @@ -56,6 +62,19 @@
    1.40  {
    1.41      assert(saved_ == '\0');
    1.42      saved_ = c;
    1.43 +    cur_.col = last_.col;
    1.44 +}
    1.45 +
    1.46 +void
    1.47 +Scanner::calcNewLine(char c)
    1.48 +{
    1.49 +    cur_.line++;
    1.50 +    cur_.col = 0;
    1.51 +    last_ = cur_;
    1.52 +
    1.53 +    char o;
    1.54 +    if (c == '\r' && ((o = getChar()) != '\n'))
    1.55 +        putChar(o);
    1.56  }
    1.57  
    1.58  void
    1.59 @@ -63,8 +82,10 @@
    1.60  {
    1.61      char c;
    1.62      while ((c = getChar()) != '\0') {
    1.63 -        if (c == '\n' || c == '\r')
    1.64 +        if (c == '\n' || c == '\r') {
    1.65 +            calcNewLine(c);
    1.66              break;
    1.67 +        }
    1.68      }
    1.69  }
    1.70  
    1.71 @@ -81,6 +102,8 @@
    1.72              if (c == '/')
    1.73                  return true;
    1.74          }
    1.75 +        if (c == '\r' || c == '\n')
    1.76 +            calcNewLine(c);
    1.77      }
    1.78  
    1.79      return false;
    1.80 @@ -214,7 +237,7 @@
    1.81  
    1.82              return r;
    1.83          }
    1.84 -        assert(false);
    1.85 +        cc_.reportError(begin(), Message_UnknownEscapeCode, c);
    1.86          return INT_MAX;
    1.87        }
    1.88      }
    1.89 @@ -230,7 +253,7 @@
    1.90          if (c == '\"')
    1.91              break;
    1.92          if (c == '\r' || c == '\n' || c == '\0') {
    1.93 -            assert(false);
    1.94 +            cc_.reportError(begin(), Message_UnterminatedString);
    1.95              return TOK_ERROR;
    1.96          }
    1.97          if (c == '\\') {
    1.98 @@ -266,7 +289,7 @@
    1.99  
   1.100      c = getChar();
   1.101      if (!IsDigit(c)) {
   1.102 -        assert(false);
   1.103 +        cc_.reportError(begin(), Message_ExpectedDigitForFloat, c);
   1.104          return TOK_ERROR;
   1.105      }
   1.106      literal_ += c;
   1.107 @@ -288,7 +311,7 @@
   1.108              c = getChar();
   1.109          }
   1.110          if (!IsDigit(c)) {
   1.111 -            assert(false);
   1.112 +            cc_.reportError(begin(), Message_ExpectedDigitForFloat, c);
   1.113              return TOK_ERROR;
   1.114          }
   1.115          literal_ += c;
   1.116 @@ -350,6 +373,8 @@
   1.117      assert(!pushed_);
   1.118  
   1.119      for (;;) {
   1.120 +        begin_ = cur_;
   1.121 +
   1.122          char c = getChar();
   1.123          switch (c) {
   1.124            case '/':
   1.125 @@ -360,14 +385,21 @@
   1.126                  break;
   1.127              }
   1.128              if (c == '*') {
   1.129 -                if (!eatComment())
   1.130 +                if (!eatComment()) {
   1.131 +                    cc_.reportError(begin(), Message_UnterminatedComment);
   1.132                      return TOK_ERROR;
   1.133 +                }
   1.134                  break;
   1.135              }
   1.136              putChar(c);
   1.137              return TOK_SLASH;
   1.138            }
   1.139  
   1.140 +          case '\n':
   1.141 +          case '\r':
   1.142 +            calcNewLine(c);
   1.143 +            break;
   1.144 +
   1.145            case ';': return TOK_SEMICOLON;
   1.146            case '{': return TOK_LBRACE;
   1.147            case '}': return TOK_RBRACE;
   1.148 @@ -465,9 +497,7 @@
   1.149  
   1.150            case ' ':
   1.151            case '\t':
   1.152 -          case '\r':
   1.153            case '\f':
   1.154 -          case '\n':
   1.155              break;
   1.156  
   1.157            case '"':
   1.158 @@ -478,7 +508,7 @@
   1.159                  return numberLiteral(c);
   1.160              if (c == '_' || (isascii(c) && isalpha(c)))
   1.161                  return identifier(c);
   1.162 -            assert(false);
   1.163 +            cc_.reportError(begin_, Message_UnexpectedCharacter, c, uint8(c));
   1.164              return TOK_ERROR;
   1.165          }
   1.166      }