feat: add zero division error handling in asmGenerator

This commit is contained in:
Guy C 2025-02-26 07:13:12 +00:00
parent fc2c58002e
commit 07c67dbef6

View File

@ -12,6 +12,24 @@ object asmGenerator {
import wacc.types._
import lexer.escapedChars
abstract case class Error() {
def strLabel: String
def errStr: String
def errLabel: String
def stringDef: Chain[AsmLine] = Chain(
Directive.Int(errStr.size),
LabelDef(strLabel),
Directive.Asciz(errStr)
)
}
object zeroDivError extends Error {
// TODO: is this bad? Can we make an error case class/some other structure?
def strLabel = ".L._errDivZero_str0"
def errStr = "fatal error: division or modulo by zero"
def errLabel = ".L._errDivZero"
}
val RAX = Register(RegSize.R64, RegName.AX)
val EAX = Register(RegSize.E32, RegName.AX)
val ESP = Register(RegSize.E32, RegName.SP)
@ -66,7 +84,7 @@ object asmGenerator {
LabelDef(s".L.str$i"),
Directive.Asciz(str.escaped)
)
}
} ++ zeroDivError.stringDef
Chain(
Directive.IntelSyntax,
@ -135,6 +153,17 @@ object asmGenerator {
)
)
chain ++= Chain(
// TODO can this be done with a call to generateStmt?
// Consider other error cases -> look to generalise
LabelDef(zeroDivError.errLabel),
stack.align(),
Load(RDI, IndexAddress(RIP, LabelArg(zeroDivError.strLabel))),
assemblyIR.Call(CLibFunc.PrintF),
Move(RDI, ImmediateVal(-1)),
assemblyIR.Call(CLibFunc.Exit)
)
chain
}
@ -254,6 +283,8 @@ object asmGenerator {
chain += stack.push(RAX)
case BinaryOperator.Div =>
chain += Compare(stack.head(SizeDir.Word), ImmediateVal(0))
chain += Jump(LabelArg(zeroDivError.errLabel), Cond.Equal)
chain += CDQ()
chain += Divide(stack.head(SizeDir.Word))
chain += stack.drop()