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

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
« no previous file with comments | « runtime/vm/object.cc ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 4833 matching lines...) Expand 10 before | Expand all | Expand 10 after
4844 ASSERT(current_block_ != NULL); 4844 ASSERT(current_block_ != NULL);
4845 ASSERT(current_block_->scope != NULL); 4845 ASSERT(current_block_->scope != NULL);
4846 ConsumeToken(); // Variable identifier. 4846 ConsumeToken(); // Variable identifier.
4847 AstNode* initialization = NULL; 4847 AstNode* initialization = NULL;
4848 if (CurrentToken() == Token::kASSIGN) { 4848 if (CurrentToken() == Token::kASSIGN) {
4849 // Variable initialization. 4849 // Variable initialization.
4850 const intptr_t assign_pos = TokenPos(); 4850 const intptr_t assign_pos = TokenPos();
4851 ConsumeToken(); 4851 ConsumeToken();
4852 AstNode* expr = ParseExpr(is_const, kConsumeCascades); 4852 AstNode* expr = ParseExpr(is_const, kConsumeCascades);
4853 initialization = new StoreLocalNode(assign_pos, variable, expr); 4853 initialization = new StoreLocalNode(assign_pos, variable, expr);
4854 if (is_const) {
4855 ASSERT(expr->IsLiteralNode());
4856 variable->SetConstValue(expr->AsLiteralNode()->literal());
4857 }
4854 } else if (is_final || is_const) { 4858 } else if (is_final || is_const) {
4855 ErrorMsg(ident_pos, 4859 ErrorMsg(ident_pos,
4856 "missing initialization of 'final' or 'const' variable"); 4860 "missing initialization of 'final' or 'const' variable");
4857 } else { 4861 } else {
4858 // Initialize variable with null. 4862 // Initialize variable with null.
4859 AstNode* null_expr = new LiteralNode(ident_pos, Instance::ZoneHandle()); 4863 AstNode* null_expr = new LiteralNode(ident_pos, Instance::ZoneHandle());
4860 initialization = new StoreLocalNode(ident_pos, variable, null_expr); 4864 initialization = new StoreLocalNode(ident_pos, variable, null_expr);
4861 } 4865 }
4862 // Add variable to scope after parsing the initalizer expression. 4866 // Add variable to scope after parsing the initalizer expression.
4863 // The expression must not be able to refer to the variable. 4867 // The expression must not be able to refer to the variable.
(...skipping 3271 matching lines...) Expand 10 before | Expand all | Expand 10 after
8135 // If node is non NULL return an AST node corresponding to the identifier. 8139 // If node is non NULL return an AST node corresponding to the identifier.
8136 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, 8140 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos,
8137 const String &ident, 8141 const String &ident,
8138 AstNode** node) { 8142 AstNode** node) {
8139 TRACE_PARSER("ResolveIdentInLocalScope"); 8143 TRACE_PARSER("ResolveIdentInLocalScope");
8140 Isolate* isolate = Isolate::Current(); 8144 Isolate* isolate = Isolate::Current();
8141 // First try to find the identifier in the nested local scopes. 8145 // First try to find the identifier in the nested local scopes.
8142 LocalVariable* local = LookupLocalScope(ident); 8146 LocalVariable* local = LookupLocalScope(ident);
8143 if (local != NULL) { 8147 if (local != NULL) {
8144 if (node != NULL) { 8148 if (node != NULL) {
8145 *node = new LoadLocalNode(ident_pos, local); 8149 if (local->IsConst()) {
8150 *node = new LiteralNode(ident_pos, *local->ConstValue());
8151 } else {
8152 *node = new LoadLocalNode(ident_pos, local);
8153 }
8146 } 8154 }
8147 return true; 8155 return true;
8148 } 8156 }
8149 8157
8150 // Try to find the identifier in the class scope of the current class. 8158 // Try to find the identifier in the class scope of the current class.
8151 Class& cls = Class::Handle(isolate, current_class().raw()); 8159 Class& cls = Class::Handle(isolate, current_class().raw());
8152 Function& func = Function::Handle(isolate, Function::null()); 8160 Function& func = Function::Handle(isolate, Function::null());
8153 Field& field = Field::Handle(isolate, Field::null()); 8161 Field& field = Field::Handle(isolate, Field::null());
8154 8162
8155 // First check if a field exists. 8163 // First check if a field exists.
(...skipping 1495 matching lines...) Expand 10 before | Expand all | Expand 10 after
9651 } 9659 }
9652 return primary; 9660 return primary;
9653 } 9661 }
9654 9662
9655 9663
9656 // Evaluate expression in expr and return the value. The expression must 9664 // Evaluate expression in expr and return the value. The expression must
9657 // be a compile time constant. 9665 // be a compile time constant.
9658 const Instance& Parser::EvaluateConstExpr(AstNode* expr) { 9666 const Instance& Parser::EvaluateConstExpr(AstNode* expr) {
9659 if (expr->IsLiteralNode()) { 9667 if (expr->IsLiteralNode()) {
9660 return expr->AsLiteralNode()->literal(); 9668 return expr->AsLiteralNode()->literal();
9669 } else if (expr->IsLoadLocalNode() &&
9670 expr->AsLoadLocalNode()->local().IsConst()) {
9671 return *expr->AsLoadLocalNode()->local().ConstValue();
9661 } else { 9672 } else {
9662 ASSERT(expr->EvalConstExpr() != NULL); 9673 ASSERT(expr->EvalConstExpr() != NULL);
9663 ReturnNode* ret = new ReturnNode(expr->token_pos(), expr); 9674 ReturnNode* ret = new ReturnNode(expr->token_pos(), expr);
9664 // Compile time constant expressions cannot reference anything from a 9675 // Compile time constant expressions cannot reference anything from a
9665 // local scope. 9676 // local scope.
9666 LocalScope* empty_scope = new LocalScope(NULL, 0, 0); 9677 LocalScope* empty_scope = new LocalScope(NULL, 0, 0);
9667 SequenceNode* seq = new SequenceNode(expr->token_pos(), empty_scope); 9678 SequenceNode* seq = new SequenceNode(expr->token_pos(), empty_scope);
9668 seq->Add(ret); 9679 seq->Add(ret);
9669 9680
9670 Object& result = Object::Handle(Compiler::ExecuteOnce(seq)); 9681 Object& result = Object::Handle(Compiler::ExecuteOnce(seq));
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
9958 void Parser::SkipQualIdent() { 9969 void Parser::SkipQualIdent() {
9959 ASSERT(IsIdentifier()); 9970 ASSERT(IsIdentifier());
9960 ConsumeToken(); 9971 ConsumeToken();
9961 if (CurrentToken() == Token::kPERIOD) { 9972 if (CurrentToken() == Token::kPERIOD) {
9962 ConsumeToken(); // Consume the kPERIOD token. 9973 ConsumeToken(); // Consume the kPERIOD token.
9963 ExpectIdentifier("identifier expected after '.'"); 9974 ExpectIdentifier("identifier expected after '.'");
9964 } 9975 }
9965 } 9976 }
9966 9977
9967 } // namespace dart 9978 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.cc ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698