// 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.
  std::string_view 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();
}
