// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "tools/gn/operators.h"

#include <stddef.h>
#include <algorithm>

#include "base/strings/string_number_conversions.h"
#include "tools/gn/err.h"
#include "tools/gn/parse_tree.h"
#include "tools/gn/scope.h"
#include "tools/gn/token.h"
#include "tools/gn/value.h"

namespace {

const char kSourcesName[] = "sources";

// Helper class used for assignment operations: =, +=, and -= to generalize
// writing to various types of destinations.
class ValueDestination {
 public:
  ValueDestination();

  bool Init(Scope* exec_scope,
            const ParseNode* dest,
            const BinaryOpNode* op_node,
            Err* err);

  // Returns the value in the destination scope if it already exists, or null
  // if it doesn't. This is for validation and does not count as a "use".
  // Other nested scopes will be searched.
  const Value* GetExistingValue() const;

  // Returns an existing version of the output if it can be modified. This will
  // not search nested scopes since writes only go into the current scope.
  // Returns null if the value does not exist, or is not in the current scope
  // (meaning assignments won't go to this value and it's not mutable). This
  // is for implementing += and -=.
  //
  // If it exists, this will mark the origin of the value to be the passed-in
  // node, and the value will be also marked unused (if possible) under the
  // assumption that it will be modified in-place.
  Value* GetExistingMutableValueIfExists(const ParseNode* origin);

  // Returns the sources assignment filter if it exists for the current
  // scope and it should be applied to this assignment. Otherwise returns null.
  const PatternList* GetAssignmentFilter(const Scope* exec_scope) const;

  // Returns a pointer to the value that was set.
  Value* SetValue(Value value, const ParseNode* set_node);

  // Fills the Err with an undefined value error appropriate for modification
  // operators: += and -= (where the source is also the dest).
  void MakeUndefinedIdentifierForModifyError(Err* err);

 private:
  enum Type { UNINITIALIZED, SCOPE, LIST };

  Type type_;

  // Valid when type_ == SCOPE.
  Scope* scope_;
  const Token* name_token_;

