mirror of
https://github.com/mcanlas/6502-opcodes.git
synced 2025-01-14 03:31:08 +00:00
add support for bit fields and enums
This commit is contained in:
parent
f8c97e31d1
commit
8ac49b7f10
@ -7,5 +7,4 @@ lazy val root =
|
||||
)
|
||||
.withCats
|
||||
.withTesting
|
||||
.withTestingBeta
|
||||
.withOrganizeImports
|
||||
|
@ -15,12 +15,6 @@ object ProjectPlugin extends AutoPlugin {
|
||||
|
||||
def withTesting: Project =
|
||||
p.settings(libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.1" % "test")
|
||||
|
||||
def withTestingBeta: Project =
|
||||
p.settings(
|
||||
libraryDependencies += "com.disneystreaming" %% "weaver-framework" % "0.4.2" % Test,
|
||||
testFrameworks += new TestFramework("weaver.framework.TestFramework")
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ class DefinitionGroupContext {
|
||||
DefinitionGroup(s, xs.toList)
|
||||
}
|
||||
|
||||
case class Definition[A : Operand](name: String, x: A)
|
||||
case class Definition[A: Operand](name: String, x: A)
|
||||
|
||||
class AsmBlockContext {
|
||||
private val xs: ListBuffer[Statement] =
|
||||
@ -40,4 +40,4 @@ class AsmBlockContext {
|
||||
|
||||
def push(x: Statement): Unit =
|
||||
xs.append(x)
|
||||
}
|
||||
}
|
||||
|
9
src/main/scala/com/htmlism/mos6502/dsl/BitField.scala
Normal file
9
src/main/scala/com/htmlism/mos6502/dsl/BitField.scala
Normal file
@ -0,0 +1,9 @@
|
||||
package com.htmlism.mos6502.dsl
|
||||
|
||||
import cats.data.NonEmptyList
|
||||
|
||||
trait BitField[A] {
|
||||
def comment: String
|
||||
|
||||
def labels: NonEmptyList[String]
|
||||
}
|
9
src/main/scala/com/htmlism/mos6502/dsl/EnumAsm.scala
Normal file
9
src/main/scala/com/htmlism/mos6502/dsl/EnumAsm.scala
Normal file
@ -0,0 +1,9 @@
|
||||
package com.htmlism.mos6502.dsl
|
||||
|
||||
import cats.data.NonEmptyList
|
||||
|
||||
trait EnumAsm[A] {
|
||||
def comment: String
|
||||
|
||||
def labels: NonEmptyList[String]
|
||||
}
|
@ -7,8 +7,7 @@ package object dsl {
|
||||
|
||||
f(ctx)
|
||||
|
||||
ctx
|
||||
.toDoc
|
||||
ctx.toDoc
|
||||
}
|
||||
|
||||
def group[A](s: String)(f: DefinitionGroupContext => A)(implicit ctx: AsmDocumentContext): A = {
|
||||
@ -24,7 +23,51 @@ package object dsl {
|
||||
ret
|
||||
}
|
||||
|
||||
def define[A <: Address : Operand](name: String, x: A)(implicit ctx: DefinitionGroupContext): Definition[A] = {
|
||||
def enum[A](implicit ctx: AsmDocumentContext, ev: EnumAsm[A]): Unit = {
|
||||
val (_, xs) =
|
||||
ev.labels
|
||||
.foldLeft(0 -> List.empty[(String, Int)]) {
|
||||
case ((next, acc), s) =>
|
||||
(next + 1) -> (acc :+ (s -> next))
|
||||
}
|
||||
|
||||
val grp =
|
||||
DefinitionGroup(
|
||||
ev.comment,
|
||||
xs
|
||||
.map {
|
||||
case (s, n) =>
|
||||
Definition(s, n)
|
||||
}
|
||||
)
|
||||
|
||||
ctx
|
||||
.push(grp)
|
||||
}
|
||||
|
||||
def bitField[A](implicit ctx: AsmDocumentContext, ev: BitField[A]): Unit = {
|
||||
val (_, xs) =
|
||||
ev.labels
|
||||
.foldLeft(1 -> List.empty[(String, Int)]) {
|
||||
case ((next, acc), s) =>
|
||||
(next << 1) -> (acc :+ (s -> next))
|
||||
}
|
||||
|
||||
val grp =
|
||||
DefinitionGroup(
|
||||
ev.comment,
|
||||
xs
|
||||
.map {
|
||||
case (s, n) =>
|
||||
Definition(s, n)
|
||||
}
|
||||
)
|
||||
|
||||
ctx
|
||||
.push(grp)
|
||||
}
|
||||
|
||||
def define[A <: Address: Operand](name: String, x: A)(implicit ctx: DefinitionGroupContext): Definition[A] = {
|
||||
val definition =
|
||||
Definition(name, x)
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.htmlism.mos6502.dsl
|
||||
|
||||
import cats.data.NonEmptyList
|
||||
import org.scalatest.flatspec._
|
||||
import org.scalatest.matchers._
|
||||
|
||||
@ -9,54 +10,122 @@ class DslSpec extends AnyFlatSpec with should.Matchers {
|
||||
val doc =
|
||||
asmDoc { implicit ctx =>
|
||||
group("snake things") { implicit g =>
|
||||
(define("snakeBodyStart", 0x12.z),
|
||||
define("snakeDirection", 0x02.z),
|
||||
define("snakeLength", 0x03.z))
|
||||
(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))
|
||||
(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))
|
||||
(define("sysRandom", 0xfe.z), define("sysLastKey", 0xff.z))
|
||||
}
|
||||
|
||||
group("constants test") { implicit g =>
|
||||
(constant("margin", 16),
|
||||
constant("secret", 42))
|
||||
(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)
|
||||
)),
|
||||
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(
|
||||
Definition("margin", 16),
|
||||
Definition("secret", 42)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
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)
|
||||
)),
|
||||
"enum" should "compile" in {
|
||||
val doc =
|
||||
asmDoc { implicit ctx =>
|
||||
enum[Foo]
|
||||
}
|
||||
|
||||
DefinitionGroup("System variables", List(
|
||||
Definition("sysRandom", 0xfe.z),
|
||||
Definition("sysLastKey", 0xff.z)
|
||||
)),
|
||||
doc shouldEqual AsmDocument(
|
||||
List(
|
||||
DefinitionGroup(
|
||||
"foo as enum",
|
||||
List(
|
||||
Definition("courage", 0),
|
||||
Definition("wisdom", 1),
|
||||
Definition("power", 2)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
DefinitionGroup("constants test", List(
|
||||
Definition("margin", 16),
|
||||
Definition("secret", 42)
|
||||
))
|
||||
))
|
||||
"bit field" should "compile" in {
|
||||
val doc =
|
||||
asmDoc { implicit ctx =>
|
||||
bitField[Foo]
|
||||
}
|
||||
|
||||
doc shouldEqual AsmDocument(
|
||||
List(
|
||||
DefinitionGroup(
|
||||
"foo as bit field",
|
||||
List(
|
||||
Definition("up", 0x01),
|
||||
Definition("down", 0x02),
|
||||
Definition("left", 0x04),
|
||||
Definition("right", 0x08)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class Foo
|
||||
|
||||
object Foo {
|
||||
implicit val enumFoo: EnumAsm[Foo] =
|
||||
new EnumAsm[Foo] {
|
||||
def comment: String =
|
||||
"foo as enum"
|
||||
|
||||
def labels: NonEmptyList[String] =
|
||||
NonEmptyList.of("courage", "wisdom", "power")
|
||||
}
|
||||
|
||||
implicit val bitFieldFoo: BitField[Foo] =
|
||||
new BitField[Foo] {
|
||||
def comment: String =
|
||||
"foo as bit field"
|
||||
|
||||
def labels: NonEmptyList[String] =
|
||||
NonEmptyList.of("up", "down", "left", "right")
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,34 +0,0 @@
|
||||
package com.htmlism.mos6502.dsl
|
||||
|
||||
import weaver.SimpleIOSuite
|
||||
import cats.effect._
|
||||
|
||||
// Suites must be "objects" for them to be picked by the framework
|
||||
object MySuite extends SimpleIOSuite {
|
||||
|
||||
// A test for non-effectful (pure) functions
|
||||
pureTest("hello pure") {
|
||||
expect("hello".size == 6)
|
||||
}
|
||||
|
||||
val random = IO(java.util.UUID.randomUUID())
|
||||
|
||||
// A test for side-effecting functions
|
||||
simpleTest("hello side-effects") {
|
||||
for {
|
||||
x <- random
|
||||
y <- random
|
||||
} yield expect(x != y)
|
||||
}
|
||||
|
||||
// A test with logs
|
||||
loggedTest("hello logs") { log =>
|
||||
for {
|
||||
x <- random
|
||||
_ <- log.info(s"x : $x")
|
||||
y <- random
|
||||
_ <- log.info(s"y : $y")
|
||||
} yield expect(x != y)
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user