/*
 * xreatemanager-decorators.cpp
 *
 * Author: pgess <v.melnychenko@xreate.org>
 * Created on July 16, 2017, 4:40 PM
 */

#include "aux/xreatemanager-decorators.h"
#include "main/Parser.h"
#include "pass/compilepass.h"
#include "pass/adhocpass.h"
#include "pass/cfapass.h"
#include "pass/dfapass.h"
#include "pass/interpretationpass.h"
#include "pass/versionspass.h"

namespace xreate {

void
XreateManagerDecoratorBase::prepareCode(std::string&& code){
    grammar::main::Scanner scanner(reinterpret_cast<const unsigned char*>(code.c_str()), code.size());
    grammar::main::Parser parser(&scanner);
    parser.Parse();
    assert(!parser.errors->count && "Parser errors");

    PassManager::prepare(parser.root->finalize());
}

void
XreateManagerDecoratorBase::prepareCode(FILE* code){
    grammar::main::Scanner scanner(code);
    grammar::main::Parser parser(&scanner);
    parser.Parse();
    assert(!parser.errors->count && "Parser errors");

    PassManager::prepare(parser.root->finalize());
}

void
XreateManagerDecoratorBase::analyse(){
    CompilePass::prepareQueries(clasp);
    clasp->run();
}

void
XreateManagerDecoratorFull::initPasses(){
    cfa::CFAPass* passCFG = new cfa::CFAPass(this);

        //TODO is it really DFGPass needs CFGpass?
    registerPass(new dfa::DFAPass(this), PassId::DFGPass, passCFG);
    registerPass(passCFG, PassId::CFGPass);
    this->registerPass(new adhoc::AdhocPass(this), PassId::AdhocPass);
    this->registerPass(new interpretation::InterpretationPass(this), PassId::InterpretationPass);
    this->registerPass(new versions::VersionsPass(this), PassId::VersionsPass);
}

void*
XreateManagerDecoratorFull::run() {
    std::unique_ptr<CompilePass> compiler(new compilation::CompilePassCustomDecorators<>(this));
    compiler->run();

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

} //namespace xreate
