Lines
100 %
Functions
Branches
//! Comparison codegen edge cases — multi-arg chains, ratio/integer
//! mix, eql/equal symmetry, neq with multiple args.
use super::common::{compile_and_validate, wrap_with_runtime_ratio};
#[test]
fn eq_multi_arg_constant_fold() {
compile_and_validate("(= 1 1 1 1)");
}
fn lt_multi_arg_chain() {
compile_and_validate("(< 1 2 3 4)");
fn gt_descending_chain() {
compile_and_validate("(> 4 3 2 1)");
fn eql_with_strings() {
compile_and_validate("(eql \"foo\" \"foo\")");
fn eql_with_symbols() {
compile_and_validate("(eql 'a 'a)");
fn eql_with_nil() {
compile_and_validate("(eql nil nil)");
fn equal_with_ratios() {
compile_and_validate("(equal (/ 1 2) (/ 1 2))");
fn equal_unequal_lists() {
compile_and_validate("(equal '(1 2) '(1 3))");
/// `EQUAL?` / `EQ?` (Scheme spellings) are documented natives + registered
/// builtin symbols; they must have real codegen handlers, not just exist as
/// names the compiler rejects. Regression for the missing `EQUAL?`/`EQ?`
/// NativeSpec rows.
fn equal_question_alias_compiles() {
compile_and_validate("(equal? 'a 'a)");
fn eq_question_alias_compiles() {
compile_and_validate("(eq? 1 1)");
/// Equality in value (stack) position — the last form of a `defun` body.
/// `EQL`/`EQUAL` used to carry `stack: None`, so this errored with
/// "cannot produce stack value". Locks in the stack handler.
fn equal_in_value_position_compiles() {
compile_and_validate("(defun same? (a b) (equal? a b)) (same? 1 1)");
/// Equality as an `and` operand drives the for-stack path; with `stack: None`
/// it failed. Mirrors the Metro script's `(and (equal? …) (equal? …))` shape.
fn equal_as_and_operand_compiles() {
compile_and_validate(&wrap_with_runtime_ratio("(and (equal? X X) (equal? X X))"));
fn cmp_runtime_lhs_string_constant() {
// Comparison helpers should refuse mixing — Ratio vs String.
use super::common::compile_expect_error;
let err = compile_expect_error(&wrap_with_runtime_ratio("(= X \"foo\")"));
assert!(!err.is_empty(), "got: {err}");
fn le_with_runtime_and_ratio_constant() {
compile_and_validate(&wrap_with_runtime_ratio("(<= (/ 1 2) X)"));
fn ge_with_runtime_and_ratio_constant() {
compile_and_validate(&wrap_with_runtime_ratio("(>= (/ 1 2) X)"));
fn cmp_eq_ratio_with_integer_literal() {
compile_and_validate(&wrap_with_runtime_ratio("(= X (/ 5 1))"));
fn not_runtime_chained() {
compile_and_validate(&wrap_with_runtime_ratio("(not (not (= X 0)))"));