Feat: documentation, UI/UX

This commit is contained in:
2026-03-01 19:09:52 +01:00
parent ecb559e556
commit db44f9b98e
57 changed files with 1531 additions and 615 deletions

View File

@@ -65,6 +65,7 @@ pub enum Op {
NewCmd,
SetParam(&'static str),
Emit,
Print,
Get,
Set,
SetKeep,

View File

@@ -328,6 +328,16 @@ impl Forth {
Op::Drop => {
pop(stack)?;
}
Op::Print => {
let val = pop(stack)?;
let text = match &val {
Value::Int(n, _) => n.to_string(),
Value::Float(f, _) => format!("{f}"),
Value::Str(s, _) => s.to_string(),
_ => format!("{val:?}"),
};
outputs.push(format!("print:{text}"));
}
Op::Swap => {
ensure(stack, 2)?;
let len = stack.len();
@@ -558,9 +568,12 @@ impl Forth {
Op::NewCmd => {
ensure(stack, 1)?;
let values = std::mem::take(stack);
let values = drain_skip_quotations(stack);
if values.is_empty() {
return Err("expected sound name".into());
}
let val = if values.len() == 1 {
values.into_iter().next().expect("single value after len check")
values.into_iter().next().unwrap()
} else {
Value::CycleList(Arc::from(values))
};
@@ -568,9 +581,12 @@ impl Forth {
}
Op::SetParam(param) => {
ensure(stack, 1)?;
let values = std::mem::take(stack);
let values = drain_skip_quotations(stack);
if values.is_empty() {
return Err("expected parameter value".into());
}
let val = if values.len() == 1 {
values.into_iter().next().expect("single value after len check")
values.into_iter().next().unwrap()
} else {
Value::CycleList(Arc::from(values))
};
@@ -1866,6 +1882,21 @@ fn pop_bool(stack: &mut Vec<Value>) -> Result<bool, String> {
Ok(pop(stack)?.is_truthy())
}
/// Drain the stack, returning non-quotation values.
/// Quotations are pushed back onto the stack (transparent).
fn drain_skip_quotations(stack: &mut Vec<Value>) -> Vec<Value> {
let values = std::mem::take(stack);
let mut result = Vec::new();
for v in values {
if matches!(v, Value::Quotation(..)) {
stack.push(v);
} else {
result.push(v);
}
}
result
}
fn ensure(stack: &[Value], n: usize) -> Result<(), String> {
if stack.len() < n {
return Err("stack underflow".into());

View File

@@ -13,6 +13,7 @@ pub(super) fn simple_op(name: &str) -> Option<Op> {
"dup" => Op::Dup,
"dupn" => Op::Dupn,
"drop" => Op::Drop,
"print" => Op::Print,
"swap" => Op::Swap,
"over" => Op::Over,
"rot" => Op::Rot,

View File

@@ -33,6 +33,16 @@ pub(super) const WORDS: &[Word] = &[
compile: Simple,
varargs: false,
},
Word {
name: "print",
aliases: &[],
category: "Stack",
stack: "(x --)",
desc: "Print top of stack to footer bar",
example: "42 print",
compile: Simple,
varargs: false,
},
Word {
name: "swap",
aliases: &[],