// 简单 AST 调试打印，便于前端验证。

#include "ast/AstNodes.h"

#include <iostream>

namespace ast {

static void PrintExpr(const Expr* expr);

static void PrintIndent(int depth) {
  for (int i = 0; i < depth; ++i) std::cout << "  ";
}

static void PrintExpr(const Expr* expr) {
  if (auto num = dynamic_cast<const NumberExpr*>(expr)) {
    std::cout << num->value;
  } else if (auto var = dynamic_cast<const VarExpr*>(expr)) {
    std::cout << var->name;
  } else if (auto bin = dynamic_cast<const BinaryExpr*>(expr)) {
    std::cout << "(";
    PrintExpr(bin->lhs.get());
    const char* op = "?";
    switch (bin->op) {
      case BinaryOp::Add:
        op = "+";
        break;
      case BinaryOp::Sub:
        op = "-";
        break;
      case BinaryOp::Mul:
        op = "*";
        break;
      case BinaryOp::Div:
        op = "/";
        break;
    }
    std::cout << " " << op << " ";
    PrintExpr(bin->rhs.get());
    std::cout << ")";
  }
}

void PrintAST(const CompUnit& cu) {
  if (!cu.func) return;
  std::cout << "func " << cu.func->name << " () {\n";
  const auto& body = cu.func->body;
  if (!body) {
    std::cout << "}\n";
    return;
  }
  for (const auto& decl : body->varDecls) {
    PrintIndent(1);
    std::cout << "var " << decl->name;
    if (decl->init) {
      std::cout << " = ";
      PrintExpr(decl->init.get());
    }
    std::cout << ";\n";
  }
  for (const auto& stmt : body->stmts) {
    if (auto ret = dynamic_cast<ReturnStmt*>(stmt.get())) {
      PrintIndent(1);
      std::cout << "return ";
      PrintExpr(ret->value.get());
      std::cout << ";\n";
    }
  }
  std::cout << "}\n";
}

}  // namespace ast
