import * as mir from "../../mir.ts";

export class Module {
    private fns: Fn[] = [];
}

export class Fn {
    constructor(
        public mirFn: mir.Fn,
        public blocks: Block[] = [],
    ) {}
}

export class Block {
    public insts: Inst[] = [];

    push(inst: Inst) {
        this.insts.push(inst);
    }
}

export class Inst {
    constructor(
        public kind: InstKind,
    ) {}
}

export type InstKind =
    | { tag: "PushR"; src: Reg }
    | { tag: "PopR"; dst: Reg }
    | { tag: "MovRR"; dst: Reg; src: Reg }
    | { tag: "SubRI"; dst: Reg; imm: number }
    | { tag: "MovRI"; dst: Reg; imm: number }
    | { tag: "MovMRR"; dst: Reg; offset: number; src: Reg }
    | { tag: "MovRMR"; dst: Reg; src: Reg; offset: number }
    | { tag: "AddR"; dst_op1: Reg; op2: Reg }
    | { tag: "Jmp"; bb: Block }
    | { tag: "Ret" };

export class Reg {
    static tempId = 1000;

    private constructor(
        public id: number,
    ) {}

    static reg(reg: Regs): Reg {
        return new Reg(reg);
    }

    static temp(): Reg {
        return new Reg(this.tempId++);
    }
}

export const Regs = {
    a: 1,
    b: 2,
    c: 3,
    si: 4,
    di: 5,
    sp: 6,
    bp: 7,
    r8: 8,
    r9: 9,
    r10: 10,
    r11: 11,
    r12: 12,
    r13: 13,
    r14: 14,
    r15: 15,
} as const;

export type Regs = typeof Regs[keyof typeof Regs];