  // Valid when type_ == LIST.
  Value* list_;
  size_t index_;  // Guaranteed in-range when Init() succeeds.
};

ValueDestination::ValueDestination()
    : type_(UNINITIALIZED),
      scope_(nullptr),
      name_token_(nullptr),
      list_(nullptr),
      index_(0) {}

bool ValueDestination::Init(Scope* exec_scope,
                            const ParseNode* dest,
                            const BinaryOpNode* op_node,
                            Err* err) {
  // Check for standard variable set.
  const IdentifierNode* dest_identifier = dest->AsIdentifier();
  if (dest_identifier) {
    type_ = SCOPE;
    scope_ = exec_scope;
    name_token_ = &dest_identifier->value();
    return true;
  }

  // Check for array and scope accesses. The base (array or scope variable
  // name) must always be defined ahead of time.
  const AccessorNode* dest_accessor = dest->AsAccessor();
  if (!dest_accessor) {
    *err = Err(op_node, "Assignment requires a lvalue.",
               "This thing on the left is not an identifier or accessor.");
    err->AppendRange(dest->GetRange());
    return false;
  }

  // Known to be an accessor.
  base::StringPiece base_str = dest_accessor->base().value();
  Value* base =
      exec_scope->GetMutableValue(base_str, Scope::SEARCH_CURRENT, false);
  if (!base) {
    // Base is either undefined or it's defined but not in the current scope.
    // Make a good error message.
    if (exec_scope->GetValue(base_str, false)) {
      *err = Err(
          dest_accessor->base(), "Suspicious in-place modification.",
          "This variable exists in a containing scope. Normally, writing to it "
          "would\nmake a copy of it into the current scope with the modified "
          "version. But\nhere you're modifying only an element of a scope or "
          "list object. It's unlikely\nyou meant to copy the entire thing just "
          "to modify this part of it.\n"
          "\n"
          "If you really wanted to do this, do:\n"
          "  " +
              std::string(base_str) + " = " + std::string(base_str) +
              "\n"
              "to copy it into the current scope before doing this operation.");
    } else {
      *err = Err(dest_accessor->base(), "Undefined identifier.");
    }
    return false;
  }

  if (dest_accessor->index()) {
    // List access with an index.
    if (!base->VerifyTypeIs(Value::LIST, err)) {
      // Errors here will confusingly refer to the variable declaration (since
      // that's all Value knows) rather than the list access. So rewrite the
      // error location to refer to the base value's location.
      *err = Err(dest_accessor->base(), err->message(), err->help_text());
      return false;
    }

    type_ = LIST;
    list_ = base;
    return dest_accessor->ComputeAndValidateListIndex(
        exec_scope, base->list_value().size(), &index_, err);
  }

  // Scope access with a dot.
  if (!base->VerifyTypeIs(Value::SCOPE, err)) {
    // As the for the list index case above, rewrite the error location.
    *err = Err(dest_accessor->base(), err->message(), err->help_text());
    return false;
  }
  type_ = SCOPE;
  scope_ = base->scope_value();
  name_token_ = &dest_accessor->member()->value();
  return true;
}

const Value* ValueDestination::GetExistingValue() const {
  if (type_ == SCOPE)
    return scope_->GetValue(name_token_->value(), true);
  else if (type_ == LIST)
    return &list_->list_value()[index_];
  return nullptr;
}

Value* ValueDestination::GetExistingMutableValueIfExists(
    const ParseNode* origin) {
  if (type_ == SCOPE) {
    Value* value = scope_->GetMutableValue(name_token_->value(),
                                           Scope::SEARCH_CURRENT, false);
    if (value) {
      // The value will be written to, reset its tracking information.
      value->set_origin(origin);
      scope_->MarkUnused(name_token_->value());
    }
  }
  if (type_ == LIST)
    return &list_->list_value()[index_];
  return nullptr;
}

const PatternList* ValueDestination::GetAssignmentFilter(
    const Scope* exec_scope) const {
  if (type_ != SCOPE)
    return nullptr;  // Destination can't be named, so no sources filtering.
  if (name_token_->value() != kSourcesName)
    return nullptr;  // Destination not named "sources".

  const PatternList* filter = exec_scope->GetSourcesAssignmentFilter();
  if (!filter || filter->is_empty())
    return nullptr;  // No filter or empty filter, don't need to do anything.
  return filter;
}

Value* ValueDestination::SetValue(Value value, const ParseNode* set_node) {
  if (type_ == SCOPE) {
    return scope_->SetValue(name_token_->value(), std::move(value), set_node);
  } else if (type_ == LIST) {
    Value* dest = &list_->list_value()[index_];
    *dest = std::move(value);
    return dest;
  }
  return nullptr;
}

void ValueDestination::MakeUndefinedIdentifierForModifyError(Err* err) {
  // When Init() succeeds, the base of any accessor has already been resolved
  // and that list indices are in-range. This means any undefined identifiers
  // are for scope accesses.
  DCHECK(type_ == SCOPE);
  *err = Err(*name_token_, "Undefined identifier.");
}

// Computes an error message for overwriting a nonempty list/scope with another.
Err MakeOverwriteError(const BinaryOpNode* op_node, const Value& old_value) {
  std::string type_name;
  std::string empty_def;

  if (old_value.type() == Value::LIST) {
    type_name = "list";
    empty_def = "[]";
  } else if (old_value.type() == Value::SCOPE) {
    type_name = "scope";
    empty_def = "{}";
  } else {
    NOTREACHED();
  }

  Err result(op_node->left()->GetRange(),
             "Replacing nonempty " + type_name + ".",
             "This overwrites a previously-defined nonempty " + type_name +
                 " with another nonempty " + type_name + ".");
  result.AppendSubErr(Err(
      old_value, "for previous definition",
      "Did you mean to append/modify instead? If you really want to overwrite, "
      "do:\n"
      "  foo = " +
          empty_def + "\nbefore reassigning."));
  return result;
}

// -----------------------------------------------------------------------------

Err MakeIncompatibleTypeError(const BinaryOpNode* op_node,
                              const Value& left,
                              const Value& right) {
  std::string msg = std::string("You can't do <") +
                    Value::DescribeType(left.type()) + "> " +
                    std::string(op_node->op().value()) + " <" +
                    Value::DescribeType(right.type()) + ">.";
  if (left.type() == Value::LIST) {
    // Append extra hint for list stuff.
    msg +=
        "\n\nHint: If you're attempting to add or remove a single item from "
        " a list, use \"foo + [ bar ]\".";
  }
  return Err(op_node, "Incompatible types for binary operator.", msg);
}

Value GetValueOrFillError(const BinaryOpNode* op_node,
                          const ParseNode* node,
                          const char* name,
                          Scope* scope,
                          Err* err) {
  Value value = node->Execute(scope, err);
  if (err->has_error())
    return Value();
  if (value.type() == Value::NONE) {
    *err = Err(op_node->op(), "Operator requires a value.",
               "This thing on the " + std::string(name) +
                   " does not evaluate to a value.");
    err->AppendRange(node->GetRange());
    return Value();
  }
  return value;
}

void RemoveMatchesFromList(const BinaryOpNode* op_node,
                           Value* list,
                           const Value& to_remove,
                           Err* err) {
  std::vector<Value>& v = list->list_value();
  switch (to_remove.type()) {
    case Value::BOOLEAN:
    case Value::INTEGER:  // Filter out the individual int/string.
    case Value::STRING:
    case Value::SCOPE: {
      bool found_match = false;
      for (size_t i = 0; i < v.size(); /* nothing */) {
        if (v[i] == to_remove) {
          found_match = true;
          v.erase(v.begin() + i);
        } else {
          i++;
        }
      }
      if (!found_match) {
        *err = Err(to_remove.origin()->GetRange(), "Item not found",
                   "You were trying to remove " + to_remove.ToString(true) +
                       "\nfrom the list but it wasn't there.");
      }
      break;
    }

    case Value::LIST:  // Filter out each individual thing.
      for (const auto& elem : to_remove.list_value()) {
        // TODO(brettw) if the nested item is a list, we may want to search
        // for the literal list rather than remote the items in it.
        RemoveMatchesFromList(op_node, list, elem, err);
        if (err->has_error())
          return;
      }
      break;

    case Value::NONE:
      break;
  }
}

// Assignment -----------------------------------------------------------------

// We return a null value from this rather than the result of doing the append.
// See ValuePlusEquals for rationale.
Value ExecuteEquals(Scope* exec_scope,
                    const BinaryOpNode* op_node,
                    ValueDestination* dest,
                    Value right,
                    Err* err) {
  const Value* old_value = dest->GetExistingValue();
  if (old_value) {
    // Check for overwriting nonempty scopes or lists with other nonempty
    // scopes or lists. This prevents mistakes that clobber a value rather than
    // appending to it. For cases where a user meant to clear a value, allow
    // overwriting a nonempty list/scope with an empty one, which can then be
    // modified.
    if (old_value->type() == Value::LIST && right.type() == Value::LIST &&
        !old_value->list_value().empty() && !right.list_value().empty()) {
      *err = MakeOverwriteError(op_node, *old_value);
      return Value();
    } else if (old_value->type() == Value::SCOPE &&
               right.type() == Value::SCOPE &&
               old_value->scope_value()->HasValues(Scope::SEARCH_CURRENT) &&
               right.scope_value()->HasValues(Scope::SEARCH_CURRENT)) {
      *err = MakeOverwriteError(op_node, *old_value);
      return Value();
    }
  }

  Value* written_value = dest->SetValue(std::move(right), op_node->right());

  // Optionally apply the assignment filter in-place.
  const PatternList* filter = dest->GetAssignmentFilter(exec_scope);
  if (filter && written_value->type() == Value::LIST) {
    std::vector<Value>& list_value = written_value->list_value();
    auto first_deleted = std::remove_if(
        list_value.begin(), list_value.end(),
        [filter](const Value& v) { return filter->MatchesValue(v); });
    list_value.erase(first_deleted, list_value.end());
  }
  return Value();
}

// Plus/minus ------------------------------------------------------------------

// allow_left_type_conversion indicates if we're allowed to change the type of
// the left value. This is set to true when doing +, and false when doing +=.
Value ExecutePlus(const BinaryOpNode* op_node,
                  Value left,
                  Value right,
                  bool allow_left_type_conversion,
                  Err* err) {
  // Left-hand-side integer.
  if (left.type() == Value::INTEGER) {
    if (right.type() == Value::INTEGER) {
      // Int + int -> addition.
      return Value(op_node, left.int_value() + right.int_value());
    } else if (right.type() == Value::STRING && allow_left_type_conversion) {
      // Int + string -> string concat.
      return Value(op_node, base::Int64ToString(left.int_value()) +
                                right.string_value());
    }
    *err = MakeIncompatibleTypeError(op_node, left, right);
    return Value();
  }

  // Left-hand-side string.
  if (left.type() == Value::STRING) {
    if (right.type() == Value::INTEGER) {
      // String + int -> string concat.
      return Value(op_node, left.string_value() +
                                base::Int64ToString(right.int_value()));
    } else if (right.type() == Value::STRING) {
      // String + string -> string concat. Since the left is passed by copy
      // we can avoid realloc if there is enough buffer by appending to left
      // and assigning.
      left.string_value().append(right.string_value());
      return left;  // FIXME(brettw) des this copy?
    }
    *err = MakeIncompatibleTypeError(op_node, left, right);
    return Value();
  }

  // Left-hand-side list. The only valid thing is to add another list.
  if (left.type() == Value::LIST && right.type() == Value::LIST) {
    // Since left was passed by copy, avoid realloc by destructively appending
    // to it and using that as the result.
    for (Value& value : right.list_value())
      left.list_value().push_back(std::move(value));
    return left;  // FIXME(brettw) does this copy?
  }

  *err = MakeIncompatibleTypeError(op_node, left, right);
  return Value();
}

// Left is passed by value because it will be modified in-place and returned
// for the list case.
Value ExecuteMinus(const BinaryOpNode* op_node,
                   Value left,
                   const Value& right,
                   Err* err) {
  // Left-hand-side int. The only thing to do is subtract another int.
  if (left.type() == Value::INTEGER && right.type() == Value::INTEGER) {
    // Int - int -> subtraction.
    return Value(op_node, left.int_value() - right.int_value());
  }

  // Left-hand-side list. The only thing to do is subtract another list.
  if (left.type() == Value::LIST && right.type() == Value::LIST) {
    // In-place modify left and return it.
    RemoveMatchesFromList(op_node, &left, right, err);
    return left;
  }

  *err = MakeIncompatibleTypeError(op_node, left, right);
  return Value();
}

// In-place plus/minus ---------------------------------------------------------

void ExecutePlusEquals(Scope* exec_scope,
                       const BinaryOpNode* op_node,
                       ValueDestination* dest,
                       Value right,
                       Err* err) {
  // There are several cases. Some things we can convert "foo += bar" to
  // "foo = foo + bar". Some cases we can't (the 'sources' variable won't
  // get the right filtering on the list). Some cases we don't want to (lists
  // and strings will get unnecessary copying so we can to optimize these).
  //
  //  - Value is already mutable in the current scope:
  //     1. List/string append: use it.
  //     2. Other types: fall back to "foo = foo + bar"
  //
  //  - Value is not mutable in the current scope:
  //     3. List/string append: copy into current scope and append to that.
  //     4. Other types: fall back to "foo = foo + bar"
  //
  // The common case is to use += for list and string appends in the local
  // scope, so this is written to avoid multiple variable lookups in that case.
  Value* mutable_dest = dest->GetExistingMutableValueIfExists(op_node);
  if (!mutable_dest) {
    const Value* existing_value = dest->GetExistingValue();
    if (!existing_value) {
      // Undefined left-hand-size for +=.
      dest->MakeUndefinedIdentifierForModifyError(err);
      return;
    }

    if (existing_value->type() != Value::STRING &&
        existing_value->type() != Value::LIST) {
      // Case #4 above.
      dest->SetValue(
          ExecutePlus(op_node, *existing_value, std::move(right), false, err),
          op_node);
      return;
    }

    // Case #3 above, copy to current scope and fall-through to appending.
    mutable_dest = dest->SetValue(*existing_value, op_node);
  } else if (mutable_dest->type() != Value::STRING &&
             mutable_dest->type() != Value::LIST) {
    // Case #2 above.
    dest->SetValue(
        ExecutePlus(op_node, *mutable_dest, std::move(right), false, err),
        op_node);
    return;
  }  // "else" is case #1 above.

  if (mutable_dest->type() == Value::STRING) {
    if (right.type() == Value::INTEGER) {
      // String + int -> string concat.
      mutable_dest->string_value().append(
          base::Int64ToString(right.int_value()));
    } else if (right.type() == Value::STRING) {
      // String + string -> string concat.
      mutable_dest->string_value().append(right.string_value());
    } else {
      *err = MakeIncompatibleTypeError(op_node, *mutable_dest, right);
    }
  } else if (mutable_dest->type() == Value::LIST) {
    // List concat.
    if (right.type() == Value::LIST) {
      // Note: don't reserve() the dest vector here since that actually hurts
      // the allocation pattern when the build script is doing multiple small
      // additions.
      const PatternList* filter = dest->GetAssignmentFilter(exec_scope);
      if (filter) {
        // Filtered list concat.
        for (Value& value : right.list_value()) {
          if (!filter->MatchesValue(value))
            mutable_dest->list_value().push_back(std::move(value));
        }
      } else {
        // Normal list concat. This is a destructive move.
        for (Value& value : right.list_value())
          mutable_dest->list_value().push_back(std::move(value));
      }
    } else {
      *err = Err(op_node->op(), "Incompatible types to add.",
                 "To append a single item to a list do \"foo += [ bar ]\".");
    }
  }
}

void ExecuteMinusEquals(const BinaryOpNode* op_node,
                        ValueDestination* dest,
                        const Value& right,
                        Err* err) {
  // Like the += case, we can convert "foo -= bar" to "foo = foo - bar". Since
  // there is no sources filtering, this is always semantically valid. The
  // only case we don't do it is for lists in the current scope which is the
  // most common case, and also the one that can be optimized the most by
  // doing it in-place.
  Value* mutable_dest = dest->GetExistingMutableValueIfExists(op_node);
  if (!mutable_dest ||
      (mutable_dest->type() != Value::LIST || right.type() != Value::LIST)) {
    const Value* existing_value = dest->GetExistingValue();
    if (!existing_value) {
      // Undefined left-hand-size for -=.
      dest->MakeUndefinedIdentifierForModifyError(err);
      return;
    }
    dest->SetValue(ExecuteMinus(op_node, *existing_value, right, err), op_node);
    return;
  }

  // In-place removal of items from "right".
  RemoveMatchesFromList(op_node, mutable_dest, right, err);
}

// Comparison -----------------------------------------------------------------

Value ExecuteEqualsEquals(Scope* scope,
                          const BinaryOpNode* op_node,
                          const Value& left,
                          const Value& right,
                          Err* err) {
  if (left == right)
    return Value(op_node, true);
  return Value(op_node, false);
}

Value ExecuteNotEquals(Scope* scope,
                       const BinaryOpNode* op_node,
                       const Value& left,
                       const Value& right,
                       Err* err) {
  // Evaluate in terms of ==.
  Value result = ExecuteEqualsEquals(scope, op_node, left, right, err);
  result.boolean_value() = !result.boolean_value();
  return result;
}

Value FillNeedsTwoIntegersError(const BinaryOpNode* op_node,
                                const Value& left,
                                const Value& right,
                                Err* err) {
  *err = Err(op_node, "Comparison requires two integers.",
             "This operator can only compare two integers.");
  err->AppendRange(left.origin()->GetRange());
  err->AppendRange(right.origin()->GetRange());
  return Value();
}

Value ExecuteLessEquals(Scope* scope,
                        const BinaryOpNode* op_node,
                        const Value& left,
                        const Value& right,
                        Err* err) {
  if (left.type() != Value::INTEGER || right.type() != Value::INTEGER)
    return FillNeedsTwoIntegersError(op_node, left, right, err);
  return Value(op_node, left.int_value() <= right.int_value());
}

Value ExecuteGreaterEquals(Scope* scope,
                           const BinaryOpNode* op_node,
                           const Value& left,
                           const Value& right,
                           Err* err) {
  if (left.type() != Value::INTEGER || right.type() != Value::INTEGER)
    return FillNeedsTwoIntegersError(op_node, left, right, err);
  return Value(op_node, left.int_value() >= right.int_value());
}

Value ExecuteGreater(Scope* scope,
                     const BinaryOpNode* op_node,
                     const Value& left,
                     const Value& right,
                     Err* err) {
  if (left.type() != Value::INTEGER || right.type() != Value::INTEGER)
    return FillNeedsTwoIntegersError(op_node, left, right, err);
  return Value(op_node, left.int_value() > right.int_value());
}

Value ExecuteLess(Scope* scope,
                  const BinaryOpNode* op_node,
                  const Value& left,
                  const Value& right,
                  Err* err) {
  if (left.type() != Value::INTEGER || right.type() != Value::INTEGER)
    return FillNeedsTwoIntegersError(op_node, left, right, err);
  return Value(op_node, left.int_value() < right.int_value());
}

// Binary ----------------------------------------------------------------------

Value ExecuteOr(Scope* scope,
                const BinaryOpNode* op_node,
                const ParseNode* left_node,
                const ParseNode* right_node,
                Err* err) {
  Value left = GetValueOrFillError(op_node, left_node, "left", scope, err);
  if (err->has_error())
    return Value();
  if (left.type() != Value::BOOLEAN) {
    *err = Err(op_node->left(), "Left side of || operator is not a boolean.",
               "Type is \"" + std::string(Value::DescribeType(left.type())) +
                   "\" instead.");
    return Value();
  }
  if (left.boolean_value())
    return Value(op_node, left.boolean_value());

  Value right = GetValueOrFillError(op_node, right_node, "right", scope, err);
  if (err->has_error())
    return Value();
  if (right.type() != Value::BOOLEAN) {
    *err = Err(op_node->right(), "Right side of || operator is not a boolean.",
               "Type is \"" + std::string(Value::DescribeType(right.type())) +
                   "\" instead.");
    return Value();
  }

  return Value(op_node, left.boolean_value() || right.boolean_value());
}

Value ExecuteAnd(Scope* scope,
                 const BinaryOpNode* op_node,
                 const ParseNode* left_node,
                 const ParseNode* right_node,
                 Err* err) {
  Value left = GetValueOrFillError(op_node, left_node, "left", scope, err);
  if (err->has_error())
    return Value();
  if (left.type() != Value::BOOLEAN) {
    *err = Err(op_node->left(), "Left side of && operator is not a boolean.",
               "Type is \"" + std::string(Value::DescribeType(left.type())) +
                   "\" instead.");
    return Value();
  }
  if (!left.boolean_value())
    return Value(op_node, left.boolean_value());

  Value right = GetValueOrFillError(op_node, right_node, "right", scope, err);
  if (err->has_error())
    return Value();
  if (right.type() != Value::BOOLEAN) {
    *err = Err(op_node->right(), "Right side of && operator is not a boolean.",
               "Type is \"" + std::string(Value::DescribeType(right.type())) +
                   "\" instead.");
    return Value();
  }
  return Value(op_node, left.boolean_value() && right.boolean_value());
}

}  // namespace

