// Path: src/main/java/com/pidanic/saral/generator/InitGenerator.java
// public class InitGenerator {
// 
//     private ClassWriter classWriter;
// 
//     public InitGenerator(ClassWriter classWriter) {
//         this.classWriter = classWriter;
//     }
// 
//     public ClassWriter generate(Init statements) {
//         Scope scope = statements.getScope();
//         MethodVisitor mv = classWriter.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
// 
// 
//         List<Statement> instructionQueue = statements.getStatements();
// 
//         CallableStatementGenerator callableStatementGenerator = new CallableStatementGenerator(classWriter, scope);
//         List<Function> functions = instructionQueue.stream()
//                 .filter(stmt -> stmt instanceof CallableStatement)
//                 .map(statement -> (Function) statement)
//                 .collect(Collectors.toList());
//         functions.forEach(procedure -> procedure.accept(callableStatementGenerator));
// 
//         StatementGenerator simpleStatementGenerator = new SimpleStatementGenerator(mv, scope);
//         StatementGenerator blockStatementGenerator = new BlockStatementGenerator(mv, scope);
//         List<Statement> notCallableStatements = instructionQueue.stream()
//                 .filter(stmt -> !(stmt instanceof CallableStatement))
//                 .collect(Collectors.toList());
//         for(Statement ins : notCallableStatements) {
//             if(ins instanceof SimpleStatement) {
//                 ins.accept(simpleStatementGenerator);
//             } else if (ins instanceof BlockStatement) {
//                 ins.accept(blockStatementGenerator);
//             }
//         }
// 
//         closeSystemInIfCreated(scope, mv);
//         mv.visitInsn(Opcodes.RETURN);
//         mv.visitMaxs(-1, -1);
//         mv.visitEnd();
// 
//         classWriter.visitEnd();
//         return classWriter;
//     }
// 
//     private void closeSystemInIfCreated(Scope scope, MethodVisitor mv) {
//         if(scope.existsLocalVariable(LocalVariable.SYSTEM_IN)) {
//             int systemInIndex = scope.getLocalVariableIndex(LocalVariable.SYSTEM_IN);
//             mv.visitVarInsn(Opcodes.ALOAD, systemInIndex);
//             mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/Scanner", "close", "()V", false);
//         }
//     }
// }
// 
// Path: src/main/java/com/pidanic/saral/scope/Scope.java
// public class Scope {
// 
//     private static final LocalVariable EMPTY = new LocalVariable("empty", BuiltInType.BOOLEAN, true);
// 
//     private List<LocalVariable> localVariables;
//     private List<Function> functions;
//     private String className;
// 
//     public Scope(String className) {
//         localVariables = new ArrayList<>();
//         functions = new ArrayList<>();
//         this.className = className;
//     }
// 
//     public Scope(Scope scope) {
//         localVariables = new ArrayList<>(scope.localVariables);
//         functions = new ArrayList<>(scope.functions);
//         className = scope.className;
//     }
// 
//     public List<LocalVariable> getLocalVariables() {
//         return Collections.unmodifiableList(localVariables);
//     }
// 
//     public void addLocalVariable(LocalVariable localVariable) {
//         localVariables.add(localVariable);
//         if(localVariable.type() == BuiltInType.LONG || localVariable.type() == BuiltInType.DOUBLE) {
//             localVariables.add(EMPTY);
//         }
//     }
// 
//     public boolean existsLocalVariable(String variableName) {
//         return localVariables.stream().anyMatch(variable -> variable.name().equals(variableName));
//     }
// 
//     public Optional<LocalVariable> getLocalVariable(String varName) {
//         return localVariables.stream()
//                 .filter(variable -> variable.name().equals(varName))
//                 .findFirst();
//     }
// 
//     public int getLocalVariableIndex(String varName) {
//         return localVariables.stream().map(LocalVariable::name).collect(Collectors.toList()).indexOf(varName);
//     }
// 
//     public Optional<Function> getFunction(String functionName) {
//         return functions.stream().filter(proc -> proc.getName().equals(functionName))
//                 .findFirst();
//     }
// 
//     public String getClassName() {
//         return className;
//     }
// 
//     public void addFunction(Function function) {
//         this.functions.add(function);
//     }
// 
//     public LocalVariable initializeLocalVariableAtIndex(int index) {
//         LocalVariable localVariable = this.localVariables.get(index);
//         LocalVariable initializedLocalVar = localVariable.initialize();
//         this.localVariables.set(index, initializedLocalVar);
//         return initializedLocalVar;
//     }
// 
//     public LocalVariable initializeLocalVariable(String name) {
//         LocalVariable localVariable = getLocalVariable(name).get();
//         int index = getLocalVariableIndex(name);
//         LocalVariable initializedLocalVar = localVariable.initialize();
//         this.localVariables.set(index, initializedLocalVar);
//         return initializedLocalVar;
//     }
// 
//     public int localVariablesCount() {
//         return localVariables.size();
//     }
// }


import com.pidanic.saral.generator.InitGenerator;
import com.pidanic.saral.scope.Scope;
import java.util.List;
package com.pidanic.saral.domain;



public class Init {
    private List<Statement> instructions;
    private Scope scope;

    public Init(Scope scope, List<Statement> instructions) {
        this.instructions = instructions;
        this.scope = scope;
    }

    public List<Statement> getStatements() {
        return instructions;
    }

