Add double-stack words (2dup, 2drop, 2swap, 2over) and forget
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
use super::harness::*;
|
||||
use cagire::forth::Value;
|
||||
|
||||
#[test]
|
||||
fn define_and_use_word() {
|
||||
@@ -113,3 +114,44 @@ fn define_word_with_conditional() {
|
||||
f.evaluate("10 maybe-double", &ctx).unwrap();
|
||||
assert_eq!(stack_int(&f), 20);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn forget_removes_word() {
|
||||
let f = forth();
|
||||
let ctx = default_ctx();
|
||||
f.evaluate(": double 2 * ;", &ctx).unwrap();
|
||||
f.evaluate("5 double", &ctx).unwrap();
|
||||
assert_eq!(stack_int(&f), 10);
|
||||
f.clear_stack();
|
||||
f.evaluate("\"double\" forget", &ctx).unwrap();
|
||||
f.evaluate("double", &ctx).unwrap();
|
||||
let stack = f.stack();
|
||||
assert_eq!(stack.len(), 1);
|
||||
match &stack[0] {
|
||||
Value::Str(s, _) => assert_eq!(s, "double"),
|
||||
other => panic!("expected Str, got {:?}", other),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn forget_nonexistent_is_noop() {
|
||||
let f = forth();
|
||||
let ctx = default_ctx();
|
||||
f.evaluate("\"nosuchword\" forget", &ctx).unwrap();
|
||||
f.evaluate("42", &ctx).unwrap();
|
||||
assert_eq!(stack_int(&f), 42);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn forget_and_redefine() {
|
||||
let f = forth();
|
||||
let ctx = default_ctx();
|
||||
f.evaluate(": foo 10 ;", &ctx).unwrap();
|
||||
f.evaluate("foo", &ctx).unwrap();
|
||||
assert_eq!(stack_int(&f), 10);
|
||||
f.clear_stack();
|
||||
f.evaluate("\"foo\" forget", &ctx).unwrap();
|
||||
f.evaluate(": foo 20 ;", &ctx).unwrap();
|
||||
f.evaluate("foo", &ctx).unwrap();
|
||||
assert_eq!(stack_int(&f), 20);
|
||||
}
|
||||
|
||||
@@ -95,6 +95,46 @@ fn tuck_underflow() {
|
||||
expect_error("1 tuck", "stack underflow");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dup2() {
|
||||
expect_stack("1 2 2dup", &[int(1), int(2), int(1), int(2)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dup2_underflow() {
|
||||
expect_error("1 2dup", "stack underflow");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn drop2() {
|
||||
expect_stack("1 2 3 2drop", &[int(1)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn drop2_underflow() {
|
||||
expect_error("1 2drop", "stack underflow");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn swap2() {
|
||||
expect_stack("1 2 3 4 2swap", &[int(3), int(4), int(1), int(2)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn swap2_underflow() {
|
||||
expect_error("1 2 3 2swap", "stack underflow");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn over2() {
|
||||
expect_stack("1 2 3 4 2over", &[int(1), int(2), int(3), int(4), int(1), int(2)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn over2_underflow() {
|
||||
expect_error("1 2 3 2over", "stack underflow");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stack_persists() {
|
||||
let f = forth();
|
||||
|
||||
Reference in New Issue
Block a user