From 0a8dd843b6eaee5f0e6f3d79921caad67d7f1d0d Mon Sep 17 00:00:00 2001 From: Forest Belton Date: Tue, 14 Sep 2021 19:03:10 -0400 Subject: [PATCH] Finish binary operation support and reduce temporaries in IR generation --- example.gby | 2 +- lib/ir.ts | 57 ++++++++++++++++++++++++++++------------------------- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/example.gby b/example.gby index 8d0e5a6..6b14518 100644 --- a/example.gby +++ b/example.gby @@ -1,4 +1,4 @@ u8 x; u8 y; -x <- y + 2; +x <- -y + 3; diff --git a/lib/ir.ts b/lib/ir.ts index 4a07c32..5f2c84f 100644 --- a/lib/ir.ts +++ b/lib/ir.ts @@ -32,55 +32,58 @@ export const convertIR = (stmts: Array): Array => { } 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 + return convertExpr(state, stmt.args.name, stmt.args.expr) } -export const convertExpr = (state: IRState, expr: Expr): [string | number, Array] => { +export const convertExpr = (state: IRState, dest: string, expr: Expr): Array => { + let expr_stmts = [] + if (typeof expr === "number" || typeof expr === "string") { - return [expr, []] + expr_stmts = [{ dest, source: expr }] } 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, + source, }) - return [name, expr_stmts] + expr_stmts = stmts } 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, source: left_source, source1: right_source, }) - return [name, expr_stmts] + expr_stmts = stmts } + + return expr_stmts +} + +const getSource = (state: IRState, expr: Expr): [string | number, Array] => { + 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 => { let output = "" 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) { - output = `${ssa.dest} = ${ssa.op} ${ssa.source}` + output = `${ssa.dest} = ${ssa.op}(${ssa.source})` } else { output = `${ssa.dest} = ${ssa.source}` }