|
|
- import type { AssignStmt, Expr, Stmt } from "./ast"
-
- // dest <- op(x, y)
- type Operand = string | number
-
- type ASSA<Data> = { dest: string, source: Operand } & Data
-
- export type SSACopy = ASSA<{ source: Operand }> // dest = source
-
- export type SSAUnary = ASSA<{ op: string }> // dest = op(source)
-
- export type SSABinary = ASSA<{ op: string, source1: Operand }> // dest = op(source, source1)
-
- export type SSA = SSACopy | SSAUnary | SSABinary
-
- type IRState = {
- nextID: number
- ssa_stmts: Array<SSA>
- }
-
- export const convertIR = (stmts: Array<Stmt>): Array<SSA> => {
- 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<SSA> => {
- 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<SSA>] => {
- const name = `temp${state.nextID++}`
- return [name, [{ dest: name, source: expr }]]
- }
-
- export const prettyPrintIR = (ssa: SSA): string => {
- let output = ""
-
- if ("source1" in ssa) {
- output = `${ssa.dest} = ${ssa.source} ${ssa.op} ${ssa.source1}`
- } else if ("op" in ssa) {
- output = `${ssa.dest} = ${ssa.op} ${ssa.source}`
- } else {
- output = `${ssa.dest} = ${ssa.source}`
- }
-
- return output
- }
|