1d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// found in the LICENSE file. 4d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 5d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/parse_tree.h" 6d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 7d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include <string> 8d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 9d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "base/stl_util.h" 10d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "base/strings/string_number_conversions.h" 11d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/functions.h" 12d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/operators.h" 13d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/scope.h" 14d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/string_utils.h" 15d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 16d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochnamespace { 17d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 18d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochstd::string IndentFor(int value) { 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return std::string(value, ' '); 20d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 21d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 22d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} // namespace 23d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciComments::Comments() { 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciComments::~Comments() { 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid Comments::ReverseSuffix() { 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (int i = 0, j = static_cast<int>(suffix_.size() - 1); i < j; ++i, --j) 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::swap(suffix_[i], suffix_[j]); 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 35d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochParseNode::ParseNode() { 36d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 37d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 38d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochParseNode::~ParseNode() { 39d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 40d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 41d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst AccessorNode* ParseNode::AsAccessor() const { return NULL; } 42d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst BinaryOpNode* ParseNode::AsBinaryOp() const { return NULL; } 43d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst BlockNode* ParseNode::AsBlock() const { return NULL; } 44d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst ConditionNode* ParseNode::AsConditionNode() const { return NULL; } 45d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst FunctionCallNode* ParseNode::AsFunctionCall() const { return NULL; } 46d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst IdentifierNode* ParseNode::AsIdentifier() const { return NULL; } 47d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst ListNode* ParseNode::AsList() const { return NULL; } 48d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst LiteralNode* ParseNode::AsLiteral() const { return NULL; } 49d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst UnaryOpNode* ParseNode::AsUnaryOp() const { return NULL; } 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst BlockCommentNode* ParseNode::AsBlockComment() const { return NULL; } 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciComments* ParseNode::comments_mutable() { 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!comments_) 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci comments_.reset(new Comments); 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return comments_.get(); 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ParseNode::PrintComments(std::ostream& out, int indent) const { 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (comments_) { 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string ind = IndentFor(indent + 1); 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (std::vector<Token>::const_iterator i(comments_->before().begin()); 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci i != comments_->before().end(); 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ++i) { 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci out << ind << "+BEFORE_COMMENT(\"" << i->value() << "\")\n"; 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (std::vector<Token>::const_iterator i(comments_->suffix().begin()); 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci i != comments_->suffix().end(); 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ++i) { 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci out << ind << "+SUFFIX_COMMENT(\"" << i->value() << "\")\n"; 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (std::vector<Token>::const_iterator i(comments_->after().begin()); 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci i != comments_->after().end(); 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ++i) { 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci out << ind << "+AFTER_COMMENT(\"" << i->value() << "\")\n"; 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 78d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 79d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// AccessorNode --------------------------------------------------------------- 80d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 81d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochAccessorNode::AccessorNode() { 82d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 83d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 84d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochAccessorNode::~AccessorNode() { 85d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 86d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 87d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst AccessorNode* AccessorNode::AsAccessor() const { 88d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return this; 89d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 90d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 91d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue AccessorNode::Execute(Scope* scope, Err* err) const { 92effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (index_) 93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return ExecuteArrayAccess(scope, err); 94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch else if (member_) 95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return ExecuteScopeAccess(scope, err); 96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch NOTREACHED(); 97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return Value(); 98effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 99effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 100effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochLocationRange AccessorNode::GetRange() const { 101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (index_) 102effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return LocationRange(base_.location(), index_->GetRange().end()); 103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch else if (member_) 104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return LocationRange(base_.location(), member_->GetRange().end()); 105effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch NOTREACHED(); 106effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return LocationRange(); 107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 109effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochErr AccessorNode::MakeErrorDescribing(const std::string& msg, 110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const std::string& help) const { 111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return Err(GetRange(), msg, help); 112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid AccessorNode::Print(std::ostream& out, int indent) const { 115effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch out << IndentFor(indent) << "ACCESSOR\n"; 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PrintComments(out, indent); 117effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch out << IndentFor(indent + 1) << base_.value() << "\n"; 118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (index_) 119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch index_->Print(out, indent + 1); 120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch else if (member_) 121effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch member_->Print(out, indent + 1); 122effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 123effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 124effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochValue AccessorNode::ExecuteArrayAccess(Scope* scope, Err* err) const { 125d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Value index_value = index_->Execute(scope, err); 126d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (err->has_error()) 127d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 128d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!index_value.VerifyTypeIs(Value::INTEGER, err)) 129d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 130d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 131d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const Value* base_value = scope->GetValue(base_.value(), true); 132d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!base_value) { 133d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = MakeErrorDescribing("Undefined identifier."); 134d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 135d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 136d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!base_value->VerifyTypeIs(Value::LIST, err)) 137d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 138d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 139d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch int64 index_int = index_value.int_value(); 140d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (index_int < 0) { 141d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(index_->GetRange(), "Negative array subscript.", 142d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "You gave me " + base::Int64ToString(index_int) + "."); 143d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 144d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 145d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t index_sizet = static_cast<size_t>(index_int); 146d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (index_sizet >= base_value->list_value().size()) { 147d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(index_->GetRange(), "Array subscript out of range.", 148d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "You gave me " + base::Int64ToString(index_int) + 149d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch " but I was expecting something from 0 to " + 150d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch base::Int64ToString( 151d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch static_cast<int64>(base_value->list_value().size()) - 1) + 152d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch ", inclusive."); 153d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 154d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 155d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 156d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Doing this assumes that there's no way in the language to do anything 157d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // between the time the reference is created and the time that the reference 158d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // is used. If there is, this will crash! Currently, this is just used for 159d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // array accesses where this "shouldn't" happen. 160d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return base_value->list_value()[index_sizet]; 161d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 162d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 163effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochValue AccessorNode::ExecuteScopeAccess(Scope* scope, Err* err) const { 164effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // We jump through some hoops here since ideally a.b will count "b" as 165effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // accessed in the given scope. The value "a" might be in some normal nested 166effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // scope and we can modify it, but it might also be inherited from the 167effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // readonly root scope and we can't do used variable tracking on it. (It's 168effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // not legal to const cast it away since the root scope will be in readonly 169effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // mode and being accessed from multiple threads without locking.) So this 170effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // code handles both cases. 171effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const Value* result = NULL; 172effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 173effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Look up the value in the scope named by "base_". 174effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch Value* mutable_base_value = scope->GetMutableValue(base_.value(), true); 175effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (mutable_base_value) { 176effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Common case: base value is mutable so we can track variable accesses 177effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // for unused value warnings. 178effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!mutable_base_value->VerifyTypeIs(Value::SCOPE, err)) 179effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return Value(); 180effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch result = mutable_base_value->scope_value()->GetValue( 181effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch member_->value().value(), true); 182effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } else { 183effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Fall back to see if the value is on a read-only scope. 184effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const Value* const_base_value = scope->GetValue(base_.value(), true); 185effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (const_base_value) { 186effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Read only value, don't try to mark the value access as a "used" one. 187effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!const_base_value->VerifyTypeIs(Value::SCOPE, err)) 188effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return Value(); 189effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch result = 190effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const_base_value->scope_value()->GetValue(member_->value().value()); 191effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } else { 192effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch *err = Err(base_, "Undefined identifier."); 193effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return Value(); 194effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 195effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 196d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 197effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!result) { 198effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch *err = Err(member_.get(), "No value named \"" + 199effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch member_->value().value() + "\" in scope \"" + base_.value() + "\""); 200effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return Value(); 201effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 202effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return *result; 203d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 204d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 205d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// BinaryOpNode --------------------------------------------------------------- 206d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 207d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochBinaryOpNode::BinaryOpNode() { 208d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 209d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 210d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochBinaryOpNode::~BinaryOpNode() { 211d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 212d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 213d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst BinaryOpNode* BinaryOpNode::AsBinaryOp() const { 214d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return this; 215d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 216d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 217d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue BinaryOpNode::Execute(Scope* scope, Err* err) const { 218d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteBinaryOperator(scope, this, left_.get(), right_.get(), err); 219d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 220d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 221d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLocationRange BinaryOpNode::GetRange() const { 222d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return left_->GetRange().Union(right_->GetRange()); 223d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 224d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 225d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochErr BinaryOpNode::MakeErrorDescribing(const std::string& msg, 226d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& help) const { 227d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Err(op_, msg, help); 228d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 229d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 230d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid BinaryOpNode::Print(std::ostream& out, int indent) const { 231d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch out << IndentFor(indent) << "BINARY(" << op_.value() << ")\n"; 2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PrintComments(out, indent); 233d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch left_->Print(out, indent + 1); 234d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch right_->Print(out, indent + 1); 235d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 236d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 237d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// BlockNode ------------------------------------------------------------------ 238d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 2393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)BlockNode::BlockNode(bool has_scope) : has_scope_(has_scope) { 240d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 241d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 242d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochBlockNode::~BlockNode() { 243d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch STLDeleteContainerPointers(statements_.begin(), statements_.end()); 244d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 245d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 246d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst BlockNode* BlockNode::AsBlock() const { 247d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return this; 248d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 249d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 250d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue BlockNode::Execute(Scope* containing_scope, Err* err) const { 251d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (has_scope_) { 252d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Scope our_scope(containing_scope); 253d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Value ret = ExecuteBlockInScope(&our_scope, err); 254d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (err->has_error()) 255d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 256d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 257d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Check for unused vars in the scope. 258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) our_scope.CheckForUnusedVars(err); 259d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ret; 260d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 261d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteBlockInScope(containing_scope, err); 262d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 263d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 264d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLocationRange BlockNode::GetRange() const { 2653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (begin_token_.type() != Token::INVALID && 2663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) end_token_.type() != Token::INVALID) { 2673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return begin_token_.range().Union(end_token_.range()); 2683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (!statements_.empty()) { 2693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return statements_[0]->GetRange().Union( 2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) statements_[statements_.size() - 1]->GetRange()); 271d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 2723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocationRange(); 273d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 274d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 275d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochErr BlockNode::MakeErrorDescribing(const std::string& msg, 276d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& help) const { 2773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return Err(GetRange(), msg, help); 278d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 279d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 280d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid BlockNode::Print(std::ostream& out, int indent) const { 281d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch out << IndentFor(indent) << "BLOCK\n"; 2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PrintComments(out, indent); 283d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (size_t i = 0; i < statements_.size(); i++) 284d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch statements_[i]->Print(out, indent + 1); 285d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 286d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 287d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue BlockNode::ExecuteBlockInScope(Scope* our_scope, Err* err) const { 288d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (size_t i = 0; i < statements_.size() && !err->has_error(); i++) { 289d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Check for trying to execute things with no side effects in a block. 290d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const ParseNode* cur = statements_[i]; 291d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (cur->AsList() || cur->AsLiteral() || cur->AsUnaryOp() || 292d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch cur->AsIdentifier()) { 293d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = cur->MakeErrorDescribing( 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "This statement has no effect.", 295d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "Either delete it or do something with the result."); 296d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 297d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 298d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch cur->Execute(our_scope, err); 299d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 300d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 301d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 302d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 303d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// ConditionNode -------------------------------------------------------------- 304d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 305d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochConditionNode::ConditionNode() { 306d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 307d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 308d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochConditionNode::~ConditionNode() { 309d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 310d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 311d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst ConditionNode* ConditionNode::AsConditionNode() const { 312d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return this; 313d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 314d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 315d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue ConditionNode::Execute(Scope* scope, Err* err) const { 316d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Value condition_result = condition_->Execute(scope, err); 317d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (err->has_error()) 318d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 3193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (condition_result.type() != Value::BOOLEAN) { 320d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = condition_->MakeErrorDescribing( 3213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "Condition does not evaluate to a boolean value.", 3223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string("This is a value of type \"") + 3233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Value::DescribeType(condition_result.type()) + 3243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\" instead."); 325d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch err->AppendRange(if_token_.range()); 326d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 327d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 328d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (condition_result.boolean_value()) { 330d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if_true_->ExecuteBlockInScope(scope, err); 331d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } else if (if_false_) { 332d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // The else block is optional. It's either another condition (for an 333d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // "else if" and we can just Execute it and the condition will handle 334d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // the scoping) or it's a block indicating an "else" in which ase we 335d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // need to be sure it inherits our scope. 336d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const BlockNode* if_false_block = if_false_->AsBlock(); 337d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (if_false_block) 338d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if_false_block->ExecuteBlockInScope(scope, err); 339d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch else 340d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if_false_->Execute(scope, err); 341d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 342d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 343d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 344d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 345d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 346d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLocationRange ConditionNode::GetRange() const { 347d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (if_false_) 348d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return if_token_.range().Union(if_false_->GetRange()); 349d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return if_token_.range().Union(if_true_->GetRange()); 350d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 351d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 352d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochErr ConditionNode::MakeErrorDescribing(const std::string& msg, 353d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& help) const { 354d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Err(if_token_, msg, help); 355d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 356d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 357d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid ConditionNode::Print(std::ostream& out, int indent) const { 358d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch out << IndentFor(indent) << "CONDITION\n"; 3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PrintComments(out, indent); 360d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch condition_->Print(out, indent + 1); 361d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if_true_->Print(out, indent + 1); 362d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (if_false_) 363d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if_false_->Print(out, indent + 1); 364d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 365d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 366d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// FunctionCallNode ----------------------------------------------------------- 367d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 368d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochFunctionCallNode::FunctionCallNode() { 369d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 370d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 371d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochFunctionCallNode::~FunctionCallNode() { 372d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 373d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 374d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst FunctionCallNode* FunctionCallNode::AsFunctionCall() const { 375d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return this; 376d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 377d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 378d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue FunctionCallNode::Execute(Scope* scope, Err* err) const { 3793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return functions::RunFunction(scope, this, args_.get(), block_.get(), err); 380d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 381d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 382d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLocationRange FunctionCallNode::GetRange() const { 3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (function_.type() == Token::INVALID) 3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return LocationRange(); // This will be null in some tests. 385d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (block_) 386d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return function_.range().Union(block_->GetRange()); 387d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return function_.range().Union(args_->GetRange()); 388d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 389d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 390d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochErr FunctionCallNode::MakeErrorDescribing(const std::string& msg, 391d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& help) const { 392d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Err(function_, msg, help); 393d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 394d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 395d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid FunctionCallNode::Print(std::ostream& out, int indent) const { 396d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch out << IndentFor(indent) << "FUNCTION(" << function_.value() << ")\n"; 3971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PrintComments(out, indent); 398d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch args_->Print(out, indent + 1); 399d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (block_) 400d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch block_->Print(out, indent + 1); 401d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 402d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 403d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// IdentifierNode -------------------------------------------------------------- 404d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 405d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochIdentifierNode::IdentifierNode() { 406d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 407d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 408d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochIdentifierNode::IdentifierNode(const Token& token) : value_(token) { 409d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 410d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 411d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochIdentifierNode::~IdentifierNode() { 412d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 413d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 414d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst IdentifierNode* IdentifierNode::AsIdentifier() const { 415d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return this; 416d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 417d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 418d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue IdentifierNode::Execute(Scope* scope, Err* err) const { 4196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const Value* value = scope->GetValue(value_.value(), true); 4206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Value result; 4216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!value) { 422d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = MakeErrorDescribing("Undefined identifier"); 4236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return result; 424d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 4256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 4266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) result = *value; 4276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) result.set_origin(this); 4286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return result; 429d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 430d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 431d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLocationRange IdentifierNode::GetRange() const { 432d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return value_.range(); 433d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 434d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 435d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochErr IdentifierNode::MakeErrorDescribing(const std::string& msg, 436d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& help) const { 437d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Err(value_, msg, help); 438d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 439d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 440d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid IdentifierNode::Print(std::ostream& out, int indent) const { 441d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch out << IndentFor(indent) << "IDENTIFIER(" << value_.value() << ")\n"; 4421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PrintComments(out, indent); 443d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 444d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 445d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// ListNode ------------------------------------------------------------------- 446d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 447d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochListNode::ListNode() { 448d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 449d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 450d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochListNode::~ListNode() { 451d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch STLDeleteContainerPointers(contents_.begin(), contents_.end()); 452d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 453d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 454d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst ListNode* ListNode::AsList() const { 455d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return this; 456d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 457d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 458d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue ListNode::Execute(Scope* scope, Err* err) const { 459d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Value result_value(this, Value::LIST); 460d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch std::vector<Value>& results = result_value.list_value(); 4611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci results.reserve(contents_.size()); 462d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 463d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (size_t i = 0; i < contents_.size(); i++) { 464d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const ParseNode* cur = contents_[i]; 4651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (cur->AsBlockComment()) 4661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci continue; 4671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci results.push_back(cur->Execute(scope, err)); 468d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (err->has_error()) 469d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 4701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (results.back().type() == Value::NONE) { 471d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = cur->MakeErrorDescribing( 472d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "This does not evaluate to a value.", 473d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "I can't do something with nothing."); 474d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 475d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 476d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 477d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return result_value; 478d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 479d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 480d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLocationRange ListNode::GetRange() const { 481d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return LocationRange(begin_token_.location(), end_token_.location()); 482d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 483d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 484d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochErr ListNode::MakeErrorDescribing(const std::string& msg, 485d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& help) const { 486d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Err(begin_token_, msg, help); 487d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 488d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 489d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid ListNode::Print(std::ostream& out, int indent) const { 490d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch out << IndentFor(indent) << "LIST\n"; 4911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PrintComments(out, indent); 492d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (size_t i = 0; i < contents_.size(); i++) 493d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch contents_[i]->Print(out, indent + 1); 494d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 495d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 496d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// LiteralNode ----------------------------------------------------------------- 497d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 498d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLiteralNode::LiteralNode() { 499d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 500d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 501d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLiteralNode::LiteralNode(const Token& token) : value_(token) { 502d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 503d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 504d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLiteralNode::~LiteralNode() { 505d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 506d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 507d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst LiteralNode* LiteralNode::AsLiteral() const { 508d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return this; 509d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 510d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 511d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue LiteralNode::Execute(Scope* scope, Err* err) const { 512d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch switch (value_.type()) { 5133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case Token::TRUE_TOKEN: 5143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return Value(this, true); 5153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case Token::FALSE_TOKEN: 5163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return Value(this, false); 517d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case Token::INTEGER: { 518d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch int64 result_int; 519d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!base::StringToInt64(value_.value(), &result_int)) { 520d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = MakeErrorDescribing("This does not look like an integer"); 521d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 522d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 523d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(this, result_int); 524d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 525d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case Token::STRING: { 526d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Value v(this, Value::STRING); 527d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch ExpandStringLiteral(scope, value_, &v, err); 528d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return v; 529d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 530d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch default: 531d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch NOTREACHED(); 532d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 533d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 534d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 535d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 536d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLocationRange LiteralNode::GetRange() const { 537d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return value_.range(); 538d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 539d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 540d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochErr LiteralNode::MakeErrorDescribing(const std::string& msg, 541d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& help) const { 542d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Err(value_, msg, help); 543d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 544d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 545d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid LiteralNode::Print(std::ostream& out, int indent) const { 546d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch out << IndentFor(indent) << "LITERAL(" << value_.value() << ")\n"; 5471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PrintComments(out, indent); 548d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 549d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 550d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// UnaryOpNode ---------------------------------------------------------------- 551d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 552d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochUnaryOpNode::UnaryOpNode() { 553d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 554d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 555d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochUnaryOpNode::~UnaryOpNode() { 556d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 557d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 558d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst UnaryOpNode* UnaryOpNode::AsUnaryOp() const { 559d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return this; 560d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 561d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 562d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue UnaryOpNode::Execute(Scope* scope, Err* err) const { 563d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Value operand_value = operand_->Execute(scope, err); 564d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (err->has_error()) 565d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 566d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteUnaryOperator(scope, this, operand_value, err); 567d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 568d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 569d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLocationRange UnaryOpNode::GetRange() const { 570d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return op_.range().Union(operand_->GetRange()); 571d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 572d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 573d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochErr UnaryOpNode::MakeErrorDescribing(const std::string& msg, 574d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& help) const { 575d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Err(op_, msg, help); 576d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 577d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 578d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid UnaryOpNode::Print(std::ostream& out, int indent) const { 579d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch out << IndentFor(indent) << "UNARY(" << op_.value() << ")\n"; 5801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PrintComments(out, indent); 581d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch operand_->Print(out, indent + 1); 582d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 5831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// BlockCommentNode ------------------------------------------------------------ 5851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciBlockCommentNode::BlockCommentNode() { 5871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 5881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciBlockCommentNode::~BlockCommentNode() { 5901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 5911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst BlockCommentNode* BlockCommentNode::AsBlockComment() const { 5931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return this; 5941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 5951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciValue BlockCommentNode::Execute(Scope* scope, Err* err) const { 5971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return Value(); 5981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 5991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciLocationRange BlockCommentNode::GetRange() const { 6011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return comment_.range(); 6021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 6031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciErr BlockCommentNode::MakeErrorDescribing(const std::string& msg, 6051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& help) const { 6061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return Err(comment_, msg, help); 6071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 6081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BlockCommentNode::Print(std::ostream& out, int indent) const { 6101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci out << IndentFor(indent) << "BLOCK_COMMENT(" << comment_.value() << ")\n"; 6111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PrintComments(out, indent); 6121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 613