Lines
100 %
Functions
Branches
//! IF / COND / AND / OR / BEGIN consumed in value position (not just
//! effect position). Each is wrapped in arithmetic or comparison so
//! `compile_*_for_stack` fires and the value lands on the wasm stack.
use super::common::{compile_and_validate, wrap_with_runtime_ratio};
#[test]
fn if_for_stack_ratio_result() {
// Both branches return X (runtime Ratio) so the outer `+` sees a
// Ratio. Locks in the `compile_if_for_stack` path for ratio-valued
// IFs.
compile_and_validate(&wrap_with_runtime_ratio("(+ (if (= X 0) X X) X)"));
}
fn if_numeric_literal_branch_coerces_to_ratio() {
// ADR-0028: an integer-literal IF arm coerces to the other arm's numeric
// type (Scalar here) instead of widening to AnyRef. `(if (= X 0) 1 X)` is a
// Ratio IF, so the outer `+ … X` composes. This is the mechanism that lets
// a recursive `(if base 1 (* n (fact …)))` keep a consistent Ratio result.
compile_and_validate(&wrap_with_runtime_ratio("(+ (if (= X 0) 1 X) X)"));
fn if_for_stack_no_else_branch() {
// No-else IF in value position; the absent branch defaults to nil
// and the codegen path emits a typed-result block. Consumed as the
// last program form so it lands on the value stack.
compile_and_validate(&wrap_with_runtime_ratio("(if (= X 0) (+ X (/ 1 1)))"));
fn runtime_if_with_string_branches_let_bound() {
// A runtime-test IF whose branches are StringRef literals, bound in a
// LET*. The binder sizes its local from the eval-time type, which must
// match the StringRef the codegen actually pushes — previously eval
// collapsed both-literal branches to I32, mis-sizing the local and
// producing an invalid module.
compile_and_validate(&wrap_with_runtime_ratio(
r#"(let* ((s (if (= X 0) "a" "b"))) s)"#,
));
fn runtime_if_with_ratio_branches_let_bound() {
"(let* ((r (if (= X 0) 11/10 12/10))) r)",
fn cond_runtime_at_effect_position() {
// COND at effect position routes through `compile_cond_for_effect`.
// The cond is a prefix form; the program's last form is X so the
// overall return is Ratio.
"(cond ((= X 0) (debug \"zero\")) ((> X 0) (debug \"positive\"))) X",
fn and_for_stack() {
compile_and_validate(&wrap_with_runtime_ratio("(if (and (> X 0) (< X 10)) 1 0)"));
fn or_for_stack() {
compile_and_validate(&wrap_with_runtime_ratio("(if (or (= X 0) (= X 1)) 1 0)"));
fn begin_for_stack() {
// `begin` at value position returns the last form's value.
compile_and_validate(&wrap_with_runtime_ratio("(+ (begin (debug \"step\") X) 1)"));
fn quote_compiles_for_value_position() {
compile_and_validate("'a");
fn quote_constant_list_compiles() {
compile_and_validate("'(1 2 3)");