#include "Scanner.h"
#include "Parser.h"
#include "ast.h"
#include <memory>
#include <iostream>
#include "clasplayer.h"
#include "passmanager.h"
#include "pass/dfgpass.h"

using namespace std;

void testParser_1()
{
    shared_ptr<Scanner> scanner(new Scanner(L"scripts/input.xreate"));
    shared_ptr<Parser> parser(new Parser(scanner.get()));
    parser->Parse();
    flush(cout);

    AST& root =  parser->root;
    LLVMLayer l;

    root.compile(l);
    root.run(l);
}

void testClasp2()
{
    shared_ptr<Scanner> scanner(new Scanner(L"scripts/input.xreate"));
    shared_ptr<Parser> parser(new Parser(scanner.get()));
    parser->Parse();
    flush(cout);

    if (parser->errors->count)
    {
        cout << "Found " << parser->errors->count << " errors. Stop" << endl;
        exit(1);
    }

    AST& root =  parser->root;
    ClaspLayer clasp;

        /*
    FunctionTagsPass(root).run(clasp);
    RulesPass(root).run(clasp);

    CFGPass(&clasp).run();

    clasp.1
    run();
        */
}

void testUnsafeCode1()
{
    shared_ptr<Scanner> scanner(new Scanner(L"scripts/cases/bugs-code.xreate"));
    shared_ptr<Parser> parser(new Parser(scanner.get()));
    parser->Parse();
    flush(cout);

    if (parser->errors->count)
    {
        cout << "Found " << parser->errors->count << " errors. Stop" << endl;
        exit(1);
    }

    AST& root =  parser->root;
    ClaspLayer clasp;

        /*
    FunctionTagsPass(root).run(clasp);
    RulesPass(root).run(clasp);

    CFGPass(&clasp).run();
    //clasp.addRule(":- call(X, Y), tag(Y, unsafe), not tag(X, unsafe), function(X), function(Y).");

    clasp.run();
        */
}

void test_DFG_1()
{
    shared_ptr<Scanner> scanner(new Scanner(L"scripts/input.xreate"));
    shared_ptr<Parser> parser(new Parser(scanner.get()));
    parser->Parse();
    flush(cout);

    if (parser->errors->count)
    {
        cout << "Found " << parser->errors->count << " errors. Stop" << endl;
        exit(1);
    }

    PassManager m;
    m.clasp = new ClaspLayer();

    m.llvm = new LLVMLayer();
    m.root = & parser->root;
    m.clasp->ast = m.root;

    m.registerPass(new DFGPass(&m));
    m.run();

    m.clasp->run();
    m.root->compile(*m.llvm);
    m.root->run(*m.llvm);
}

int main()
{
    test_DFG_1();

    return 0;
}
