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

Side by Side Diff: runtime/vm/parser.cc

Issue 11265047: Implement const expressions for local variables (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/parser.h" 5 #include "vm/parser.h"
6 6
7 #include "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/class_finalizer.h" 8 #include "vm/class_finalizer.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/compiler_stats.h" 10 #include "vm/compiler_stats.h"
(...skipping 4826 matching lines...) Expand 10 before | Expand all | Expand 10 after
4837 ASSERT(current_block_ != NULL); 4837 ASSERT(current_block_ != NULL);
4838 ASSERT(current_block_->scope != NULL); 4838 ASSERT(current_block_->scope != NULL);
4839 ConsumeToken(); // Variable identifier. 4839 ConsumeToken(); // Variable identifier.
4840 AstNode* initialization = NULL; 4840 AstNode* initialization = NULL;
4841 if (CurrentToken() == Token::kASSIGN) { 4841 if (CurrentToken() == Token::kASSIGN) {
4842 // Variable initialization. 4842 // Variable initialization.
4843 const intptr_t assign_pos = TokenPos(); 4843 const intptr_t assign_pos = TokenPos();
4844 ConsumeToken(); 4844 ConsumeToken();
4845 AstNode* expr = ParseExpr(is_const, kConsumeCascades); 4845 AstNode* expr = ParseExpr(is_const, kConsumeCascades);
4846 initialization = new StoreLocalNode(assign_pos, variable, expr); 4846 initialization = new StoreLocalNode(assign_pos, variable, expr);
4847 if (is_const) {
4848 ASSERT(expr->IsLiteralNode());
4849 variable->SetConstValue(expr->AsLiteralNode()->literal());
4850 }
4847 } else if (is_final || is_const) { 4851 } else if (is_final || is_const) {
4848 ErrorMsg(ident_pos, 4852 ErrorMsg(ident_pos,
4849 "missing initialization of 'final' or 'const' variable"); 4853 "missing initialization of 'final' or 'const' variable");
4850 } else { 4854 } else {
4851 // Initialize variable with null. 4855 // Initialize variable with null.
4852 AstNode* null_expr = new LiteralNode(ident_pos, Instance::ZoneHandle()); 4856 AstNode* null_expr = new LiteralNode(ident_pos, Instance::ZoneHandle());
4853 initialization = new StoreLocalNode(ident_pos, variable, null_expr); 4857 initialization = new StoreLocalNode(ident_pos, variable, null_expr);
4854 } 4858 }
4855 // Add variable to scope after parsing the initalizer expression. 4859 // Add variable to scope after parsing the initalizer expression.
4856 // The expression must not be able to refer to the variable. 4860 // The expression must not be able to refer to the variable.
(...skipping 3271 matching lines...) Expand 10 before | Expand all | Expand 10 after
8128 // If node is non NULL return an AST node corresponding to the identifier. 8132 // If node is non NULL return an AST node corresponding to the identifier.
8129 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, 8133 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos,
8130 const String &ident, 8134 const String &ident,
8131 AstNode** node) { 8135 AstNode** node) {
8132 TRACE_PARSER("ResolveIdentInLocalScope"); 8136 TRACE_PARSER("ResolveIdentInLocalScope");
8133 Isolate* isolate = Isolate::Current(); 8137 Isolate* isolate = Isolate::Current();
8134 // First try to find the identifier in the nested local scopes. 8138 // First try to find the identifier in the nested local scopes.
8135 LocalVariable* local = LookupLocalScope(ident); 8139 LocalVariable* local = LookupLocalScope(ident);
8136 if (local != NULL) { 8140 if (local != NULL) {
8137 if (node != NULL) { 8141 if (node != NULL) {
8138 *node = new LoadLocalNode(ident_pos, local); 8142 if (local->IsConst()) {
8143 *node = new LiteralNode(ident_pos, *local->ConstValue());
8144 } else {
8145 *node = new LoadLocalNode(ident_pos, local);
8146 }
8139 } 8147 }
8140 return true; 8148 return true;
8141 } 8149 }
8142 8150
8143 // Try to find the identifier in the class scope of the current class. 8151 // Try to find the identifier in the class scope of the current class.
8144 Class& cls = Class::Handle(isolate, current_class().raw()); 8152 Class& cls = Class::Handle(isolate, current_class().raw());
8145 Function& func = Function::Handle(isolate, Function::null()); 8153 Function& func = Function::Handle(isolate, Function::null());
8146 Field& field = Field::Handle(isolate, Field::null()); 8154 Field& field = Field::Handle(isolate, Field::null());
8147 8155
8148 // First check if a field exists. 8156 // First check if a field exists.
(...skipping 1495 matching lines...) Expand 10 before | Expand all | Expand 10 after
9644 } 9652 }
9645 return primary; 9653 return primary;
9646 } 9654 }
9647 9655
9648 9656
9649 // Evaluate expression in expr and return the value. The expression must 9657 // Evaluate expression in expr and return the value. The expression must
9650 // be a compile time constant. 9658 // be a compile time constant.
9651 const Instance& Parser::EvaluateConstExpr(AstNode* expr) { 9659 const Instance& Parser::EvaluateConstExpr(AstNode* expr) {
9652 if (expr->IsLiteralNode()) { 9660 if (expr->IsLiteralNode()) {
9653 return expr->AsLiteralNode()->literal(); 9661 return expr->AsLiteralNode()->literal();
9662 } else if (expr->IsLoadLocalNode() &&
9663 expr->AsLoadLocalNode()->local().IsConst()) {
9664 return *expr->AsLoadLocalNode()->local().ConstValue();
9654 } else { 9665 } else {
9655 ASSERT(expr->EvalConstExpr() != NULL); 9666 ASSERT(expr->EvalConstExpr() != NULL);
9656 ReturnNode* ret = new ReturnNode(expr->token_pos(), expr); 9667 ReturnNode* ret = new ReturnNode(expr->token_pos(), expr);
9657 // Compile time constant expressions cannot reference anything from a 9668 // Compile time constant expressions cannot reference anything from a
9658 // local scope. 9669 // local scope.
9659 LocalScope* empty_scope = new LocalScope(NULL, 0, 0); 9670 LocalScope* empty_scope = new LocalScope(NULL, 0, 0);
9660 SequenceNode* seq = new SequenceNode(expr->token_pos(), empty_scope); 9671 SequenceNode* seq = new SequenceNode(expr->token_pos(), empty_scope);
9661 seq->Add(ret); 9672 seq->Add(ret);
9662 9673
9663 Object& result = Object::Handle(Compiler::ExecuteOnce(seq)); 9674 Object& result = Object::Handle(Compiler::ExecuteOnce(seq));
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
9951 void Parser::SkipQualIdent() { 9962 void Parser::SkipQualIdent() {
9952 ASSERT(IsIdentifier()); 9963 ASSERT(IsIdentifier());
9953 ConsumeToken(); 9964 ConsumeToken();
9954 if (CurrentToken() == Token::kPERIOD) { 9965 if (CurrentToken() == Token::kPERIOD) {
9955 ConsumeToken(); // Consume the kPERIOD token. 9966 ConsumeToken(); // Consume the kPERIOD token.
9956 ExpectIdentifier("identifier expected after '.'"); 9967 ExpectIdentifier("identifier expected after '.'");
9957 } 9968 }
9958 } 9969 }
9959 9970
9960 } // namespace dart 9971 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/ast.cc ('k') | runtime/vm/scopes.h » ('j') | runtime/vm/scopes.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698