    public void accept(InitGenerator generator) {
        generator.generate(this);
    }

// Path: src/main/java/com/pidanic/saral/generator/InitGenerator.java
// public class InitGenerator {
// 
//     private ClassWriter classWriter;
// 
//     public InitGenerator(ClassWriter classWriter) {
//         this.classWriter = classWriter;
//     }
// 
//     public ClassWriter generate(Init statements) {
//         Scope scope = statements.getScope();
//         MethodVisitor mv = classWriter.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
// 
// 
//         List<Statement> instructionQueue = statements.getStatements();
// 
//         CallableStatementGenerator callableStatementGenerator = new CallableStatementGenerator(classWriter, scope);
//         List<Function> functions = instructionQueue.stream()
//                 .filter(stmt -> stmt instanceof CallableStatement)
//                 .map(statement -> (Function) statement)
//                 .collect(Collectors.toList());
//         functions.forEach(procedure -> procedure.accept(callableStatementGenerator));
// 
//         StatementGenerator simpleStatementGenerator = new SimpleStatementGenerator(mv, scope);
//         StatementGenerator blockStatementGenerator = new BlockStatementGenerator(mv, scope);
//         List<Statement> notCallableStatements = instructionQueue.stream()
//                 .filter(stmt -> !(stmt instanceof CallableStatement))
//                 .collect(Collectors.toList());
//         for(Statement ins : notCallableStatements) {
//             if(ins instanceof SimpleStatement) {
//                 ins.accept(simpleStatementGenerator);
//             } else if (ins instanceof BlockStatement) {
//                 ins.accept(blockStatementGenerator);
//             }
//         }
// 
//         closeSystemInIfCreated(scope, mv);
//         mv.visitInsn(Opcodes.RETURN);
//         mv.visitMaxs(-1, -1);
//         mv.visitEnd();
// 
//         classWriter.visitEnd();
//         return classWriter;
//     }
// 
//     private void closeSystemInIfCreated(Scope scope, MethodVisitor mv) {
//         if(scope.existsLocalVariable(LocalVariable.SYSTEM_IN)) {
//             int systemInIndex = scope.getLocalVariableIndex(LocalVariable.SYSTEM_IN);
//             mv.visitVarInsn(Opcodes.ALOAD, systemInIndex);
//             mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/Scanner", "close", "()V", false);
//         }
//     }
// }
// 
// Path: src/main/java/com/pidanic/saral/scope/Scope.java
// public class Scope {
// 
//     private static final LocalVariable EMPTY = new LocalVariable("empty", BuiltInType.BOOLEAN, true);
// 
//     private List<LocalVariable> localVariables;
//     private List<Function> functions;
//     private String className;
// 
//     public Scope(String className) {
//         localVariables = new ArrayList<>();
//         functions = new ArrayList<>();
//         this.className = className;
//     }
// 
//     public Scope(Scope scope) {
//         localVariables = new ArrayList<>(scope.localVariables);
//         functions = new ArrayList<>(scope.functions);
//         className = scope.className;
//     }
// 
//     public List<LocalVariable> getLocalVariables() {
//         return Collections.unmodifiableList(localVariables);
//     }
// 
//     public void addLocalVariable(LocalVariable localVariable) {
//         localVariables.add(localVariable);
//         if(localVariable.type() == BuiltInType.LONG || localVariable.type() == BuiltInType.DOUBLE) {
//             localVariables.add(EMPTY);
//         }
//     }
// 
//     public boolean existsLocalVariable(String variableName) {
//         return localVariables.stream().anyMatch(variable -> variable.name().equals(variableName));
//     }
// 
//     public Optional<LocalVariable> getLocalVariable(String varName) {
//         return localVariables.stream()
//                 .filter(variable -> variable.name().equals(varName))
//                 .findFirst();
//     }
// 
//     public int getLocalVariableIndex(String varName) {
//         return localVariables.stream().map(LocalVariable::name).collect(Collectors.toList()).indexOf(varName);
//     }
// 
//     public Optional<Function> getFunction(String functionName) {
//         return functions.stream().filter(proc -> proc.getName().equals(functionName))
//                 .findFirst();
//     }
// 
//     public String getClassName() {
//         return className;
//     }
// 
//     public void addFunction(Function function) {
//         this.functions.add(function);
//     }
// 
//     public LocalVariable initializeLocalVariableAtIndex(int index) {
//         LocalVariable localVariable = this.localVariables.get(index);
//         LocalVariable initializedLocalVar = localVariable.initialize();
//         this.localVariables.set(index, initializedLocalVar);
//         return initializedLocalVar;
//     }
// 
//     public LocalVariable initializeLocalVariable(String name) {
//         LocalVariable localVariable = getLocalVariable(name).get();
//         int index = getLocalVariableIndex(name);
//         LocalVariable initializedLocalVar = localVariable.initialize();
//         this.localVariables.set(index, initializedLocalVar);
//         return initializedLocalVar;
//     }
// 
//     public int localVariablesCount() {
//         return localVariables.size();
//     }
// }


// Path: src/main/java/com/pidanic/saral/domain/Init.java
import com.pidanic.saral.generator.InitGenerator;
import com.pidanic.saral.scope.Scope;
import java.util.List;

package com.pidanic.saral.domain;



public class Init {
    private List<Statement> instructions;
    private Scope scope;

    public Init(Scope scope, List<Statement> instructions) {
        this.instructions = instructions;
        this.scope = scope;
    }

    public List<Statement> getStatements() {
        return instructions;
    }

    public void accept(InitGenerator generator) {
        generator.generate(this);
    }

    public Scope getScope() {