Feat: lots of things, preparing for live gig
This commit is contained in:
@@ -59,29 +59,29 @@ fn iter() {
|
||||
#[test]
|
||||
fn every_true_on_zero() {
|
||||
let ctx = ctx_with(|c| c.iter = 0);
|
||||
let f = run_ctx("4 every", &ctx);
|
||||
assert_eq!(stack_int(&f), 1);
|
||||
let f = run_ctx("{ 100 } 4 every", &ctx);
|
||||
assert_eq!(stack_int(&f), 100);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn every_true_on_multiple() {
|
||||
let ctx = ctx_with(|c| c.iter = 8);
|
||||
let f = run_ctx("4 every", &ctx);
|
||||
assert_eq!(stack_int(&f), 1);
|
||||
let f = run_ctx("{ 100 } 4 every", &ctx);
|
||||
assert_eq!(stack_int(&f), 100);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn every_false_between() {
|
||||
for i in 1..4 {
|
||||
let ctx = ctx_with(|c| c.iter = i);
|
||||
let f = run_ctx("4 every", &ctx);
|
||||
assert_eq!(stack_int(&f), 0, "iter={} should be false", i);
|
||||
let f = run_ctx("{ 100 } 4 every", &ctx);
|
||||
assert!(f.stack().is_empty(), "iter={} should not execute quotation", i);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn every_zero_count() {
|
||||
expect_error("0 every", "every count must be > 0");
|
||||
expect_error("{ 1 } 0 every", "every count must be > 0");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -97,3 +97,77 @@ fn context_in_computation() {
|
||||
let f = run_ctx("60 step +", &ctx);
|
||||
assert_eq!(stack_int(&f), 63);
|
||||
}
|
||||
|
||||
// bjork (runs-based)
|
||||
|
||||
#[test]
|
||||
fn bjork_tresillo() {
|
||||
// Bresenham(3,8) hits at positions 0, 2, 5
|
||||
for runs in 0..8 {
|
||||
let ctx = ctx_with(|c| c.runs = runs);
|
||||
let f = run_ctx("{ 100 } 3 8 bjork", &ctx);
|
||||
let hit = ((runs + 1) * 3) / 8 != (runs * 3) / 8;
|
||||
if hit {
|
||||
assert_eq!(stack_int(&f), 100, "runs={} should hit", runs);
|
||||
} else {
|
||||
assert!(f.stack().is_empty(), "runs={} should miss", runs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bjork_hit_count() {
|
||||
// Bjorklund(3,8) should produce exactly 3 hits
|
||||
let mut hit_count = 0;
|
||||
for runs in 0..8 {
|
||||
let ctx = ctx_with(|c| c.runs = runs);
|
||||
let f = run_ctx("{ 100 } 3 8 bjork", &ctx);
|
||||
if !f.stack().is_empty() {
|
||||
hit_count += 1;
|
||||
}
|
||||
}
|
||||
assert_eq!(hit_count, 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bjork_all_hits() {
|
||||
let ctx = ctx_with(|c| c.runs = 0);
|
||||
let f = run_ctx("{ 100 } 8 8 bjork", &ctx);
|
||||
assert_eq!(stack_int(&f), 100);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bjork_zero_hits() {
|
||||
let ctx = ctx_with(|c| c.runs = 0);
|
||||
let f = run_ctx("{ 100 } 0 8 bjork", &ctx);
|
||||
assert!(f.stack().is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bjork_invalid() {
|
||||
expect_error("{ 1 } 3 0 bjork", "bjork");
|
||||
}
|
||||
|
||||
// pbjork (iter-based)
|
||||
|
||||
#[test]
|
||||
fn pbjork_cinquillo() {
|
||||
let mut hit_count = 0;
|
||||
for iter in 0..8 {
|
||||
let ctx = ctx_with(|c| c.iter = iter);
|
||||
let f = run_ctx("{ 100 } 5 8 pbjork", &ctx);
|
||||
if !f.stack().is_empty() {
|
||||
hit_count += 1;
|
||||
}
|
||||
}
|
||||
assert_eq!(hit_count, 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pbjork_wraps() {
|
||||
let ctx0 = ctx_with(|c| c.iter = 0);
|
||||
let ctx8 = ctx_with(|c| c.iter = 8);
|
||||
let f0 = run_ctx("{ 100 } 3 8 pbjork", &ctx0);
|
||||
let f8 = run_ctx("{ 100 } 3 8 pbjork", &ctx8);
|
||||
assert_eq!(f0.stack().is_empty(), f8.stack().is_empty());
|
||||
}
|
||||
|
||||
@@ -29,14 +29,14 @@ fn when_with_arithmetic() {
|
||||
|
||||
#[test]
|
||||
fn when_with_every() {
|
||||
// iter=0, every 2 should be true
|
||||
// iter=0, every 2 executes quotation
|
||||
let ctx = ctx_with(|c| c.iter = 0);
|
||||
let f = run_ctx("{ 100 } 2 every ?", &ctx);
|
||||
let f = run_ctx("{ 100 } 2 every", &ctx);
|
||||
assert_eq!(stack_int(&f), 100);
|
||||
|
||||
// iter=1, every 2 should be false
|
||||
// iter=1, every 2 skips quotation
|
||||
let ctx = ctx_with(|c| c.iter = 1);
|
||||
let f = run_ctx("50 { 100 } 2 every ?", &ctx);
|
||||
let f = run_ctx("50 { 100 } 2 every", &ctx);
|
||||
assert_eq!(stack_int(&f), 50); // quotation not executed
|
||||
}
|
||||
|
||||
@@ -104,13 +104,12 @@ fn unexpected_close_error() {
|
||||
|
||||
#[test]
|
||||
fn every_with_quotation_integration() {
|
||||
// Simulating: { 2 distort } 2 every ?
|
||||
// On even iterations, distort is applied
|
||||
// { 2 distort } 2 every — on even iterations, distort is applied
|
||||
for iter in 0..4 {
|
||||
let ctx = ctx_with(|c| c.iter = iter);
|
||||
let f = forth();
|
||||
let outputs = f
|
||||
.evaluate(r#""kick" s { 2 distort } 2 every ? ."#, &ctx)
|
||||
.evaluate(r#""kick" s { 2 distort } 2 every ."#, &ctx)
|
||||
.unwrap();
|
||||
if iter % 2 == 0 {
|
||||
assert!(
|
||||
@@ -128,6 +127,18 @@ fn every_with_quotation_integration() {
|
||||
}
|
||||
}
|
||||
|
||||
// bjork with sound
|
||||
|
||||
#[test]
|
||||
fn bjork_with_sound() {
|
||||
let ctx = ctx_with(|c| c.runs = 2); // position 2 is a hit for (3,8)
|
||||
let f = forth();
|
||||
let outputs = f
|
||||
.evaluate(r#""kick" s { 2 distort } 3 8 bjork ."#, &ctx)
|
||||
.unwrap();
|
||||
assert!(outputs[0].contains("distort/2"));
|
||||
}
|
||||
|
||||
// Unless (!?) tests
|
||||
|
||||
#[test]
|
||||
@@ -142,28 +153,15 @@ fn unless_true_skips() {
|
||||
assert_eq!(stack_int(&f), 99);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unless_with_every() {
|
||||
// iter=0, every 2 is true, so unless skips
|
||||
let ctx = ctx_with(|c| c.iter = 0);
|
||||
let f = run_ctx("50 { 100 } 2 every !?", &ctx);
|
||||
assert_eq!(stack_int(&f), 50);
|
||||
|
||||
// iter=1, every 2 is false, so unless executes
|
||||
let ctx = ctx_with(|c| c.iter = 1);
|
||||
let f = run_ctx("{ 100 } 2 every !?", &ctx);
|
||||
assert_eq!(stack_int(&f), 100);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn when_and_unless_complementary() {
|
||||
// Using both ? and !? for if-else like behavior
|
||||
// Using iter mod + ?/!? for if-else behavior (every no longer pushes bool)
|
||||
for iter in 0..4 {
|
||||
let ctx = ctx_with(|c| c.iter = iter);
|
||||
let f = forth();
|
||||
let outputs = f
|
||||
.evaluate(
|
||||
r#""kick" s { 2 distort } 2 every ? { 4 distort } 2 every !? ."#,
|
||||
r#""kick" s { 2 distort } iter 2 mod 0 = ? { 4 distort } iter 2 mod 0 = !? ."#,
|
||||
&ctx,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
Reference in New Issue
Block a user