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