source("/home/allaun/SilverSight/r/AVMIsa/avm.r")

# Test 1: add Q16
prog <- list(
  instr_push_q16(5 * 65536),
  instr_push_q16(3 * 65536),
  instr_prim(PRIM_ADD_Q16),
  instr_halt()
)
s <- new_state(0)
s <- run(s, prog, 100)
stopifnot(s$halted)
stopifnot(length(s$stack) == 1)
stopifnot(s$stack[[1]]$val == 8 * 65536)
cat("PASS: add Q16\n")

# Test 2: jump_if
prog <- list(
  instr_push_bool(TRUE),
  instr_jump_if(4),
  instr_push_q16(0),
  instr_halt(),
  instr_push_q16(65536),
  instr_halt()
)
s <- new_state(0)
s <- run(s, prog, 100)
stopifnot(s$halted)
stopifnot(length(s$stack) == 1)
stopifnot(s$stack[[1]]$val == 65536)
cat("PASS: jump_if\n")

# Test 3: store/load
prog <- list(
  instr_push_q16(42 * 65536),
  instr_store(0),
  instr_load(0),
  instr_halt()
)
s <- new_state(1)
s <- run(s, prog, 100)
stopifnot(length(s$stack) == 1)
stopifnot(s$stack[[1]]$val == 42 * 65536)
cat("PASS: store/load\n")

# Test 4: type error
prog <- list(
  instr_push_bool(TRUE),
  instr_push_q16(65536),
  instr_prim(PRIM_ADD_Q16),
  instr_halt()
)
s <- new_state(0)
result <- tryCatch(run(s, prog, 100), error = function(e) e)
stopifnot(inherits(result, "error"))
cat("PASS: type error\n")

# Test 5: division by zero
prog <- list(
  instr_push_q16(65536),
  instr_push_q16(0),
  instr_prim(PRIM_DIV_Q16),
  instr_halt()
)
s <- new_state(0)
result <- tryCatch(run(s, prog, 100), error = function(e) e)
stopifnot(inherits(result, "error"))
cat("PASS: division by zero\n")

cat("\nAll R AVM tests passed!\n")
