Work on documentation
This commit is contained in:
@@ -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(
|
||||
"_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(
|
||||
"_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()?;
|
||||
|
||||
Reference in New Issue
Block a user