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