// Copyright 2015 Google Inc. All rights reserved
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// +build ignore

#include "ast.h"

#include "eval.h"
#include "stringprintf.h"
#include "strutil.h"
#include "value.h"

AST::AST() {}

AST::~AST() {}

string RuleAST::DebugString() const {
  return StringPrintf("RuleAST(expr=%s term=%d after_term=%s loc=%s:%d)",
                      expr->DebugString().c_str(),
                      term,
                      after_term->DebugString().c_str(),
                      LOCF(loc()));
}

string AssignAST::DebugString() const {
  const char* opstr = "???";
  switch (op) {
    case AssignOp::EQ: opstr = "EQ"; break;
    case AssignOp::COLON_EQ: opstr = "COLON_EQ"; break;
    case AssignOp::PLUS_EQ: opstr = "PLUS_EQ"; break;
    case AssignOp::QUESTION_EQ: opstr = "QUESTION_EQ"; break;
  }
  const char* dirstr = "???";
  switch (directive) {
    case AssignDirective::NONE: dirstr = ""; break;
    case AssignDirective::OVERRIDE: dirstr = "override"; break;
    case AssignDirective::EXPORT: dirstr = "export"; break;
  }
  return StringPrintf("AssignAST(lhs=%s rhs=%s (%s) "
                      "opstr=%s dir=%s loc=%s:%d)",
                      lhs->DebugString().c_str(),
                      rhs->DebugString().c_str(),
                      NoLineBreak(orig_rhs.as_string()).c_str(),
                      opstr, dirstr, LOCF(loc()));
}

string CommandAST::DebugString() const {
  return StringPrintf("CommandAST(%s, loc=%s:%d)",
                      expr->DebugString().c_str(), LOCF(loc()));
}

string IfAST::DebugString() const {
  const char* opstr = "???";
  switch (op) {
    case CondOp::IFEQ: opstr = "ifeq"; break;
    case CondOp::IFNEQ: opstr = "ifneq"; break;
    case CondOp::IFDEF: opstr = "ifdef"; break;
    case CondOp::IFNDEF: opstr = "ifndef"; break;
  }
  return StringPrintf("IfAST(op=%s, lhs=%s, rhs=%s t=%zu f=%zu loc=%s:%d)",
                      opstr,
                      lhs->DebugString().c_str(),
                      rhs->DebugString().c_str(),
                      true_asts.size(),
                      false_asts.size(),
                      LOCF(loc()));
}

string IncludeAST::DebugString() const {
  return StringPrintf("IncludeAST(%s, loc=%s:%d)",
                      expr->DebugString().c_str(), LOCF(loc()));
}

RuleAST::~RuleAST() {
  delete expr;
  delete after_term;
}

void RuleAST::Eval(Evaluator* ev) const {
  ev->EvalRule(this);
}

AssignAST::~AssignAST() {
  delete lhs;
  delete rhs;
}

void AssignAST::Eval(Evaluator* ev) const {
  ev->EvalAssign(this);
}

CommandAST::~CommandAST() {
  delete expr;
}

void CommandAST::Eval(Evaluator* ev) const {
  ev->EvalCommand(this);
}

IfAST::~IfAST() {
  delete lhs;
  delete rhs;
}

void IfAST::Eval(Evaluator* ev) const {
  ev->EvalIf(this);
}

IncludeAST::~IncludeAST() {
  delete expr;
}

void IncludeAST::Eval(Evaluator* ev) const {
  ev->EvalInclude(this);
}
