|
|
- import type { BinaryOp, UnaryOp } from "../ast"
- import type { Loc } from "./loc"
-
- export type Operand = Loc | number
-
- export type AbsInsnCopy = {
- type: "copy",
- dest: Loc,
- source: Operand,
- }
-
- export type AbsInsnGoto = {
- type: "goto",
- dest: string,
- }
-
- export type AbsInsnLabel = {
- type: "label",
- dest: string,
- }
-
- type UnaryInsn<Op> = {
- type: "unary",
- dest: Loc,
- op: Op,
- source: Operand,
- }
-
- // NOTE: We convert binary -> unary when going SSA3 -> SSA2
- export type AbsInsn2Unary = UnaryInsn<UnaryOp | BinaryOp>
-
- // Abstract instruction in two-address form
- export type AbsInsn2 = AbsInsnCopy | AbsInsnLabel | AbsInsnGoto | AbsInsn2Unary
-
- 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 UnaryFn2<A> = UnaryFn<UnaryOp | BinaryOp, A>
-
- 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 AbsInsnBinary = {
- type: "binary",
- dest: Loc,
- source: Operand,
- op: BinaryOp,
- source1: Operand
- }
-
- // Abstract instruction in three-address form
- export type AbsInsn3 = AbsInsnCopy | AbsInsnLabel | AbsInsnGoto | AbsInsn3Unary | AbsInsnBinary
-
- export const CopyInsn = (dest: Loc, source: Operand): AbsInsnCopy => ({
- type: 'copy',
- dest,
- source,
- })
-
- export const UnaryInsn = <Op>(dest: Loc, op: Op, source: Operand): UnaryInsn<Op> => ({
- type: 'unary',
- dest,
- op,
- source,
- })
-
- export const BinaryInsn = (dest: Loc, source: Operand, op: BinaryOp, source1: Operand): AbsInsnBinary => ({
- type: 'binary',
- dest,
- source,
- op,
- source1,
- })
-
- export const LabelInsn = (dest: string): AbsInsnLabel => ({
- type: 'label',
- dest,
- })
-
- export const GotoInsn = (dest: string): AbsInsnGoto => ({
- type: 'goto',
- dest,
- })
|