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