refactor: use LabelGenerator for RuntimeErrors

This commit is contained in:
2025-02-28 14:07:00 +00:00
parent 967a6fe58b
commit fb5799dbfd
4 changed files with 91 additions and 86 deletions

View File

@@ -4,18 +4,16 @@ import cats.data.Chain
import wacc.assemblyIR._
sealed trait RuntimeError {
def strLabel: String
def errStr: String
def errLabel: String
val name: String
protected val errStr: String
def stringDef: Chain[AsmLine] = Chain(
Directive.Int(errStr.length),
LabelDef(strLabel),
Directive.Asciz(errStr)
)
protected def getErrLabel(using labelGenerator: LabelGenerator): String =
labelGenerator.getLabel(errStr, name = name)
def generateHandler: Chain[AsmLine]
protected def generateHandler(using labelGenerator: LabelGenerator): Chain[AsmLine]
def generate(using labelGenerator: LabelGenerator): Chain[AsmLine] =
LabelDef(labelGenerator.getLabel(this)) +: generateHandler
}
object RuntimeError {
@@ -36,14 +34,12 @@ object RuntimeError {
// private val RCX = Register(Q64, CX)
case object ZeroDivError extends RuntimeError {
val strLabel = ".L._errDivZero_str0"
val errStr = "fatal error: division or modulo by zero"
val errLabel = ".L._errDivZero"
val name = "errDivZero"
protected val errStr = "fatal error: division or modulo by zero"
def generateHandler: Chain[AsmLine] = Chain(
LabelDef(ZeroDivError.errLabel),
protected def generateHandler(using labelGenerator: LabelGenerator): Chain[AsmLine] = Chain(
stackAlign,
Load(RDI, IndexAddress(RIP, LabelArg(ZeroDivError.strLabel))),
Load(RDI, IndexAddress(RIP, LabelArg(getErrLabel))),
assemblyIR.Call(CLibFunc.PrintF),
Move(RDI, ImmediateVal(-1)),
assemblyIR.Call(CLibFunc.Exit)
@@ -52,15 +48,13 @@ object RuntimeError {
}
case object BadChrError extends RuntimeError {
val strLabel = ".L._errBadChr_str0"
val errStr = "fatal error: int %d is not an ASCII character 0-127"
val errLabel = ".L._errBadChr"
val name = "errBadChr"
protected val errStr = "fatal error: int %d is not an ASCII character 0-127"
def generateHandler: Chain[AsmLine] = Chain(
LabelDef(BadChrError.errLabel),
protected def generateHandler(using labelGenerator: LabelGenerator): Chain[AsmLine] = Chain(
Pop(RSI),
stackAlign,
Load(RDI, IndexAddress(RIP, LabelArg(BadChrError.strLabel))),
Load(RDI, IndexAddress(RIP, LabelArg(getErrLabel))),
assemblyIR.Call(CLibFunc.PrintF),
Move(RDI, ImmediateVal(255)),
assemblyIR.Call(CLibFunc.Exit)
@@ -69,14 +63,12 @@ object RuntimeError {
}
case object NullPtrError extends RuntimeError {
val strLabel = ".L._errNullPtr_str0"
val errStr = "fatal error: null pair dereferenced or freed"
val errLabel = ".L._errNullPtr"
val name = "errNullPtr"
protected val errStr = "fatal error: null pair dereferenced or freed"
def generateHandler: Chain[AsmLine] = Chain(
LabelDef(NullPtrError.errLabel),
protected def generateHandler(using labelGenerator: LabelGenerator): Chain[AsmLine] = Chain(
stackAlign,
Load(RDI, IndexAddress(RIP, LabelArg(NullPtrError.strLabel))),
Load(RDI, IndexAddress(RIP, LabelArg(getErrLabel))),
assemblyIR.Call(CLibFunc.PrintF),
Move(RDI, ImmediateVal(255)),
assemblyIR.Call(CLibFunc.Exit)
@@ -85,14 +77,12 @@ object RuntimeError {
}
case object OverflowError extends RuntimeError {
val strLabel = ".L._errOverflow_str0"
val errStr = "fatal error: integer overflow or underflow occurred"
val errLabel = ".L._errOverflow"
val name = "errOverflow"
protected val errStr = "fatal error: integer overflow or underflow occurred"
def generateHandler: Chain[AsmLine] = Chain(
LabelDef(OverflowError.errLabel),
protected def generateHandler(using labelGenerator: LabelGenerator): Chain[AsmLine] = Chain(
stackAlign,
Load(RDI, IndexAddress(RIP, LabelArg(OverflowError.strLabel))),
Load(RDI, IndexAddress(RIP, LabelArg(getErrLabel))),
assemblyIR.Call(CLibFunc.PrintF),
Move(RDI, ImmediateVal(255)),
assemblyIR.Call(CLibFunc.Exit)
@@ -101,16 +91,13 @@ object RuntimeError {
}
case object OutOfBoundsError extends RuntimeError {
val name = "errOutOfBounds"
protected val errStr = "fatal error: array index %d out of bounds"
val strLabel = ".L._errOutOfBounds_str0"
val errStr = "fatal error: array index %d out of bounds"
val errLabel = ".L._errOutOfBounds"
def generateHandler: Chain[AsmLine] = Chain(
LabelDef(OutOfBoundsError.errLabel),
protected def generateHandler(using labelGenerator: LabelGenerator): Chain[AsmLine] = Chain(
Move(RSI, Register(Q64, CX)),
stackAlign,
Load(RDI, IndexAddress(RIP, LabelArg(OutOfBoundsError.strLabel))),
Load(RDI, IndexAddress(RIP, LabelArg(getErrLabel))),
assemblyIR.Call(CLibFunc.PrintF),
Move(RDI, ImmediateVal(255)),
assemblyIR.Call(CLibFunc.Exit)