mirror of
https://github.com/mcanlas/6502-opcodes.git
synced 2024-06-12 13:29:32 +00:00
103 lines
2.7 KiB
Scala
103 lines
2.7 KiB
Scala
package com.htmlism.mos6502.dsl
|
|
|
|
import scala.collection.immutable.ListSet
|
|
import scala.collection.mutable.ListBuffer
|
|
|
|
import cats.syntax.all._
|
|
|
|
case class AsmDocument(xs: List[TopLevelAsmDocumentFragment]):
|
|
def toAsm: String =
|
|
xs
|
|
.map(_.toAsm)
|
|
.mkString("\n\n")
|
|
|
|
class AsmDocumentContext:
|
|
private val xs: ListBuffer[TopLevelAsmDocumentFragment] =
|
|
ListBuffer()
|
|
|
|
private var jumps: ListSet[Subroutine] =
|
|
ListSet()
|
|
|
|
def push(x: TopLevelAsmDocumentFragment): Unit =
|
|
xs.append(x)
|
|
|
|
def addJumpRegistry(ys: ListSet[Subroutine]): Unit =
|
|
jumps = jumps ++ ys
|
|
|
|
def toDoc: AsmDocument =
|
|
val asmFragmentsAndSubroutines =
|
|
xs.toList ::: jumps.toList ++ jumps.flatMap(_.jumpRegistry).toList
|
|
|
|
AsmDocument(asmFragmentsAndSubroutines)
|
|
|
|
sealed trait TopLevelAsmDocumentFragment:
|
|
def toAsm: String
|
|
|
|
case class AsmFragment(xs: List[Statement]) extends TopLevelAsmDocumentFragment:
|
|
def toAsm: String =
|
|
xs.map(_.toAsm).mkString("\n")
|
|
|
|
case class Subroutine(name: String, fragment: AsmFragment, jumpRegistry: ListSet[Subroutine])
|
|
extends TopLevelAsmDocumentFragment:
|
|
def toAsm: String =
|
|
name + ":" + "\n" + fragment.toAsm
|
|
|
|
case class DefinitionGroup(comment: String, xs: List[Definition[_]]) extends TopLevelAsmDocumentFragment:
|
|
def toAsm: String =
|
|
val groupCommentLine =
|
|
"; " + comment
|
|
|
|
val definitionLines =
|
|
xs
|
|
.map { d =>
|
|
d.comment match
|
|
case Some(c) =>
|
|
f"define ${d.name}%-20s${d.value} ; $c"
|
|
|
|
case None =>
|
|
f"define ${d.name}%-20s${d.value}"
|
|
}
|
|
|
|
(groupCommentLine :: definitionLines)
|
|
.mkString("\n")
|
|
|
|
class DefinitionGroupContext:
|
|
private val xs: ListBuffer[Definition[_]] =
|
|
ListBuffer()
|
|
|
|
def push[A](x: A)(using ev: NamedResource[A]): Unit =
|
|
ev
|
|
.toDefinitions(x)
|
|
.foreach(xs.append)
|
|
|
|
def toGroup(s: String): DefinitionGroup =
|
|
DefinitionGroup(s, xs.toList)
|
|
|
|
/**
|
|
* @param comment
|
|
* Typically used by resources to describe their type safety
|
|
*/
|
|
case class Definition[A](name: String, x: A, comment: Option[String])(using ev: DefinitionValue[A]):
|
|
lazy val value: String =
|
|
ev
|
|
.value(x)
|
|
|
|
object Definition:
|
|
given namedResourceForDefinition[A]: NamedResource[Definition[A]] =
|
|
new NamedResource[Definition[A]]:
|
|
def toDefinitions(x: Definition[A]): List[Definition[_]] =
|
|
List(x)
|
|
|
|
def apply[A: DefinitionValue](name: String, x: A): Definition[A] =
|
|
Definition(name, x, None)
|
|
|
|
def apply[A: DefinitionValue](name: String, x: A, comment: String): Definition[A] =
|
|
Definition(name, x, comment.some)
|
|
|
|
class AsmBlockContext:
|
|
private val xs: ListBuffer[Statement] =
|
|
ListBuffer()
|
|
|
|
def push(x: Statement): Unit =
|
|
xs.append(x)
|