Work on documentation

This commit is contained in:
2026-01-31 13:46:43 +01:00
parent 08029ec604
commit 0299012725
45 changed files with 668 additions and 1318 deletions

View File

@@ -91,45 +91,51 @@ impl Forth {
let mut pc = 0;
let trace_cell = std::cell::RefCell::new(trace);
let run_quotation =
|quot: Value, stack: &mut Vec<Value>, outputs: &mut Vec<String>, cmd: &mut CmdRegister| -> Result<(), String> {
match quot {
Value::Quotation(quot_ops, body_span) => {
if let Some(span) = body_span {
if let Some(trace) = trace_cell.borrow_mut().as_mut() {
trace.executed_spans.push(span);
}
let run_quotation = |quot: Value,
stack: &mut Vec<Value>,
outputs: &mut Vec<String>,
cmd: &mut CmdRegister|
-> Result<(), String> {
match quot {
Value::Quotation(quot_ops, body_span) => {
if let Some(span) = body_span {
if let Some(trace) = trace_cell.borrow_mut().as_mut() {
trace.executed_spans.push(span);
}
let mut trace_opt = trace_cell.borrow_mut().take();
self.execute_ops(
&quot_ops,
ctx,
stack,
outputs,
cmd,
trace_opt.as_deref_mut(),
)?;
*trace_cell.borrow_mut() = trace_opt;
Ok(())
}
_ => Err("expected quotation".into()),
}
};
let select_and_run =
|selected: Value, stack: &mut Vec<Value>, outputs: &mut Vec<String>, cmd: &mut CmdRegister| -> Result<(), String> {
if let Some(span) = selected.span() {
if let Some(trace) = trace_cell.borrow_mut().as_mut() {
trace.selected_spans.push(span);
}
}
if matches!(selected, Value::Quotation(..)) {
run_quotation(selected, stack, outputs, cmd)
} else {
stack.push(selected);
let mut trace_opt = trace_cell.borrow_mut().take();
self.execute_ops(
&quot_ops,
ctx,
stack,
outputs,
cmd,
trace_opt.as_deref_mut(),
)?;
*trace_cell.borrow_mut() = trace_opt;
Ok(())
}
};
_ => Err("expected quotation".into()),
}
};
let select_and_run = |selected: Value,
stack: &mut Vec<Value>,
outputs: &mut Vec<String>,
cmd: &mut CmdRegister|
-> Result<(), String> {
if let Some(span) = selected.span() {
if let Some(trace) = trace_cell.borrow_mut().as_mut() {
trace.selected_spans.push(span);
}
}
if matches!(selected, Value::Quotation(..)) {
run_quotation(selected, stack, outputs, cmd)
} else {
stack.push(selected);
Ok(())
}
};
let drain_select_run = |count: usize,
idx: usize,
@@ -146,15 +152,20 @@ impl Forth {
select_and_run(selected, stack, outputs, cmd)
};
let emit_with_cycling = |cmd: &CmdRegister, emit_idx: usize, delta_secs: f64, outputs: &mut Vec<String>| -> Result<Option<Value>, String> {
let emit_with_cycling = |cmd: &CmdRegister,
emit_idx: usize,
delta_secs: f64,
outputs: &mut Vec<String>|
-> Result<Option<Value>, String> {
let (sound_opt, params) = cmd.snapshot().ok_or("nothing to emit")?;
let resolved_sound_val = sound_opt.map(|sv| resolve_cycling(sv, emit_idx));
let sound_str = match &resolved_sound_val {
Some(v) => Some(v.as_str()?.to_string()),
None => None,
};
let resolved_params: Vec<(String, String)> =
params.iter().map(|(k, v)| {
let resolved_params: Vec<(String, String)> = params
.iter()
.map(|(k, v)| {
let resolved = resolve_cycling(v, emit_idx);
if let Value::CycleList(_) = v {
if let Some(span) = resolved.span() {
@@ -164,8 +175,15 @@ impl Forth {
}
}
(k.clone(), resolved.to_param_string())
}).collect();
emit_output(sound_str.as_deref(), &resolved_params, ctx.step_duration(), delta_secs, outputs);
})
.collect();
emit_output(
sound_str.as_deref(),
&resolved_params,
ctx.step_duration(),
delta_secs,
outputs,
);
Ok(resolved_sound_val.map(|v| v.into_owned()))
};
@@ -369,7 +387,9 @@ impl Forth {
trace.selected_spans.push(span);
}
}
if let Some(sound_val) = emit_with_cycling(cmd, emit_idx, delta_secs, outputs)? {
if let Some(sound_val) =
emit_with_cycling(cmd, emit_idx, delta_secs, outputs)?
{
if let Some(span) = sound_val.span() {
if let Some(trace) = trace_cell.borrow_mut().as_mut() {
trace.selected_spans.push(span);
@@ -417,7 +437,11 @@ impl Forth {
let a = stack.pop().ok_or("stack underflow")?;
match (&a, &b) {
(Value::Int(a_i, _), Value::Int(b_i, _)) => {
let (lo, hi) = if a_i <= b_i { (*a_i, *b_i) } else { (*b_i, *a_i) };
let (lo, hi) = if a_i <= b_i {
(*a_i, *b_i)
} else {
(*b_i, *a_i)
};
let val = self.rng.lock().unwrap().gen_range(lo..=hi);
stack.push(Value::Int(val, None));
}
@@ -708,16 +732,6 @@ impl Forth {
cmd.clear();
}
Op::EmitN => {
let n = stack.pop().ok_or("stack underflow")?.as_int()?;
if n < 0 {
return Err("emit count must be >= 0".into());
}
for i in 0..n as usize {
emit_with_cycling(cmd, i, ctx.nudge_secs, outputs)?;
}
}
Op::IntRange => {
let end = stack.pop().ok_or("stack underflow")?.as_int()?;
let start = stack.pop().ok_or("stack underflow")?.as_int()?;
@@ -748,6 +762,21 @@ impl Forth {
}
}
Op::Times => {
let quot = stack.pop().ok_or("stack underflow")?;
let count = stack.pop().ok_or("stack underflow")?.as_int()?;
if count < 0 {
return Err("times count must be >= 0".into());
}
for i in 0..count {
self.vars
.lock()
.unwrap()
.insert("i".to_string(), Value::Int(i, None));
run_quotation(quot.clone(), stack, outputs, cmd)?;
}
}
Op::GeomRange => {
let count = stack.pop().ok_or("stack underflow")?.as_int()?;
let ratio = stack.pop().ok_or("stack underflow")?.as_float()?;