with call graph construction

This commit is contained in:
Mark Canlas 2022-12-07 17:49:56 -05:00
parent bf3ad70090
commit 192b36e0a8
4 changed files with 59 additions and 4 deletions

View File

@ -1,3 +1,18 @@
JSR init JSR init
JSR loop JSR loop
init:
RTS
loop:
RTS
initSnake:
RTS

View File

@ -4,10 +4,13 @@ import cats.syntax.all.*
import com.htmlism.firepower.core.* import com.htmlism.firepower.core.*
/**
* Anything that can be compiled into an `Intent`
*/
sealed trait MetaIntent sealed trait MetaIntent
object MetaIntent: object MetaIntent:
case class Jump(target: String) case class Jump(target: String, xs: () => List[MetaIntent.Jump]) extends MetaIntent
object Jump: object Jump:
def toIntent(j: Jump): AsmBlock.Intent = def toIntent(j: Jump): AsmBlock.Intent =

View File

@ -4,9 +4,9 @@ import cats.syntax.all.*
import com.htmlism.firepower.core.AsmBlock._ import com.htmlism.firepower.core.AsmBlock._
case class Subroutine(name: String, intents: List[MetaIntent]): case class Subroutine(name: String, intents: List[MetaIntent.Jump]):
def call: MetaIntent.Jump = def call: MetaIntent.Jump =
MetaIntent.Jump(name) MetaIntent.Jump(name, () => intents)
def attach: NamedCodeBlock = def attach: NamedCodeBlock =
NamedCodeBlock(name, "this is a named block".some, intents.map(_ => Intent("TODO".some, Nil))) NamedCodeBlock(name, "this is a named block".some, intents.map(_ => Intent("TODO".some, Nil)))

View File

@ -1,5 +1,7 @@
package com.htmlism.firepower.demo package com.htmlism.firepower.demo
import scala.annotation.tailrec
import scala.collection.immutable.ListMap
import scala.util.chaining.* import scala.util.chaining.*
import com.htmlism.firepower.core.AsmBlock.Intent import com.htmlism.firepower.core.AsmBlock.Intent
@ -14,6 +16,11 @@ object SnakeEasy6502:
lazy val init = lazy val init =
Subroutine("init") Subroutine("init")
.copy(intents =
List(
initSnake.call
)
)
lazy val loop = lazy val loop =
Subroutine("loop") Subroutine("loop")
@ -26,7 +33,37 @@ object SnakeEasy6502:
.AnonymousCodeBlock(xs.map(MetaIntent.Jump.toIntent)) .AnonymousCodeBlock(xs.map(MetaIntent.Jump.toIntent))
def callGraph(xs: List[MetaIntent.Jump]): List[AsmBlock.NamedCodeBlock] = def callGraph(xs: List[MetaIntent.Jump]): List[AsmBlock.NamedCodeBlock] =
Nil callGraphRecur(ListMap.empty, xs)
.values
.toList
@tailrec
private def callGraphRecur(
callGraph: ListMap[String, AsmBlock.NamedCodeBlock],
todo: List[MetaIntent.Jump]
): ListMap[String, AsmBlock.NamedCodeBlock] =
todo match
case head :: tail =>
if (callGraph.contains(head.target)) callGraphRecur(callGraph, tail)
else
val sub =
AsmBlock.NamedCodeBlock(
head.target,
None,
List(
AsmBlock.Intent(
None,
List(
AsmBlock.Intent.Instruction.zero("rts")
)
)
)
)
callGraphRecur(callGraph.updated(head.target, sub), todo ::: head.xs())
case Nil =>
callGraph
def assemble(opts: AssemblerOptions): List[String] = def assemble(opts: AssemblerOptions): List[String] =
(firstCodeBlock(program) :: callGraph(program)) (firstCodeBlock(program) :: callGraph(program))