18b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// Features shared by parsing and pre-parsing scanners.
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "scanner.h"
31589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
32589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "../include/v8stdint.h"
33589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#include "char-predicates-inl.h"
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Scanner
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
413ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochScanner::Scanner(UnicodeCache* unicode_cache)
423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    : unicode_cache_(unicode_cache),
433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      octal_pos_(Location::invalid()),
443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      harmony_scoping_(false),
453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      harmony_modules_(false) { }
4685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
4785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Scanner::Initialize(Utf16CharacterStream* source) {
493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  source_ = source;
503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Need to capture identifiers in order to recognize "get" and "set"
513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // in object literals.
523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Init();
533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Skip initial whitespace allowing HTML comment ends just like
543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // after a newline and scan first token.
553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  has_line_terminator_before_next_ = true;
563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  SkipWhiteSpace();
573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Scan();
58589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}
59b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
60589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
61589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochuc32 Scanner::ScanHexNumber(int expected_length) {
62589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  ASSERT(expected_length <= 4);  // prevent overflow
63589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
64589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  uc32 digits[4] = { 0, 0, 0, 0 };
65589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  uc32 x = 0;
66589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  for (int i = 0; i < expected_length; i++) {
67589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    digits[i] = c0_;
68589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    int d = HexValue(c0_);
69589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (d < 0) {
70589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // According to ECMA-262, 3rd, 7.8.4, page 18, these hex escapes
71589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // should be illegal, but other JS VMs just return the
72589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // non-escaped version of the original character.
73589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
74589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // Push back digits that we have advanced past.
75589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      for (int j = i-1; j >= 0; j--) {
76589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        PushBack(digits[j]);
77589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      }
78589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      return -1;
79589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
80589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    x = x * 16 + d;
81589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    Advance();
82b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
83589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
84589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return x;
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
88589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// Ensure that tokens can be stored in a byte.
89589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochSTATIC_ASSERT(Token::NUM_TOKENS <= 0x100);
90589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
91589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// Table of one-character tokens, by character (0x00..0x7f only).
92589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochstatic const byte one_char_tokens[] = {
93589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
94589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
95589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
96589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
97589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
98589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
99589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
100589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
101589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
102589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
103589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
104589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
105589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
106589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
107589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
108589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
109589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
110589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
111589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
112589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
113589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
114589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
115589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
116589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
117589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
118589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
119589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
120589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
121589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
122589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
123589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
124589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
125589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
126589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
127589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
128589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
129589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
130589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
131589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
132589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
133589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::LPAREN,       // 0x28
134589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::RPAREN,       // 0x29
135589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
136589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
137589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::COMMA,        // 0x2c
138589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
139589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
140589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
141589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
142589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
143589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
144589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
145589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
146589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
147589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
148589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
149589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
150589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
151589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::COLON,        // 0x3a
152589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::SEMICOLON,    // 0x3b
153589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
154589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
155589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
156589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::CONDITIONAL,  // 0x3f
157589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
158589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
159589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
160589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
161589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
162589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
163589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
164589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
165589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
166589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
167589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
168589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
169589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
170589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
171589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
172589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
173589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
174589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
175589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
176589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
177589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
178589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
179589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
180589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
181589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
182589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
183589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
184589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::LBRACK,     // 0x5b
185589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
186589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::RBRACK,     // 0x5d
187589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
188589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
189589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
190589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
191589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
192589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
193589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
194589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
195589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
196589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
197589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
198589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
199589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
200589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
201589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
202589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
203589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
204589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
205589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
206589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
207589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
208589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
209589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
210589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
211589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
212589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
213589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
214589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
215589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
216589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::LBRACE,       // 0x7b
217589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL,
218589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::RBRACE,       // 0x7d
219589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::BIT_NOT,      // 0x7e
220589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::ILLEGAL
221589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch};
222589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
223589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
2243ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochToken::Value Scanner::Next() {
225589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  current_ = next_;
226589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  has_line_terminator_before_next_ = false;
227589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  has_multiline_comment_before_next_ = false;
228589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (static_cast<unsigned>(c0_) <= 0x7f) {
229589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    Token::Value token = static_cast<Token::Value>(one_char_tokens[c0_]);
230589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (token != Token::ILLEGAL) {
231589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      int pos = source_pos();
232589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      next_.token = token;
233589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      next_.location.beg_pos = pos;
234589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      next_.location.end_pos = pos + 1;
235589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      Advance();
236589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      return current_.token;
237589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
239589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Scan();
240589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return current_.token;
241b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
242b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
243b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
244589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochstatic inline bool IsByteOrderMark(uc32 c) {
245589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // The Unicode value U+FFFE is guaranteed never to be assigned as a
246589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Unicode character; this implies that in a Unicode context the
247589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // 0xFF, 0xFE byte pattern can only be interpreted as the U+FEFF
248589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // character expressed in little-endian byte order (since it could
249589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // not be a U+FFFE character expressed in big-endian byte
250589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // order). Nevertheless, we check for it to be compatible with
251589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Spidermonkey.
252589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return c == 0xFEFF || c == 0xFFFE;
253b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
254b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
255589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
2563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool Scanner::SkipWhiteSpace() {
257589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  int start_position = source_pos();
258589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
259589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  while (true) {
260589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // We treat byte-order marks (BOMs) as whitespace for better
261589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // compatibility with Spidermonkey and other JavaScript engines.
262589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    while (unicode_cache_->IsWhiteSpace(c0_) || IsByteOrderMark(c0_)) {
263589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // IsWhiteSpace() includes line terminators!
264589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      if (unicode_cache_->IsLineTerminator(c0_)) {
265589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        // Ignore line terminators, but remember them. This is necessary
266589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        // for automatic semicolon insertion.
267589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        has_line_terminator_before_next_ = true;
268589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      }
269589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      Advance();
270589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
271589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
272589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // If there is an HTML comment end '-->' at the beginning of a
273589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // line (with only whitespace in front of it), we treat the rest
274589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // of the line as a comment. This is in line with the way
275589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // SpiderMonkey handles it.
276589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (c0_ == '-' && has_line_terminator_before_next_) {
277589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      Advance();
278589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      if (c0_ == '-') {
279589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        Advance();
280589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        if (c0_ == '>') {
281589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          // Treat the rest of the line as a comment.
282589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          SkipSingleLineComment();
283589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          // Continue skipping white space after the comment.
284589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          continue;
285589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        }
286589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        PushBack('-');  // undo Advance()
287589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      }
288589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      PushBack('-');  // undo Advance()
289589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
290589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // Return whether or not we skipped any characters.
291589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    return source_pos() != start_position;
292589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
293b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
294b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2963ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochToken::Value Scanner::SkipSingleLineComment() {
297589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Advance();
298b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
299589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // The line terminator at the end of the line is not considered
300589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // to be part of the single-line comment; it is recognized
301589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // separately by the lexical grammar and becomes part of the
302589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // stream of input elements for the syntactic grammar (see
303589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // ECMA-262, section 7.4).
304589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  while (c0_ >= 0 && !unicode_cache_->IsLineTerminator(c0_)) {
305589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    Advance();
306589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
307b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
308589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return Token::WHITESPACE;
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3123ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochToken::Value Scanner::SkipMultiLineComment() {
313589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  ASSERT(c0_ == '*');
314589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Advance();
315589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
316589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  while (c0_ >= 0) {
317589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    uc32 ch = c0_;
318589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    Advance();
319589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (unicode_cache_->IsLineTerminator(ch)) {
320589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // Following ECMA-262, section 7.4, a comment containing
321589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // a newline will make the comment count as a line-terminator.
322589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      has_multiline_comment_before_next_ = true;
323589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
324589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // If we have reached the end of the multi-line comment, we
325589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // consume the '/' and insert a whitespace. This way all
326589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // multi-line comments are treated as whitespace.
327589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (ch == '*' && c0_ == '/') {
328589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      c0_ = ' ';
329589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      return Token::WHITESPACE;
330589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
331b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
332589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
333589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Unterminated multi-line comment.
334589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return Token::ILLEGAL;
335b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
336b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
337b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3383ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochToken::Value Scanner::ScanHtmlComment() {
339589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Check for <!-- comments.
340589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  ASSERT(c0_ == '!');
341589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Advance();
342589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (c0_ == '-') {
343589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    Advance();
344589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (c0_ == '-') return SkipSingleLineComment();
345589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    PushBack('-');  // undo Advance()
346589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
347589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  PushBack('!');  // undo Advance()
348589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  ASSERT(c0_ == '!');
349589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return Token::LT;
350b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
351b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
352b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Scanner::Scan() {
354589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  next_.literal_chars = NULL;
355589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Token::Value token;
356589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  do {
357589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // Remember the position of the next token
358589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    next_.location.beg_pos = source_pos();
359589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
360589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    switch (c0_) {
361589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case ' ':
362589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case '\t':
363589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        Advance();
364589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        token = Token::WHITESPACE;
365589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
366589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
367589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case '\n':
368589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        Advance();
369589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        has_line_terminator_before_next_ = true;
370589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        token = Token::WHITESPACE;
371589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
372589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
373589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case '"': case '\'':
374589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        token = ScanString();
375589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
376589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
377589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case '<':
378589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        // < <= << <<= <!--
379589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        Advance();
380589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        if (c0_ == '=') {
381589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Select(Token::LTE);
382589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        } else if (c0_ == '<') {
383589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Select('=', Token::ASSIGN_SHL, Token::SHL);
384589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        } else if (c0_ == '!') {
385589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = ScanHtmlComment();
386589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        } else {
387589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Token::LT;
388589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        }
389589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
390589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
391589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case '>':
392589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        // > >= >> >>= >>> >>>=
393589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        Advance();
394589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        if (c0_ == '=') {
395589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Select(Token::GTE);
396589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        } else if (c0_ == '>') {
397589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          // >> >>= >>> >>>=
398589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          Advance();
399589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          if (c0_ == '=') {
400589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch            token = Select(Token::ASSIGN_SAR);
401589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          } else if (c0_ == '>') {
402589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch            token = Select('=', Token::ASSIGN_SHR, Token::SHR);
403589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          } else {
404589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch            token = Token::SAR;
405589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          }
406589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        } else {
407589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Token::GT;
408589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        }
409589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
410589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
411589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case '=':
412589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        // = == ===
413589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        Advance();
414589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        if (c0_ == '=') {
415589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Select('=', Token::EQ_STRICT, Token::EQ);
416589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        } else {
417589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Token::ASSIGN;
418589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        }
419589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
420589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
421589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case '!':
422589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        // ! != !==
423589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        Advance();
424589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        if (c0_ == '=') {
425589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Select('=', Token::NE_STRICT, Token::NE);
426589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        } else {
427589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Token::NOT;
428589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        }
429589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
430589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
431589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case '+':
432589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        // + ++ +=
433589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        Advance();
434589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        if (c0_ == '+') {
435589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Select(Token::INC);
436589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        } else if (c0_ == '=') {
437589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Select(Token::ASSIGN_ADD);
438589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        } else {
439589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Token::ADD;
440589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        }
441589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
442589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
443589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case '-':
444589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        // - -- --> -=
445589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        Advance();
446589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        if (c0_ == '-') {
447589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          Advance();
448589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          if (c0_ == '>' && has_line_terminator_before_next_) {
449589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch            // For compatibility with SpiderMonkey, we skip lines that
450589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch            // start with an HTML comment end '-->'.
451589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch            token = SkipSingleLineComment();
452589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          } else {
453589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch            token = Token::DEC;
454589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          }
455589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        } else if (c0_ == '=') {
456589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Select(Token::ASSIGN_SUB);
457589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        } else {
458589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Token::SUB;
459589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        }
460589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
461589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
462589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case '*':
463589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        // * *=
464589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        token = Select('=', Token::ASSIGN_MUL, Token::MUL);
465589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
466b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
467589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case '%':
468589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        // % %=
469589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        token = Select('=', Token::ASSIGN_MOD, Token::MOD);
470589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
471b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
472589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case '/':
473589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        // /  // /* /=
474589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        Advance();
475589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        if (c0_ == '/') {
476589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = SkipSingleLineComment();
477589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        } else if (c0_ == '*') {
478589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = SkipMultiLineComment();
479589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        } else if (c0_ == '=') {
480589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Select(Token::ASSIGN_DIV);
481589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        } else {
482589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Token::DIV;
483589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        }
484589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
485589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
486589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case '&':
487589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        // & && &=
488589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        Advance();
489589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        if (c0_ == '&') {
490589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Select(Token::AND);
491589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        } else if (c0_ == '=') {
492589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Select(Token::ASSIGN_BIT_AND);
493589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        } else {
494589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Token::BIT_AND;
495589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        }
496589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
497589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
498589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case '|':
499589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        // | || |=
500589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        Advance();
501589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        if (c0_ == '|') {
502589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Select(Token::OR);
503589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        } else if (c0_ == '=') {
504589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Select(Token::ASSIGN_BIT_OR);
505589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        } else {
506589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Token::BIT_OR;
507589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        }
508589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
509589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
510589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case '^':
511589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        // ^ ^=
512589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        token = Select('=', Token::ASSIGN_BIT_XOR, Token::BIT_XOR);
513589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
514589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
515589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case '.':
516589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        // . Number
517589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        Advance();
518589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        if (IsDecimalDigit(c0_)) {
519589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = ScanNumber(true);
520589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        } else {
521589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Token::PERIOD;
522589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        }
523589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
524589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
525589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case ':':
526589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        token = Select(Token::COLON);
527589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
528589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
529589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case ';':
530589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        token = Select(Token::SEMICOLON);
531589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
532589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
533589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case ',':
534589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        token = Select(Token::COMMA);
535589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
536589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
537589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case '(':
538589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        token = Select(Token::LPAREN);
539589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
540589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
541589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case ')':
542589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        token = Select(Token::RPAREN);
543589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
544589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
545589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case '[':
546589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        token = Select(Token::LBRACK);
547589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
548589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
549589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case ']':
550589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        token = Select(Token::RBRACK);
551589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
552589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
553589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case '{':
554589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        token = Select(Token::LBRACE);
555589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
556589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
557589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case '}':
558589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        token = Select(Token::RBRACE);
559589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
560589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
561589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case '?':
562589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        token = Select(Token::CONDITIONAL);
563589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
564589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
565589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      case '~':
566589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        token = Select(Token::BIT_NOT);
567589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
568589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
569589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      default:
570589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        if (unicode_cache_->IsIdentifierStart(c0_)) {
571589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = ScanIdentifierOrKeyword();
572589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        } else if (IsDecimalDigit(c0_)) {
573589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = ScanNumber(false);
574589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        } else if (SkipWhiteSpace()) {
575589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Token::WHITESPACE;
576589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        } else if (c0_ < 0) {
577589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Token::EOS;
578589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        } else {
579589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          token = Select(Token::ILLEGAL);
580589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        }
581589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
582589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
583589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
584589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // Continue scanning for tokens as long as we're just skipping
585589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // whitespace.
586589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  } while (token == Token::WHITESPACE);
587589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
588589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  next_.location.end_pos = source_pos();
589589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  next_.token = token;
590b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
591b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
592b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Scanner::SeekForward(int pos) {
594589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // After this call, we will have the token at the given position as
595589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // the "next" token. The "current" token will be invalid.
596589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (pos == next_.location.beg_pos) return;
597589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  int current_pos = source_pos();
598589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  ASSERT_EQ(next_.location.end_pos, current_pos);
599589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Positions inside the lookahead token aren't supported.
600589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  ASSERT(pos >= current_pos);
601589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (pos != current_pos) {
602589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    source_->SeekForward(pos - source_->pos());
603589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    Advance();
604589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // This function is only called to seek to the location
605589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // of the end of a function (at the "}" token). It doesn't matter
606589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // whether there was a line terminator in the part we skip.
607589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    has_line_terminator_before_next_ = false;
608589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    has_multiline_comment_before_next_ = false;
609b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
610589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Scan();
611589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}
612589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
613589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
6143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Scanner::ScanEscape() {
615589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  uc32 c = c0_;
616589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Advance();
617589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
618589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Skip escaped newlines.
619589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (unicode_cache_->IsLineTerminator(c)) {
620589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // Allow CR+LF newlines in multiline string literals.
621589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (IsCarriageReturn(c) && IsLineFeed(c0_)) Advance();
622589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // Allow LF+CR newlines in multiline string literals.
623589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (IsLineFeed(c) && IsCarriageReturn(c0_)) Advance();
624589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    return;
625589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
626589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
627589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  switch (c) {
628589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    case '\'':  // fall through
629589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    case '"' :  // fall through
630589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    case '\\': break;
631589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    case 'b' : c = '\b'; break;
632589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    case 'f' : c = '\f'; break;
633589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    case 'n' : c = '\n'; break;
634589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    case 'r' : c = '\r'; break;
635589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    case 't' : c = '\t'; break;
636589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    case 'u' : {
637589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      c = ScanHexNumber(4);
638589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      if (c < 0) c = 'u';
639589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      break;
640589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
641589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    case 'v' : c = '\v'; break;
642589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    case 'x' : {
643589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      c = ScanHexNumber(2);
644589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      if (c < 0) c = 'x';
645589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      break;
646b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
647589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    case '0' :  // fall through
648589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    case '1' :  // fall through
649589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    case '2' :  // fall through
650589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    case '3' :  // fall through
651589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    case '4' :  // fall through
652589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    case '5' :  // fall through
653589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    case '6' :  // fall through
654589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    case '7' : c = ScanOctalEscape(c, 2); break;
655b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
656589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
657589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // According to ECMA-262, 3rd, 7.8.4 (p 18ff) these
658589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // should be illegal, but they are commonly handled
659589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // as non-escaped characters by JS VMs.
660589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  AddLiteralChar(c);
661b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
662b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
663b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
664589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// Octal escapes of the forms '\0xx' and '\xxx' are not a part of
665589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// ECMA-262. Other JS VMs support them.
6663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochuc32 Scanner::ScanOctalEscape(uc32 c, int length) {
667589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  uc32 x = c - '0';
668589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  int i = 0;
669589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  for (; i < length; i++) {
670589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    int d = c0_ - '0';
671589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (d < 0 || d > 7) break;
672589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    int nx = x * 8 + d;
673589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (nx >= 256) break;
674589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    x = nx;
675589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    Advance();
676589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
677589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Anything except '\0' is an octal escape sequence, illegal in strict mode.
678589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Remember the position of octal escape sequences so that an error
679589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // can be reported later (in strict mode).
680589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // We don't report the error immediately, because the octal escape can
681589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // occur before the "use strict" directive.
682589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (c != '0' || i > 0) {
683589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    octal_pos_ = Location(source_pos() - i - 1, source_pos() - 1);
684589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
685589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return x;
686589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}
687589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
688589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
6893ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochToken::Value Scanner::ScanString() {
690589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  uc32 quote = c0_;
691589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Advance();  // consume quote
692b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
693589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  LiteralScope literal(this);
694589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  while (c0_ != quote && c0_ >= 0
695589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch         && !unicode_cache_->IsLineTerminator(c0_)) {
696589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    uc32 c = c0_;
697589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    Advance();
698589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (c == '\\') {
699589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      if (c0_ < 0) return Token::ILLEGAL;
700589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      ScanEscape();
701589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    } else {
702589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      AddLiteralChar(c);
703589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
704589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
705589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (c0_ != quote) return Token::ILLEGAL;
706589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  literal.Complete();
707b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
708589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Advance();  // consume quote
709589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return Token::STRING;
710b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
711b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
712b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
7133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Scanner::ScanDecimalDigits() {
714589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  while (IsDecimalDigit(c0_))
715589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    AddLiteralCharAdvance();
716b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
717b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
718b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
7193ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochToken::Value Scanner::ScanNumber(bool seen_period) {
720589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  ASSERT(IsDecimalDigit(c0_));  // the first digit of the number or the fraction
721589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
722589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  enum { DECIMAL, HEX, OCTAL } kind = DECIMAL;
723589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
724589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  LiteralScope literal(this);
725589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (seen_period) {
726589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // we have already seen a decimal point of the float
727589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    AddLiteralChar('.');
728589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    ScanDecimalDigits();  // we know we have at least one digit
729589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
730589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  } else {
731589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // if the first character is '0' we must check for octals and hex
732589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (c0_ == '0') {
733589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      int start_pos = source_pos();  // For reporting octal positions.
734589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      AddLiteralCharAdvance();
735589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
736589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // either 0, 0exxx, 0Exxx, 0.xxx, an octal number, or a hex number
737589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      if (c0_ == 'x' || c0_ == 'X') {
738589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        // hex number
739589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        kind = HEX;
740589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        AddLiteralCharAdvance();
741589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        if (!IsHexDigit(c0_)) {
742589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          // we must have at least one hex digit after 'x'/'X'
743589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          return Token::ILLEGAL;
744589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        }
745589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        while (IsHexDigit(c0_)) {
746589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          AddLiteralCharAdvance();
747589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        }
748589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      } else if ('0' <= c0_ && c0_ <= '7') {
749589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        // (possible) octal number
750589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        kind = OCTAL;
751589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        while (true) {
752589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          if (c0_ == '8' || c0_ == '9') {
753589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch            kind = DECIMAL;
754589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch            break;
755589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          }
756589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          if (c0_  < '0' || '7'  < c0_) {
757589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch            // Octal literal finished.
758589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch            octal_pos_ = Location(start_pos, source_pos());
759589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch            break;
760589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          }
761589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          AddLiteralCharAdvance();
762589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        }
763589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      }
764589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
765589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
766589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // Parse decimal digits and allow trailing fractional part.
767589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (kind == DECIMAL) {
768589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      ScanDecimalDigits();  // optional
769589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      if (c0_ == '.') {
770589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        AddLiteralCharAdvance();
771589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        ScanDecimalDigits();  // optional
772589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      }
773589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
774b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
775589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
776589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // scan exponent, if any
777589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (c0_ == 'e' || c0_ == 'E') {
778589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    ASSERT(kind != HEX);  // 'e'/'E' must be scanned as part of the hex number
779589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (kind == OCTAL) return Token::ILLEGAL;  // no exponent for octals allowed
780589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // scan exponent
781589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    AddLiteralCharAdvance();
782589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (c0_ == '+' || c0_ == '-')
783589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      AddLiteralCharAdvance();
784589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (!IsDecimalDigit(c0_)) {
785589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // we must have at least one decimal digit after 'e'/'E'
786589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      return Token::ILLEGAL;
787589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
788589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    ScanDecimalDigits();
789589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
790589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
791589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // The source character immediately following a numeric literal must
792589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // not be an identifier start or a decimal digit; see ECMA-262
793589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // section 7.8.3, page 17 (note that we read only one decimal digit
794589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // if the value is 0).
795589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (IsDecimalDigit(c0_) || unicode_cache_->IsIdentifierStart(c0_))
796589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    return Token::ILLEGAL;
797589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
798589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  literal.Complete();
799589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
800589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return Token::NUMBER;
801b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
802b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
803b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
8043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochuc32 Scanner::ScanIdentifierUnicodeEscape() {
805589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Advance();
806589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (c0_ != 'u') return -1;
807589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Advance();
808589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  uc32 result = ScanHexNumber(4);
809589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (result < 0) PushBack('u');
810589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return result;
811589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}
812589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
813589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
814589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// ----------------------------------------------------------------------------
815589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// Keyword Matcher
816589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
817589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#define KEYWORDS(KEYWORD_GROUP, KEYWORD)                            \
818589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD_GROUP('b')                                                \
819589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("break", Token::BREAK)                                    \
820589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD_GROUP('c')                                                \
821589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("case", Token::CASE)                                      \
822589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("catch", Token::CATCH)                                    \
823589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("class", Token::FUTURE_RESERVED_WORD)                     \
824589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("const", Token::CONST)                                    \
825589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("continue", Token::CONTINUE)                              \
826589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD_GROUP('d')                                                \
827589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("debugger", Token::DEBUGGER)                              \
828589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("default", Token::DEFAULT)                                \
829589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("delete", Token::DELETE)                                  \
830589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("do", Token::DO)                                          \
831589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD_GROUP('e')                                                \
832589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("else", Token::ELSE)                                      \
833589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("enum", Token::FUTURE_RESERVED_WORD)                      \
8343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  KEYWORD("export", harmony_modules                                 \
8353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                    ? Token::EXPORT : Token::FUTURE_RESERVED_WORD)  \
836589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("extends", Token::FUTURE_RESERVED_WORD)                   \
837589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD_GROUP('f')                                                \
838589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("false", Token::FALSE_LITERAL)                            \
839589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("finally", Token::FINALLY)                                \
840589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("for", Token::FOR)                                        \
841589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("function", Token::FUNCTION)                              \
842589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD_GROUP('i')                                                \
843589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("if", Token::IF)                                          \
844589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("implements", Token::FUTURE_STRICT_RESERVED_WORD)         \
8453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  KEYWORD("import", harmony_modules                                 \
8463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                    ? Token::IMPORT : Token::FUTURE_RESERVED_WORD)  \
847589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("in", Token::IN)                                          \
848589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("instanceof", Token::INSTANCEOF)                          \
849589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("interface", Token::FUTURE_STRICT_RESERVED_WORD)          \
850589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD_GROUP('l')                                                \
8513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  KEYWORD("let", harmony_scoping                                    \
852589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                 ? Token::LET : Token::FUTURE_STRICT_RESERVED_WORD) \
853589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD_GROUP('n')                                                \
854589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("new", Token::NEW)                                        \
855589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("null", Token::NULL_LITERAL)                              \
856589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD_GROUP('p')                                                \
857589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("package", Token::FUTURE_STRICT_RESERVED_WORD)            \
858589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("private", Token::FUTURE_STRICT_RESERVED_WORD)            \
859589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("protected", Token::FUTURE_STRICT_RESERVED_WORD)          \
860589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("public", Token::FUTURE_STRICT_RESERVED_WORD)             \
861589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD_GROUP('r')                                                \
862589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("return", Token::RETURN)                                  \
863589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD_GROUP('s')                                                \
864589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("static", Token::FUTURE_STRICT_RESERVED_WORD)             \
865589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("super", Token::FUTURE_RESERVED_WORD)                     \
866589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("switch", Token::SWITCH)                                  \
867589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD_GROUP('t')                                                \
868589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("this", Token::THIS)                                      \
869589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("throw", Token::THROW)                                    \
870589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("true", Token::TRUE_LITERAL)                              \
871589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("try", Token::TRY)                                        \
872589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("typeof", Token::TYPEOF)                                  \
873589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD_GROUP('v')                                                \
874589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("var", Token::VAR)                                        \
875589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("void", Token::VOID)                                      \
876589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD_GROUP('w')                                                \
877589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("while", Token::WHILE)                                    \
878589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("with", Token::WITH)                                      \
879589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD_GROUP('y')                                                \
880589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  KEYWORD("yield", Token::FUTURE_STRICT_RESERVED_WORD)
881589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
882589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
883589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochstatic Token::Value KeywordOrIdentifierToken(const char* input,
884589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                             int input_length,
8853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                             bool harmony_scoping,
8863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                             bool harmony_modules) {
887589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  ASSERT(input_length >= 1);
888589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  const int kMinLength = 2;
889589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  const int kMaxLength = 10;
890589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (input_length < kMinLength || input_length > kMaxLength) {
891589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    return Token::IDENTIFIER;
892b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
893589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  switch (input[0]) {
894589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    default:
895589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#define KEYWORD_GROUP_CASE(ch)                                \
896589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      break;                                                  \
897589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    case ch:
898589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch#define KEYWORD(keyword, token)                               \
899589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    {                                                         \
900589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      /* 'keyword' is a char array, so sizeof(keyword) is */  \
901589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      /* strlen(keyword) plus 1 for the NUL char. */          \
902589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      const int keyword_length = sizeof(keyword) - 1;         \
903589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      STATIC_ASSERT(keyword_length >= kMinLength);            \
904589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      STATIC_ASSERT(keyword_length <= kMaxLength);            \
905589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      if (input_length == keyword_length &&                   \
906589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          input[1] == keyword[1] &&                           \
907589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          (keyword_length <= 2 || input[2] == keyword[2]) &&  \
908589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          (keyword_length <= 3 || input[3] == keyword[3]) &&  \
909589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          (keyword_length <= 4 || input[4] == keyword[4]) &&  \
910589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          (keyword_length <= 5 || input[5] == keyword[5]) &&  \
911589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          (keyword_length <= 6 || input[6] == keyword[6]) &&  \
912589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          (keyword_length <= 7 || input[7] == keyword[7]) &&  \
913589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          (keyword_length <= 8 || input[8] == keyword[8]) &&  \
914589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          (keyword_length <= 9 || input[9] == keyword[9])) {  \
915589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        return token;                                         \
916589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      }                                                       \
917589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
918589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    KEYWORDS(KEYWORD_GROUP_CASE, KEYWORD)
919589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
920589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return Token::IDENTIFIER;
921b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
922b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
923b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
9243ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochToken::Value Scanner::ScanIdentifierOrKeyword() {
925589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  ASSERT(unicode_cache_->IsIdentifierStart(c0_));
926589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  LiteralScope literal(this);
927589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Scan identifier start character.
928589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (c0_ == '\\') {
929589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    uc32 c = ScanIdentifierUnicodeEscape();
930589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // Only allow legal identifier start characters.
931589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (c < 0 ||
932589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        c == '\\' ||  // No recursive escapes.
933589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        !unicode_cache_->IsIdentifierStart(c)) {
934589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      return Token::ILLEGAL;
935589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
936589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    AddLiteralChar(c);
937589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    return ScanIdentifierSuffix(&literal);
938b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
939589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
940589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  uc32 first_char = c0_;
941589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Advance();
942589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  AddLiteralChar(first_char);
943589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
944589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Scan the rest of the identifier characters.
945589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  while (unicode_cache_->IsIdentifierPart(c0_)) {
946589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (c0_ != '\\') {
947589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      uc32 next_char = c0_;
948589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      Advance();
949589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      AddLiteralChar(next_char);
950589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      continue;
951589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
952589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // Fallthrough if no longer able to complete keyword.
953589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    return ScanIdentifierSuffix(&literal);
954b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
955589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
956589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  literal.Complete();
957589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
958589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (next_.literal_chars->is_ascii()) {
959589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    Vector<const char> chars = next_.literal_chars->ascii_literal();
960589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    return KeywordOrIdentifierToken(chars.start(),
961589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                    chars.length(),
9623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    harmony_scoping_,
9633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    harmony_modules_);
964589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
965589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
966589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return Token::IDENTIFIER;
967b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
968b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
969b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
9703ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochToken::Value Scanner::ScanIdentifierSuffix(LiteralScope* literal) {
971589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Scan the rest of the identifier characters.
972589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  while (unicode_cache_->IsIdentifierPart(c0_)) {
973589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (c0_ == '\\') {
974589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      uc32 c = ScanIdentifierUnicodeEscape();
975589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // Only allow legal identifier part characters.
976589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      if (c < 0 ||
977589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          c == '\\' ||
978589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          !unicode_cache_->IsIdentifierPart(c)) {
979589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        return Token::ILLEGAL;
980589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      }
981589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      AddLiteralChar(c);
982589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    } else {
983589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      AddLiteralChar(c0_);
984589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      Advance();
985589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
986589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
987589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  literal->Complete();
988589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
989589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return Token::IDENTIFIER;
990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool Scanner::ScanRegExpPattern(bool seen_equal) {
994589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Scan: ('/' | '/=') RegularExpressionBody '/' RegularExpressionFlags
995589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  bool in_character_class = false;
99680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
997589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Previous token is either '/' or '/=', in the second case, the
998589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // pattern starts at =.
999589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  next_.location.beg_pos = source_pos() - (seen_equal ? 2 : 1);
1000589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  next_.location.end_pos = source_pos() - (seen_equal ? 1 : 0);
1001589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1002589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Scan regular expression body: According to ECMA-262, 3rd, 7.8.5,
1003589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // the scanner should pass uninterpreted bodies to the RegExp
1004589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // constructor.
1005589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  LiteralScope literal(this);
1006589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (seen_equal) {
1007589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    AddLiteralChar('=');
1008589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
1009589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1010589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  while (c0_ != '/' || in_character_class) {
1011589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (unicode_cache_->IsLineTerminator(c0_) || c0_ < 0) return false;
1012589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (c0_ == '\\') {  // Escape sequence.
1013589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      AddLiteralCharAdvance();
1014589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      if (unicode_cache_->IsLineTerminator(c0_) || c0_ < 0) return false;
1015589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      AddLiteralCharAdvance();
1016589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // If the escape allows more characters, i.e., \x??, \u????, or \c?,
1017589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // only "safe" characters are allowed (letters, digits, underscore),
1018589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // otherwise the escape isn't valid and the invalid character has
1019589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // its normal meaning. I.e., we can just continue scanning without
1020589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // worrying whether the following characters are part of the escape
1021589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // or not, since any '/', '\\' or '[' is guaranteed to not be part
1022589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // of the escape sequence.
1023589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1024589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // TODO(896): At some point, parse RegExps more throughly to capture
1025589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // octal esacpes in strict mode.
1026589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    } else {  // Unescaped character.
1027589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      if (c0_ == '[') in_character_class = true;
1028589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      if (c0_ == ']') in_character_class = false;
1029589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      AddLiteralCharAdvance();
1030589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
1031589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
1032589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Advance();  // consume '/'
1033589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1034589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  literal.Complete();
1035589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1036589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return true;
103780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}
103880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
103980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
10403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool Scanner::ScanLiteralUnicodeEscape() {
1041589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  ASSERT(c0_ == '\\');
1042589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  uc32 chars_read[6] = {'\\', 'u', 0, 0, 0, 0};
1043589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Advance();
1044589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  int i = 1;
1045589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (c0_ == 'u') {
1046589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    i++;
1047589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    while (i < 6) {
1048589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      Advance();
1049589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      if (!IsHexDigit(c0_)) break;
1050589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      chars_read[i] = c0_;
1051589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      i++;
1052589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
1053589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
1054589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (i < 6) {
1055589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // Incomplete escape. Undo all advances and return false.
1056589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    while (i > 0) {
1057589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      i--;
1058589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      PushBack(chars_read[i]);
1059589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
1060589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    return false;
1061589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
1062589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Complete escape. Add all chars to current literal buffer.
1063589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  for (int i = 0; i < 6; i++) {
1064589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    AddLiteralChar(chars_read[i]);
1065589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
1066589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return true;
106780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}
106880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
106980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
10703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool Scanner::ScanRegExpFlags() {
1071589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Scan regular expression flags.
1072589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  LiteralScope literal(this);
1073589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  while (unicode_cache_->IsIdentifierPart(c0_)) {
1074589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (c0_ != '\\') {
1075589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      AddLiteralCharAdvance();
1076589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    } else {
1077589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      if (!ScanLiteralUnicodeEscape()) {
1078589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        break;
1079589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      }
1080589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
1081589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
1082589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  literal.Complete();
1083589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1084589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  next_.location.end_pos = source_pos() - 1;
1085589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return true;
108680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen}
108780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
1088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
1089