package org.jcnc.snow.compiler.semantic.analyzers.statement;

import org.jcnc.snow.compiler.parser.ast.FunctionNode;
import org.jcnc.snow.compiler.parser.ast.LoopNode;
import org.jcnc.snow.compiler.semantic.analyzers.base.StatementAnalyzer;
import org.jcnc.snow.compiler.semantic.core.Context;
import org.jcnc.snow.compiler.semantic.core.ModuleInfo;
import org.jcnc.snow.compiler.semantic.error.SemanticError;
import org.jcnc.snow.compiler.semantic.symbol.SymbolTable;
import org.jcnc.snow.compiler.semantic.type.BuiltinType;
import org.jcnc.snow.compiler.semantic.type.Type;

/**
 * 改进版 {@code LoopAnalyzer}，为循环结构提供块级作用域支持。
 */
public class LoopAnalyzer implements StatementAnalyzer<LoopNode> {

    @Override
    public void analyze(Context ctx,
                        ModuleInfo mi,
                        FunctionNode fn,
                        SymbolTable locals,
                        LoopNode ln) {

        // 1. 整个循环的块级作用域
        SymbolTable loopScope = new SymbolTable(locals);

        // 2. 初始化语句
        var initAnalyzer = ctx.getRegistry().getStatementAnalyzer(ln.initializer());
        if (initAnalyzer != null) {
            initAnalyzer.analyze(ctx, mi, fn, loopScope, ln.initializer());
        }

        // 3. 条件表达式
        var condAnalyzer = ctx.getRegistry().getExpressionAnalyzer(ln.condition());
        Type condType = condAnalyzer.analyze(ctx, mi, fn, loopScope, ln.condition());
        if (condType != BuiltinType.INT) {
            ctx.getErrors().add(new SemanticError(ln, "loop 条件必须为 int 类型(表示真假)"));
        }

        // 4. 更新语句
        var updateAnalyzer = ctx.getRegistry().getStatementAnalyzer(ln.update());
        if (updateAnalyzer != null) {
            updateAnalyzer.analyze(ctx, mi, fn, loopScope, ln.update());
        }

        // 5. 循环体
        for (var stmt : ln.body()) {
            var stAnalyzer = ctx.getRegistry().getStatementAnalyzer(stmt);
            if (stAnalyzer != null) {
                stAnalyzer.analyze(ctx, mi, fn, loopScope, stmt);
            } else {
                ctx.getErrors().add(new SemanticError(stmt, "不支持的语句类型: " + stmt));
            }
        }
    }
}
