#ifndef CODEINSTRUCTIONS_H
#define CODEINSTRUCTIONS_H

#include "llvmlayer.h"
#include "ast.h"
#include <llvm/IR/Value.h>

namespace xreate {

class InstructionMap
{
public:
    InstructionMap(const Expression& e, LLVMLayer& l);
    llvm::Value* compileDefault(const std::string * const hintRetVar);

private:
    LLVMLayer& llvm;
    const Expression& __data;
};

class InstructionList
{
public:
    InstructionList(const Expression& e, LLVMLayer& l);
    llvm::Value* compileDefault(const std::string * const hintRetVar);

private:
    LLVMLayer& llvm;
    int __size;
    const Expression& __data;
};


    template<Operator Instruction>
    struct InstructionClasses {};

    template<>
    struct InstructionClasses<Operator::LIST> {
        typedef InstructionList base;
    };

    template<>
    struct InstructionClasses<Operator::LOOP> {
        typedef InstructionMap base;
    };

    template<Operator Instruction>
    class CodeInstruction: public InstructionClasses<Instruction>::base
    {
        typedef  typename InstructionClasses<Instruction>::base InstructionImpl;

    public:
        CodeInstruction(const Expression& e, LLVMLayer& l)
                : InstructionImpl(e, l)
        {}

        llvm::Value* compile(const std::string * const hintRetVar)
        {
            InstructionImpl::compileDefault(hintRetVar);
        }
    };
}


#endif //CODEINSTRUCTIONS_H