|
@ -9,6 +9,16 @@ export type AbsInsnCopy = { |
|
|
source: Operand, |
|
|
source: Operand, |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
export type AbsInsnGoto = { |
|
|
|
|
|
type: "goto", |
|
|
|
|
|
dest: string, |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
export type AbsInsnLabel = { |
|
|
|
|
|
type: "label", |
|
|
|
|
|
dest: string, |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
type UnaryInsn<Op> = { |
|
|
type UnaryInsn<Op> = { |
|
|
type: "unary", |
|
|
type: "unary", |
|
|
dest: Loc, |
|
|
dest: Loc, |
|
@ -20,16 +30,31 @@ type UnaryInsn = { |
|
|
export type AbsInsn2Unary = UnaryInsn<UnaryOp | BinaryOp> |
|
|
export type AbsInsn2Unary = UnaryInsn<UnaryOp | BinaryOp> |
|
|
|
|
|
|
|
|
// Abstract instruction in two-address form
|
|
|
// Abstract instruction in two-address form
|
|
|
export type AbsInsn2 = AbsInsnCopy | AbsInsn2Unary |
|
|
|
|
|
|
|
|
export type AbsInsn2 = AbsInsnCopy | AbsInsnLabel | AbsInsnGoto | AbsInsn2Unary |
|
|
|
|
|
|
|
|
type CopyFn<A> = (dest: Loc, source: Operand) => A |
|
|
type CopyFn<A> = (dest: Loc, source: Operand) => A |
|
|
|
|
|
type StringFn<A> = (name: string) => A |
|
|
type UnaryFn<Op, A> = (dest: Loc, op: Op, source: Operand) => A |
|
|
type UnaryFn<Op, A> = (dest: Loc, op: Op, source: Operand) => A |
|
|
type UnaryFn2<A> = UnaryFn<UnaryOp | BinaryOp, A> |
|
|
type UnaryFn2<A> = UnaryFn<UnaryOp | BinaryOp, A> |
|
|
|
|
|
|
|
|
export const insnReduce2 = <A>(copy: CopyFn<A>, unary: UnaryFn2<A>, insn: AbsInsn2): A => |
|
|
|
|
|
insn.type === 'copy' |
|
|
|
|
|
? copy(insn.dest, insn.source) |
|
|
|
|
|
: unary(insn.dest, insn.op, insn.source) |
|
|
|
|
|
|
|
|
export const insnReduce2 = <A>( |
|
|
|
|
|
copy: CopyFn<A>, |
|
|
|
|
|
label: StringFn<A>, |
|
|
|
|
|
goto: StringFn<A>, |
|
|
|
|
|
unary: UnaryFn2<A>, |
|
|
|
|
|
insn: AbsInsn2 |
|
|
|
|
|
): A => { |
|
|
|
|
|
switch (insn.type) { |
|
|
|
|
|
case 'copy': |
|
|
|
|
|
return copy(insn.dest, insn.source) |
|
|
|
|
|
case 'label': |
|
|
|
|
|
return label(insn.dest) |
|
|
|
|
|
case 'goto': |
|
|
|
|
|
return goto(insn.dest) |
|
|
|
|
|
case 'unary': |
|
|
|
|
|
return unary(insn.dest, insn.op, insn.source) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
export type AbsInsn3Unary = UnaryInsn<UnaryOp> |
|
|
export type AbsInsn3Unary = UnaryInsn<UnaryOp> |
|
|
|
|
|
|
|
@ -42,7 +67,7 @@ export type AbsInsnBinary = { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Abstract instruction in three-address form
|
|
|
// Abstract instruction in three-address form
|
|
|
export type AbsInsn3 = AbsInsnCopy | AbsInsn3Unary | AbsInsnBinary |
|
|
|
|
|
|
|
|
export type AbsInsn3 = AbsInsnCopy | AbsInsnLabel | AbsInsnGoto | AbsInsn3Unary | AbsInsnBinary |
|
|
|
|
|
|
|
|
export const CopyInsn = (dest: Loc, source: Operand): AbsInsnCopy => ({ |
|
|
export const CopyInsn = (dest: Loc, source: Operand): AbsInsnCopy => ({ |
|
|
type: 'copy', |
|
|
type: 'copy', |
|
@ -64,3 +89,13 @@ export const BinaryInsn = (dest: Loc, source: Operand, op: BinaryOp, source1: Op |
|
|
op, |
|
|
op, |
|
|
source1, |
|
|
source1, |
|
|
}) |
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
export const LabelInsn = (dest: string): AbsInsnLabel => ({ |
|
|
|
|
|
type: 'label', |
|
|
|
|
|
dest, |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
export const GotoInsn = (dest: string): AbsInsnGoto => ({ |
|
|
|
|
|
type: 'goto', |
|
|
|
|
|
dest, |
|
|
|
|
|
}) |