parse_tree.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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) { 19d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch std::string ret; 20d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (int i = 0; i < value; i++) 21d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch ret.append(" "); 22d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ret; 23d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 24d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 25d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} // namespace 26d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 27d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochParseNode::ParseNode() { 28d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 29d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 30d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochParseNode::~ParseNode() { 31d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 32d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 33d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst AccessorNode* ParseNode::AsAccessor() const { return NULL; } 34d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst BinaryOpNode* ParseNode::AsBinaryOp() const { return NULL; } 35d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst BlockNode* ParseNode::AsBlock() const { return NULL; } 36d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst ConditionNode* ParseNode::AsConditionNode() const { return NULL; } 37d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst FunctionCallNode* ParseNode::AsFunctionCall() const { return NULL; } 38d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst IdentifierNode* ParseNode::AsIdentifier() const { return NULL; } 39d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst ListNode* ParseNode::AsList() const { return NULL; } 40d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst LiteralNode* ParseNode::AsLiteral() const { return NULL; } 41d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst UnaryOpNode* ParseNode::AsUnaryOp() const { return NULL; } 42d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 43d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// AccessorNode --------------------------------------------------------------- 44d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 45d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochAccessorNode::AccessorNode() { 46d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 47d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 48d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochAccessorNode::~AccessorNode() { 49d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 50d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 51d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst AccessorNode* AccessorNode::AsAccessor() const { 52d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return this; 53d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 54d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 55d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue AccessorNode::Execute(Scope* scope, Err* err) const { 56d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Value index_value = index_->Execute(scope, err); 57d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (err->has_error()) 58d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 59d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!index_value.VerifyTypeIs(Value::INTEGER, err)) 60d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 61d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 62d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const Value* base_value = scope->GetValue(base_.value(), true); 63d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!base_value) { 64d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = MakeErrorDescribing("Undefined identifier."); 65d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 66d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 67d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!base_value->VerifyTypeIs(Value::LIST, err)) 68d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 69d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 70d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch int64 index_int = index_value.int_value(); 71d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (index_int < 0) { 72d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(index_->GetRange(), "Negative array subscript.", 73d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "You gave me " + base::Int64ToString(index_int) + "."); 74d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 75d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 76d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch size_t index_sizet = static_cast<size_t>(index_int); 77d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (index_sizet >= base_value->list_value().size()) { 78d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(index_->GetRange(), "Array subscript out of range.", 79d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "You gave me " + base::Int64ToString(index_int) + 80d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch " but I was expecting something from 0 to " + 81d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch base::Int64ToString( 82d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch static_cast<int64>(base_value->list_value().size()) - 1) + 83d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch ", inclusive."); 84d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 85d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 86d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 87d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Doing this assumes that there's no way in the language to do anything 88d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // between the time the reference is created and the time that the reference 89d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // is used. If there is, this will crash! Currently, this is just used for 90d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // array accesses where this "shouldn't" happen. 91d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return base_value->list_value()[index_sizet]; 92d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 93d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 94d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLocationRange AccessorNode::GetRange() const { 95d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return LocationRange(base_.location(), index_->GetRange().end()); 96d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 97d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 98d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochErr AccessorNode::MakeErrorDescribing(const std::string& msg, 99d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& help) const { 100d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Err(GetRange(), msg, help); 101d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 102d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 103d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid AccessorNode::Print(std::ostream& out, int indent) const { 104d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch out << IndentFor(indent) << "ACCESSOR\n"; 105d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch out << IndentFor(indent + 1) << base_.value() << "\n"; 106d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch index_->Print(out, indent + 1); 107d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 108d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 109d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// BinaryOpNode --------------------------------------------------------------- 110d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 111d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochBinaryOpNode::BinaryOpNode() { 112d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 113d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 114d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochBinaryOpNode::~BinaryOpNode() { 115d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 116d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 117d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst BinaryOpNode* BinaryOpNode::AsBinaryOp() const { 118d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return this; 119d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 120d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 121d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue BinaryOpNode::Execute(Scope* scope, Err* err) const { 122d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteBinaryOperator(scope, this, left_.get(), right_.get(), err); 123d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 124d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 125d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLocationRange BinaryOpNode::GetRange() const { 126d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return left_->GetRange().Union(right_->GetRange()); 127d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 128d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 129d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochErr BinaryOpNode::MakeErrorDescribing(const std::string& msg, 130d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& help) const { 131d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Err(op_, msg, help); 132d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 133d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 134d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid BinaryOpNode::Print(std::ostream& out, int indent) const { 135d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch out << IndentFor(indent) << "BINARY(" << op_.value() << ")\n"; 136d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch left_->Print(out, indent + 1); 137d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch right_->Print(out, indent + 1); 138d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 139d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 140d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// BlockNode ------------------------------------------------------------------ 141d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)BlockNode::BlockNode(bool has_scope) : has_scope_(has_scope) { 143d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 144d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 145d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochBlockNode::~BlockNode() { 146d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch STLDeleteContainerPointers(statements_.begin(), statements_.end()); 147d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 148d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 149d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst BlockNode* BlockNode::AsBlock() const { 150d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return this; 151d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 152d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 153d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue BlockNode::Execute(Scope* containing_scope, Err* err) const { 154d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (has_scope_) { 155d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Scope our_scope(containing_scope); 156d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Value ret = ExecuteBlockInScope(&our_scope, err); 157d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (err->has_error()) 158d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 159d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 160d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Check for unused vars in the scope. 161d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch //our_scope.CheckForUnusedVars(err); 162d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ret; 163d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 164d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteBlockInScope(containing_scope, err); 165d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 166d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 167d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLocationRange BlockNode::GetRange() const { 1683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (begin_token_.type() != Token::INVALID && 1693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) end_token_.type() != Token::INVALID) { 1703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return begin_token_.range().Union(end_token_.range()); 1713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (!statements_.empty()) { 1723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return statements_[0]->GetRange().Union( 1733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) statements_[statements_.size() - 1]->GetRange()); 174d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 1753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return LocationRange(); 176d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 177d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 178d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochErr BlockNode::MakeErrorDescribing(const std::string& msg, 179d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& help) const { 1803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return Err(GetRange(), msg, help); 181d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 182d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 183d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid BlockNode::Print(std::ostream& out, int indent) const { 184d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch out << IndentFor(indent) << "BLOCK\n"; 185d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (size_t i = 0; i < statements_.size(); i++) 186d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch statements_[i]->Print(out, indent + 1); 187d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 188d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 189d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue BlockNode::ExecuteBlockInScope(Scope* our_scope, Err* err) const { 190d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (size_t i = 0; i < statements_.size() && !err->has_error(); i++) { 191d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Check for trying to execute things with no side effects in a block. 192d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const ParseNode* cur = statements_[i]; 193d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (cur->AsList() || cur->AsLiteral() || cur->AsUnaryOp() || 194d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch cur->AsIdentifier()) { 195d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = cur->MakeErrorDescribing( 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "This statement has no effect.", 197d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "Either delete it or do something with the result."); 198d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 199d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 200d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch cur->Execute(our_scope, err); 201d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 202d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 203d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 204d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 205d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// ConditionNode -------------------------------------------------------------- 206d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 207d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochConditionNode::ConditionNode() { 208d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 209d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 210d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochConditionNode::~ConditionNode() { 211d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 212d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 213d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst ConditionNode* ConditionNode::AsConditionNode() const { 214d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return this; 215d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 216d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 217d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue ConditionNode::Execute(Scope* scope, Err* err) const { 218d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Value condition_result = condition_->Execute(scope, err); 219d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (err->has_error()) 220d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 2213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (condition_result.type() != Value::BOOLEAN) { 222d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = condition_->MakeErrorDescribing( 2233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "Condition does not evaluate to a boolean value.", 2243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string("This is a value of type \"") + 2253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Value::DescribeType(condition_result.type()) + 2263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\" instead."); 227d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch err->AppendRange(if_token_.range()); 228d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 229d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 230d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 2313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (condition_result.boolean_value()) { 232d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if_true_->ExecuteBlockInScope(scope, err); 233d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } else if (if_false_) { 234d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // The else block is optional. It's either another condition (for an 235d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // "else if" and we can just Execute it and the condition will handle 236d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // the scoping) or it's a block indicating an "else" in which ase we 237d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // need to be sure it inherits our scope. 238d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const BlockNode* if_false_block = if_false_->AsBlock(); 239d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (if_false_block) 240d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if_false_block->ExecuteBlockInScope(scope, err); 241d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch else 242d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if_false_->Execute(scope, err); 243d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 244d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 245d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 246d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 247d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 248d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLocationRange ConditionNode::GetRange() const { 249d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (if_false_) 250d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return if_token_.range().Union(if_false_->GetRange()); 251d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return if_token_.range().Union(if_true_->GetRange()); 252d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 253d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 254d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochErr ConditionNode::MakeErrorDescribing(const std::string& msg, 255d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& help) const { 256d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Err(if_token_, msg, help); 257d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 258d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 259d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid ConditionNode::Print(std::ostream& out, int indent) const { 260d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch out << IndentFor(indent) << "CONDITION\n"; 261d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch condition_->Print(out, indent + 1); 262d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if_true_->Print(out, indent + 1); 263d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (if_false_) 264d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if_false_->Print(out, indent + 1); 265d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 266d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 267d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// FunctionCallNode ----------------------------------------------------------- 268d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 269d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochFunctionCallNode::FunctionCallNode() { 270d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 271d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 272d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochFunctionCallNode::~FunctionCallNode() { 273d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 274d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 275d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst FunctionCallNode* FunctionCallNode::AsFunctionCall() const { 276d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return this; 277d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 278d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 279d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue FunctionCallNode::Execute(Scope* scope, Err* err) const { 2803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return functions::RunFunction(scope, this, args_.get(), block_.get(), err); 281d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 282d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 283d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLocationRange FunctionCallNode::GetRange() const { 284d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (block_) 285d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return function_.range().Union(block_->GetRange()); 286d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return function_.range().Union(args_->GetRange()); 287d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 288d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 289d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochErr FunctionCallNode::MakeErrorDescribing(const std::string& msg, 290d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& help) const { 291d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Err(function_, msg, help); 292d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 293d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 294d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid FunctionCallNode::Print(std::ostream& out, int indent) const { 295d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch out << IndentFor(indent) << "FUNCTION(" << function_.value() << ")\n"; 296d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch args_->Print(out, indent + 1); 297d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (block_) 298d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch block_->Print(out, indent + 1); 299d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 300d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 301d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// IdentifierNode -------------------------------------------------------------- 302d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 303d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochIdentifierNode::IdentifierNode() { 304d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 305d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 306d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochIdentifierNode::IdentifierNode(const Token& token) : value_(token) { 307d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 308d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 309d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochIdentifierNode::~IdentifierNode() { 310d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 311d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 312d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst IdentifierNode* IdentifierNode::AsIdentifier() const { 313d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return this; 314d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 315d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 316d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue IdentifierNode::Execute(Scope* scope, Err* err) const { 317d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const Value* result = scope->GetValue(value_.value(), true); 318d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!result) { 319d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = MakeErrorDescribing("Undefined identifier"); 320d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 321d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 322d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return *result; 323d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 324d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 325d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLocationRange IdentifierNode::GetRange() const { 326d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return value_.range(); 327d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 328d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 329d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochErr IdentifierNode::MakeErrorDescribing(const std::string& msg, 330d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& help) const { 331d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Err(value_, msg, help); 332d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 333d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 334d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid IdentifierNode::Print(std::ostream& out, int indent) const { 335d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch out << IndentFor(indent) << "IDENTIFIER(" << value_.value() << ")\n"; 336d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 337d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 338d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// ListNode ------------------------------------------------------------------- 339d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 340d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochListNode::ListNode() { 341d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 342d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 343d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochListNode::~ListNode() { 344d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch STLDeleteContainerPointers(contents_.begin(), contents_.end()); 345d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 346d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 347d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst ListNode* ListNode::AsList() const { 348d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return this; 349d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 350d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 351d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue ListNode::Execute(Scope* scope, Err* err) const { 352d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Value result_value(this, Value::LIST); 353d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch std::vector<Value>& results = result_value.list_value(); 354d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch results.resize(contents_.size()); 355d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 356d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (size_t i = 0; i < contents_.size(); i++) { 357d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const ParseNode* cur = contents_[i]; 358d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch results[i] = cur->Execute(scope, err); 359d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (err->has_error()) 360d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 361d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (results[i].type() == Value::NONE) { 362d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = cur->MakeErrorDescribing( 363d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "This does not evaluate to a value.", 364d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "I can't do something with nothing."); 365d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 366d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 367d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 368d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return result_value; 369d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 370d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 371d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLocationRange ListNode::GetRange() const { 372d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return LocationRange(begin_token_.location(), end_token_.location()); 373d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 374d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 375d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochErr ListNode::MakeErrorDescribing(const std::string& msg, 376d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& help) const { 377d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Err(begin_token_, msg, help); 378d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 379d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 380d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid ListNode::Print(std::ostream& out, int indent) const { 381d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch out << IndentFor(indent) << "LIST\n"; 382d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (size_t i = 0; i < contents_.size(); i++) 383d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch contents_[i]->Print(out, indent + 1); 384d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 385d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 386d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// LiteralNode ----------------------------------------------------------------- 387d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 388d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLiteralNode::LiteralNode() { 389d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 390d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 391d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLiteralNode::LiteralNode(const Token& token) : value_(token) { 392d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 393d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 394d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLiteralNode::~LiteralNode() { 395d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 396d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 397d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst LiteralNode* LiteralNode::AsLiteral() const { 398d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return this; 399d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 400d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 401d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue LiteralNode::Execute(Scope* scope, Err* err) const { 402d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch switch (value_.type()) { 4033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case Token::TRUE_TOKEN: 4043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return Value(this, true); 4053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case Token::FALSE_TOKEN: 4063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return Value(this, false); 407d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case Token::INTEGER: { 408d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch int64 result_int; 409d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!base::StringToInt64(value_.value(), &result_int)) { 410d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = MakeErrorDescribing("This does not look like an integer"); 411d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 412d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 413d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(this, result_int); 414d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 415d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch case Token::STRING: { 416d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Value v(this, Value::STRING); 417d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch ExpandStringLiteral(scope, value_, &v, err); 418d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return v; 419d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 420d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch default: 421d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch NOTREACHED(); 422d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 423d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 424d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 425d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 426d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLocationRange LiteralNode::GetRange() const { 427d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return value_.range(); 428d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 429d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 430d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochErr LiteralNode::MakeErrorDescribing(const std::string& msg, 431d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& help) const { 432d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Err(value_, msg, help); 433d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 434d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 435d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid LiteralNode::Print(std::ostream& out, int indent) const { 436d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch out << IndentFor(indent) << "LITERAL(" << value_.value() << ")\n"; 437d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 438d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 439d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// UnaryOpNode ---------------------------------------------------------------- 440d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 441d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochUnaryOpNode::UnaryOpNode() { 442d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 443d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 444d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochUnaryOpNode::~UnaryOpNode() { 445d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 446d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 447d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst UnaryOpNode* UnaryOpNode::AsUnaryOp() const { 448d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return this; 449d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 450d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 451d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochValue UnaryOpNode::Execute(Scope* scope, Err* err) const { 452d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Value operand_value = operand_->Execute(scope, err); 453d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (err->has_error()) 454d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 455d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteUnaryOperator(scope, this, operand_value, err); 456d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 457d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 458d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochLocationRange UnaryOpNode::GetRange() const { 459d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return op_.range().Union(operand_->GetRange()); 460d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 461d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 462d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochErr UnaryOpNode::MakeErrorDescribing(const std::string& msg, 463d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& help) const { 464d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Err(op_, msg, help); 465d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 466d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 467d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid UnaryOpNode::Print(std::ostream& out, int indent) const { 468d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch out << IndentFor(indent) << "UNARY(" << op_.value() << ")\n"; 469d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch operand_->Print(out, indent + 1); 470d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 471