Feat: UI / UX
This commit is contained in:
@@ -60,3 +60,6 @@ mod chords;
|
||||
|
||||
#[path = "forth/euclidean.rs"]
|
||||
mod euclidean;
|
||||
|
||||
#[path = "forth/case_statement.rs"]
|
||||
mod case_statement;
|
||||
|
||||
108
tests/forth/case_statement.rs
Normal file
108
tests/forth/case_statement.rs
Normal file
@@ -0,0 +1,108 @@
|
||||
use super::harness::*;
|
||||
|
||||
#[test]
|
||||
fn single_clause_match() {
|
||||
expect_int("1 case 1 of 42 endof endcase", 42);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_clause_no_match() {
|
||||
let f = run("1 case 2 of 42 endof endcase");
|
||||
assert!(f.stack().is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multi_clause_first() {
|
||||
expect_int("0 case 0 of 10 endof 1 of 20 endof 2 of 30 endof endcase", 10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multi_clause_middle() {
|
||||
expect_int("1 case 0 of 10 endof 1 of 20 endof 2 of 30 endof endcase", 20);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multi_clause_last() {
|
||||
expect_int("2 case 0 of 10 endof 1 of 20 endof 2 of 30 endof endcase", 30);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_match_stack_clean() {
|
||||
let f = run("99 case 0 of 10 endof 1 of 20 endof endcase");
|
||||
assert!(f.stack().is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn expression_test_value() {
|
||||
expect_int("3 case 1 2 + of 42 endof endcase", 42);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn expression_case_value() {
|
||||
expect_int("1 2 + case 3 of 42 endof endcase", 42);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn body_with_computation() {
|
||||
expect_int("1 case 1 of 10 20 + endof endcase", 30);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_clause() {
|
||||
// Default drops case value and pushes replacement twice (endcase drops one)
|
||||
expect_int("99 case 0 of 10 endof 1 of 20 endof drop 42 42 endcase", 42);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_clause_uses_case_value() {
|
||||
// dup preserves case value through endcase's drop
|
||||
expect_int("99 case 0 of 10 endof dup endcase", 99);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_clause_not_reached_on_match() {
|
||||
expect_int("0 case 0 of 10 endof 999 endcase", 10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nested_case_in_case() {
|
||||
// outer matches 1, inner matches 2
|
||||
expect_int("1 case 1 of 2 case 2 of 42 endof endcase endof endcase", 42);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn if_inside_case_body() {
|
||||
expect_int("1 case 1 of 1 if 42 else 99 then endof endcase", 42);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn case_inside_if_body() {
|
||||
expect_int("1 if 2 case 2 of 42 endof endcase then", 42);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn preserves_stack_below() {
|
||||
let f = run("100 1 case 1 of 42 endof endcase");
|
||||
let stack = f.stack();
|
||||
assert_eq!(stack.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_endcase() {
|
||||
expect_error("1 case 0 of 10 endof", "missing 'endcase'");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stray_of() {
|
||||
expect_error("1 of", "unexpected 'of'");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stray_endof() {
|
||||
expect_error("1 endof", "unexpected 'endof'");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stray_endcase() {
|
||||
expect_error("1 endcase", "unexpected 'endcase'");
|
||||
}
|
||||
@@ -42,3 +42,28 @@ fn float_var() {
|
||||
fn increment_pattern() {
|
||||
expect_int(r#"0 !n @n 1 + !n @n 1 + !n @n"#, 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_keep() {
|
||||
expect_int(r#"42 ,x"#, 42);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_keep_stores() {
|
||||
let f = forth();
|
||||
let ctx = default_ctx();
|
||||
f.evaluate(r#"42 ,x"#, &ctx).unwrap();
|
||||
f.clear_stack();
|
||||
f.evaluate(r#"@x"#, &ctx).unwrap();
|
||||
assert_eq!(stack_int(&f), 42);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_keep_chain() {
|
||||
let f = forth();
|
||||
let ctx = default_ctx();
|
||||
f.evaluate(r#"10 ,a ,b"#, &ctx).unwrap();
|
||||
f.clear_stack();
|
||||
f.evaluate(r#"@a @b +"#, &ctx).unwrap();
|
||||
assert_eq!(stack_int(&f), 20);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user