feat: add zero division error handling in asmGenerator
This commit is contained in:
parent
fc2c58002e
commit
07c67dbef6
@ -12,6 +12,24 @@ object asmGenerator {
|
|||||||
import wacc.types._
|
import wacc.types._
|
||||||
import lexer.escapedChars
|
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 RAX = Register(RegSize.R64, RegName.AX)
|
||||||
val EAX = Register(RegSize.E32, RegName.AX)
|
val EAX = Register(RegSize.E32, RegName.AX)
|
||||||
val ESP = Register(RegSize.E32, RegName.SP)
|
val ESP = Register(RegSize.E32, RegName.SP)
|
||||||
@ -66,7 +84,7 @@ object asmGenerator {
|
|||||||
LabelDef(s".L.str$i"),
|
LabelDef(s".L.str$i"),
|
||||||
Directive.Asciz(str.escaped)
|
Directive.Asciz(str.escaped)
|
||||||
)
|
)
|
||||||
}
|
} ++ zeroDivError.stringDef
|
||||||
|
|
||||||
Chain(
|
Chain(
|
||||||
Directive.IntelSyntax,
|
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
|
chain
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,6 +283,8 @@ object asmGenerator {
|
|||||||
chain += stack.push(RAX)
|
chain += stack.push(RAX)
|
||||||
|
|
||||||
case BinaryOperator.Div =>
|
case BinaryOperator.Div =>
|
||||||
|
chain += Compare(stack.head(SizeDir.Word), ImmediateVal(0))
|
||||||
|
chain += Jump(LabelArg(zeroDivError.errLabel), Cond.Equal)
|
||||||
chain += CDQ()
|
chain += CDQ()
|
||||||
chain += Divide(stack.head(SizeDir.Word))
|
chain += Divide(stack.head(SizeDir.Word))
|
||||||
chain += stack.drop()
|
chain += stack.drop()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user