93 lines
1.7 KiB
Rust
93 lines
1.7 KiB
Rust
use super::harness::*;
|
|
|
|
#[test]
|
|
fn empty_script() {
|
|
expect_error("", "empty script");
|
|
}
|
|
|
|
#[test]
|
|
fn whitespace_only() {
|
|
expect_error(" \n\t ", "empty script");
|
|
}
|
|
|
|
#[test]
|
|
fn unknown_word() {
|
|
expect_error("foobar", "unknown word");
|
|
}
|
|
|
|
#[test]
|
|
fn string_not_number() {
|
|
expect_error(r#""hello" neg"#, "expected number");
|
|
}
|
|
|
|
#[test]
|
|
fn comment_ignored() {
|
|
expect_int("1 (this is a comment) 2 +", 3);
|
|
}
|
|
|
|
#[test]
|
|
fn multiline_comment() {
|
|
expect_int("1 (multi\nline\ncomment) 2 +", 3);
|
|
}
|
|
|
|
#[test]
|
|
fn negative_literal() {
|
|
expect_int("-5", -5);
|
|
}
|
|
|
|
#[test]
|
|
fn float_literal() {
|
|
let f = run("3.14159");
|
|
let val = stack_float(&f);
|
|
assert!((val - 3.14159).abs() < 1e-9);
|
|
}
|
|
|
|
#[test]
|
|
fn string_with_spaces() {
|
|
let f = run(r#""hello world" !x @x"#);
|
|
match stack_top(&f) {
|
|
cagire::model::forth::Value::Str(s, _) => assert_eq!(s, "hello world"),
|
|
other => panic!("expected string, got {:?}", other),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn list_count() {
|
|
let f = run("[ 1 2 3 ]");
|
|
assert_eq!(stack_int(&f), 3);
|
|
}
|
|
|
|
#[test]
|
|
fn list_empty() {
|
|
expect_int("[ ]", 0);
|
|
}
|
|
|
|
#[test]
|
|
fn list_preserves_values() {
|
|
expect_int("[ 10 20 ] drop +", 30);
|
|
}
|
|
|
|
#[test]
|
|
fn conditional_based_on_step() {
|
|
let ctx0 = ctx_with(|c| c.step = 0);
|
|
let ctx1 = ctx_with(|c| c.step = 1);
|
|
|
|
let f0 = run_ctx("step 2 mod 0 = if 100 else 200 then", &ctx0);
|
|
let f1 = run_ctx("step 2 mod 0 = if 100 else 200 then", &ctx1);
|
|
|
|
assert_eq!(stack_int(&f0), 100);
|
|
assert_eq!(stack_int(&f1), 200);
|
|
}
|
|
|
|
#[test]
|
|
fn accumulator() {
|
|
let f = forth();
|
|
let ctx = default_ctx();
|
|
f.evaluate(r#"0 !acc"#, &ctx).unwrap();
|
|
for _ in 0..5 {
|
|
f.clear_stack();
|
|
f.evaluate(r#"@acc 1 + dup !acc"#, &ctx).unwrap();
|
|
}
|
|
assert_eq!(stack_int(&f), 5);
|
|
}
|