// ----------------------------------------------------------------------------

Value ExecuteUnaryOperator(Scope* scope,
                           const UnaryOpNode* op_node,
                           const Value& expr,
                           Err* err) {
  DCHECK(op_node->op().type() == Token::BANG);

  if (expr.type() != Value::BOOLEAN) {
    *err = Err(op_node, "Operand of ! operator is not a boolean.",
               "Type is \"" + std::string(Value::DescribeType(expr.type())) +
                   "\" instead.");
    return Value();
  }
  // TODO(scottmg): Why no unary minus?
  return Value(op_node, !expr.boolean_value());
}

Value ExecuteBinaryOperator(Scope* scope,
                            const BinaryOpNode* op_node,
                            const ParseNode* left,
                            const ParseNode* right,
                            Err* err) {
  const Token& op = op_node->op();

  // First handle the ones that take an lvalue.
  if (op.type() == Token::EQUAL || op.type() == Token::PLUS_EQUALS ||
      op.type() == Token::MINUS_EQUALS) {
    // Compute the left side.
    ValueDestination dest;
    if (!dest.Init(scope, left, op_node, err))
      return Value();

    // Compute the right side.
    Value right_value = right->Execute(scope, err);
    if (err->has_error())
      return Value();
    if (right_value.type() == Value::NONE) {
      *err = Err(op, "Operator requires a rvalue.",
                 "This thing on the right does not evaluate to a value.");
      err->AppendRange(right->GetRange());
      return Value();
    }

    // "foo += bar" (same for "-=") is converted to "foo = foo + bar" here, but
    // we pass the original value of "foo" by pointer to avoid a copy.
    if (op.type() == Token::EQUAL) {
      ExecuteEquals(scope, op_node, &dest, std::move(right_value), err);
    } else if (op.type() == Token::PLUS_EQUALS) {
      ExecutePlusEquals(scope, op_node, &dest, std::move(right_value), err);
    } else if (op.type() == Token::MINUS_EQUALS) {
      ExecuteMinusEquals(op_node, &dest, right_value, err);
    } else {
      NOTREACHED();
    }
    return Value();
  }

  // ||, &&. Passed the node instead of the value so that they can avoid
  // evaluating the RHS on early-out.
  if (op.type() == Token::BOOLEAN_OR)
    return ExecuteOr(scope, op_node, left, right, err);
  if (op.type() == Token::BOOLEAN_AND)
    return ExecuteAnd(scope, op_node, left, right, err);

  // Everything else works on the evaluated left and right values.
  Value left_value = GetValueOrFillError(op_node, left, "left", scope, err);
  if (err->has_error())
    return Value();
  Value right_value = GetValueOrFillError(op_node, right, "right", scope, err);
  if (err->has_error())
    return Value();

  // +, -.
  if (op.type() == Token::MINUS)
    return ExecuteMinus(op_node, std::move(left_value), right_value, err);
  if (op.type() == Token::PLUS) {
    return ExecutePlus(op_node, std::move(left_value), std::move(right_value),
                       true, err);
  }

  // Comparisons.
  if (op.type() == Token::EQUAL_EQUAL)
    return ExecuteEqualsEquals(scope, op_node, left_value, right_value, err);
  if (op.type() == Token::NOT_EQUAL)
    return ExecuteNotEquals(scope, op_node, left_value, right_value, err);
  if (op.type() == Token::GREATER_EQUAL)
    return ExecuteGreaterEquals(scope, op_node, left_value, right_value, err);
  if (op.type() == Token::LESS_EQUAL)
    return ExecuteLessEquals(scope, op_node, left_value, right_value, err);
  if (op.type() == Token::GREATER_THAN)
    return ExecuteGreater(scope, op_node, left_value, right_value, err);
  if (op.type() == Token::LESS_THAN)
    return ExecuteLess(scope, op_node, left_value, right_value, err);

  return Value();
}
