#include "irgen/IRGen.h"

#include <stdexcept>

#include "SysYParser.h"
#include "ir/IR.h"
#include "utils/Log.h"

// 语句生成当前只实现了最小子集。
// 目前支持：
// - return <exp>;
// - 赋值语句：lVal = exp;
//
// 还未支持：
// - if / while 等控制流
// - 空语句、块语句嵌套分发之外的更多语句形态

std::any IRGenImpl::visitStmt(SysYParser::StmtContext* ctx) {
  if (!ctx) {
    throw std::runtime_error(FormatError("irgen", "缺少语句"));
  }
  
  // 检查是否是赋值语句：lVal ASSIGN exp SEMICOLON
  if (ctx->lVal() && ctx->ASSIGN()) {
    if (!ctx->exp()) {
      throw std::runtime_error(FormatError("irgen", "赋值语句缺少表达式"));
    }
    
    // 1. 计算右值表达式的值
    ir::Value* rhs = EvalExpr(*ctx->exp());
    
    // 2. 找到左值变量对应的存储槽位
    auto* lval_ctx = ctx->lVal();
    if (!lval_ctx || !lval_ctx->ID()) {
      throw std::runtime_error(FormatError("irgen", "当前仅支持普通整型变量赋值"));
    }
    
    const auto* decl = sema_.ResolveObjectUse(lval_ctx);
    if (!decl) {
      throw std::runtime_error(
          FormatError("irgen",
                      "变量使用缺少语义绑定：" + lval_ctx->ID()->getText()));
    }
    
    std::string var_name = lval_ctx->ID()->getText();
    auto it = storage_map_.find(var_name);
    if (it == storage_map_.end()) {
      throw std::runtime_error(
          FormatError("irgen",
                      "变量声明缺少存储槽位：" + var_name));
    }
    
    // 3. 生成 store 指令
    builder_.CreateStore(rhs, it->second);
    return BlockFlow::Continue;
  }
  
  // 检查是否是 return 语句：RETURN exp? SEMICOLON
  if (ctx->RETURN()) {
    if (!ctx->exp()) {
      throw std::runtime_error(FormatError("irgen", "return 缺少表达式"));
    }
    ir::Value* v = EvalExpr(*ctx->exp());
    builder_.CreateRet(v);
    return BlockFlow::Terminated;
  }
  
  throw std::runtime_error(FormatError("irgen", "暂不支持的语句类型"));
}
