import type { AssignStmt, Expr, Stmt } from "./ast" // dest <- op(x, y) type Operand = string | number type ASSA = { dest: string } & Data type SSA = ASSA<{ source: Operand }> | ASSA<{ source: Operand, op: string }> | ASSA<{ source1: Operand, op: string, source2: Operand }> type IRState = { nextID: number ssa_stmts: Array } export const convertIR = (stmts: Array): Array => { const state: IRState = { nextID: 0, ssa_stmts: [], } stmts.forEach(stmt => { const ssa_stmts = convertAssignStmt(state, stmt) state.ssa_stmts.push(...ssa_stmts) }) return state.ssa_stmts } export const convertAssignStmt = (state: IRState, stmt: AssignStmt): Array => { const dest = stmt.args.name const [source, expr_stmts] = convertExpr(state, stmt.args.expr) expr_stmts.push({ dest, source, }) return expr_stmts } export const convertExpr = (state: IRState, expr: Expr): [string, Array] => { const name = `temp${state.nextID++}` return [name, [{ dest: name, source: expr }]] }