// 管理基础类型、整型常量池和临时名生成。
// ir/IR.cpp

#include "ir/IR.h"
#include <cstring>  // for memcpy
#include <sstream>

namespace ir {

Context::~Context() = default;

ConstantInt* Context::GetConstInt(int v) {
  auto it = const_ints_.find(v);
  if (it != const_ints_.end()) return it->second.get();
  auto inserted =
      const_ints_.emplace(v, std::make_unique<ConstantInt>(Type::GetInt32Type(), v)).first;
  return inserted->second.get();
}

// 新增：获取浮点常量
ConstantFloat* Context::GetConstFloat(float v) {
  // 使用浮点数的二进制表示作为键，避免精度问题
  uint32_t key;
  std::memcpy(&key, &v, sizeof(float));
  
  auto it = const_floats_.find(key);
  if (it != const_floats_.end()) {
    return it->second.get();
  }
  
  auto float_ty = Type::GetFloatType();
  auto constant = std::make_unique<ConstantFloat>(float_ty, v);
  auto* ptr = constant.get();
  const_floats_[key] = std::move(constant);
  return ptr;
}

// 新增：创建数组常量
ConstantArray* Context::GetConstArray(std::shared_ptr<ArrayType> ty, 
                                       std::vector<ConstantValue*> elements) {
  auto constant = std::make_unique<ConstantArray>(ty, std::move(elements));
  auto* ptr = constant.get();
  const_arrays_.push_back(std::move(constant));
  return ptr;
}

// 新增：获取零常量
ConstantZero* Context::GetZeroConstant(std::shared_ptr<Type> ty) {
  auto it = zero_constants_.find(ty.get());
  if (it != zero_constants_.end()) {
    return it->second.get();
  }
  
  auto constant = std::make_unique<ConstantZero>(ty);
  auto* ptr = constant.get();
  zero_constants_[ty.get()] = std::move(constant);
  return ptr;
}

// 新增：获取聚合类型的零常量
ConstantAggregateZero* Context::GetAggregateZero(std::shared_ptr<Type> ty) {
  auto it = aggregate_zeros_.find(ty.get());
  if (it != aggregate_zeros_.end()) {
    return it->second.get();
  }
  
  auto constant = std::make_unique<ConstantAggregateZero>(ty);
  auto* ptr = constant.get();
  aggregate_zeros_[ty.get()] = std::move(constant);
  return ptr;
}

std::string Context::NextTemp() {
  std::ostringstream oss;
  oss << "%t" << ++temp_index_;
  return oss.str();
}


}  // namespace ir