but now with types

This commit is contained in:
Mark Canlas 2022-10-03 01:52:37 -04:00
parent 08bc50f137
commit 474785df8b
3 changed files with 21 additions and 21 deletions

View File

@ -5,18 +5,18 @@ sealed trait Address:
def alias: String
case class ZeroPageAddress(n: Int, alias: String) extends Address
class ZeroPageAddress(val n: Int, val alias: String) extends Address
case class AbsoluteAddress(n: Int, alias: String) extends Address
class AbsoluteAddress(val n: Int, val alias: String) extends Address
sealed trait ReadAddress[A <: Address]:
def addr: A
sealed trait ReadAddress[A] extends Address
sealed trait WriteAddress[A <: Address]:
def addr: A
sealed trait WriteAddress[A] extends Address:
def write[B: Loadable](x: B): syntax.PartiallyAppliedWrite[B, A] =
new syntax.PartiallyAppliedWrite(this, x)
case class Volatile[A <: Address](addr: A) extends ReadAddress[A]
trait Volatile[A] extends ReadAddress[A]
case class ReadWriteAddress[A <: Address](addr: A) extends ReadAddress[A] with WriteAddress[A]
trait ReadWriteAddress[A] extends ReadAddress[A] with WriteAddress[A]
case class WriteOnlyAddress[A <: Address](addr: A) extends WriteAddress[A]
trait WriteOnlyAddress[A] extends WriteAddress[A]

View File

@ -1,11 +1,7 @@
package com.htmlism.scratchpad
package object syntax:
implicit class WriteRegisterOps[B <: Address](reg: WriteAddress[B]):
def write[A: Loadable](x: A): PartiallyAppliedWrite[A, B] =
new PartiallyAppliedWrite(reg, x)
class PartiallyAppliedWrite[A: Loadable, B <: Address](reg: WriteAddress[B], x: A):
class PartiallyAppliedWrite[A: Loadable, B](reg: WriteAddress[B], x: A):
def apply[C: Load: Store: Register]: String =
val literal =
summon[Loadable[A]].show(x)
@ -23,9 +19,9 @@ package object syntax:
s"$loadInstruction $literal"
val second =
s"$storeInstruction ${reg.addr.n.toString}"
s"$storeInstruction ${reg.n.toString}"
val desc =
s"${reg.addr.alias} = $literal, via $register"
s"${reg.alias} = $literal, via $register"
s"$first $second ; $desc"

View File

@ -5,25 +5,29 @@ import org.scalatest.matchers.should._
import com.htmlism.scratchpad.syntax._
object ExampleRegister extends ZeroPageAddress(0x01, "example") with WriteOnlyAddress[ExampleRegister]
class ExampleRegister
class FeatureSpec extends AnyFunSuite with Matchers:
test("zero page address as write only supports writing") {
WriteOnlyAddress(ZeroPageAddress(0x01, "example"))
ExampleRegister
.write(2)[A] shouldBe "LDA 2 STA 1 ; example = 2, via A"
}
test("zero page address as read/write supports writing") {
ReadWriteAddress(ZeroPageAddress(0x01, "example"))
ExampleRegister
.write(2)[A] shouldBe "LDA 2 STA 1 ; example = 2, via A"
}
test("writing to an address can use A, X, and Y registers for bouncing") {
ReadWriteAddress(ZeroPageAddress(0x01, "example"))
ExampleRegister
.write(2)[A] shouldBe "LDA 2 STA 1 ; example = 2, via A"
ReadWriteAddress(ZeroPageAddress(0x01, "example"))
ExampleRegister
.write(2)[X] shouldBe "LDX 2 STX 1 ; example = 2, via X"
ReadWriteAddress(ZeroPageAddress(0x01, "example"))
ExampleRegister
.write(2)[Y] shouldBe "LDY 2 STY 1 ; example = 2, via Y"
}