1ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
2fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// Redistribution and use in source and binary forms, with or without
3fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// modification, are permitted provided that the following conditions are
4fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// met:
5fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org//
6fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org//     * Redistributions of source code must retain the above copyright
7fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org//       notice, this list of conditions and the following disclaimer.
8fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org//     * Redistributions in binary form must reproduce the above
9fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org//       copyright notice, this list of conditions and the following
10fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org//       disclaimer in the documentation and/or other materials provided
11fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org//       with the distribution.
12fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org//     * Neither the name of Google Inc. nor the names of its
13fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org//       contributors may be used to endorse or promote products derived
14fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org//       from this software without specific prior written permission.
15fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org//
16fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org
28fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org#ifndef V8_PREPARSER_H
29fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org#define V8_PREPARSER_H
30fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org
31ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org#include "hashmap.h"
3255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org#include "token.h"
3355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org#include "scanner.h"
3455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
35fa943b736b1d996084393011529d568165bb5d83lrn@chromium.orgnamespace v8 {
3655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.orgnamespace internal {
37dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org
38a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org// Common base class shared between parser and pre-parser.
39a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.orgclass ParserBase {
40a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org public:
41a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  ParserBase(Scanner* scanner, uintptr_t stack_limit)
42a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      : scanner_(scanner),
43a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org        stack_limit_(stack_limit),
44a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org        stack_overflow_(false),
45a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org        allow_lazy_(false),
46a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org        allow_natives_syntax_(false),
47a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org        allow_generators_(false),
48a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org        allow_for_of_(false) { }
49a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  // TODO(mstarzinger): Only virtual until message reporting has been unified.
50a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  virtual ~ParserBase() { }
51a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
52a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  // Getters that indicate whether certain syntactical constructs are
53a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  // allowed to be parsed by this instance of the parser.
54a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  bool allow_lazy() const { return allow_lazy_; }
55a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  bool allow_natives_syntax() const { return allow_natives_syntax_; }
56a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  bool allow_generators() const { return allow_generators_; }
57a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  bool allow_for_of() const { return allow_for_of_; }
58a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  bool allow_modules() const { return scanner()->HarmonyModules(); }
59a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); }
60a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  bool allow_harmony_numeric_literals() const {
61a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    return scanner()->HarmonyNumericLiterals();
62a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  }
63a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
64a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  // Setters that determine whether certain syntactical constructs are
65a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  // allowed to be parsed by this instance of the parser.
66a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
67a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
68a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  void set_allow_generators(bool allow) { allow_generators_ = allow; }
69a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  void set_allow_for_of(bool allow) { allow_for_of_ = allow; }
70a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); }
71a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  void set_allow_harmony_scoping(bool allow) {
72a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    scanner()->SetHarmonyScoping(allow);
73a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  }
74a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  void set_allow_harmony_numeric_literals(bool allow) {
75a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    scanner()->SetHarmonyNumericLiterals(allow);
76a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  }
77a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
78a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org protected:
79a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  Scanner* scanner() const { return scanner_; }
80b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  int position() { return scanner_->location().beg_pos; }
81b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  int peek_position() { return scanner_->peek_location().beg_pos; }
82a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  bool stack_overflow() const { return stack_overflow_; }
83a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  void set_stack_overflow() { stack_overflow_ = true; }
84a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
85a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  INLINE(Token::Value peek()) {
86a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    if (stack_overflow_) return Token::ILLEGAL;
87a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    return scanner()->peek();
88a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  }
89a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
90a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  INLINE(Token::Value Next()) {
91a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    if (stack_overflow_) return Token::ILLEGAL;
92a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    {
93a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      int marker;
94a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      if (reinterpret_cast<uintptr_t>(&marker) < stack_limit_) {
95a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org        // Any further calls to Next or peek will return the illegal token.
96a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org        // The current call must return the next token, which might already
97a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org        // have been peek'ed.
98a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org        stack_overflow_ = true;
99a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      }
100a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    }
101a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    return scanner()->Next();
102a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  }
103a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
104a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  void Consume(Token::Value token) {
105a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    Token::Value next = Next();
106a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    USE(next);
107a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    USE(token);
108a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    ASSERT(next == token);
109a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  }
110a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
111a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  bool Check(Token::Value token) {
112a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    Token::Value next = peek();
113a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    if (next == token) {
114a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      Consume(next);
115a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      return true;
116a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    }
117a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    return false;
118a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  }
119a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
120a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  void Expect(Token::Value token, bool* ok) {
121a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    Token::Value next = Next();
122a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    if (next != token) {
123a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      ReportUnexpectedToken(next);
124a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      *ok = false;
125a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    }
126a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  }
127a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
128a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  bool peek_any_identifier();
129a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  void ExpectSemicolon(bool* ok);
130b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  bool CheckContextualKeyword(Vector<const char> keyword);
131b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  void ExpectContextualKeyword(Vector<const char> keyword, bool* ok);
132b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org
133b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  // Strict mode octal literal validation.
134b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok);
135b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org
136b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  // Determine precedence of given token.
137b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  static int Precedence(Token::Value token, bool accept_IN);
138a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
139a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  // Report syntax errors.
140a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  virtual void ReportUnexpectedToken(Token::Value token) = 0;
141b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  virtual void ReportMessageAt(Scanner::Location loc, const char* type) = 0;
142b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org
143b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  // Used to detect duplicates in object literals. Each of the values
144b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  // kGetterProperty, kSetterProperty and kValueProperty represents
145b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  // a type of object literal property. When parsing a property, its
146b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  // type value is stored in the DuplicateFinder for the property name.
147b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  // Values are chosen so that having intersection bits means the there is
148b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  // an incompatibility.
149b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  // I.e., you can add a getter to a property that already has a setter, since
150b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  // kGetterProperty and kSetterProperty doesn't intersect, but not if it
151b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  // already has a getter or a value. Adding the getter to an existing
152b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  // setter will store the value (kGetterProperty | kSetterProperty), which
153b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  // is incompatible with adding any further properties.
154b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  enum PropertyKind {
155b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    kNone = 0,
156b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    // Bit patterns representing different object literal property types.
157b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    kGetterProperty = 1,
158b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    kSetterProperty = 2,
159b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    kValueProperty = 7,
160b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    // Helper constants.
161b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    kValueFlag = 4
162b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  };
163b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org
164b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  // Validation per ECMA 262 - 11.1.5 "Object Initialiser".
165b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  class ObjectLiteralChecker {
166b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org   public:
167b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    ObjectLiteralChecker(ParserBase* parser, LanguageMode mode)
168b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org        : parser_(parser),
169b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org          finder_(scanner()->unicode_cache()),
170b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org          language_mode_(mode) { }
171b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org
172b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    void CheckProperty(Token::Value property, PropertyKind type, bool* ok);
173b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org
174b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org   private:
175b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    ParserBase* parser() const { return parser_; }
176b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    Scanner* scanner() const { return parser_->scanner(); }
177b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org
178b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    // Checks the type of conflict based on values coming from PropertyType.
179b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    bool HasConflict(PropertyKind type1, PropertyKind type2) {
180b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org      return (type1 & type2) != 0;
181b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    }
182b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    bool IsDataDataConflict(PropertyKind type1, PropertyKind type2) {
183b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org      return ((type1 & type2) & kValueFlag) != 0;
184b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    }
185b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    bool IsDataAccessorConflict(PropertyKind type1, PropertyKind type2) {
186b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org      return ((type1 ^ type2) & kValueFlag) != 0;
187b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    }
188b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    bool IsAccessorAccessorConflict(PropertyKind type1, PropertyKind type2) {
189b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org      return ((type1 | type2) & kValueFlag) == 0;
190b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    }
191b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org
192b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    ParserBase* parser_;
193b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    DuplicateFinder finder_;
194b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    LanguageMode language_mode_;
195b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  };
196a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
197a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org private:
198a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  Scanner* scanner_;
199a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  uintptr_t stack_limit_;
200a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  bool stack_overflow_;
201a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org
202a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  bool allow_lazy_;
203a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  bool allow_natives_syntax_;
204a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  bool allow_generators_;
205a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  bool allow_for_of_;
206a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org};
207fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org
20855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org
209fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// Preparsing checks a JavaScript program and emits preparse-data that helps
210fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// a later parsing to be faster.
2111c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org// See preparse-data-format.h for the data format.
212fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org
213fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// The PreParser checks that the syntax follows the grammar for JavaScript,
214fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// and collects some information about the program along the way.
215fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// The grammar check is only performed in order to understand the program
216fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// sufficiently to deduce some information about it, that can be used
217fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// to speed up later parsing. Finding errors is not the goal of pre-parsing,
218fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// rather it is to speed up properly written and correct programs.
219fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// That means that contextual checks (like a label being declared where
220fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// it is used) are generally omitted.
221a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.orgclass PreParser : public ParserBase {
222fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org public:
223a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  enum PreParseResult {
224a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    kPreParseStackOverflow,
225a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    kPreParseSuccess
226a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  };
227a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
228b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  PreParser(Scanner* scanner,
229b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org            ParserRecorder* log,
230e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org            uintptr_t stack_limit)
231a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      : ParserBase(scanner, stack_limit),
2321b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        log_(log),
2331b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        scope_(NULL),
234b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org        strict_mode_violation_location_(Scanner::Location::invalid()),
2351b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org        strict_mode_violation_type_(NULL),
236e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org        parenthesized_function_(false) { }
2371b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
23855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  ~PreParser() {}
239fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org
240fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  // Pre-parse the program from the character stream; returns true on
241fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  // success (even if parsing failed, the pre-parse data successfully
242fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  // captured the syntax error), and false if a stack-overflow happened
243fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  // during parsing.
244e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  PreParseResult PreParseProgram() {
245e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    Scope top_scope(&scope_, kTopLevelScope);
246e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    bool ok = true;
247a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    int start_position = scanner()->peek_location().beg_pos;
248b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    ParseSourceElements(Token::EOS, &ok);
249a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    if (stack_overflow()) return kPreParseStackOverflow;
250e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    if (!ok) {
251a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      ReportUnexpectedToken(scanner()->current_token());
252e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    } else if (!scope_->is_classic_mode()) {
253a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org      CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok);
254e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    }
255e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    return kPreParseSuccess;
256fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  }
257fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org
2581b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  // Parses a single function literal, from the opening parentheses before
2591b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  // parameters to the closing brace after the body.
260cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org  // Returns a FunctionEntry describing the body of the function in enough
2611b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  // detail that it can be lazily compiled.
262f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  // The scanner is expected to have matched the "function" or "function*"
263f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  // keyword and parameters, and have consumed the initial '{'.
264cddc71f18a46e6117cc765b1c53ca122e7aaa318rossberg@chromium.org  // At return, unless an error occurred, the scanner is positioned before the
2651b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  // the final '}'.
266b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  PreParseResult PreParseLazyFunction(LanguageMode mode,
267f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                                      bool is_generator,
268b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                                      ParserRecorder* log);
2691b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
270fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org private:
271ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // These types form an algebra over syntactic categories that is just
272ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // rich enough to let us recognize and propagate the constructs that
273ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // are either being counted in the preparser data, or is important
274ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // to throw the correct syntax error exceptions.
275ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
276fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  enum ScopeType {
277fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    kTopLevelScope,
278fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    kFunctionScope
279fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  };
280fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org
281b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  enum VariableDeclarationContext {
282b645116853c677aca8a316381b87441ba6004f67danno@chromium.org    kSourceElement,
283b645116853c677aca8a316381b87441ba6004f67danno@chromium.org    kStatement,
284b645116853c677aca8a316381b87441ba6004f67danno@chromium.org    kForStatement
285b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  };
286b645116853c677aca8a316381b87441ba6004f67danno@chromium.org
287394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // If a list of variable declarations includes any initializers.
288394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  enum VariableDeclarationProperties {
289394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    kHasInitializers,
290394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    kHasNoInitializers
291394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  };
292394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
293ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  class Expression;
294ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
295ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  class Identifier {
296ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org   public:
297ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    static Identifier Default() {
298ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      return Identifier(kUnknownIdentifier);
299ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    }
300ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    static Identifier Eval()  {
301ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      return Identifier(kEvalIdentifier);
302ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    }
303ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    static Identifier Arguments()  {
304ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      return Identifier(kArgumentsIdentifier);
305ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    }
306ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    static Identifier FutureReserved()  {
307ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      return Identifier(kFutureReservedIdentifier);
308ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    }
30904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    static Identifier FutureStrictReserved()  {
31004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      return Identifier(kFutureStrictReservedIdentifier);
31104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    }
312f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    static Identifier Yield()  {
313f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      return Identifier(kYieldIdentifier);
314f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    }
315ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    bool IsEval() { return type_ == kEvalIdentifier; }
316ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    bool IsArguments() { return type_ == kArgumentsIdentifier; }
317ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; }
318f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    bool IsYield() { return type_ == kYieldIdentifier; }
319ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; }
32004921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    bool IsFutureStrictReserved() {
32104921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      return type_ == kFutureStrictReservedIdentifier;
32204921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org    }
323ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; }
324e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org
325ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org   private:
326ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    enum Type {
327ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      kUnknownIdentifier,
328ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      kFutureReservedIdentifier,
32904921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org      kFutureStrictReservedIdentifier,
330f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      kYieldIdentifier,
331ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      kEvalIdentifier,
332ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      kArgumentsIdentifier
333ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    };
334ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    explicit Identifier(Type type) : type_(type) { }
335ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    Type type_;
336ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
337ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    friend class Expression;
338a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  };
339a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
340ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // Bits 0 and 1 are used to identify the type of expression:
341ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // If bit 0 is set, it's an identifier.
342ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // if bit 1 is set, it's a string literal.
343ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // If neither is set, it's no particular type, and both set isn't
344ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // use yet.
345ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // Bit 2 is used to mark the expression as being parenthesized,
346ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // so "(foo)" isn't recognized as a pure identifier (and possible label).
347ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  class Expression {
348ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org   public:
349ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    static Expression Default() {
350ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      return Expression(kUnknownExpression);
351ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    }
352ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
353ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    static Expression FromIdentifier(Identifier id) {
354ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      return Expression(kIdentifierFlag | (id.type_ << kIdentifierShift));
355ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    }
356ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
357ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    static Expression StringLiteral() {
358ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      return Expression(kUnknownStringLiteral);
359ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    }
360ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
361ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    static Expression UseStrictStringLiteral() {
362ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      return Expression(kUseStrictString);
363ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    }
364ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
365ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    static Expression This() {
366ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      return Expression(kThisExpression);
367ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    }
368ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
369ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    static Expression ThisProperty() {
370ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      return Expression(kThisPropertyExpression);
371ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    }
372ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
373ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    static Expression StrictFunction() {
374ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      return Expression(kStrictFunctionExpression);
375ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    }
376ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
377ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    bool IsIdentifier() {
378ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      return (code_ & kIdentifierFlag) != 0;
379ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    }
380ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
381ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    // Only works corretly if it is actually an identifier expression.
382ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    PreParser::Identifier AsIdentifier() {
383ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      return PreParser::Identifier(
384ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org          static_cast<PreParser::Identifier::Type>(code_ >> kIdentifierShift));
385ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    }
386ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
387ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    bool IsParenthesized() {
388ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      // If bit 0 or 1 is set, we interpret bit 2 as meaning parenthesized.
389ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      return (code_ & 7) > 4;
390ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    }
391ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
392ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    bool IsRawIdentifier() {
393ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      return !IsParenthesized() && IsIdentifier();
394ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    }
395ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
396ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; }
397ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
398ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    bool IsRawStringLiteral() {
399ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      return !IsParenthesized() && IsStringLiteral();
400ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    }
401ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
402ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    bool IsUseStrictLiteral() {
403ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      return (code_ & kStringLiteralMask) == kUseStrictString;
404ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    }
405ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
406ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    bool IsThis() {
407ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      return code_ == kThisExpression;
408ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    }
409ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
410ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    bool IsThisProperty() {
411ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      return code_ == kThisPropertyExpression;
412ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    }
413ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
414ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    bool IsStrictFunction() {
415ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      return code_ == kStrictFunctionExpression;
416ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    }
417ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
418ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    Expression Parenthesize() {
419ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      int type = code_ & 3;
420ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      if (type != 0) {
421ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org        // Identifiers and string literals can be parenthesized.
422ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org        // They no longer work as labels or directive prologues,
423ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org        // but are still recognized in other contexts.
424f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        return Expression(code_ | kParenthesizedExpressionFlag);
425ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      }
426ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      // For other types of expressions, it's not important to remember
427ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      // the parentheses.
428ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      return *this;
429ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    }
430ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
431ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org   private:
432ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    // First two/three bits are used as flags.
433ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    // Bit 0 and 1 represent identifiers or strings literals, and are
434ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    // mutually exclusive, but can both be absent.
435ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    // If bit 0 or 1 are set, bit 2 marks that the expression has
436ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    // been wrapped in parentheses (a string literal can no longer
437ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    // be a directive prologue, and an identifier can no longer be
438ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    // a label.
439ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    enum  {
440ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      kUnknownExpression = 0,
441ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      // Identifiers
442ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      kIdentifierFlag = 1,  // Used to detect labels.
443ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      kIdentifierShift = 3,
444ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
445ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      kStringLiteralFlag = 2,  // Used to detect directive prologue.
446ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      kUnknownStringLiteral = kStringLiteralFlag,
447ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      kUseStrictString = kStringLiteralFlag | 8,
448ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      kStringLiteralMask = kUseStrictString,
449ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
450f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      // Only if identifier or string literal.
451f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      kParenthesizedExpressionFlag = 4,
452ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
453ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      // Below here applies if neither identifier nor string literal.
454ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      kThisExpression = 4,
455ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      kThisPropertyExpression = 8,
456ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      kStrictFunctionExpression = 12
457ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    };
458ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
459ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    explicit Expression(int expression_code) : code_(expression_code) { }
460ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
461ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    int code_;
462a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  };
463a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
464ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  class Statement {
465ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org   public:
466ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    static Statement Default() {
467ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      return Statement(kUnknownStatement);
468ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    }
469ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
47040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    static Statement FunctionDeclaration() {
47140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org      return Statement(kFunctionDeclaration);
47240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    }
47340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org
474ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    // Creates expression statement from expression.
475ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    // Preserves being an unparenthesized string literal, possibly
476ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    // "use strict".
477ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    static Statement ExpressionStatement(Expression expression) {
478ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      if (!expression.IsParenthesized()) {
479ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org        if (expression.IsUseStrictLiteral()) {
480ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org          return Statement(kUseStrictExpressionStatement);
481ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org        }
482ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org        if (expression.IsStringLiteral()) {
483ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org          return Statement(kStringLiteralExpressionStatement);
484ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org        }
485ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      }
486ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      return Default();
487ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    }
488ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
489ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    bool IsStringLiteral() {
4902efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org      return code_ == kStringLiteralExpressionStatement;
491ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    }
492ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
493ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    bool IsUseStrictLiteral() {
494ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      return code_ == kUseStrictExpressionStatement;
495ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    }
496ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
49740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    bool IsFunctionDeclaration() {
49840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org      return code_ == kFunctionDeclaration;
49940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    }
50040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org
501ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org   private:
502ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    enum Type {
503ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      kUnknownStatement,
504ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org      kStringLiteralExpressionStatement,
50540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org      kUseStrictExpressionStatement,
50640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org      kFunctionDeclaration
507ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    };
508ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
509ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    explicit Statement(Type code) : code_(code) {}
510ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    Type code_;
511a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  };
512a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
513ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  enum SourceElements {
514ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org    kUnknownSourceElements
515a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  };
516a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
517a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  typedef int Arguments;
518a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
519fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  class Scope {
520fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org   public:
521fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    Scope(Scope** variable, ScopeType type)
522fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org        : variable_(variable),
523fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org          prev_(*variable),
524fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org          type_(type),
525fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org          materialized_literal_count_(0),
526fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org          expected_properties_(0),
5271c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org          with_nesting_count_(0),
5281b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org          language_mode_(
529b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org              (prev_ != NULL) ? prev_->language_mode() : CLASSIC_MODE),
530f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org          is_generator_(false) {
531fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org      *variable = this;
532fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    }
533fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    ~Scope() { *variable_ = prev_; }
534fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    void NextMaterializedLiteralIndex() { materialized_literal_count_++; }
535fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    void AddProperty() { expected_properties_++; }
536fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    ScopeType type() { return type_; }
537fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    int expected_properties() { return expected_properties_; }
538fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    int materialized_literal_count() { return materialized_literal_count_; }
539fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    bool IsInsideWith() { return with_nesting_count_ != 0; }
540f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    bool is_generator() { return is_generator_; }
541f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    void set_is_generator(bool is_generator) { is_generator_ = is_generator; }
5421b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    bool is_classic_mode() {
543b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org      return language_mode_ == CLASSIC_MODE;
5441b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    }
545b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    LanguageMode language_mode() {
5461b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      return language_mode_;
547394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    }
548b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    void set_language_mode(LanguageMode language_mode) {
5491b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org      language_mode_ = language_mode;
550394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    }
5512c26cb18967944507a81a07ac6f1c921ebb4ab75danno@chromium.org
5522c26cb18967944507a81a07ac6f1c921ebb4ab75danno@chromium.org    class InsideWith {
5532c26cb18967944507a81a07ac6f1c921ebb4ab75danno@chromium.org     public:
5542c26cb18967944507a81a07ac6f1c921ebb4ab75danno@chromium.org      explicit InsideWith(Scope* scope) : scope_(scope) {
5552c26cb18967944507a81a07ac6f1c921ebb4ab75danno@chromium.org        scope->with_nesting_count_++;
5562c26cb18967944507a81a07ac6f1c921ebb4ab75danno@chromium.org      }
5572c26cb18967944507a81a07ac6f1c921ebb4ab75danno@chromium.org
5582c26cb18967944507a81a07ac6f1c921ebb4ab75danno@chromium.org      ~InsideWith() { scope_->with_nesting_count_--; }
5592c26cb18967944507a81a07ac6f1c921ebb4ab75danno@chromium.org
5602c26cb18967944507a81a07ac6f1c921ebb4ab75danno@chromium.org     private:
5612c26cb18967944507a81a07ac6f1c921ebb4ab75danno@chromium.org      Scope* scope_;
5622c26cb18967944507a81a07ac6f1c921ebb4ab75danno@chromium.org      DISALLOW_COPY_AND_ASSIGN(InsideWith);
5632c26cb18967944507a81a07ac6f1c921ebb4ab75danno@chromium.org    };
564fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org
565fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org   private:
566fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    Scope** const variable_;
567fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    Scope* const prev_;
568fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    const ScopeType type_;
569fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    int materialized_literal_count_;
570fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    int expected_properties_;
571fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    int with_nesting_count_;
572b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    LanguageMode language_mode_;
573f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    bool is_generator_;
574fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  };
575fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org
576fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  // Report syntax error
577b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  void ReportUnexpectedToken(Token::Value token);
578b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  void ReportMessageAt(Scanner::Location location, const char* type) {
579b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    ReportMessageAt(location, type, NULL);
580b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  }
581b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  void ReportMessageAt(Scanner::Location location,
58255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org                       const char* type,
583b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                       const char* name_opt) {
58455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org    log_->LogMessage(location.beg_pos, location.end_pos, type, name_opt);
58555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org  }
586fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  void ReportMessageAt(int start_pos,
587fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org                       int end_pos,
588fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org                       const char* type,
589fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org                       const char* name_opt) {
590fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org    log_->LogMessage(start_pos, end_pos, type, name_opt);
591fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  }
592fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org
593fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  // All ParseXXX functions take as the last argument an *ok parameter
594fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  // which is set to false if parsing failed; it is unchanged otherwise.
595fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  // By making the 'exception handling' explicit, we are forced to check
596fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  // for failure at the call sites.
597b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  Statement ParseSourceElement(bool* ok);
598fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  SourceElements ParseSourceElements(int end_token, bool* ok);
599fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Statement ParseStatement(bool* ok);
600fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Statement ParseFunctionDeclaration(bool* ok);
601fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Statement ParseBlock(bool* ok);
602b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  Statement ParseVariableStatement(VariableDeclarationContext var_context,
603b645116853c677aca8a316381b87441ba6004f67danno@chromium.org                                   bool* ok);
604b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  Statement ParseVariableDeclarations(VariableDeclarationContext var_context,
605394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                      VariableDeclarationProperties* decl_props,
606b645116853c677aca8a316381b87441ba6004f67danno@chromium.org                                      int* num_decl,
607b645116853c677aca8a316381b87441ba6004f67danno@chromium.org                                      bool* ok);
608fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Statement ParseExpressionOrLabelledStatement(bool* ok);
609fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Statement ParseIfStatement(bool* ok);
610fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Statement ParseContinueStatement(bool* ok);
611fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Statement ParseBreakStatement(bool* ok);
612fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Statement ParseReturnStatement(bool* ok);
613fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Statement ParseWithStatement(bool* ok);
614fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Statement ParseSwitchStatement(bool* ok);
615fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Statement ParseDoWhileStatement(bool* ok);
616fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Statement ParseWhileStatement(bool* ok);
617fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Statement ParseForStatement(bool* ok);
618fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Statement ParseThrowStatement(bool* ok);
619fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Statement ParseTryStatement(bool* ok);
620fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Statement ParseDebuggerStatement(bool* ok);
621fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org
622fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Expression ParseExpression(bool accept_IN, bool* ok);
623fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Expression ParseAssignmentExpression(bool accept_IN, bool* ok);
624f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  Expression ParseYieldExpression(bool* ok);
625fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Expression ParseConditionalExpression(bool accept_IN, bool* ok);
626fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Expression ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
627fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Expression ParseUnaryExpression(bool* ok);
628fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Expression ParsePostfixExpression(bool* ok);
629fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Expression ParseLeftHandSideExpression(bool* ok);
630fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Expression ParseNewExpression(bool* ok);
631fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Expression ParseMemberExpression(bool* ok);
632f0ac72dfa39ec827de605aafc57d4834237aa7f3whesse@chromium.org  Expression ParseMemberWithNewPrefixesExpression(unsigned new_count, bool* ok);
633fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Expression ParsePrimaryExpression(bool* ok);
634fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Expression ParseArrayLiteral(bool* ok);
635fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Expression ParseObjectLiteral(bool* ok);
636fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Expression ParseRegExpLiteral(bool seen_equal, bool* ok);
637fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Expression ParseV8Intrinsic(bool* ok);
638fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org
639fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Arguments ParseArguments(bool* ok);
640f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  Expression ParseFunctionLiteral(bool is_generator, bool* ok);
6411b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  void ParseLazyFunctionLiteralBody(bool* ok);
642fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org
643fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Identifier ParseIdentifier(bool* ok);
644fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Identifier ParseIdentifierName(bool* ok);
64504921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org  Identifier ParseIdentifierNameOrGetOrSet(bool* is_get,
64604921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org                                           bool* is_set,
64704921a8093ce8bbec34084bd742b7aa3d299be15ager@chromium.org                                           bool* ok);
648fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org
6495d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  // Logs the currently parsed literal as a symbol in the preparser data.
6505d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  void LogSymbol();
6515d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  // Log the currently parsed identifier.
652fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Identifier GetIdentifierSymbol();
6535d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org  // Log the currently parsed string literal.
654fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Expression GetStringSymbol();
655fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org
656b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  void set_language_mode(LanguageMode language_mode) {
6571b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    scope_->set_language_mode(language_mode);
6581c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  }
6591c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
6601b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  bool is_classic_mode() {
661b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    return scope_->language_mode() == CLASSIC_MODE;
6621b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
6631b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
6641b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  bool is_extended_mode() {
665b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    return scope_->language_mode() == EXTENDED_MODE;
6661b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
6676e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.com
668b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  LanguageMode language_mode() { return scope_->language_mode(); }
6691c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
67041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  bool CheckInOrOf(bool accept_OF);
6711fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
672b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  void SetStrictModeViolation(Scanner::Location,
673ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org                              const char* type,
674f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com                              bool* ok);
675ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
676ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  void CheckDelayedStrictModeViolation(int beg_pos, int end_pos, bool* ok);
677ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
678b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  void StrictModeIdentifierViolation(Scanner::Location,
679ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org                                     const char* eval_args_type,
680ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org                                     Identifier identifier,
681ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org                                     bool* ok);
682ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
683b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  ParserRecorder* log_;
684fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Scope* scope_;
685b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  Scanner::Location strict_mode_violation_location_;
686ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  const char* strict_mode_violation_type_;
687c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  bool parenthesized_function_;
688fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org};
689dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org
690a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org} }  // v8::internal
691fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org
692fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org#endif  // V8_PREPARSER_H
693