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 loop
init:
RTS
loop:
RTS
initSnake:
RTS

View File

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

View File

@ -4,9 +4,9 @@ import cats.syntax.all.*
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 =
MetaIntent.Jump(name)
MetaIntent.Jump(name, () => intents)
def attach: NamedCodeBlock =
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
import scala.annotation.tailrec
import scala.collection.immutable.ListMap
import scala.util.chaining.*
import com.htmlism.firepower.core.AsmBlock.Intent
@ -14,6 +16,11 @@ object SnakeEasy6502:
lazy val init =
Subroutine("init")
.copy(intents =
List(
initSnake.call
)
)
lazy val loop =
Subroutine("loop")
@ -26,7 +33,37 @@ object SnakeEasy6502:
.AnonymousCodeBlock(xs.map(MetaIntent.Jump.toIntent))
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] =
(firstCodeBlock(program) :: callGraph(program))