#include <pass/abstractpass.h>
#include "query/containers.h"
#include "passmanager.h"
#include "pass/compilepass.h"

#include "Parser.h"
#include "pass/dfgpass.h"
#include "pass/functiontagspass.h"
#include "pass/logging.h"

using namespace xreate;
using namespace std;

PassManager*
PassManager::prepareForCode(std::string&& code){
      Scanner scanner(reinterpret_cast<const unsigned char*>(code.c_str()), code.size());
      return prepareForCode(scanner);
}

PassManager*
PassManager::prepareForCode(Scanner& scanner){
      Parser parser(&scanner);
      parser.Parse();
      assert(!parser.errors->count && "Parser errors");

      PassManager* man = new PassManager;
      AST* ast = new AST(parser.root);

      man->root = ast;
      man->clasp = new ClaspLayer();

      man->clasp->ast = man->root;
      man->llvm = new LLVMLayer(man->root);
      man->registerPass(new DFGPass(man));
      man->registerPass(new FunctionTagsPass(man));

      return man;
}



void
PassManager::registerPass(AbstractPassBase* pass)
{
    __passes.push_back(pass);
}

void*
PassManager::run()
{
    for (AbstractPassBase* pass: __passes)
    {
        pass->run();
        pass->finish();
    }

    clasp->registerdQuery(new containers::Query());
    clasp->run();

    CompilePass* compiler = new CompilePass(this);
    compiler->run();

    		//Compiler Dependents:
    Logging* logger = new Logging(this);
	logger->initDependencies(compiler);
	logger->run();

    llvm->print();
    llvm->initJit();
    return llvm->getFunctionPointer(compiler->getEntryFunction());
}

void PassManager::runWithoutCompilation(){
    for (AbstractPassBase* pass: __passes)
    {
        pass->run();
        pass->finish();
    }

    clasp->registerdQuery(new containers::Query());
    clasp->run();
}

PassManager::~PassManager(){}
