// 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 "stmt.h"

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

Stmt::Stmt() {}

Stmt::~Stmt() {}

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

string AssignStmt::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("AssignStmt(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 CommandStmt::DebugString() const {
  return StringPrintf("CommandStmt(%s, loc=%s:%d)",
                      expr->DebugString().c_str(), LOCF(loc()));
}

string IfStmt::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("IfStmt(op=%s, lhs=%s, rhs=%s t=%zu f=%zu loc=%s:%d)",
                      opstr,
                      lhs->DebugString().c_str(),
                      rhs->DebugString().c_str(),
                      true_stmts.size(),
                      false_stmts.size(),
                      LOCF(loc()));
}

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

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

string ParseErrorStmt::DebugString() const {
  return StringPrintf("ParseErrorStmt(%s, loc=%s:%d)",
                      msg.c_str(),
                      LOCF(loc()));
}

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

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

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

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

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

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

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

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

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

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

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

void ExportStmt::Eval(Evaluator* ev) const {
  ev->EvalExport(this);
}

ParseErrorStmt::~ParseErrorStmt() {
}

void ParseErrorStmt::Eval(Evaluator* ev) const {
  ev->set_loc(loc());
  ev->Error(msg);
}
