Feat: lots of convenience stuff

This commit is contained in:
2026-02-24 00:52:40 +01:00
parent 8f131b46cc
commit 848d0e773f
15 changed files with 440 additions and 26 deletions

View File

@@ -140,6 +140,7 @@ impl Forth {
var_writes: &mut HashMap<String, Value>,
) -> Result<(), String> {
let mut pc = 0;
let mut marks: Vec<usize> = Vec::new();
let trace_cell = std::cell::RefCell::new(trace);
let var_writes_cell = std::cell::RefCell::new(Some(var_writes));
@@ -1541,6 +1542,29 @@ impl Forth {
.unwrap_or(0);
stack.push(Value::Int(val as i64, None));
}
Op::Mark => {
marks.push(stack.len());
}
Op::Count(span) => {
let mark = marks.pop().ok_or("count without mark")?;
stack.push(Value::Int((stack.len() - mark) as i64, *span));
}
Op::Index(word_span) => {
let idx = pop_int(stack)?;
let count = pop_int(stack)? as usize;
if count == 0 {
return Err("index count must be > 0".into());
}
let resolved_idx = ((idx % count as i64 + count as i64) % count as i64) as usize;
if let Some(span) = word_span {
if stack.len() >= count {
let start = stack.len() - count;
let selected = &stack[start + resolved_idx];
record_resolved_from_value(&trace_cell, Some(*span), selected);
}
}
drain_select_run(count, resolved_idx, stack, outputs, cmd)?;
}
Op::Forget => {
let name = pop(stack)?;
self.dict.lock().remove(name.as_str()?);