Feat: prelude and new words
Some checks failed
Deploy Website / deploy (push) Failing after 4m48s

This commit is contained in:
2026-02-05 00:58:53 +01:00
parent abafea8ddf
commit de56598fca
21 changed files with 533 additions and 29 deletions

View File

@@ -345,6 +345,77 @@ impl Forth {
stack.push(a);
stack.push(b);
}
Op::Rev => {
let count = stack.pop().ok_or("stack underflow")?.as_int()? as usize;
if count > stack.len() {
return Err("stack underflow".into());
}
let start = stack.len() - count;
stack[start..].reverse();
}
Op::Shuffle => {
let count = stack.pop().ok_or("stack underflow")?.as_int()? as usize;
if count > stack.len() {
return Err("stack underflow".into());
}
let start = stack.len() - count;
let slice = &mut stack[start..];
let mut rng = self.rng.lock();
for i in (1..slice.len()).rev() {
let j = rng.gen_range(0..=i);
slice.swap(i, j);
}
}
Op::Sort => {
let count = stack.pop().ok_or("stack underflow")?.as_int()? as usize;
if count > stack.len() {
return Err("stack underflow".into());
}
let start = stack.len() - count;
stack[start..].sort_by(|a, b| {
a.as_float()
.unwrap_or(0.0)
.partial_cmp(&b.as_float().unwrap_or(0.0))
.unwrap_or(std::cmp::Ordering::Equal)
});
}
Op::RSort => {
let count = stack.pop().ok_or("stack underflow")?.as_int()? as usize;
if count > stack.len() {
return Err("stack underflow".into());
}
let start = stack.len() - count;
stack[start..].sort_by(|a, b| {
b.as_float()
.unwrap_or(0.0)
.partial_cmp(&a.as_float().unwrap_or(0.0))
.unwrap_or(std::cmp::Ordering::Equal)
});
}
Op::Sum => {
let count = stack.pop().ok_or("stack underflow")?.as_int()? as usize;
if count > stack.len() {
return Err("stack underflow".into());
}
let start = stack.len() - count;
let total: f64 = stack
.drain(start..)
.map(|v| v.as_float().unwrap_or(0.0))
.sum();
stack.push(float_to_value(total));
}
Op::Prod => {
let count = stack.pop().ok_or("stack underflow")?.as_int()? as usize;
if count > stack.len() {
return Err("stack underflow".into());
}
let start = stack.len() - count;
let product: f64 = stack
.drain(start..)
.map(|v| v.as_float().unwrap_or(1.0))
.product();
stack.push(float_to_value(product));
}
Op::Add => binary_op(stack, |a, b| a + b)?,
Op::Sub => binary_op(stack, |a, b| a - b)?,
@@ -889,6 +960,25 @@ impl Forth {
}
}
Op::StepRange => {
let step = stack.pop().ok_or("stack underflow")?.as_float()?;
let end = stack.pop().ok_or("stack underflow")?.as_float()?;
let start = stack.pop().ok_or("stack underflow")?.as_float()?;
if step == 0.0 {
return Err("step cannot be zero".into());
}
let ascending = step > 0.0;
let mut val = start;
loop {
let done = if ascending { val > end } else { val < end };
if done {
break;
}
stack.push(float_to_value(val));
val += step;
}
}
Op::Generate => {
let count = stack.pop().ok_or("stack underflow")?.as_int()?;
let quot = stack.pop().ok_or("stack underflow")?;