A "high-level" language for the Gameboy
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

66 lines
1.6 KiB

  1. import type { BinaryOp, UnaryOp } from "../ast"
  2. import type { Loc } from "./loc"
  3. export type Operand = Loc | number
  4. export type AbsInsnCopy = {
  5. type: "copy",
  6. dest: Loc,
  7. source: Operand,
  8. }
  9. type UnaryInsn<Op> = {
  10. type: "unary",
  11. dest: Loc,
  12. op: Op,
  13. source: Operand,
  14. }
  15. // NOTE: We convert binary -> unary when going SSA3 -> SSA2
  16. export type AbsInsn2Unary = UnaryInsn<UnaryOp | BinaryOp>
  17. // Abstract instruction in two-address form
  18. export type AbsInsn2 = AbsInsnCopy | AbsInsn2Unary
  19. type CopyFn<A> = (dest: Loc, source: Operand) => A
  20. type UnaryFn<Op, A> = (dest: Loc, op: Op, source: Operand) => A
  21. type UnaryFn2<A> = UnaryFn<UnaryOp | BinaryOp, A>
  22. export const insnReduce2 = <A>(copy: CopyFn<A>, unary: UnaryFn2<A>, insn: AbsInsn2): A =>
  23. insn.type === 'copy'
  24. ? copy(insn.dest, insn.source)
  25. : unary(insn.dest, insn.op, insn.source)
  26. export type AbsInsn3Unary = UnaryInsn<UnaryOp>
  27. export type AbsInsnBinary = {
  28. type: "binary",
  29. dest: Loc,
  30. source: Operand,
  31. op: BinaryOp,
  32. source1: Operand
  33. }
  34. // Abstract instruction in three-address form
  35. export type AbsInsn3 = AbsInsnCopy | AbsInsn3Unary | AbsInsnBinary
  36. export const CopyInsn = (dest: Loc, source: Operand): AbsInsnCopy => ({
  37. type: 'copy',
  38. dest,
  39. source,
  40. })
  41. export const UnaryInsn = <Op>(dest: Loc, op: Op, source: Operand): UnaryInsn<Op> => ({
  42. type: 'unary',
  43. dest,
  44. op,
  45. source,
  46. })
  47. export const BinaryInsn = (dest: Loc, source: Operand, op: BinaryOp, source1: Operand): AbsInsnBinary => ({
  48. type: 'binary',
  49. dest,
  50. source,
  51. op,
  52. source1,
  53. })