#include "Scanner.h"
#include "Parser.h"
#include "ast.h"
#include <memory>
#include <iostream>
#include "pass/cfgpass.h"
#include "pass/functiontagspass.h"
#include "pass/rulespass.h"

#include "clasplayer.h"
#include <sstream>

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(root).run(clasp);
    //clasp.addRule(":- call(X, Y), tag(Y, unsafe), not tag(X, unsafe), function(X), function(Y).");

    clasp.run();
}

void testUnsafeCode1()
{
    shared_ptr<Scanner> scanner(new Scanner(L"scripts/cases/unsafe-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(root).run(clasp);
    //clasp.addRule(":- call(X, Y), tag(Y, unsafe), not tag(X, unsafe), function(X), function(Y).");

    clasp.run();
}

void tests_ListsMultiply()
{

}

int main()
{
    testUnsafeCode1();

    return 0;
}
