|
@ -32,55 +32,58 @@ export const convertIR = (stmts: Array): Array => { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
export const convertAssignStmt = (state: IRState, stmt: AssignStmt): Array<SSA> => { |
|
|
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 |
|
|
|
|
|
|
|
|
return convertExpr(state, stmt.args.name, stmt.args.expr) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
export const convertExpr = (state: IRState, expr: Expr): [string | number, Array<SSA>] => { |
|
|
|
|
|
|
|
|
export const convertExpr = (state: IRState, dest: string, expr: Expr): Array<SSA> => { |
|
|
|
|
|
let expr_stmts = [] |
|
|
|
|
|
|
|
|
if (typeof expr === "number" || typeof expr === "string") { |
|
|
if (typeof expr === "number" || typeof expr === "string") { |
|
|
return [expr, []] |
|
|
|
|
|
|
|
|
expr_stmts = [{ dest, source: expr }] |
|
|
} else if (expr.type === "unary") { |
|
|
} else if (expr.type === "unary") { |
|
|
const [source, expr_stmts] = convertExpr(state, expr.arg) |
|
|
|
|
|
|
|
|
|
|
|
const name = `temp${state.nextID++}` |
|
|
|
|
|
expr_stmts.push({ |
|
|
|
|
|
dest: name, |
|
|
|
|
|
source, |
|
|
|
|
|
|
|
|
const [source, stmts] = getSource(state, expr.arg) |
|
|
|
|
|
stmts.push({ |
|
|
|
|
|
dest, |
|
|
op: expr.op, |
|
|
op: expr.op, |
|
|
|
|
|
source, |
|
|
}) |
|
|
}) |
|
|
|
|
|
|
|
|
return [name, expr_stmts] |
|
|
|
|
|
|
|
|
expr_stmts = stmts |
|
|
} else { |
|
|
} else { |
|
|
const [left_source, left_stmts] = convertExpr(state, expr.left) |
|
|
|
|
|
const [right_source, right_stmts] = convertExpr(state, expr.right) |
|
|
|
|
|
const expr_stmts = [...left_stmts, ...right_stmts] |
|
|
|
|
|
|
|
|
const [left_source, left_stmts] = getSource(state, expr.left) |
|
|
|
|
|
const [right_source, right_stmts] = getSource(state, expr.right) |
|
|
|
|
|
|
|
|
const name = `temp${state.nextID++}` |
|
|
|
|
|
expr_stmts.push({ |
|
|
|
|
|
dest: name, |
|
|
|
|
|
|
|
|
const stmts = [...left_stmts, ...right_stmts] |
|
|
|
|
|
stmts.push({ |
|
|
|
|
|
dest, |
|
|
op: expr.op, |
|
|
op: expr.op, |
|
|
source: left_source, |
|
|
source: left_source, |
|
|
source1: right_source, |
|
|
source1: right_source, |
|
|
}) |
|
|
}) |
|
|
|
|
|
|
|
|
return [name, expr_stmts] |
|
|
|
|
|
|
|
|
expr_stmts = stmts |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return expr_stmts |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const getSource = (state: IRState, expr: Expr): [string | number, Array<SSA>] => { |
|
|
|
|
|
if (typeof expr === "number" || typeof expr === "string") { |
|
|
|
|
|
return [expr, []] |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const source = `temp${state.nextID++}` |
|
|
|
|
|
const stmts = convertExpr(state, source, expr) |
|
|
|
|
|
return [source, stmts] |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
export const prettyPrintIR = (ssa: SSA): string => { |
|
|
export const prettyPrintIR = (ssa: SSA): string => { |
|
|
let output = "" |
|
|
let output = "" |
|
|
|
|
|
|
|
|
if ("source1" in ssa) { |
|
|
if ("source1" in ssa) { |
|
|
output = `${ssa.dest} = ${ssa.source} ${ssa.op} ${ssa.source1}` |
|
|
|
|
|
|
|
|
output = `${ssa.dest} = ${ssa.op}(${ssa.source}, ${ssa.source1})` |
|
|
} else if ("op" in ssa) { |
|
|
} else if ("op" in ssa) { |
|
|
output = `${ssa.dest} = ${ssa.op} ${ssa.source}` |
|
|
|
|
|
|
|
|
output = `${ssa.dest} = ${ssa.op}(${ssa.source})` |
|
|
} else { |
|
|
} else { |
|
|
output = `${ssa.dest} = ${ssa.source}` |
|
|
output = `${ssa.dest} = ${ssa.source}` |
|
|
} |
|
|
} |
|
|