6502-opcodes/src/main/scala/com/htmlism/mos6502/dsl/AsmDocumentContext.scala

103 lines
2.7 KiB
Scala
Raw Normal View History

2020-08-15 18:38:08 +00:00
package com.htmlism.mos6502.dsl
2020-08-21 07:11:27 +00:00
import scala.collection.immutable.ListSet
2020-08-15 18:38:08 +00:00
import scala.collection.mutable.ListBuffer
2023-10-03 20:15:10 +00:00
import cats.syntax.all.*
2020-08-26 06:32:27 +00:00
2022-02-14 23:11:45 +00:00
case class AsmDocument(xs: List[TopLevelAsmDocumentFragment]):
2020-08-16 05:17:39 +00:00
def toAsm: String =
xs
.map(_.toAsm)
.mkString("\n\n")
2020-08-15 18:38:08 +00:00
2022-02-14 23:11:45 +00:00
class AsmDocumentContext:
2020-08-15 18:38:08 +00:00
private val xs: ListBuffer[TopLevelAsmDocumentFragment] =
ListBuffer()
2020-08-21 07:11:27 +00:00
private var jumps: ListSet[Subroutine] =
ListSet()
2020-08-15 18:38:08 +00:00
def push(x: TopLevelAsmDocumentFragment): Unit =
xs.append(x)
2020-08-21 07:11:27 +00:00
def addJumpRegistry(ys: ListSet[Subroutine]): Unit =
jumps = jumps ++ ys
2022-02-14 23:11:45 +00:00
def toDoc: AsmDocument =
2020-08-21 07:11:27 +00:00
val asmFragmentsAndSubroutines =
2020-08-21 20:43:23 +00:00
xs.toList ::: jumps.toList ++ jumps.flatMap(_.jumpRegistry).toList
2020-08-16 16:55:21 +00:00
2020-08-21 07:11:27 +00:00
AsmDocument(asmFragmentsAndSubroutines)
2020-08-15 18:38:08 +00:00
2022-02-14 23:11:45 +00:00
sealed trait TopLevelAsmDocumentFragment:
2020-08-16 05:17:39 +00:00
def toAsm: String
2020-08-15 18:38:08 +00:00
2022-02-14 23:11:45 +00:00
case class AsmFragment(xs: List[Statement]) extends TopLevelAsmDocumentFragment:
2020-08-16 05:17:39 +00:00
def toAsm: String =
xs.map(_.toAsm).mkString("\n")
2020-08-15 18:38:08 +00:00
2020-08-21 20:43:23 +00:00
case class Subroutine(name: String, fragment: AsmFragment, jumpRegistry: ListSet[Subroutine])
2022-02-14 23:11:45 +00:00
extends TopLevelAsmDocumentFragment:
2020-08-16 16:55:21 +00:00
def toAsm: String =
name + ":" + "\n" + fragment.toAsm
2022-02-14 23:11:45 +00:00
case class DefinitionGroup(comment: String, xs: List[Definition[_]]) extends TopLevelAsmDocumentFragment:
def toAsm: String =
2020-08-26 06:37:12 +00:00
val groupCommentLine =
2020-08-16 05:17:39 +00:00
"; " + comment
val definitionLines =
xs
2020-08-26 06:37:12 +00:00
.map { d =>
2022-02-14 23:11:45 +00:00
d.comment match
2020-08-26 06:37:12 +00:00
case Some(c) =>
f"define ${d.name}%-20s${d.value} ; $c"
2020-08-16 05:17:39 +00:00
2020-08-26 06:37:12 +00:00
case None =>
f"define ${d.name}%-20s${d.value}"
}
(groupCommentLine :: definitionLines)
2020-08-16 05:17:39 +00:00
.mkString("\n")
2020-08-15 18:38:08 +00:00
2022-02-14 23:11:45 +00:00
class DefinitionGroupContext:
2020-08-15 18:38:08 +00:00
private val xs: ListBuffer[Definition[_]] =
ListBuffer()
2023-06-19 09:30:17 +00:00
def push[A](x: A)(using ev: NamedResource[A]): Unit =
2020-08-26 06:15:40 +00:00
ev
.toDefinitions(x)
.foreach(xs.append)
2020-08-15 18:38:08 +00:00
2020-08-15 18:45:08 +00:00
def toGroup(s: String): DefinitionGroup =
DefinitionGroup(s, xs.toList)
2020-08-15 18:38:08 +00:00
2020-08-26 06:37:12 +00:00
/**
2021-09-06 08:16:08 +00:00
* @param comment
* Typically used by resources to describe their type safety
2020-08-26 06:37:12 +00:00
*/
2023-06-19 09:30:17 +00:00
case class Definition[A](name: String, x: A, comment: Option[String])(using ev: DefinitionValue[A]):
2020-08-16 05:17:39 +00:00
lazy val value: String =
2020-08-26 07:16:19 +00:00
ev
.value(x)
2020-08-15 18:38:08 +00:00
2022-02-14 23:11:45 +00:00
object Definition:
2023-06-19 09:33:38 +00:00
given namedResourceForDefinition[A]: NamedResource[Definition[A]] =
2022-09-07 15:21:22 +00:00
new NamedResource[Definition[A]]:
2020-08-26 06:15:40 +00:00
def toDefinitions(x: Definition[A]): List[Definition[_]] =
List(x)
2020-08-26 06:32:27 +00:00
2020-08-26 07:16:19 +00:00
def apply[A: DefinitionValue](name: String, x: A): Definition[A] =
2020-08-26 06:32:27 +00:00
Definition(name, x, None)
2020-08-26 07:16:19 +00:00
def apply[A: DefinitionValue](name: String, x: A, comment: String): Definition[A] =
2020-08-26 06:32:27 +00:00
Definition(name, x, comment.some)
2020-08-26 06:06:54 +00:00
2022-02-14 23:11:45 +00:00
class AsmBlockContext:
2020-08-15 18:38:08 +00:00
private val xs: ListBuffer[Statement] =
ListBuffer()
def push(x: Statement): Unit =
xs.append(x)