use super::harness::*; #[test] fn choose_from_stack() { let f = forth(); let ctx = default_ctx(); f.evaluate("1 2 3 3 choose", &ctx).unwrap(); let val = stack_int(&f); assert!(val >= 1 && val <= 3, "expected 1, 2, or 3, got {}", val); } #[test] fn cycle_by_runs() { let ctx = ctx_with(|c| c.runs = 0); let f = run_ctx("10 20 30 3 cycle", &ctx); assert_eq!(stack_int(&f), 10); let ctx = ctx_with(|c| c.runs = 1); let f = run_ctx("10 20 30 3 cycle", &ctx); assert_eq!(stack_int(&f), 20); let ctx = ctx_with(|c| c.runs = 2); let f = run_ctx("10 20 30 3 cycle", &ctx); assert_eq!(stack_int(&f), 30); let ctx = ctx_with(|c| c.runs = 3); let f = run_ctx("10 20 30 3 cycle", &ctx); assert_eq!(stack_int(&f), 10); } #[test] fn pcycle_by_iter() { let ctx = ctx_with(|c| c.iter = 0); let f = run_ctx("10 20 30 3 pcycle", &ctx); assert_eq!(stack_int(&f), 10); let ctx = ctx_with(|c| c.iter = 1); let f = run_ctx("10 20 30 3 pcycle", &ctx); assert_eq!(stack_int(&f), 20); let ctx = ctx_with(|c| c.iter = 2); let f = run_ctx("10 20 30 3 pcycle", &ctx); assert_eq!(stack_int(&f), 30); } #[test] fn cycle_with_quotations() { let ctx = ctx_with(|c| c.runs = 0); let f = run_ctx("5 { dup } { 2 * } 2 cycle", &ctx); let stack = f.stack(); assert_eq!(stack.len(), 2); assert_eq!(stack_int(&f), 5); let ctx = ctx_with(|c| c.runs = 1); let f = run_ctx("5 { dup } { 2 * } 2 cycle", &ctx); assert_eq!(stack_int(&f), 10); } #[test] fn cycle_executes_quotation() { let ctx = ctx_with(|c| c.runs = 0); let f = run_ctx("10 { 3 + } { 5 + } 2 cycle", &ctx); assert_eq!(stack_int(&f), 13); } #[test] fn dupn_basic() { // 5 3 dupn -> 5 5 5, then + + -> 15 expect_int("5 3 dupn + +", 15); } #[test] fn dupn_alias() { expect_int("5 3 ! + +", 15); } #[test] fn cycle_zero_count_error() { expect_error("1 2 3 0 cycle", "cycle count must be > 0"); } #[test] fn choose_zero_count_error() { expect_error("1 2 3 0 choose", "choose count must be > 0"); }