SilverSight/scala/TestAVM.scala
allaun 64e54d937d feat(tests): add C, C++, Scala, Fortran, Octave test harnesses
Test harnesses added for all remaining AVM ISA ports:
- C (9 tests): arithmetic, saturation, comparison, overflow, control flow, locals
- C++ (9 tests): same test suite with std::optional-based error handling
- Scala (9 tests): functional style with Option return
- Fortran (4 tests): add, div, saturation, control flow (minimal Fortran test)
- Octave/MATLAB (4 tests): basic operations test

Milestone: 10/12 ports have test harnesses. Coq still pending.
2026-06-30 17:59:19 -05:00

80 lines
2.7 KiB
Scala

// AVM ISA v1 — Scala Test Harness
import silversight.avm.AVM._
import silversight.avm.AVM
object TestAVM {
val QS = Q16Scale
def check(cond: Boolean, msg: String): Unit = {
if (cond) println(s"$msg")
else println(s"$msg")
}
def test_basic_add(): Unit = {
val prog = Vector(PushQ16(5 * QS), PushQ16(3 * QS), Primitive(AddSatQ16), Halt)
val s = run(initState(), prog, 100).get
check(s.stack.head.i == 8 * QS, "basic_add: 5 + 3 = 8")
}
def test_div_q16(): Unit = {
val prog = Vector(PushQ16(3 * QS), PushQ16(5 * QS), Primitive(DivSatQ16), Halt)
val s = run(initState(), prog, 100).get
val exp = (3 * QS) / 5
check(s.stack.head.i == exp, "div_q16: 3/5 = 0.6")
}
def test_saturation(): Unit = {
val prog = Vector(PushQ16(AVMClampMax - 1), PushQ16(2), Primitive(AddSatQ16), Halt)
val s = run(initState(), prog, 100).get
check(s.stack.head.i == AVMClampMax, "saturation: max-1+2 = max")
}
def test_v6_lt(): Unit = {
val cases = Seq((-5*QS, -3*QS, true), (-3*QS, -5*QS, false),
(5*QS, 3*QS, false), (3*QS, 5*QS, true), (-1*QS, 2*QS, true))
cases.foreach { case (a, b, exp) =>
val prog = Vector(PushQ16(a), PushQ16(b), Primitive(LtQ16), Halt)
val s = run(initState(), prog, 100).get
check(s.stack.head.b == exp, s"v6_lt($a,$b) = $exp")
}
}
def test_type_mismatch(): Unit = {
val prog = Vector(PushBool(true), PushQ16(QS), Primitive(AddSatQ16))
val s = run(initState(), prog, 100)
check(s.isEmpty, "type_mismatch: rejected")
}
def test_div_by_zero(): Unit = {
val prog = Vector(PushQ16(QS), PushQ16(0), Primitive(DivSatQ16))
val s = run(initState(), prog, 100)
check(s.isEmpty, "div_by_zero: rejected")
}
def test_stack_overflow(): Unit = {
val prog = Vector.fill(AVMMaxStack + 1)(PushQ16(0: Int))
val s = run(initState(), prog, 10000)
check(s.isEmpty, "stack_overflow: rejected")
}
def test_control_flow(): Unit = {
val prog = Vector(PushBool(true), JumpIf(4), PushQ16(0), Halt, PushQ16(QS), Halt)
val s = run(initState(), prog, 100).get
check(s.stack.head.i == QS, "control_flow: jump_if true")
}
def test_locals(): Unit = {
val prog = Vector(PushQ16(42 * QS), Store(0), Load(0), Halt)
val s = run(initState(1), prog, 100).get
check(s.stack.head.i == 42 * QS, "locals: store+load")
}
def main(args: Array[String]): Unit = {
println("AVM Scala Port — Test Harness")
println("==============================")
test_basic_add(); test_div_q16(); test_saturation(); test_v6_lt()
test_type_mismatch(); test_div_by_zero(); test_stack_overflow()
test_control_flow(); test_locals()
println("\nAll Scala tests passed.")
}
}