Serene Runtime 1.0.0-dev
C runtime for the Serene programming language
Loading...
Searching...
No Matches
value_tests.h
Go to the documentation of this file.
1/* -*- C -*-
2 * Serene programming language
3 * Copyright (C) 2019-2026 Sameer Rahmani <[email protected]>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 */
18
19#pragma once
20
21#include <serene/rt/core.h>
23#include <serene/rt/lists.h>
24#include <serene/rt/maps.h>
25#include <serene/rt/protocols.h>
26
27#include "base.h"
28
29#define VALUE_TESTS(X) \
30 X("values::basics", test_value_basics), \
31 X("values::f64_zero_eq_hash", test_value_f64_zero_eq_hash), \
32 X("values::list_cons_type_check", test_value_list_cons_type_check), \
33 X("values::map_unhashable_key", test_value_map_unhashable_key),
34
35#if defined(V_DEBUG)
36# define V_TEST_LOG(...) DBG("VALUE_TEST", __VA_ARGS__)
37#else
38# define V_TEST_LOG(...)
39#endif
40
41static void test_value_basics() {
42 MAKE_ENGINE(mm, engine);
43 MAKE_CONTEXT(engine, ctx);
44
47
48 TEST_CHECK(x1->type == VI64);
49 TEST_CHECK(x1->as.i64 == 5);
50 TEST_CHECK(x2->as.i64 == -15);
51
52 RELEASE_CONTEXT(ctx);
53 SHUTDOWN_ENGINE(mm, engine);
54}
55
56/// IEEE equality makes +0.0 and -0.0 equal, so the documented eq => hash
57/// invariant requires them to hash the same despite different bit patterns.
59 MAKE_ENGINE(mm, engine);
60 MAKE_CONTEXT(engine, ctx);
61
62 srn_value_t pos = {.type = VF64, .metadata = &absurd_metadata, .as = {.f64 = 0.0}};
63 srn_value_t neg = {.type = VF64, .metadata = &absurd_metadata, .as = {.f64 = -0.0}};
64
65 TEST_CHECK(TYPE(srn_value_eq(ctx, &pos, &neg)) == VTrue);
66 TEST_CHECK(srn_value_hash(ctx, &pos) == srn_value_hash(ctx, &neg));
67
68 RELEASE_CONTEXT(ctx);
69 SHUTDOWN_ENGINE(mm, engine);
70}
71
72/// Consing onto a value that is neither nil nor a list must produce an error
73/// value, not reinterpret the payload as a list pointer.
75 MAKE_ENGINE(mm, engine);
76 MAKE_CONTEXT(engine, ctx);
77
78 srn_value_t *not_a_list = srn_make_i64(ctx, &absurd_metadata, 42);
80
81 srn_value_t *res = srn_list_cons(ctx, &absurd_metadata, x, not_a_list);
82 TEST_CHECK(TYPE(res) == VError);
83
84 RELEASE_CONTEXT(ctx);
85 SHUTDOWN_ENGINE(mm, engine);
86}
87
88/// A key the hash protocol cannot hash must come back as an error value from
89/// assoc, not abort the process from inside srn_value_hash.
91 MAKE_ENGINE(mm, engine);
92 MAKE_CONTEXT(engine, ctx);
93
95 TEST_ASSERT(TYPE(m) == VMap);
96
98 srn_value_t *lst = srn_list_make(ctx, &absurd_metadata, &item, 1);
100
101 srn_value_t *res = srn_map_assoc(ctx, &absurd_metadata, m, lst, val);
102 TEST_CHECK(TYPE(res) == VError);
103
104 RELEASE_CONTEXT(ctx);
105 SHUTDOWN_ENGINE(mm, engine);
106}
#define TEST_CHECK(cond)
Definition acutest.h:95
#define TEST_ASSERT(cond)
Definition acutest.h:117
#define RELEASE_CONTEXT(x)
Definition base.h:46
#define SHUTDOWN_ENGINE(mm, engine)
Definition base.h:38
#define MAKE_ENGINE(mm, engine)
Definition base.h:32
#define MAKE_CONTEXT(engine, x)
Definition base.h:42
srn_metadata_t absurd_metadata
We use this for testing. Defined once in core.c.
Definition core.c:26
#define TYPE(value_ref)
Definition core.h:165
@ VF64
Definition core.h:117
@ VI64
Definition core.h:116
@ VMap
Definition core.h:126
@ VError
VError should be last.
Definition core.h:128
@ VTrue
Definition core.h:114
srn_value_t * srn_list_cons(srn_context_t *ctx, srn_metadata_t *metadata, srn_value_t *value, srn_value_t *list)
Prepend value to list, returning a new list.
Definition lists.c:51
srn_value_t * srn_list_make(srn_context_t *ctx, srn_metadata_t *metadata, srn_value_t *const *items, size_t count)
Build a list from an array of elements.
Definition lists.c:25
srn_value_t * srn_map_assoc(srn_context_t *ctx, srn_metadata_t *metadata, srn_value_t *map, srn_value_t *key, srn_value_t *value)
Definition maps.c:71
srn_value_t * srn_map_empty(srn_context_t *ctx, srn_metadata_t *metadata)
Definition maps.c:64
static srn_value_t * srn_make_i64(srn_context_t *ctx, srn_metadata_t *metadata, int64_t x)
Definition numbers.h:24
srn_hash_t srn_value_hash(const srn_context_t *ctx, const srn_value_t *v)
Compute the xxHash32 of a value using the engine seed.
Definition protocols.c:152
srn_value_t * srn_value_eq(const srn_context_t *ctx, const srn_value_t *a, const srn_value_t *b)
Check to values for equality. Return a boolean.
Definition protocols.c:38
int64_t i64
We represent all the immidiate numbers with this field and cast as we to an appropriate type.
Definition core.h:138
union srn_value_t::@033047061046230251001111174367071167226300135003 as
IMPORTANT NOTE: The size of this union should never be larger than a word.
srn_value_tag_t type
Definition core.h:132
static void test_value_f64_zero_eq_hash()
IEEE equality makes +0.0 and -0.0 equal, so the documented eq => hash invariant requires them to hash...
Definition value_tests.h:58
static void test_value_map_unhashable_key()
A key the hash protocol cannot hash must come back as an error value from assoc, not abort the proces...
Definition value_tests.h:90
static void test_value_list_cons_type_check()
Consing onto a value that is neither nil nor a list must produce an error value, not reinterpret the ...
Definition value_tests.h:74
static void test_value_basics()
Definition value_tests.h:41