SilverSight/c/test_avm.c
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

152 lines
4 KiB
C

/* AVM ISA v1 — C Test Harness */
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "avm.c"
void test_basic_add() {
Instr prog[] = {
{OP_PUSH_Q16, 5 * Q16_SCALE, 0},
{OP_PUSH_Q16, 3 * Q16_SCALE, 0},
{OP_PRIM, PRIM_ADD_Q16, 0},
{OP_HALT, 0, 0},
};
State s; init_state(&s, 0);
int err = run(&s, prog, 4, 100);
assert(err == 0);
assert(s.halted);
assert(s.stack[0].val.i == 8 * Q16_SCALE);
printf(" ✅ basic_add: 5 + 3 = 8\n");
}
void test_div_q16() {
Instr prog[] = {
{OP_PUSH_Q16, 3 * Q16_SCALE, 0},
{OP_PUSH_Q16, 5 * Q16_SCALE, 0},
{OP_PRIM, PRIM_DIV_Q16, 0},
{OP_HALT, 0, 0},
};
State s; init_state(&s, 0);
int err = run(&s, prog, 4, 100);
assert(err == 0);
int expected = (3 * Q16_SCALE) / 5;
assert(s.stack[0].val.i == expected);
printf(" ✅ div_q16: 3/5 = 0.6\n");
}
void test_saturation() {
Instr prog[] = {
{OP_PUSH_Q16, AVM_CLAMP_MAX - 1, 0},
{OP_PUSH_Q16, 2, 0},
{OP_PRIM, PRIM_ADD_Q16, 0},
{OP_HALT, 0, 0},
};
State s; init_state(&s, 0);
int err = run(&s, prog, 4, 100);
assert(err == 0);
assert(s.stack[0].val.i == AVM_CLAMP_MAX);
printf(" ✅ saturation: max-1+2 = max\n");
}
void test_v6_lt() {
struct { int a, b; int exp; } cases[] = {
{-5*Q16_SCALE, -3*Q16_SCALE, 1},
{-3*Q16_SCALE, -5*Q16_SCALE, 0},
{5*Q16_SCALE, 3*Q16_SCALE, 0},
{3*Q16_SCALE, 5*Q16_SCALE, 1},
{-1*Q16_SCALE, 2*Q16_SCALE, 1},
};
for (int i = 0; i < 5; i++) {
Instr prog[] = {
{OP_PUSH_Q16, cases[i].a, 0},
{OP_PUSH_Q16, cases[i].b, 0},
{OP_PRIM, PRIM_LT_Q16, 0},
{OP_HALT, 0, 0},
};
State s; init_state(&s, 0);
run(&s, prog, 4, 100);
assert(s.stack[0].val.b == cases[i].exp);
}
printf(" ✅ v6_lt: 5 cases pass\n");
}
void test_type_mismatch() {
Instr prog[] = {
{OP_PUSH_BOOL, 0, 1},
{OP_PUSH_Q16, Q16_SCALE, 0},
{OP_PRIM, PRIM_ADD_Q16, 0},
};
State s; init_state(&s, 0);
int err = run(&s, prog, 3, 100);
assert(err != 0);
printf(" ✅ type_mismatch: rejected\n");
}
void test_div_by_zero() {
Instr prog[] = {
{OP_PUSH_Q16, Q16_SCALE, 0},
{OP_PUSH_Q16, 0, 0},
{OP_PRIM, PRIM_DIV_Q16, 0},
};
State s; init_state(&s, 0);
int err = run(&s, prog, 3, 100);
assert(err != 0);
printf(" ✅ div_by_zero: rejected\n");
}
void test_stack_overflow() {
Instr prog[AVM_MAX_STACK + 2];
for (int i = 0; i < AVM_MAX_STACK + 1; i++)
prog[i] = (Instr){OP_PUSH_Q16, 0, 0};
prog[AVM_MAX_STACK + 1] = (Instr){OP_HALT, 0, 0};
State s; init_state(&s, 0);
int err = run(&s, prog, AVM_MAX_STACK + 2, 100);
assert(err != 0);
printf(" ✅ stack_overflow: rejected\n");
}
void test_control_flow() {
Instr prog[] = {
{OP_PUSH_BOOL, 0, 1},
{OP_JUMP_IF, 4, 0},
{OP_PUSH_Q16, 0, 0},
{OP_HALT, 0, 0},
{OP_PUSH_Q16, Q16_SCALE, 0},
{OP_HALT, 0, 0},
};
State s; init_state(&s, 0);
int err = run(&s, prog, 6, 100);
assert(err == 0);
assert(s.stack[0].val.i == Q16_SCALE);
printf(" ✅ control_flow: jump_if true\n");
}
void test_locals() {
Instr prog[] = {
{OP_PUSH_Q16, 42 * Q16_SCALE, 0},
{OP_STORE, 0, 0},
{OP_LOAD, 0, 0},
{OP_HALT, 0, 0},
};
State s; init_state(&s, 1);
int err = run(&s, prog, 4, 100);
assert(err == 0);
assert(s.stack[0].val.i == 42 * Q16_SCALE);
printf(" ✅ locals: store+load\n");
}
int main() {
printf("AVM C Port — Test Harness\n");
printf("=========================\n");
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();
printf("\nAll C tests passed.\n");
return 0;
}