feat: implemented println and exit

This commit is contained in:
Barf-Vader
2025-02-21 22:53:20 +00:00
parent 67f7e64b95
commit 02e741c52e
2 changed files with 158 additions and 9 deletions

View File

@@ -0,0 +1,111 @@
package wacc
import scala.collection.mutable.LinkedHashMap
import scala.collection.mutable.ListBuffer
object asmGenerator {
import microWacc._
import assemblyIR._
import wacc.types._
def generateAsm(microProg: Program): List[AsmLine] = {
given stack: LinkedHashMap[Ident, Int] = LinkedHashMap[Ident, Int]()
given strings: ListBuffer[String] = ListBuffer[String]()
val Program(funcs, main) = microProg
val progAsm =
LabelDef("main") ::
main.flatMap(generateStmt) ++
List(assemblyIR.Return()) ++
generateFuncs()
val strDirs = strings.toList.zipWithIndex.flatMap { case (str, i) =>
List(Directive.Int(str.size), LabelDef(s".L.str$i:"), Directive.Asciz(str))
}
List(Directive.IntelSyntax, Directive.Global("main"), Directive.RoData) ++
strDirs ++
List(Directive.Text) ++
progAsm
}
//TODO
def generateFuncs()(using stack: LinkedHashMap[Ident, Int], strings: ListBuffer[String]): List[AsmLine] = {
List()
}
def generateStmt(stmt: Stmt)(using stack: LinkedHashMap[Ident, Int], strings: ListBuffer[String]): List[AsmLine] =
stmt match {
case microWacc.Call(Builtin.Exit, code :: _) =>
alignStack() ++
evalExprIntoReg(code, Register(RegSize.R64, RegName.DI)) ++
List(assemblyIR.Call(CLibFunc.Exit))
case microWacc.Call(Builtin.Println, expr :: _) =>
alignStack() ++
evalExprIntoReg(expr, Register(RegSize.R64, RegName.DI)) ++
List(
assemblyIR.Call(CLibFunc.Puts),
Move(Register(RegSize.R64, RegName.DI), ImmediateVal(0)),
assemblyIR.Call(CLibFunc.Fflush)) ++
restoreStack()
case microWacc.Call(Builtin.ReadInt, expr :: _) =>
List()
case Assign(lhs, rhs) =>
lhs match {
case ident: Ident =>
stack += (ident -> stack.size)
evalExprIntoReg(rhs, Register(RegSize.R64, RegName.AX)) ++
List(Push(Register(RegSize.R64, RegName.AX)))
case _ => List()
}
case _ => List()
}
def evalExprIntoReg(expr: Expr, dest: Register)
(using stack: LinkedHashMap[Ident, Int], strings: ListBuffer[String]): List[AsmLine] = {
var src: Src = ImmediateVal(0) // Placeholder
(expr match {
case IntLiter(v) =>
src = ImmediateVal(v)
List()
case ident: Ident =>
List(
Move(
dest,
IndexAddress(Register(RegSize.R64, RegName.SP), (stack.size - stack(ident)) * 4)
)
)
case ArrayLiter(elems) => expr.ty match {
case KnownType.Char =>
strings += elems.mkString
List(
Load(dest, IndexAddress(Register(RegSize.R64, RegName.IP),LabelArg(s".L.str${strings.size - 1}")))
)
case _ => List()
}
case _ => List()
}) ++ List(Move(dest, src))
}
def alignStack()(using stack: LinkedHashMap[Ident, Int]): List[AsmLine] = {
List(
And(Register(RegSize.R64, RegName.SP), ImmediateVal(-16)),
// Store stack pointer in rbp as it is callee saved
Push(Register(RegSize.R64, RegName.BP)),
Move(Register(RegSize.R64, RegName.BP), Register(RegSize.R64, RegName.SP))
)
}
def restoreStack()(using stack: LinkedHashMap[Ident, Int]): List[AsmLine] = {
List(
Move(Register(RegSize.R64, RegName.SP), Register(RegSize.R64, RegName.BP)),
Pop(Register(RegSize.R64, RegName.BP))
)
}
// def saveRegs(regList: List[Register]): List[AsmLine] = regList.map(Push(_))
// def restoreRegs(regList: List[Register]): List[AsmLine] = regList.reverse.map(Pop(_))
}