feat: implement all runtime errors #32
@@ -12,5 +12,19 @@ case class RuntimeError(strLabel: String, errStr: String, errLabel: String) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
object RuntimeErrors {
|
object RuntimeErrors {
|
||||||
val zeroDivError = RuntimeError(".L._errDivZero_str0", "fatal error: division or modulo by zero", ".L._errDivZero")
|
val zeroDivError = RuntimeError(
|
||||||
|
".L._errDivZero_str0",
|
||||||
|
"fatal error: division or modulo by zero",
|
||||||
|
".L._errDivZero"
|
||||||
|
)
|
||||||
|
val badChrError = RuntimeError(
|
||||||
|
".L._errBadChr_str0",
|
||||||
|
"fatal error: int %d is not ascii character 0-127",
|
||||||
|
".L._errBadChr"
|
||||||
|
)
|
||||||
|
val nullPtrError = RuntimeError(
|
||||||
|
".L._errNullPtr_str0",
|
||||||
|
"fatal error: null pair dereferenced or freed",
|
||||||
|
".L._errNullPtr"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import cats.data.Chain
|
|||||||
import cats.syntax.foldable._
|
import cats.syntax.foldable._
|
||||||
import wacc.RuntimeErrors._
|
import wacc.RuntimeErrors._
|
||||||
|
|
||||||
|
|
||||||
object asmGenerator {
|
object asmGenerator {
|
||||||
import microWacc._
|
import microWacc._
|
||||||
import assemblyIR._
|
import assemblyIR._
|
||||||
@@ -65,6 +64,8 @@ object asmGenerator {
|
|||||||
Directive.Asciz(str.escaped)
|
Directive.Asciz(str.escaped)
|
||||||
)
|
)
|
||||||
} ++ zeroDivError.stringDef
|
} ++ zeroDivError.stringDef
|
||||||
|
++ badChrError.stringDef
|
||||||
|
++ nullPtrError.stringDef // TODO COLLATE TO ONE LIST INSTANCE
|
||||||
|
|
||||||
Chain(
|
Chain(
|
||||||
Directive.IntelSyntax,
|
Directive.IntelSyntax,
|
||||||
@@ -145,7 +146,16 @@ object asmGenerator {
|
|||||||
// Out of memory check is optional
|
// Out of memory check is optional
|
||||||
)
|
)
|
||||||
|
|
||||||
chain ++= wrapBuiltinFunc(labelGenerator.getLabel(Builtin.Free), Chain.empty)
|
chain ++= wrapBuiltinFunc(
|
||||||
|
labelGenerator.getLabel(Builtin.Free),
|
||||||
|
Chain(
|
||||||
|
stackAlign,
|
||||||
|
Move(RDI, RAX),
|
||||||
|
Compare(RDI, ImmediateVal(0)),
|
||||||
|
Jump(LabelArg(nullPtrError.errLabel), Cond.Equal),
|
||||||
|
assemblyIR.Call(CLibFunc.Free)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
chain ++= wrapBuiltinFunc(
|
chain ++= wrapBuiltinFunc(
|
||||||
labelGenerator.getLabel(Builtin.Read),
|
labelGenerator.getLabel(Builtin.Read),
|
||||||
@@ -170,6 +180,25 @@ object asmGenerator {
|
|||||||
assemblyIR.Call(CLibFunc.Exit)
|
assemblyIR.Call(CLibFunc.Exit)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
chain ++= Chain(
|
||||||
|
LabelDef(badChrError.errLabel),
|
||||||
|
Pop(RSI),
|
||||||
|
stackAlign,
|
||||||
|
Load(RDI, IndexAddress(RIP, LabelArg(badChrError.strLabel))),
|
||||||
|
assemblyIR.Call(CLibFunc.PrintF),
|
||||||
|
Move(RDI, ImmediateVal(-1)),
|
||||||
|
assemblyIR.Call(CLibFunc.Exit)
|
||||||
|
)
|
||||||
|
|
||||||
|
chain ++= Chain(
|
||||||
|
LabelDef(nullPtrError.errLabel),
|
||||||
|
stackAlign,
|
||||||
|
Load(RDI, IndexAddress(RIP, LabelArg(nullPtrError.strLabel))),
|
||||||
|
assemblyIR.Call(CLibFunc.PrintF),
|
||||||
|
Move(RDI, ImmediateVal(255)),
|
||||||
|
assemblyIR.Call(CLibFunc.Exit)
|
||||||
|
)
|
||||||
|
|
||||||
chain
|
chain
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,7 +334,12 @@ object asmGenerator {
|
|||||||
case UnaryOp(x, op) =>
|
case UnaryOp(x, op) =>
|
||||||
chain ++= evalExprOntoStack(x)
|
chain ++= evalExprOntoStack(x)
|
||||||
op match {
|
op match {
|
||||||
case UnaryOperator.Chr | UnaryOperator.Ord => // No op needed
|
case UnaryOperator.Chr =>
|
||||||
|
chain += Move(EAX, stack.head)
|
||||||
|
chain += And(EAX, ImmediateVal(-128))
|
||||||
|
chain += Compare(EAX, ImmediateVal(0))
|
||||||
|
chain += Jump(LabelArg(badChrError.errLabel), Cond.NotEqual)
|
||||||
|
case UnaryOperator.Ord => // No op needed
|
||||||
case UnaryOperator.Len =>
|
case UnaryOperator.Len =>
|
||||||
chain += stack.pop(RAX)
|
chain += stack.pop(RAX)
|
||||||
chain += Move(EAX, MemLocation(RAX, D32))
|
chain += Move(EAX, MemLocation(RAX, D32))
|
||||||
@@ -343,6 +377,8 @@ object asmGenerator {
|
|||||||
chain += stack.push(destX.size, RAX)
|
chain += stack.push(destX.size, RAX)
|
||||||
|
|
||||||
case BinaryOperator.Mod =>
|
case BinaryOperator.Mod =>
|
||||||
|
chain += Compare(stack.head, ImmediateVal(0))
|
||||||
|
chain += Jump(LabelArg(zeroDivError.errLabel), Cond.Equal)
|
||||||
chain += CDQ()
|
chain += CDQ()
|
||||||
chain += Divide(stack.head)
|
chain += Divide(stack.head)
|
||||||
chain += stack.drop()
|
chain += stack.drop()
|
||||||
|
|||||||
Reference in New Issue
Block a user