sink/src tests

This commit is contained in:
Mark Canlas 2020-08-28 02:50:34 -04:00
parent 151f68a55d
commit 3c1d811aef
9 changed files with 124 additions and 8 deletions

View File

@ -1,5 +1,11 @@
package com.htmlism.nescant
object GlobalAddress {}
object GlobalAddress {
implicit val sourceForGlobalAddress: Source[GlobalAddress] =
new Source[GlobalAddress] {}
implicit val sinkForGlobalAddress: Sink[GlobalAddress] =
new Sink[GlobalAddress] {}
}
case class GlobalAddress(n: Int)

View File

@ -1,7 +1,10 @@
package com.htmlism.nescant
sealed trait Operand
trait Operand[A] {
def encode(x: A): String
}
case class LiteralOperand(value: String) extends Operand
case class NamedOperand(name: String, value: String) extends Operand
object Operand {
implicit val operandForInt: Operand[Int] =
_.toString
}

View File

@ -0,0 +1,21 @@
package com.htmlism.nescant
/**
* @param name A name for this location, used to alias its address
*
* @tparam A The input type of the write and the output type of the read
*/
case class ReadWriteLocation[A](name: String, address: ZeroPageAddress)
object ReadWriteLocation {
implicit def sourceForReadWriteLocation[A: Operand]: Source[ReadWriteLocation[A]] =
new Source[ReadWriteLocation[A]] {}
implicit def sinkForReadWriteLocation[A: Operand]: Sink[ReadWriteLocation[A]] =
new Sink[ReadWriteLocation[A]] {}
implicit def operandForReadWriteLocation[A: Operand]: Operand[ReadWriteLocation[A]] =
new Operand[ReadWriteLocation[A]] {
def encode(x: ReadWriteLocation[A]): String = ""
}
}

View File

@ -3,6 +3,6 @@ package com.htmlism.nescant
trait Source[A]
object Source {
// TODO int can be a source
// TODO a volitile device can be a source
implicit val sourceForInt: Source[Int] =
new Source[Int] {}
}

View File

@ -0,0 +1,22 @@
package com.htmlism.nescant
//import com.htmlism.mos6502.model._
/**
* For a memory-mapped device that may return different values across multiple reads (e.g. a random number generator)
*
* @param name A name for this device, used to alias its address
*
* @tparam A The output type of the read
*/
case class VolatileDevice[A](name: String, address: ZeroPageAddress)
object VolatileDevice {
implicit def sourceForVolatileDevice[A: Operand]: Source[VolatileDevice[A]] =
new Source[VolatileDevice[A]] {}
implicit def operandForVolatileDevice[A: Operand]: Operand[VolatileDevice[A]] =
new Operand[VolatileDevice[A]] {
def encode(x: VolatileDevice[A]): String = ""
}
}

View File

@ -1,5 +1,11 @@
package com.htmlism.nescant
object ZeroPageAddress {}
object ZeroPageAddress {
implicit val sourceForZeroPageAddress: Source[ZeroPageAddress] =
new Source[ZeroPageAddress] {}
implicit val sinkForZeroPageAddress: Sink[ZeroPageAddress] =
new Sink[ZeroPageAddress] {}
}
case class ZeroPageAddress(n: Int)

View File

@ -8,4 +8,10 @@ package object dsl {
def g: GlobalAddress =
GlobalAddress(n)
}
implicit class SinkOps[A: Sink](x: A) {
def write[B: Source](src: B): Unit = {
val _ = src
}
}
}

View File

@ -0,0 +1,21 @@
package com.htmlism.nescant
package dsl
import org.scalatest.flatspec._
import org.scalatest.matchers._
class SinkSpec extends AnyFlatSpec with should.Matchers {
"A zero page address" should "be a sink" in {
123.z.write(456)
}
"A global address" should "be a sink" in {
123.g.write(456)
}
"A read write location" should "be a sink" in {
val sink = ReadWriteLocation[Int]("", 0.z)
sink.write(456)
}
}

View File

@ -0,0 +1,31 @@
package com.htmlism.nescant
package dsl
import org.scalatest.flatspec._
import org.scalatest.matchers._
class SourceSpec extends AnyFlatSpec with should.Matchers {
"A number" should "be a source" in {
123.z.write(456)
}
"A zero page address" should "be a source" in {
123.z.write(456.z)
}
"A global address" should "be a source" in {
123.z.write(456.g)
}
"A volatile device" should "be a source" in {
val src = VolatileDevice[Int]("", 0.z)
123.z.write(src)
}
"A read write location" should "be a source" in {
val src = ReadWriteLocation[Int]("", 0.z)
123.z.write(src)
}
}