definition as typeclass

This commit is contained in:
Mark Canlas 2020-08-26 02:06:54 -04:00
parent da9bd24368
commit dd0cfbf445
8 changed files with 45 additions and 48 deletions

View File

@ -11,7 +11,7 @@ object ZeroAddress {
MemoryLocation
def toShow(x: ZeroAddress): String =
String.format("global address 0x%02x", x.n)
String.format("zero address 0x%02x", x.n)
def toDefinitionLiteral(x: ZeroAddress): String =
toAddressLiteral(x)

View File

@ -64,8 +64,8 @@ class DefinitionGroupContext {
private val xs: ListBuffer[Definition[_]] =
ListBuffer()
def push(x: Definition[_]): Unit =
xs.append(x)
def push[A](x: A)(implicit ev: Definable[A]): Unit =
xs.append(ev.toDefinition(x))
def toGroup(s: String): DefinitionGroup =
DefinitionGroup(s, xs.toList)
@ -77,6 +77,14 @@ case class Definition[A: Operand](name: String, x: A) {
.toDefinitionLiteral(x)
}
object Definition {
implicit def definitionDefinable[A]: Definable[Definition[A]] =
new Definable[Definition[A]] {
def toDefinition(x: Definition[A]) =
x
}
}
class AsmBlockContext {
private val xs: ListBuffer[Statement] =
ListBuffer()

View File

@ -0,0 +1,5 @@
package com.htmlism.mos6502.dsl
trait Definable[A] {
def toDefinition(x: A): Definition[_]
}

View File

@ -18,3 +18,11 @@ case class ReadWriteLocation[A](name: String, address: Address) {
// ctx.push(STA, ev, s"write ${ev.toShow(x)} to $name ($n)")
}
}
object ReadWriteLocation {
implicit def readWriteLocationDefinable[A]: Definable[ReadWriteLocation[A]] =
new Definable[ReadWriteLocation[A]] {
def toDefinition(x: ReadWriteLocation[A]): Definition[ZeroAddress] =
Definition(x.name, 0x00.z)
}
}

View File

@ -15,3 +15,11 @@ case class VolatileDevice[A](name: String, address: Address) {
// ctx.push(LDA, ev, s"write ${ev.toShow(x)} to $name ($n)")
}
}
object VolatileDevice {
implicit def volatileDeviceDefinable[A]: Definable[VolatileDevice[A]] =
new Definable[VolatileDevice[A]] {
def toDefinition(x: VolatileDevice[A]): Definition[ZeroAddress] =
Definition(x.name, 0x00.z)
}
}

View File

@ -15,17 +15,14 @@ trait AsmDocSyntax {
.push(asmCtx.toFragment)
}
def group[A](s: String)(f: DefinitionGroupContext => A)(implicit ctx: AsmDocumentContext): A = {
def group[A](s: String)(f: DefinitionGroupContext => A)(implicit ctx: AsmDocumentContext): Unit = {
val g: DefinitionGroupContext =
new DefinitionGroupContext
val ret =
f(g)
f(g)
ctx
.push(g.toGroup(s))
ret
}
def enum[A](implicit ctx: AsmDocumentContext, ev: EnumAsm[A]): Unit = {

View File

@ -9,51 +9,13 @@ class DslSpec extends AnyFlatSpec with should.Matchers {
"the dsl" should "compile" in {
val doc =
asmDoc { implicit ctx =>
group("snake things") { implicit g =>
(define("snakeBodyStart", 0x12.z), define("snakeDirection", 0x02.z), define("snakeLength", 0x03.z))
}
group("ASCII values of keys controlling the snake") { implicit g =>
(define("ASCII_w", 0x77.z), define("ASCII_a", 0x61.z), define("ASCII_s", 0x73.z), define("ASCII_d", 0x64.z))
}
group("System variables") { implicit g =>
(define("sysRandom", 0xfe.z), define("sysLastKey", 0xff.z))
}
group("constants test") { implicit g =>
(constant("margin", 16), constant("secret", 42))
}
()
}
doc shouldEqual AsmDocument(
List(
DefinitionGroup(
"snake things",
List(
Definition("snakeBodyStart", 0x12.z),
Definition("snakeDirection", 0x02.z),
Definition("snakeLength", 0x03.z)
)
),
DefinitionGroup(
"ASCII values of keys controlling the snake",
List(
Definition("ASCII_w", 0x77.z),
Definition("ASCII_a", 0x61.z),
Definition("ASCII_s", 0x73.z),
Definition("ASCII_d", 0x64.z)
)
),
DefinitionGroup(
"System variables",
List(
Definition("sysRandom", 0xfe.z),
Definition("sysLastKey", 0xff.z)
)
),
DefinitionGroup(
"constants test",
List(

View File

@ -68,8 +68,8 @@ class Easy6502Spec extends AnyFlatSpec with should.Matchers {
}
"snake" should "compile" in {
val sysRandom = VolatileDevice[Int]("sysRandom", 0xfe.z)
val sysLastKey = VolatileDevice[AsciiValue]("sysLastKey", 0xff.z)
val sysRandom = VolatileDevice[Int]("sysRandom", 0xfe.z)
val sysLastKey = VolatileDevice[AsciiValue]("sysLastKey", 0xff.z)
val appleLocation = ReadWriteLocation[Int]("appleLocation", 0x00.z)
val snakeDirection = ReadWriteLocation[Direction]("snakeDirection", 0x02.z)
@ -135,6 +135,15 @@ class Easy6502Spec extends AnyFlatSpec with should.Matchers {
val doc =
asmDoc { implicit ctx =>
group("6502js") { implicit g =>
g.push(sysRandom)
g.push(sysLastKey)
}
group("snake") { implicit g =>
val _ = g
}
bitField[Direction]
mapping[AsciiValue]