From cf5994e604d7d5761361feaa96d9525989506b01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Forment?= Date: Sat, 24 Jan 2026 12:47:19 +0100 Subject: [PATCH] Loop word --- crates/forth/src/ops.rs | 1 + crates/forth/src/vm.rs | 7 +++++++ crates/forth/src/words.rs | 8 ++++++++ 3 files changed, 16 insertions(+) diff --git a/crates/forth/src/ops.rs b/crates/forth/src/ops.rs index 374b117..54f972b 100644 --- a/crates/forth/src/ops.rs +++ b/crates/forth/src/ops.rs @@ -80,4 +80,5 @@ pub enum Op { Range, Noise, Chain, + Loop, } diff --git a/crates/forth/src/vm.rs b/crates/forth/src/vm.rs index 5000e28..b3b8c52 100644 --- a/crates/forth/src/vm.rs +++ b/crates/forth/src/vm.rs @@ -647,6 +647,13 @@ impl Forth { } } + Op::Loop => { + let beats = stack.pop().ok_or("stack underflow")?.as_float()?; + let dur = beats * 60.0 / ctx.tempo / ctx.speed; + cmd.set_param("fit".into(), dur.to_string()); + cmd.set_param("dur".into(), dur.to_string()); + } + Op::ListStart => { stack.push(Value::Marker); } diff --git a/crates/forth/src/words.rs b/crates/forth/src/words.rs index b410c16..9e3ac58 100644 --- a/crates/forth/src/words.rs +++ b/crates/forth/src/words.rs @@ -614,6 +614,13 @@ pub const WORDS: &[Word] = &[ example: "{ emit } 3 div for", compile: Simple, }, + Word { + name: "loop", + stack: "(n --)", + desc: "Fit sample to n beats", + example: "\"break\" s 4 loop emit", + compile: Simple, + }, Word { name: "|", stack: "(-- marker)", @@ -1565,6 +1572,7 @@ pub(super) fn simple_op(name: &str) -> Option { "range" => Op::Range, "noise" => Op::Noise, "chain" => Op::Chain, + "loop" => Op::Loop, _ => return None, }) }