package org.jcnc.snow.compiler.ir.builder;

import org.jcnc.snow.compiler.ir.core.IRFunction;
import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
import org.jcnc.snow.compiler.parser.ast.FunctionNode;
import org.jcnc.snow.compiler.parser.ast.ParameterNode;
import org.jcnc.snow.compiler.parser.ast.base.StatementNode;

/**
 * FunctionBuilder 负责将 AST 中的 FunctionNode 构建为可执行的 IRFunction。
 * <p>
 * 构建流程：
 * <ol>
 *   <li>创建 IRFunction 实例并初始化 IRContext；</li>
 *   <li>将函数签名中的参数声明为虚拟寄存器；</li>
 *   <li>遍历函数体中的每个语句节点，通过 StatementBuilder 生成对应 IR 指令；</li>
 *   <li>最终返回构建完成的 IRFunction 对象。</li>
 * </ol>
 */
public class FunctionBuilder {

    /**
     * 构建函数的 IR 表示
     *
     * @param functionNode 要构建的函数 AST 节点
     * @return 构建完成的 IRFunction 对象
     */
    public IRFunction build(FunctionNode functionNode) {
        // 创建 IRFunction 并包装到上下文
        IRFunction irFunction = new IRFunction(functionNode.name());
        IRContext irContext = new IRContext(irFunction);

        // 声明函数参数
        for (ParameterNode parameterNode : functionNode.parameters()) {

            /* 1) 为参数新建一个虚拟寄存器 */
            IRVirtualRegister paramReg = irFunction.newRegister();

            /* 2) 在当前作用域绑定 变量名 → 寄存器 */
            irContext.getScope().declare(parameterNode.name(), paramReg);

            /* 3) 记录到 IRFunction 的形参列表
          —— 供 RegisterAllocator 在 slot 0,1,2… 分配 */
            irFunction.addParameter(paramReg);
        }


        // 使用 StatementBuilder 遍历并生成函数体所有语句的 IR
        StatementBuilder statementBuilder = new StatementBuilder(irContext);
        for (StatementNode statementNode : functionNode.body()) {
            statementBuilder.build(statementNode);
        }

        // 返回构建好的 IRFunction
        return irFunction;
    }
}
