import { Parser, Grammar } from "nearley"
import compiledGrammar from "./grammar.out"
import { Compiler, Instruction, Register, Value, X86Generator as X8664Generator, locateAndSetJumpedToInstructions } from "./compiler";
import fs from "fs/promises";
import { exec } from "child_process";

function executeCommand(command: string) {
    return new Promise<void>((resolve, reject) => {
        exec(command, {}, (error, stdout, stderr) => {
            if (stdout) console.log(stdout);
            if (stderr) console.error(stderr);

            if (error) {
                console.error(error);
                reject();
                return;
            }

            resolve();
        });
    });
}

async function main(args: string[]) {
    const parser = new Parser(Grammar.fromCompiled(compiledGrammar));

    const input = args[2];

    if (input === null)
        throw new Error("input fucked")

    parser.feed(input);

    const ast = parser.results[0];

    console.log(JSON.stringify(ast, null, 4))

    const compiler = new Compiler();
    compiler.compileExpr(ast);
    let ir = compiler.result;
    console.log(ir);
    locateAndSetJumpedToInstructions(ir);
    console.log(ir);

    const generator = new X8664Generator();
    const asm = generator.generate(ir);
    console.log(asm);

    await fs.writeFile("generated.out.asm", asm);

    await executeCommand("nasm -f elf64 -o generated.out.o generated.out.asm");

    await executeCommand("ld generated.out.o -o a.out");
}

main(process.argv);