1
//! Extra DO / DO* / DOLIST paths — value-position dispatch
2
//! (`compile_do_runtime_for_stack`) and edge cases.
3

            
4
use super::common::{compile_and_validate, wrap_with_runtime_i32, wrap_with_runtime_ratio};
5

            
6
/// DO at value position — the loop's result form lands on the wasm
7
/// stack. Exercises `compile_do_runtime_for_stack`.
8
#[test]
9
1
fn do_for_stack_result() {
10
1
    compile_and_validate(&wrap_with_runtime_ratio(
11
1
        "(+ (do ((i 0 (+ i 1))) ((>= i 3) i)) X)",
12
1
    ));
13
1
}
14

            
15
#[test]
16
1
fn do_star_for_stack_result() {
17
1
    compile_and_validate(&wrap_with_runtime_ratio(
18
1
        "(+ (do* ((i 0 (+ i 1))) ((>= i 3) i)) X)",
19
1
    ));
20
1
}
21

            
22
#[test]
23
1
fn do_with_constant_iteration_static_folds() {
24
1
    compile_and_validate("(do ((i 0 (+ i 1))) ((= i 3) i))");
25
1
}
26

            
27
#[test]
28
1
fn dolist_at_value_position_returns_nil() {
29
1
    compile_and_validate("(+ (begin (dolist (x '(1 2)) x) 0) 0)");
30
1
}
31

            
32
#[test]
33
1
fn dolist_with_unbounded_runtime_chain() {
34
    // Iteration over a runtime pair chain — locks in the
35
    // compile_dolist_runtime path.
36
1
    compile_and_validate(
37
1
        "(let* ((acc 0)) \
38
1
           (dolist (i (cons 1 (cons 2 nil))) (setf acc (+ acc i))) \
39
1
           acc)",
40
    );
41
1
}
42

            
43
#[test]
44
1
fn do_with_nested_do() {
45
1
    compile_and_validate(
46
1
        "(let* ((sum 0)) \
47
1
           (do ((i 0 (+ i 1))) ((>= i 2)) \
48
1
             (do ((j 0 (+ j 1))) ((>= j 2)) \
49
1
               (setf sum (+ sum 1)))) \
50
1
           sum)",
51
    );
52
1
}
53

            
54
/// DO* with sequential init — the second var's init can reference
55
/// the first.
56
#[test]
57
1
fn do_star_sequential_init_visibility() {
58
    // IDX is a runtime Index; `limit` (init IDX, step 0) and the counter `i`
59
    // stay in the Index stratum so the loop var types are consistent.
60
1
    compile_and_validate(&wrap_with_runtime_i32(
61
1
        "(do* ((i 0 (+ i 1)) (limit IDX 0)) ((>= i limit) limit))",
62
1
    ));
63
1
}