mirror of
https://github.com/mcanlas/6502-opcodes.git
synced 2024-09-25 23:56:38 +00:00
45 lines
1.1 KiB
Scala
45 lines
1.1 KiB
Scala
package com.htmlism
|
|
|
|
import scala.annotation.tailrec
|
|
|
|
/**
|
|
* Given an `Int`, destructure it into smaller `Int`s that use less bits
|
|
*/
|
|
trait BitExtractor[A]:
|
|
self =>
|
|
|
|
def length: Int
|
|
|
|
def unapply(n: Int): Option[A]
|
|
|
|
/**
|
|
* A combinator for appending one extractor to another
|
|
*/
|
|
def >>[B](that: BitExtractor[B]): BitExtractor[(A, B)] =
|
|
new BitExtractor[(A, B)]:
|
|
def length: Int = self.length + that.length
|
|
|
|
def unapply(n: Int): Option[(A, B)] =
|
|
for
|
|
b <- that.unapply(n)
|
|
shifted = n >> that.length
|
|
a <- self.unapply(shifted)
|
|
yield (a, b)
|
|
|
|
object AtomExtractor:
|
|
@tailrec
|
|
def pow(ex: Int, acc: Int = 1): Int =
|
|
if ex == 0 then acc
|
|
else pow(ex - 1, acc * 2)
|
|
|
|
abstract class PrimitiveBitExtractor(val length: Int) extends BitExtractor[Int]:
|
|
private lazy val mask =
|
|
AtomExtractor.pow(length) - 1
|
|
|
|
def unapply(n: Int): Option[Int] =
|
|
Some(n & mask)
|
|
|
|
object OneBit extends PrimitiveBitExtractor(1)
|
|
object TwoBits extends PrimitiveBitExtractor(2)
|
|
object ThreeBits extends PrimitiveBitExtractor(3)
|