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_becomes_string() { expect_str("foobar", "foobar"); } #[test] fn string_not_number() { expect_error(r#""hello" neg"#, "expected number"); } #[test] fn comment_ignored() { expect_int("1 ;; this is a comment\n2 +", 3); } #[test] fn multiline_comment() { expect_int("1 ;; first comment\n;; entire line comment\n2 +", 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::forth::Value::Str(s, _) => assert_eq!(s.as_ref(), "hello world"), other => panic!("expected string, got {:?}", other), } } #[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); }