diff --git a/src/main/scala/com/htmlism/mos6502/dsl/AsmDocumentContext.scala b/src/main/scala/com/htmlism/mos6502/dsl/AsmDocumentContext.scala
index 8b1225d..5526274 100644
--- a/src/main/scala/com/htmlism/mos6502/dsl/AsmDocumentContext.scala
+++ b/src/main/scala/com/htmlism/mos6502/dsl/AsmDocumentContext.scala
@@ -16,6 +16,9 @@ class AsmDocumentContext {
def push(x: TopLevelAsmDocumentFragment): Unit =
xs.append(x)
+ def attach(sub: Subroutine): Unit =
+ xs.append(sub)
+
def toDoc: AsmDocument =
AsmDocument(xs.toList)
}
@@ -29,6 +32,11 @@ case class AsmFragment(xs: List[Statement]) extends TopLevelAsmDocumentFragment
xs.map(_.toAsm).mkString("\n")
}
+case class Subroutine(name: String, fragment: AsmFragment) extends TopLevelAsmDocumentFragment {
+ def toAsm: String =
+ name + ":" + "\n" + fragment.toAsm
+}
+
case class DefinitionGroup(comment: String, xs: List[Definition[_]]) extends TopLevelAsmDocumentFragment {
def toAsm: String = {
val commentLine =
diff --git a/src/main/scala/com/htmlism/mos6502/dsl/syntax/AsmSyntax.scala b/src/main/scala/com/htmlism/mos6502/dsl/syntax/AsmSyntax.scala
index cdede0b..3007a02 100644
--- a/src/main/scala/com/htmlism/mos6502/dsl/syntax/AsmSyntax.scala
+++ b/src/main/scala/com/htmlism/mos6502/dsl/syntax/AsmSyntax.scala
@@ -1,8 +1,23 @@
package com.htmlism.mos6502.dsl
package syntax
+import com.htmlism.mos6502.model._
+
trait AsmSyntax {
def label(s: String)(implicit ctx: AssemblyContext): Unit =
ctx
.label(s)
+
+ def sub(s: String)(f: AssemblyContext => Unit): Subroutine = {
+ val ctx: AssemblyContext =
+ new AssemblyContext
+
+ f(ctx)
+
+ Subroutine(s, ctx.toFragment)
+ }
+
+ def jump(s: Subroutine)(implicit ctx: AssemblyContext): Unit =
+ ctx
+ .branch(JSR, s.name)
}
diff --git a/src/test/scala/com/htmlism/mos6502/dsl/Easy6502Spec.scala b/src/test/scala/com/htmlism/mos6502/dsl/Easy6502Spec.scala
index e579519..d8d66ba 100644
--- a/src/test/scala/com/htmlism/mos6502/dsl/Easy6502Spec.scala
+++ b/src/test/scala/com/htmlism/mos6502/dsl/Easy6502Spec.scala
@@ -66,6 +66,26 @@ class Easy6502Spec extends AnyFlatSpec with should.Matchers {
)
}
+ "sub demo" should "compile" in {
+ val init =
+ sub("init") { implicit a =>
+ registers.X.incr
+ }
+
+ val doc =
+ asmDoc { implicit ctx =>
+ asm { implicit a =>
+ jump(init)
+ }
+
+ ctx.attach(init)
+ }
+
+ println(
+ doc.toAsm
+ )
+ }
+
def withAssemblyContext(f: AssemblyContext => Unit): AssemblyContext = {
val ctx: AssemblyContext =
new AssemblyContext