Skip to content

Instantly share code, notes, and snippets.

@chadselph
Created August 6, 2016 02:55
Show Gist options
  • Save chadselph/957d1748b6e0ae45845dafb186af978e to your computer and use it in GitHub Desktop.
Save chadselph/957d1748b6e0ae45845dafb186af978e to your computer and use it in GitHub Desktop.
object Test extends App {
trait BitPrinter[B <: BitDescription] {
def printBits(value: Long): (List[String], Long)
}
trait BitDescription
trait BitField extends BitDescription
trait BitFieldWidth1 extends BitField
trait BitFieldWidth2 extends BitField
trait BitFieldWidth3 extends BitField
trait BitFieldWidth4 extends BitField
trait BitFieldWidth8 extends BitField
def fixedWidthBitFieldPrinter[B <: BitField](width: Int): BitPrinter[B] = new BitPrinter[B] {
final def printLastHex(value: Long, n: Int): String = s"$n bits: ${(value & ((1 << n) - 1)).toHexString}"
final def printLastBinary(value: Long, n: Int): String = s"$n bits: ${(value & ((1 << n) - 1)).toBinaryString}"
override def printBits(value: Long): (List[String], Long) = (List(printLastBinary(value, width)), value >> width)
}
implicit def bfw1printer: BitPrinter[BitFieldWidth1] = fixedWidthBitFieldPrinter(1)
implicit def bfw2printer: BitPrinter[BitFieldWidth2] = fixedWidthBitFieldPrinter(2)
implicit def bfw3printer: BitPrinter[BitFieldWidth3] = fixedWidthBitFieldPrinter(3)
implicit def bfw4printer: BitPrinter[BitFieldWidth4] = fixedWidthBitFieldPrinter(4)
final case class BitCons[H <: BitDescription, T <: BitDescription](head: H, tail: T) extends BitDescription
// sealed class BitNil extends BitDescription
type ::[H <: BitDescription, T <: BitDescription] = BitCons[H, T]
implicit def NextBitConsPrinter[H <: BitDescription : BitPrinter, T <: BitDescription : BitPrinter] = new BitPrinter[BitCons[H, T]] {
override def printBits(value: Long): (List[String], Long) = {
val (head, remainder) = implicitly[BitPrinter[H]].printBits(value)
val tail = implicitly[BitPrinter[T]].printBits(remainder)
(head ++ tail._1, tail._2)
}
}
trait BitFieldContainer[Repr <: Long] extends Any {
def value: Repr
type BitFields <: BitDescription
protected def isNthBitSet(bit: Int) = (value & (1 >> bit)) != 0
def showBits(implicit bitPrinter: BitPrinter[BitFields]) = bitPrinter.printBits(value).toString
}
class EsmClass(val value: Long) extends AnyVal with BitFieldContainer[Long] {
type BitFields = BitFieldWidth1 :: BitFieldWidth1 :: BitFieldWidth4
override def toString = showBits
}
println(
new EsmClass(0x25)
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment