package TP2.llvm;
import TP2.llvm.ProgramLLVM.*;

public interface Interface {
    //////////ProgramLLVM (Program)
    public interface ProgLLVM{
        public <H,S> S accept(ProgramLLVMVisitor<H,S> v, H h);
        public String prettyprinter(); 
    }

    public interface ProgramLLVMVisitor<H,S> {
        public S visitProgramLLVM(ProgramLLVMImp prog, H h);
    }
    
    //////////DefineLLVM (function)
    public interface DefineLLVM{
        public <H,S> S accept(DefineLLVMVisitor<H,S> v, H h);
    }

    public interface DefineLLVMVisitor<H,S> {
        public S visitDefineLLVM(DefineLLVMImp define, H h);
    }

    public interface InstructionLLVM{
        public <H,S> S accept(InstructionLLVMVisitor<H,S> v, H h);
    }

    public interface InstructionLLVMVisitor<H,S> {
        public S visitReturnLLVM(ReturnLLVMImp instr, H h);
        public S visitAssignLLVM(AssignLLVMImp instr, H h);
        public S visitStoreLLVM(StoreLLVMImp instr, H h);
        public S visitPrintLLVM(PrintLLVMImp instr, H h);
        public S visitScanLLVM(ScanLLVMImp instr, H h);
        public S visitLabelLLVM(LabelLLVMImp instr, H h);
        public S visitBrLLVM(BrLLVMImp instr, H h);
        public S visitBrCondLLVM(BrCondLLVMImp instr, H h);
        public S visitCallVoidLLVM(CallVoidLLVMImp instr, H h);
        public S visitDeclarGlobalLLVM(DeclarGlobalLLVMImp instr, H h);
    }

    //////////ExpressionLLVM (expression)
    public interface ExpressionLLVM{
        public <H,S> S accept(ExpressionLLVMVisitor<H,S> v, H h);
        public TypeLLVM getType();
    }

    public interface ValLLVM extends ExpressionLLVM{
    }  

    public interface ExpressionLLVMVisitor<H,S> {
        public S visitBinOpLLVM(BinOpLLVMImp e, H h);
        public S visitAllocaLLVM(allocaLLVMImp e,H h);
        public S visitLoadLLVM(LoadLLVMImp e,H h);
        public S visitValLLVM(ValLLVMImp e,H h);
        public S visitVarLLVM(VarLLVMImp e,H h);
        public S visitIcmpLLVM(IcmpLLVMImp e, H h);
        public S visitCallLLVM(CallLLVMImp e, H h);
        public S visitGetElementPtrLLVM(GetElementPtr getElementPtr, H h);
    }

    /*public interface IdentifierLLVM{ //globaux @ et local %
        public String prettyprinter(); 
    }

    public interface IndentifierLLVMVisitor<H,S> {
    }*/

    public interface TypeLLVM{
        public <H,S> S accept(TypeLLVMVisitor<H,S> v, H h);
    }

    public interface TypeLLVMVisitor<H,S> {
        public S visitIntLLVM(IntLLVMImp e,H h);
        public S visitVoidLLVM(VoidLLVMImp e, H h);
        public S visitBooleanLLVM(BooleanLLVMImp e, H h);
        public S visitCharLLVM(CharLLVMImp e, H h);
        public S visitPointerLLVM(PointerLLVMImp e,H h);
        public S visitArrayLLVM(ArrayLLVMImp e, H h);
    }

}
