scanner.cc revision 80d68eab642096c1a48b6474d6ec33064b0ad1f5
1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2006-2008 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 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h" 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "ast.h" 316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "handles.h" 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "scanner.h" 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ---------------------------------------------------------------------------- 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Character predicates 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockunibrow::Predicate<IdentifierStart, 128> Scanner::kIsIdentifierStart; 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockunibrow::Predicate<IdentifierPart, 128> Scanner::kIsIdentifierPart; 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockunibrow::Predicate<unibrow::LineTerminator, 128> Scanner::kIsLineTerminator; 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockunibrow::Predicate<unibrow::WhiteSpace, 128> Scanner::kIsWhiteSpace; 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockStaticResource<Scanner::Utf8Decoder> Scanner::utf8_decoder_; 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ---------------------------------------------------------------------------- 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// UTF8Buffer 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian MonsenUTF8Buffer::UTF8Buffer() : buffer_(kInitialCapacity) { } 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian MonsenUTF8Buffer::~UTF8Buffer() {} 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid UTF8Buffer::AddCharSlow(uc32 c) { 6080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen ASSERT(static_cast<unsigned>(c) > unibrow::Utf8::kMaxOneByteChar); 6180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int length = unibrow::Utf8::Length(c); 6280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Vector<char> block = buffer_.AddBlock(length, '\0'); 6380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#ifdef DEBUG 6480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen int written_length = unibrow::Utf8::Encode(block.start(), c); 6580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen CHECK_EQ(length, written_length); 6680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#else 6780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen unibrow::Utf8::Encode(block.start(), c); 6880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen#endif 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ---------------------------------------------------------------------------- 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// UTF16Buffer 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockUTF16Buffer::UTF16Buffer() 776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block : pos_(0), end_(Scanner::kNoEndPosition) { } 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// CharacterStreamUTF16Buffer 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCharacterStreamUTF16Buffer::CharacterStreamUTF16Buffer() 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : pushback_buffer_(0), last_(0), stream_(NULL) { } 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CharacterStreamUTF16Buffer::Initialize(Handle<String> data, 866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block unibrow::CharacterStream* input, 876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int start_position, 886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int end_position) { 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stream_ = input; 906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (start_position > 0) { 916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block SeekForward(start_position); 926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block end_ = end_position != Scanner::kNoEndPosition ? end_position : kMaxInt; 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CharacterStreamUTF16Buffer::PushBack(uc32 ch) { 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pushback_buffer()->Add(last_); 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block last_ = ch; 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pos_--; 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockuc32 CharacterStreamUTF16Buffer::Advance() { 1056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(end_ != Scanner::kNoEndPosition); 1066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(end_ >= 0); 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // NOTE: It is of importance to Persian / Farsi resources that we do 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // *not* strip format control characters in the scanner; see 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // https://bugzilla.mozilla.org/show_bug.cgi?id=274152 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // So, even though ECMA-262, section 7.1, page 11, dictates that we 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // must remove Unicode format-control characters, we do not. This is 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // in line with how IE and SpiderMonkey handles it. 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!pushback_buffer()->is_empty()) { 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pos_++; 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return last_ = pushback_buffer()->RemoveLast(); 1186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else if (stream_->has_more() && pos_ < end_) { 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pos_++; 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 next = stream_->GetNext(); 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return last_ = next; 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Note: currently the following increment is necessary to avoid a 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // test-parser problem! 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pos_++; 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return last_ = static_cast<uc32>(-1); 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CharacterStreamUTF16Buffer::SeekForward(int pos) { 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pos_ = pos; 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(pushback_buffer()->is_empty()); 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stream_->Seek(pos); 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// ExternalStringUTF16Buffer 1396ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocktemplate <typename StringType, typename CharType> 1406ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockExternalStringUTF16Buffer<StringType, CharType>::ExternalStringUTF16Buffer() 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : raw_data_(NULL) { } 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1446ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocktemplate <typename StringType, typename CharType> 1456ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid ExternalStringUTF16Buffer<StringType, CharType>::Initialize( 1466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<StringType> data, 1476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int start_position, 1486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int end_position) { 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!data.is_null()); 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block raw_data_ = data->resource()->data(); 1516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(end_position <= data->length()); 1536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (start_position > 0) { 1546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block SeekForward(start_position); 1556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 1566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block end_ = 1576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block end_position != Scanner::kNoEndPosition ? end_position : data->length(); 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1616ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocktemplate <typename StringType, typename CharType> 1626ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockuc32 ExternalStringUTF16Buffer<StringType, CharType>::Advance() { 1636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (pos_ < end_) { 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return raw_data_[pos_++]; 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // note: currently the following increment is necessary to avoid a 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // test-parser problem! 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pos_++; 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return static_cast<uc32>(-1); 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1746ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocktemplate <typename StringType, typename CharType> 1756ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid ExternalStringUTF16Buffer<StringType, CharType>::PushBack(uc32 ch) { 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pos_--; 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(pos_ >= Scanner::kCharacterLookaheadBufferSize); 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(raw_data_[pos_ - Scanner::kCharacterLookaheadBufferSize] == ch); 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1826ded16be15dd865a9b21ea304d5273c8be299c87Steve Blocktemplate <typename StringType, typename CharType> 1836ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid ExternalStringUTF16Buffer<StringType, CharType>::SeekForward(int pos) { 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pos_ = pos; 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ---------------------------------------------------------------------------- 189d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Keyword Matcher 1909dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 191d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockKeywordMatcher::FirstState KeywordMatcher::first_states_[] = { 192d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block { "break", KEYWORD_PREFIX, Token::BREAK }, 193d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block { NULL, C, Token::ILLEGAL }, 194d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block { NULL, D, Token::ILLEGAL }, 195d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block { "else", KEYWORD_PREFIX, Token::ELSE }, 196d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block { NULL, F, Token::ILLEGAL }, 197d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block { NULL, UNMATCHABLE, Token::ILLEGAL }, 198d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block { NULL, UNMATCHABLE, Token::ILLEGAL }, 199d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block { NULL, I, Token::ILLEGAL }, 200d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block { NULL, UNMATCHABLE, Token::ILLEGAL }, 201d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block { NULL, UNMATCHABLE, Token::ILLEGAL }, 202d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block { NULL, UNMATCHABLE, Token::ILLEGAL }, 203d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block { NULL, UNMATCHABLE, Token::ILLEGAL }, 204d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block { NULL, N, Token::ILLEGAL }, 205d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block { NULL, UNMATCHABLE, Token::ILLEGAL }, 206d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block { NULL, UNMATCHABLE, Token::ILLEGAL }, 207d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block { NULL, UNMATCHABLE, Token::ILLEGAL }, 208d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block { "return", KEYWORD_PREFIX, Token::RETURN }, 209d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block { "switch", KEYWORD_PREFIX, Token::SWITCH }, 210d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block { NULL, T, Token::ILLEGAL }, 211d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block { NULL, UNMATCHABLE, Token::ILLEGAL }, 212d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block { NULL, V, Token::ILLEGAL }, 213d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block { NULL, W, Token::ILLEGAL } 214d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}; 215d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 216d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 217d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid KeywordMatcher::Step(uc32 input) { 218d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block switch (state_) { 219d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case INITIAL: { 220d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // matching the first character is the only state with significant fanout. 221d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Match only lower-case letters in range 'b'..'w'. 222d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block unsigned int offset = input - kFirstCharRangeMin; 223d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (offset < kFirstCharRangeLength) { 224d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block state_ = first_states_[offset].state; 225d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (state_ == KEYWORD_PREFIX) { 226d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block keyword_ = first_states_[offset].keyword; 227d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block counter_ = 1; 228d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block keyword_token_ = first_states_[offset].token; 229d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 230d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return; 231d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 232d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 233d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 234d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case KEYWORD_PREFIX: 235d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (keyword_[counter_] == input) { 236d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT_NE(input, '\0'); 237d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block counter_++; 238d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (keyword_[counter_] == '\0') { 239d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block state_ = KEYWORD_MATCHED; 240d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block token_ = keyword_token_; 241d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 242d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return; 243d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 244d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 245d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case KEYWORD_MATCHED: 246d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block token_ = Token::IDENTIFIER; 247d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 248d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case C: 249d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchState(input, 'a', CA)) return; 250d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchState(input, 'o', CO)) return; 251d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 252d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case CA: 253d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeywordStart(input, "case", 2, Token::CASE)) return; 254d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeywordStart(input, "catch", 2, Token::CATCH)) return; 255d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 256d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case CO: 257d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchState(input, 'n', CON)) return; 258d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 259d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case CON: 260d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeywordStart(input, "const", 3, Token::CONST)) return; 261d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeywordStart(input, "continue", 3, Token::CONTINUE)) return; 262d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 263d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case D: 264d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchState(input, 'e', DE)) return; 265d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeyword(input, 'o', KEYWORD_MATCHED, Token::DO)) return; 266d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 267d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case DE: 268d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeywordStart(input, "debugger", 2, Token::DEBUGGER)) return; 269d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeywordStart(input, "default", 2, Token::DEFAULT)) return; 270d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeywordStart(input, "delete", 2, Token::DELETE)) return; 271d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 272d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case F: 273d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeywordStart(input, "false", 1, Token::FALSE_LITERAL)) return; 274d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeywordStart(input, "finally", 1, Token::FINALLY)) return; 275d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeywordStart(input, "for", 1, Token::FOR)) return; 276d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeywordStart(input, "function", 1, Token::FUNCTION)) return; 277d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 278d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case I: 279d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeyword(input, 'f', KEYWORD_MATCHED, Token::IF)) return; 280d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeyword(input, 'n', IN, Token::IN)) return; 281d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 282d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case IN: 283d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block token_ = Token::IDENTIFIER; 284d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeywordStart(input, "instanceof", 2, Token::INSTANCEOF)) { 285d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return; 286d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 287d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 288d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case N: 289d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeywordStart(input, "native", 1, Token::NATIVE)) return; 290d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeywordStart(input, "new", 1, Token::NEW)) return; 291d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeywordStart(input, "null", 1, Token::NULL_LITERAL)) return; 292d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 293d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case T: 294d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchState(input, 'h', TH)) return; 295d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchState(input, 'r', TR)) return; 296d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeywordStart(input, "typeof", 1, Token::TYPEOF)) return; 297d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 298d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case TH: 299d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeywordStart(input, "this", 2, Token::THIS)) return; 300d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeywordStart(input, "throw", 2, Token::THROW)) return; 301d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 302d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case TR: 303d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeywordStart(input, "true", 2, Token::TRUE_LITERAL)) return; 304d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeyword(input, 'y', KEYWORD_MATCHED, Token::TRY)) return; 305d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 306d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case V: 307d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeywordStart(input, "var", 1, Token::VAR)) return; 308d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeywordStart(input, "void", 1, Token::VOID)) return; 309d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 310d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block case W: 311d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeywordStart(input, "while", 1, Token::WHILE)) return; 312d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (MatchKeywordStart(input, "with", 1, Token::WITH)) return; 313d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block break; 314d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block default: 315d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block UNREACHABLE(); 316d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 317d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // On fallthrough, it's a failure. 318d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block state_ = UNMATCHABLE; 319d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 320d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 321d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 32280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 32380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// ---------------------------------------------------------------------------- 32480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen// Scanner::LiteralScope 32580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 32680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian MonsenScanner::LiteralScope::LiteralScope(Scanner* self) 32780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen : scanner_(self), complete_(false) { 32880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen self->StartLiteral(); 32980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 33080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 33180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 33280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian MonsenScanner::LiteralScope::~LiteralScope() { 33380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (!complete_) scanner_->DropLiteral(); 33480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 33580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 33680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 33780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenvoid Scanner::LiteralScope::Complete() { 33880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen scanner_->TerminateLiteral(); 33980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen complete_ = true; 34080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 34180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 342d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// ---------------------------------------------------------------------------- 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Scanner 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3454515c472dc3e5ed2448a564600976759e569a0a8Leon ClarkeScanner::Scanner(ParserMode pre) 3469dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen : is_pre_parsing_(pre == PREPARSE), stack_overflow_(false) { } 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3496ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Scanner::Initialize(Handle<String> source, 3506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ParserLanguage language) { 3513bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Init(source, NULL, 0, source->length(), language); 3526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 3536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3556ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Scanner::Initialize(Handle<String> source, 3566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block unibrow::CharacterStream* stream, 3576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ParserLanguage language) { 3586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Init(source, stream, 0, kNoEndPosition, language); 3596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 3606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3626ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Scanner::Initialize(Handle<String> source, 3636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int start_position, 3646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int end_position, 3656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ParserLanguage language) { 3663bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch Init(source, NULL, start_position, end_position, language); 3676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 3686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3704515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkevoid Scanner::Init(Handle<String> source, 3714515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke unibrow::CharacterStream* stream, 3726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int start_position, 3736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int end_position, 3744515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke ParserLanguage language) { 3753bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch // Either initialize the scanner from a character stream or from a 3763bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch // string. 3773bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch ASSERT(source.is_null() || stream == NULL); 3783bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Initialize the source buffer. 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!source.is_null() && StringShape(*source).IsExternalTwoByte()) { 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block two_byte_string_buffer_.Initialize( 3826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<ExternalTwoByteString>::cast(source), 3836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block start_position, 3846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block end_position); 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source_ = &two_byte_string_buffer_; 3866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else if (!source.is_null() && StringShape(*source).IsExternalAscii()) { 3876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ascii_string_buffer_.Initialize( 3886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<ExternalAsciiString>::cast(source), 3896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block start_position, 3906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block end_position); 3916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block source_ = &ascii_string_buffer_; 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 3933bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch if (!source.is_null()) { 3943bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch safe_string_input_buffer_.Reset(source.location()); 3953bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch stream = &safe_string_input_buffer_; 3963bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch } 3976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block char_stream_buffer_.Initialize(source, 3986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block stream, 3996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block start_position, 4006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block end_position); 401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source_ = &char_stream_buffer_; 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4044515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke is_parsing_json_ = (language == JSON); 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set c0_ (one character ahead) 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(kCharacterLookaheadBufferSize == 1); 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 40980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Initialize current_ to not refer to a literal. 41080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen current_.literal_chars = Vector<const char>(); 41180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Reset literal buffer. 41280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen literal_buffer_.Reset(); 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Skip initial whitespace allowing HTML comment ends just like 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // after a newline and scan first token. 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block has_line_terminator_before_next_ = true; 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SkipWhiteSpace(); 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Scan(); 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockToken::Value Scanner::Next() { 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // BUG 1215673: Find a thread safe way to set a stack limit in 424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // pre-parse mode. Otherwise, we cannot safely pre-parse from other 425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // threads. 426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block current_ = next_; 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check for stack-overflow before returning any tokens. 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackLimitCheck check; 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (check.HasOverflowed()) { 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stack_overflow_ = true; 431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block next_.token = Token::ILLEGAL; 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Scan(); 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return current_.token; 436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Scanner::StartLiteral() { 44080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen literal_buffer_.StartLiteral(); 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Scanner::AddChar(uc32 c) { 44580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen literal_buffer_.AddChar(c); 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Scanner::TerminateLiteral() { 45080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen next_.literal_chars = literal_buffer_.EndLiteral(); 45180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen} 45280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 45380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 45480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenvoid Scanner::DropLiteral() { 45580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen literal_buffer_.DropLiteral(); 456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Scanner::AddCharAdvance() { 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AddChar(c0_); 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline bool IsByteOrderMark(uc32 c) { 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The Unicode value U+FFFE is guaranteed never to be assigned as a 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Unicode character; this implies that in a Unicode context the 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 0xFF, 0xFE byte pattern can only be interpreted as the U+FEFF 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // character expressed in little-endian byte order (since it could 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // not be a U+FFFE character expressed in big-endian byte 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // order). Nevertheless, we check for it to be compatible with 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Spidermonkey. 473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return c == 0xFEFF || c == 0xFFFE; 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4774515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkebool Scanner::SkipJsonWhiteSpace() { 4784515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke int start_position = source_pos(); 4794515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // JSON WhiteSpace is tab, carrige-return, newline and space. 4804515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke while (c0_ == ' ' || c0_ == '\n' || c0_ == '\r' || c0_ == '\t') { 4814515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Advance(); 4824515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 4834515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke return source_pos() != start_position; 4844515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 4854515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 4864515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 4874515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkebool Scanner::SkipJavaScriptWhiteSpace() { 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int start_position = source_pos(); 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (true) { 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // We treat byte-order marks (BOMs) as whitespace for better 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // compatibility with Spidermonkey and other JavaScript engines. 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (kIsWhiteSpace.get(c0_) || IsByteOrderMark(c0_)) { 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // IsWhiteSpace() includes line terminators! 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (kIsLineTerminator.get(c0_)) { 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Ignore line terminators, but remember them. This is necessary 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // for automatic semicolon insertion. 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block has_line_terminator_before_next_ = true; 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If there is an HTML comment end '-->' at the beginning of a 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // line (with only whitespace in front of it), we treat the rest 505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // of the line as a comment. This is in line with the way 506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // SpiderMonkey handles it. 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == '-' && has_line_terminator_before_next_) { 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == '-') { 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == '>') { 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Treat the rest of the line as a comment. 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SkipSingleLineComment(); 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Continue skipping white space after the comment. 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PushBack('-'); // undo Advance() 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PushBack('-'); // undo Advance() 520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return whether or not we skipped any characters. 522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return source_pos() != start_position; 523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockToken::Value Scanner::SkipSingleLineComment() { 528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The line terminator at the end of the line is not considered 531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // to be part of the single-line comment; it is recognized 532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // separately by the lexical grammar and becomes part of the 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // stream of input elements for the syntactic grammar (see 534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ECMA-262, section 7.4, page 12). 535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (c0_ >= 0 && !kIsLineTerminator.get(c0_)) { 536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Token::WHITESPACE; 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockToken::Value Scanner::SkipMultiLineComment() { 544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(c0_ == '*'); 545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (c0_ >= 0) { 548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char ch = c0_; 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If we have reached the end of the multi-line comment, we 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // consume the '/' and insert a whitespace. This way all 552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // multi-line comments are treated as whitespace - even the ones 553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // containing line terminators. This contradicts ECMA-262, section 554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // 7.4, page 12, that says that multi-line comments containing 555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // line terminators should be treated as a line terminator, but it 556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // matches the behaviour of SpiderMonkey and KJS. 557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (ch == '*' && c0_ == '/') { 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block c0_ = ' '; 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Token::WHITESPACE; 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Unterminated multi-line comment. 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Token::ILLEGAL; 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockToken::Value Scanner::ScanHtmlComment() { 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check for <!-- comments. 570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(c0_ == '!'); 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == '-') { 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == '-') return SkipSingleLineComment(); 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PushBack('-'); // undo Advance() 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PushBack('!'); // undo Advance() 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(c0_ == '!'); 579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Token::LT; 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5834515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 5844515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkevoid Scanner::ScanJson() { 58580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen next_.literal_chars = Vector<const char>(); 5864515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Token::Value token; 5874515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke has_line_terminator_before_next_ = false; 5884515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke do { 5894515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // Remember the position of the next token 5904515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke next_.location.beg_pos = source_pos(); 5914515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke switch (c0_) { 5924515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case '\t': 5934515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case '\r': 5944515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case '\n': 5954515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case ' ': 5964515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Advance(); 5974515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke token = Token::WHITESPACE; 5984515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke break; 5994515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case '{': 6004515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Advance(); 6014515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke token = Token::LBRACE; 6024515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke break; 6034515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case '}': 6044515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Advance(); 6054515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke token = Token::RBRACE; 6064515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke break; 6074515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case '[': 6084515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Advance(); 6094515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke token = Token::LBRACK; 6104515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke break; 6114515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case ']': 6124515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Advance(); 6134515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke token = Token::RBRACK; 6144515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke break; 6154515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case ':': 6164515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Advance(); 6174515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke token = Token::COLON; 6184515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke break; 6194515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case ',': 6204515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Advance(); 6214515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke token = Token::COMMA; 6224515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke break; 6234515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case '"': 6244515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke token = ScanJsonString(); 6254515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke break; 6264515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case '-': 6274515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case '0': 6284515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case '1': 6294515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case '2': 6304515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case '3': 6314515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case '4': 6324515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case '5': 6334515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case '6': 6344515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case '7': 6354515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case '8': 6364515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case '9': 6374515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke token = ScanJsonNumber(); 6384515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke break; 6394515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case 't': 6404515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke token = ScanJsonIdentifier("true", Token::TRUE_LITERAL); 6414515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke break; 6424515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case 'f': 6434515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke token = ScanJsonIdentifier("false", Token::FALSE_LITERAL); 6444515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke break; 6454515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case 'n': 6464515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke token = ScanJsonIdentifier("null", Token::NULL_LITERAL); 6474515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke break; 6484515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke default: 6494515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if (c0_ < 0) { 6504515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Advance(); 6514515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke token = Token::EOS; 6524515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } else { 6534515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Advance(); 6544515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke token = Select(Token::ILLEGAL); 6554515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 6564515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 6574515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } while (token == Token::WHITESPACE); 6584515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 6594515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke next_.location.end_pos = source_pos(); 6604515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke next_.token = token; 6614515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 6624515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 6634515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 6644515c472dc3e5ed2448a564600976759e569a0a8Leon ClarkeToken::Value Scanner::ScanJsonString() { 6654515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke ASSERT_EQ('"', c0_); 6664515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Advance(); 66780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen LiteralScope literal(this); 6684515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke while (c0_ != '"' && c0_ > 0) { 6694515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // Check for control character (0x00-0x1f) or unterminated string (<0). 6704515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if (c0_ < 0x20) return Token::ILLEGAL; 6714515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if (c0_ != '\\') { 6724515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke AddCharAdvance(); 6734515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } else { 6744515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Advance(); 6754515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke switch (c0_) { 6764515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case '"': 6774515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case '\\': 6784515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case '/': 6794515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke AddChar(c0_); 6804515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke break; 6814515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case 'b': 6824515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke AddChar('\x08'); 6834515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke break; 6844515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case 'f': 6854515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke AddChar('\x0c'); 6864515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke break; 6874515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case 'n': 6884515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke AddChar('\x0a'); 6894515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke break; 6904515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case 'r': 6914515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke AddChar('\x0d'); 6924515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke break; 6934515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case 't': 6944515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke AddChar('\x09'); 6954515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke break; 6964515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke case 'u': { 6974515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke uc32 value = 0; 6984515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke for (int i = 0; i < 4; i++) { 6994515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Advance(); 7004515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke int digit = HexValue(c0_); 70180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (digit < 0) { 70280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen return Token::ILLEGAL; 70380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 7044515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke value = value * 16 + digit; 7054515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 7064515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke AddChar(value); 7074515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke break; 7084515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 7094515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke default: 7104515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke return Token::ILLEGAL; 7114515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 7124515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Advance(); 7134515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 7144515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 7154515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if (c0_ != '"') { 7164515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke return Token::ILLEGAL; 7174515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 71880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen literal.Complete(); 7194515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Advance(); 7204515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke return Token::STRING; 7214515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 7224515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 7234515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 7244515c472dc3e5ed2448a564600976759e569a0a8Leon ClarkeToken::Value Scanner::ScanJsonNumber() { 72580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen LiteralScope literal(this); 7264515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if (c0_ == '-') AddCharAdvance(); 7274515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if (c0_ == '0') { 7284515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke AddCharAdvance(); 7294515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // Prefix zero is only allowed if it's the only digit before 7304515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // a decimal point or exponent. 7314515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if ('0' <= c0_ && c0_ <= '9') return Token::ILLEGAL; 7324515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } else { 7334515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if (c0_ < '1' || c0_ > '9') return Token::ILLEGAL; 7344515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke do { 7354515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke AddCharAdvance(); 7364515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } while (c0_ >= '0' && c0_ <= '9'); 7374515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 7384515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if (c0_ == '.') { 7394515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke AddCharAdvance(); 7404515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if (c0_ < '0' || c0_ > '9') return Token::ILLEGAL; 7414515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke do { 7424515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke AddCharAdvance(); 7434515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } while (c0_ >= '0' && c0_ <= '9'); 7444515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 7454515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if ((c0_ | 0x20) == 'e') { 7464515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke AddCharAdvance(); 7474515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if (c0_ == '-' || c0_ == '+') AddCharAdvance(); 7484515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if (c0_ < '0' || c0_ > '9') return Token::ILLEGAL; 7494515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke do { 7504515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke AddCharAdvance(); 7514515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } while (c0_ >= '0' && c0_ <= '9'); 7524515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 75380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen literal.Complete(); 7544515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke return Token::NUMBER; 7554515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 7564515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 7574515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 7584515c472dc3e5ed2448a564600976759e569a0a8Leon ClarkeToken::Value Scanner::ScanJsonIdentifier(const char* text, 7594515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Token::Value token) { 76080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen LiteralScope literal(this); 7614515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke while (*text != '\0') { 7624515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if (c0_ != *text) return Token::ILLEGAL; 7634515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke Advance(); 7644515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke text++; 7654515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 7664515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke if (kIsIdentifierPart.get(c0_)) return Token::ILLEGAL; 76780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen literal.Complete(); 7684515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke return token; 7694515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 7704515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 7714515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 7724515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkevoid Scanner::ScanJavaScript() { 77380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen next_.literal_chars = Vector<const char>(); 774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Token::Value token; 775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block has_line_terminator_before_next_ = false; 776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { 777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Remember the position of the next token 778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block next_.location.beg_pos = source_pos(); 779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (c0_) { 781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case ' ': 782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '\t': 783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Token::WHITESPACE; 785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '\n': 788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block has_line_terminator_before_next_ = true; 790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Token::WHITESPACE; 791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '"': case '\'': 794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = ScanString(); 795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '<': 798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // < <= << <<= <!-- 799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == '=') { 801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select(Token::LTE); 802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (c0_ == '<') { 803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select('=', Token::ASSIGN_SHL, Token::SHL); 804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (c0_ == '!') { 805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = ScanHtmlComment(); 806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Token::LT; 808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '>': 812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // > >= >> >>= >>> >>>= 813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == '=') { 815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select(Token::GTE); 816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (c0_ == '>') { 817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // >> >>= >>> >>>= 818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == '=') { 820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select(Token::ASSIGN_SAR); 821a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (c0_ == '>') { 822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select('=', Token::ASSIGN_SHR, Token::SHR); 823a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Token::SAR; 825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Token::GT; 828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '=': 832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // = == === 833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == '=') { 835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select('=', Token::EQ_STRICT, Token::EQ); 836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Token::ASSIGN; 838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '!': 842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ! != !== 843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == '=') { 845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select('=', Token::NE_STRICT, Token::NE); 846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Token::NOT; 848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '+': 852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // + ++ += 853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == '+') { 855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select(Token::INC); 856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (c0_ == '=') { 857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select(Token::ASSIGN_ADD); 858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Token::ADD; 860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '-': 864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // - -- --> -= 865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == '-') { 867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == '>' && has_line_terminator_before_next_) { 869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // For compatibility with SpiderMonkey, we skip lines that 870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // start with an HTML comment end '-->'. 871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = SkipSingleLineComment(); 872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Token::DEC; 874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (c0_ == '=') { 876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select(Token::ASSIGN_SUB); 877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Token::SUB; 879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '*': 883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // * *= 884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select('=', Token::ASSIGN_MUL, Token::MUL); 885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '%': 888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // % %= 889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select('=', Token::ASSIGN_MOD, Token::MOD); 890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '/': 893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // / // /* /= 894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == '/') { 896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = SkipSingleLineComment(); 897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (c0_ == '*') { 898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = SkipMultiLineComment(); 899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (c0_ == '=') { 900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select(Token::ASSIGN_DIV); 901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Token::DIV; 903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '&': 907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // & && &= 908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == '&') { 910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select(Token::AND); 911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (c0_ == '=') { 912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select(Token::ASSIGN_BIT_AND); 913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Token::BIT_AND; 915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '|': 919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // | || |= 920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == '|') { 922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select(Token::OR); 923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (c0_ == '=') { 924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select(Token::ASSIGN_BIT_OR); 925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Token::BIT_OR; 927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '^': 931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ^ ^= 932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select('=', Token::ASSIGN_BIT_XOR, Token::BIT_XOR); 933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '.': 936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // . Number 937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsDecimalDigit(c0_)) { 939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = ScanNumber(true); 940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Token::PERIOD; 942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case ':': 946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select(Token::COLON); 947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case ';': 950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select(Token::SEMICOLON); 951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case ',': 954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select(Token::COMMA); 955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '(': 958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select(Token::LPAREN); 959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case ')': 962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select(Token::RPAREN); 963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '[': 966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select(Token::LBRACK); 967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case ']': 970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select(Token::RBRACK); 971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '{': 974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select(Token::LBRACE); 975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '}': 978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select(Token::RBRACE); 979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '?': 982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select(Token::CONDITIONAL); 983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '~': 986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select(Token::BIT_NOT); 987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: 990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (kIsIdentifierStart.get(c0_)) { 991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = ScanIdentifier(); 992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (IsDecimalDigit(c0_)) { 993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = ScanNumber(false); 994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (SkipWhiteSpace()) { 995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Token::WHITESPACE; 996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (c0_ < 0) { 997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Token::EOS; 998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block token = Select(Token::ILLEGAL); 1000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 1002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Continue scanning for tokens as long as we're just skipping 1005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // whitespace. 1006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (token == Token::WHITESPACE); 1007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block next_.location.end_pos = source_pos(); 1009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block next_.token = token; 1010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Scanner::SeekForward(int pos) { 1014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block source_->SeekForward(pos - 1); 1015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 1016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Scan(); 1017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockuc32 Scanner::ScanHexEscape(uc32 c, int length) { 1021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(length <= 4); // prevent overflow 1022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 digits[4]; 1024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 x = 0; 1025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < length; i++) { 1026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block digits[i] = c0_; 1027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int d = HexValue(c0_); 1028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (d < 0) { 1029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // According to ECMA-262, 3rd, 7.8.4, page 18, these hex escapes 1030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // should be illegal, but other JS VMs just return the 1031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // non-escaped version of the original character. 1032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Push back digits read, except the last one (in c0_). 1034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int j = i-1; j >= 0; j--) { 1035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PushBack(digits[j]); 1036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Notice: No handling of error - treat it as "\u"->"u". 1038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return c; 1039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block x = x * 16 + d; 1041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 1042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return x; 1045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Octal escapes of the forms '\0xx' and '\xxx' are not a part of 1049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262. Other JS VMs support them. 1050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockuc32 Scanner::ScanOctalEscape(uc32 c, int length) { 1051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 x = c - '0'; 1052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < length; i++) { 1053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int d = c0_ - '0'; 1054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (d < 0 || d > 7) break; 1055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int nx = x * 8 + d; 1056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (nx >= 256) break; 1057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block x = nx; 1058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 1059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return x; 1061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Scanner::ScanEscape() { 1065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 c = c0_; 1066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 1067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Skip escaped newlines. 1069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (kIsLineTerminator.get(c)) { 1070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Allow CR+LF newlines in multiline string literals. 1071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsCarriageReturn(c) && IsLineFeed(c0_)) Advance(); 1072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Allow LF+CR newlines in multiline string literals. 1073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsLineFeed(c) && IsCarriageReturn(c0_)) Advance(); 1074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 1075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (c) { 1078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '\'': // fall through 1079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '"' : // fall through 1080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '\\': break; 1081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'b' : c = '\b'; break; 1082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'f' : c = '\f'; break; 1083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'n' : c = '\n'; break; 1084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'r' : c = '\r'; break; 1085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 't' : c = '\t'; break; 1086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'u' : c = ScanHexEscape(c, 4); break; 1087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'v' : c = '\v'; break; 1088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'x' : c = ScanHexEscape(c, 2); break; 1089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '0' : // fall through 1090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '1' : // fall through 1091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '2' : // fall through 1092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '3' : // fall through 1093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '4' : // fall through 1094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '5' : // fall through 1095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '6' : // fall through 1096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '7' : c = ScanOctalEscape(c, 2); break; 1097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // According to ECMA-262, 3rd, 7.8.4 (p 18ff) these 1100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // should be illegal, but they are commonly handled 1101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // as non-escaped characters by JS VMs. 1102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AddChar(c); 1103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockToken::Value Scanner::ScanString() { 1107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 quote = c0_; 1108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); // consume quote 1109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 111080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen LiteralScope literal(this); 1111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (c0_ != quote && c0_ >= 0 && !kIsLineTerminator.get(c0_)) { 1112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 c = c0_; 1113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c == '\\') { 1115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ < 0) return Token::ILLEGAL; 1116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScanEscape(); 1117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AddChar(c); 1119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 112180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (c0_ != quote) return Token::ILLEGAL; 112280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen literal.Complete(); 1123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); // consume quote 1125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Token::STRING; 1126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockToken::Value Scanner::Select(Token::Value tok) { 1130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 1131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return tok; 1132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockToken::Value Scanner::Select(uc32 next, Token::Value then, Token::Value else_) { 1136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 1137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == next) { 1138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 1139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return then; 1140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return else_; 1142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Returns true if any decimal digits were scanned, returns false otherwise. 1147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Scanner::ScanDecimalDigits() { 1148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (IsDecimalDigit(c0_)) 1149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AddCharAdvance(); 1150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockToken::Value Scanner::ScanNumber(bool seen_period) { 1154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsDecimalDigit(c0_)); // the first digit of the number or the fraction 1155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum { DECIMAL, HEX, OCTAL } kind = DECIMAL; 1157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 115880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen LiteralScope literal(this); 1159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (seen_period) { 1160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // we have already seen a decimal point of the float 1161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AddChar('.'); 1162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScanDecimalDigits(); // we know we have at least one digit 1163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // if the first character is '0' we must check for octals and hex 1166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == '0') { 1167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AddCharAdvance(); 1168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // either 0, 0exxx, 0Exxx, 0.xxx, an octal number, or a hex number 1170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == 'x' || c0_ == 'X') { 1171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // hex number 1172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block kind = HEX; 1173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AddCharAdvance(); 117480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (!IsHexDigit(c0_)) { 1175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // we must have at least one hex digit after 'x'/'X' 1176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Token::ILLEGAL; 117780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 117880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen while (IsHexDigit(c0_)) { 1179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AddCharAdvance(); 118080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 1181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if ('0' <= c0_ && c0_ <= '7') { 1182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // (possible) octal number 1183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block kind = OCTAL; 1184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (true) { 1185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == '8' || c0_ == '9') { 1186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block kind = DECIMAL; 1187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 1188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ < '0' || '7' < c0_) break; 1190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AddCharAdvance(); 1191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Parse decimal digits and allow trailing fractional part. 1196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (kind == DECIMAL) { 1197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScanDecimalDigits(); // optional 1198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == '.') { 1199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AddCharAdvance(); 1200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScanDecimalDigits(); // optional 1201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // scan exponent, if any 1206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == 'e' || c0_ == 'E') { 1207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(kind != HEX); // 'e'/'E' must be scanned as part of the hex number 1208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (kind == OCTAL) return Token::ILLEGAL; // no exponent for octals allowed 1209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // scan exponent 1210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AddCharAdvance(); 1211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == '+' || c0_ == '-') 1212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AddCharAdvance(); 121380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (!IsDecimalDigit(c0_)) { 1214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // we must have at least one decimal digit after 'e'/'E' 1215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Token::ILLEGAL; 121680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 1217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ScanDecimalDigits(); 1218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The source character immediately following a numeric literal must 1221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // not be an identifier start or a decimal digit; see ECMA-262 1222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // section 7.8.3, page 17 (note that we read only one decimal digit 1223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // if the value is 0). 1224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsDecimalDigit(c0_) || kIsIdentifierStart.get(c0_)) 1225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Token::ILLEGAL; 1226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 122780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen literal.Complete(); 122880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen 1229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Token::NUMBER; 1230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockuc32 Scanner::ScanIdentifierUnicodeEscape() { 1234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 1235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ != 'u') return unibrow::Utf8::kBadChar; 1236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 1237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 c = ScanHexEscape('u', 4); 1238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // We do not allow a unicode escape sequence to start another 1239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // unicode escape sequence. 1240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c == '\\') return unibrow::Utf8::kBadChar; 1241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return c; 1242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockToken::Value Scanner::ScanIdentifier() { 1246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(kIsIdentifierStart.get(c0_)); 1247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 124880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen LiteralScope literal(this); 1249d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block KeywordMatcher keyword_match; 1250d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 1251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Scan identifier start character. 1252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == '\\') { 1253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 c = ScanIdentifierUnicodeEscape(); 1254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Only allow legal identifier start characters. 1255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!kIsIdentifierStart.get(c)) return Token::ILLEGAL; 1256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AddChar(c); 1257d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block keyword_match.Fail(); 1258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AddChar(c0_); 1260d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block keyword_match.AddChar(c0_); 1261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 1262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Scan the rest of the identifier characters. 1265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (kIsIdentifierPart.get(c0_)) { 1266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == '\\') { 1267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 c = ScanIdentifierUnicodeEscape(); 1268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Only allow legal identifier part characters. 1269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!kIsIdentifierPart.get(c)) return Token::ILLEGAL; 1270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AddChar(c); 1271d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block keyword_match.Fail(); 1272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AddChar(c0_); 1274d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block keyword_match.AddChar(c0_); 1275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); 1276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 127880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen literal.Complete(); 1279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1280d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block return keyword_match.token(); 1281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Scanner::IsIdentifier(unibrow::CharacterStream* buffer) { 1286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Checks whether the buffer contains an identifier (no escape). 1287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!buffer->has_more()) return false; 1288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!kIsIdentifierStart.get(buffer->GetNext())) return false; 1289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (buffer->has_more()) { 1290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!kIsIdentifierPart.get(buffer->GetNext())) return false; 1291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 1293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Scanner::ScanRegExpPattern(bool seen_equal) { 1297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Scan: ('/' | '/=') RegularExpressionBody '/' RegularExpressionFlags 1298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool in_character_class = false; 1299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Previous token is either '/' or '/=', in the second case, the 1301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // pattern starts at =. 1302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block next_.location.beg_pos = source_pos() - (seen_equal ? 2 : 1); 1303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block next_.location.end_pos = source_pos() - (seen_equal ? 1 : 0); 1304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Scan regular expression body: According to ECMA-262, 3rd, 7.8.5, 1306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the scanner should pass uninterpreted bodies to the RegExp 1307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // constructor. 130880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen LiteralScope literal(this); 1309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (seen_equal) 1310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AddChar('='); 1311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (c0_ != '/' || in_character_class) { 131380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (kIsLineTerminator.get(c0_) || c0_ < 0) return false; 1314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == '\\') { // escaped character 1315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AddCharAdvance(); 131680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (kIsLineTerminator.get(c0_) || c0_ < 0) return false; 1317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AddCharAdvance(); 1318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { // unescaped character 131980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (c0_ == '[') in_character_class = true; 132080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen if (c0_ == ']') in_character_class = false; 1321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AddCharAdvance(); 1322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Advance(); // consume '/' 1325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 132680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen literal.Complete(); 1327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 1329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Scanner::ScanRegExpFlags() { 1332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Scan regular expression flags. 133380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen LiteralScope literal(this); 1334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (kIsIdentifierPart.get(c0_)) { 1335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c0_ == '\\') { 1336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uc32 c = ScanIdentifierUnicodeEscape(); 1337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c != static_cast<uc32>(unibrow::Utf8::kBadChar)) { 1338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // We allow any escaped character, unlike the restriction on 1339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // IdentifierPart when it is used to build an IdentifierName. 1340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AddChar(c); 1341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; 1342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AddCharAdvance(); 1345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 134680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen literal.Complete(); 1347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block next_.location.end_pos = source_pos() - 1; 1349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 1350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 1353