Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(159)

Side by Side Diff: src/preparser.h

Issue 952243002: Implement experimental exponentiation operator via desugaring (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_PREPARSER_H 5 #ifndef V8_PREPARSER_H
6 #define V8_PREPARSER_H 6 #define V8_PREPARSER_H
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/bailout-reason.h" 10 #include "src/bailout-reason.h"
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 } 110 }
111 bool allow_harmony_templates() const { return scanner()->HarmonyTemplates(); } 111 bool allow_harmony_templates() const { return scanner()->HarmonyTemplates(); }
112 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; } 112 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; }
113 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); } 113 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); }
114 bool allow_harmony_computed_property_names() const { 114 bool allow_harmony_computed_property_names() const {
115 return allow_harmony_computed_property_names_; 115 return allow_harmony_computed_property_names_;
116 } 116 }
117 bool allow_harmony_rest_params() const { 117 bool allow_harmony_rest_params() const {
118 return allow_harmony_rest_params_; 118 return allow_harmony_rest_params_;
119 } 119 }
120 120 bool allow_harmony_exponentiation() const {
121 return scanner()->HarmonyExponentiation();
122 }
121 bool allow_strong_mode() const { return allow_strong_mode_; } 123 bool allow_strong_mode() const { return allow_strong_mode_; }
122 124
123 // Setters that determine whether certain syntactical constructs are 125 // Setters that determine whether certain syntactical constructs are
124 // allowed to be parsed by this instance of the parser. 126 // allowed to be parsed by this instance of the parser.
125 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } 127 void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
126 void set_allow_natives(bool allow) { allow_natives_ = allow; } 128 void set_allow_natives(bool allow) { allow_natives_ = allow; }
127 void set_allow_harmony_arrow_functions(bool allow) { 129 void set_allow_harmony_arrow_functions(bool allow) {
128 allow_harmony_arrow_functions_ = allow; 130 allow_harmony_arrow_functions_ = allow;
129 } 131 }
130 void set_allow_harmony_modules(bool allow) { 132 void set_allow_harmony_modules(bool allow) {
(...skipping 19 matching lines...) Expand all
150 } 152 }
151 void set_allow_harmony_unicode(bool allow) { 153 void set_allow_harmony_unicode(bool allow) {
152 scanner()->SetHarmonyUnicode(allow); 154 scanner()->SetHarmonyUnicode(allow);
153 } 155 }
154 void set_allow_harmony_computed_property_names(bool allow) { 156 void set_allow_harmony_computed_property_names(bool allow) {
155 allow_harmony_computed_property_names_ = allow; 157 allow_harmony_computed_property_names_ = allow;
156 } 158 }
157 void set_allow_harmony_rest_params(bool allow) { 159 void set_allow_harmony_rest_params(bool allow) {
158 allow_harmony_rest_params_ = allow; 160 allow_harmony_rest_params_ = allow;
159 } 161 }
162 void set_allow_harmony_exponentiation(bool allow) {
163 scanner()->SetHarmonyExponentiation(allow);
164 }
160 void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; } 165 void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; }
161 166
162 protected: 167 protected:
163 enum AllowEvalOrArgumentsAsIdentifier { 168 enum AllowEvalOrArgumentsAsIdentifier {
164 kAllowEvalOrArguments, 169 kAllowEvalOrArguments,
165 kDontAllowEvalOrArguments 170 kDontAllowEvalOrArguments
166 }; 171 };
167 172
168 enum Mode { 173 enum Mode {
169 PARSE_LAZILY, 174 PARSE_LAZILY,
(...skipping 995 matching lines...) Expand 10 before | Expand all | Expand 10 after
1165 PreParserExpression NewCall(PreParserExpression expression, 1170 PreParserExpression NewCall(PreParserExpression expression,
1166 PreParserExpressionList arguments, 1171 PreParserExpressionList arguments,
1167 int pos) { 1172 int pos) {
1168 return PreParserExpression::Call(); 1173 return PreParserExpression::Call();
1169 } 1174 }
1170 PreParserExpression NewCallNew(PreParserExpression expression, 1175 PreParserExpression NewCallNew(PreParserExpression expression,
1171 PreParserExpressionList arguments, 1176 PreParserExpressionList arguments,
1172 int pos) { 1177 int pos) {
1173 return PreParserExpression::Default(); 1178 return PreParserExpression::Default();
1174 } 1179 }
1180 PreParserExpression NewCallRuntime(const AstRawString* name,
1181 const Runtime::Function* func,
1182 PreParserExpressionList arguments,
1183 int pos) {
1184 return PreParserExpression::Call();
1185 }
1175 PreParserStatement NewReturnStatement(PreParserExpression expression, 1186 PreParserStatement NewReturnStatement(PreParserExpression expression,
1176 int pos) { 1187 int pos) {
1177 return PreParserStatement::Default(); 1188 return PreParserStatement::Default();
1178 } 1189 }
1179 PreParserExpression NewFunctionLiteral( 1190 PreParserExpression NewFunctionLiteral(
1180 PreParserIdentifier name, AstValueFactory* ast_value_factory, 1191 PreParserIdentifier name, AstValueFactory* ast_value_factory,
1181 Scope* scope, PreParserStatementList body, int materialized_literal_count, 1192 Scope* scope, PreParserStatementList body, int materialized_literal_count,
1182 int expected_property_count, int handler_count, int parameter_count, 1193 int expected_property_count, int handler_count, int parameter_count,
1183 FunctionLiteral::ParameterFlag has_duplicate_parameters, 1194 FunctionLiteral::ParameterFlag has_duplicate_parameters,
1184 FunctionLiteral::FunctionType function_type, 1195 FunctionLiteral::FunctionType function_type,
(...skipping 1148 matching lines...) Expand 10 before | Expand all | Expand 10 after
2333 ExpressionT expression = 2344 ExpressionT expression =
2334 this->ParseConditionalExpression(accept_IN, CHECK_OK); 2345 this->ParseConditionalExpression(accept_IN, CHECK_OK);
2335 2346
2336 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) { 2347 if (allow_harmony_arrow_functions() && peek() == Token::ARROW) {
2337 checkpoint.Restore(); 2348 checkpoint.Restore();
2338 expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos, 2349 expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos,
2339 expression, CHECK_OK); 2350 expression, CHECK_OK);
2340 return expression; 2351 return expression;
2341 } 2352 }
2342 2353
2354 bool desugar_exponentiation = false;
2343 if (!Token::IsAssignmentOp(peek())) { 2355 if (!Token::IsAssignmentOp(peek())) {
2344 if (fni_ != NULL) fni_->Leave(); 2356 if (fni_ != NULL) fni_->Leave();
2345 // Parsed conditional expression only (no assignment). 2357 // Parsed conditional expression only (no assignment).
2346 return expression; 2358 return expression;
2347 } 2359 }
2348 2360
2349 expression = this->CheckAndRewriteReferenceExpression( 2361 expression = this->CheckAndRewriteReferenceExpression(
2350 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); 2362 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK);
2351 expression = this->MarkExpressionAsAssigned(expression); 2363 expression = this->MarkExpressionAsAssigned(expression);
2352 2364
2353 Token::Value op = Next(); // Get assignment operator. 2365 Token::Value op = Next(); // Get assignment operator.
2366 if (op == Token::ASSIGN_EXP) {
2367 // TODO(caitp): Desugaring in the parser makes it observable that lhs is
2368 // retrieved twice. Fixed by moving implementation to compiler rather than
2369 // desugaring, or by allocating a temporary variable.
2370 op = Token::ASSIGN;
2371 desugar_exponentiation = true;
2372 }
2373
2354 int pos = position(); 2374 int pos = position();
2355 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK); 2375 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK);
2356 2376
2357 // TODO(1231235): We try to estimate the set of properties set by 2377 // TODO(1231235): We try to estimate the set of properties set by
2358 // constructors. We define a new property whenever there is an 2378 // constructors. We define a new property whenever there is an
2359 // assignment to a property of 'this'. We should probably only add 2379 // assignment to a property of 'this'. We should probably only add
2360 // properties if we haven't seen them before. Otherwise we'll 2380 // properties if we haven't seen them before. Otherwise we'll
2361 // probably overestimate the number of properties. 2381 // probably overestimate the number of properties.
2362 if (op == Token::ASSIGN && this->IsThisProperty(expression)) { 2382 if (op == Token::ASSIGN && this->IsThisProperty(expression)) {
2363 function_state_->AddProperty(); 2383 function_state_->AddProperty();
2364 } 2384 }
2365 2385
2366 this->CheckAssigningFunctionLiteralToProperty(expression, right); 2386 this->CheckAssigningFunctionLiteralToProperty(expression, right);
2367 2387
2368 if (fni_ != NULL) { 2388 if (fni_ != NULL) {
2369 // Check if the right hand side is a call to avoid inferring a 2389 // Check if the right hand side is a call to avoid inferring a
2370 // name if we're dealing with "a = function(){...}();"-like 2390 // name if we're dealing with "a = function(){...}();"-like
2371 // expression. 2391 // expression.
2372 if ((op == Token::INIT_VAR 2392 if ((op == Token::INIT_VAR
2373 || op == Token::INIT_CONST_LEGACY 2393 || op == Token::INIT_CONST_LEGACY
2374 || op == Token::ASSIGN) 2394 || op == Token::ASSIGN)
2375 && (!right->IsCall() && !right->IsCallNew())) { 2395 && (!right->IsCall() && !right->IsCallNew())) {
2376 fni_->Infer(); 2396 fni_->Infer();
2377 } else { 2397 } else {
2378 fni_->RemoveLastFunction(); 2398 fni_->RemoveLastFunction();
2379 } 2399 }
2380 fni_->Leave(); 2400 fni_->Leave();
2381 } 2401 }
2382 2402
2403 if (desugar_exponentiation) {
2404 // Desugar to runtime call
2405 typename Traits::Type::ExpressionList args =
2406 this->NewExpressionList(2, zone_);
2407 args->Add(expression, zone_);
2408 args->Add(right, zone_);
2409 right = factory()->NewCallRuntime(
2410 ast_value_factory()->math_pow_string(), NULL, args, pos);
2411 }
2412
2383 return factory()->NewAssignment(op, expression, right, pos); 2413 return factory()->NewAssignment(op, expression, right, pos);
2384 } 2414 }
2385 2415
2386 template <class Traits> 2416 template <class Traits>
2387 typename ParserBase<Traits>::ExpressionT 2417 typename ParserBase<Traits>::ExpressionT
2388 ParserBase<Traits>::ParseYieldExpression(bool* ok) { 2418 ParserBase<Traits>::ParseYieldExpression(bool* ok) {
2389 // YieldExpression :: 2419 // YieldExpression ::
2390 // 'yield' ([no line terminator] '*'? AssignmentExpression)? 2420 // 'yield' ([no line terminator] '*'? AssignmentExpression)?
2391 int pos = peek_position(); 2421 int pos = peek_position();
2392 Expect(Token::YIELD, CHECK_OK); 2422 Expect(Token::YIELD, CHECK_OK);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
2458 typename ParserBase<Traits>::ExpressionT 2488 typename ParserBase<Traits>::ExpressionT
2459 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { 2489 ParserBase<Traits>::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) {
2460 DCHECK(prec >= 4); 2490 DCHECK(prec >= 4);
2461 ExpressionT x = this->ParseUnaryExpression(CHECK_OK); 2491 ExpressionT x = this->ParseUnaryExpression(CHECK_OK);
2462 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { 2492 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) {
2463 // prec1 >= 4 2493 // prec1 >= 4
2464 while (Precedence(peek(), accept_IN) == prec1) { 2494 while (Precedence(peek(), accept_IN) == prec1) {
2465 Token::Value op = Next(); 2495 Token::Value op = Next();
2466 Scanner::Location op_location = scanner()->location(); 2496 Scanner::Location op_location = scanner()->location();
2467 int pos = position(); 2497 int pos = position();
2468 ExpressionT y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); 2498 ExpressionT y = Traits::EmptyExpression();
2499
2500 if (op != Token::EXP) {
2501 // Left-to-right associativity
2502 y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK);
2503 } else {
2504 // Right-to-left associativity
2505 y = ParseBinaryExpression(prec1, accept_IN, CHECK_OK);
2506 }
2469 2507
2470 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos, 2508 if (this->ShortcutNumericLiteralBinaryExpression(&x, y, op, pos,
2471 factory())) { 2509 factory())) {
2472 continue; 2510 continue;
2473 } 2511 }
2474 2512
2475 // For now we distinguish between comparisons and other binary 2513 // For now we distinguish between comparisons and other binary
2476 // operations. (We could combine the two and get rid of this 2514 // operations. (We could combine the two and get rid of this
2477 // code and AST node eventually.) 2515 // code and AST node eventually.)
2478 if (Token::IsCompareOp(op)) { 2516 if (Token::IsCompareOp(op)) {
(...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after
3109 *ok = false; 3147 *ok = false;
3110 return; 3148 return;
3111 } 3149 }
3112 has_seen_constructor_ = true; 3150 has_seen_constructor_ = true;
3113 return; 3151 return;
3114 } 3152 }
3115 } 3153 }
3116 } } // v8::internal 3154 } } // v8::internal
3117 3155
3118 #endif // V8_PREPARSER_H 3156 #endif // V8_PREPARSER_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698