Unleashed v1.4
[unleashed.git] / contrib / libjeffpc / test_sexpr_eval.c
blobbe1e1679d664caeaa2f83d2a26d32a546e180480
1 /*
2 * Copyright (c) 2016 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
23 #include <jeffpc/types.h>
24 #include <jeffpc/sexpr.h>
25 #include <jeffpc/jeffpc.h>
27 #include "test.c"
29 static inline struct val *op0(char *op)
31 struct val *arr[1];
32 struct val *ret;
34 arr[0] = VAL_ALLOC_SYM_CSTR(op);
36 ret = sexpr_array_to_list(arr, ARRAY_LEN(arr));
38 sexpr_dump_file(stderr, ret, false);
40 return ret;
43 static inline struct val *op1(char *op, struct val *a)
45 struct val *arr[2];
46 struct val *ret;
48 arr[0] = VAL_ALLOC_SYM_CSTR(op);
49 arr[1] = a;
51 ret = sexpr_array_to_list(arr, ARRAY_LEN(arr));
53 sexpr_dump_file(stderr, ret, false);
55 return ret;
58 static inline struct val *op2(char *op, struct val *a, struct val *b)
60 struct val *arr[3];
61 struct val *ret;
63 arr[0] = VAL_ALLOC_SYM_CSTR(op);
64 arr[1] = a;
65 arr[2] = b;
67 ret = sexpr_array_to_list(arr, ARRAY_LEN(arr));
69 sexpr_dump_file(stderr, ret, false);
71 return ret;
74 static inline struct val *op3(char *op, struct val *a, struct val *b, struct val *c)
76 struct val *arr[4];
77 struct val *ret;
79 arr[0] = VAL_ALLOC_SYM_CSTR(op);
80 arr[1] = a;
81 arr[2] = b;
82 arr[3] = c;
84 ret = sexpr_array_to_list(arr, ARRAY_LEN(arr));
86 sexpr_dump_file(stderr, ret, false);
88 return ret;
91 static void test_int_op(char *opname, enum val_type type, uint64_t expected,
92 struct val *expr)
94 struct val *res;
96 res = sexpr_eval(expr, NULL, NULL);
98 fprintf(stderr, " -> ");
99 sexpr_dump_file(stderr, res, false);
100 fprintf(stderr, "\n");
102 ASSERT3U(res->type, ==, type);
103 switch (type) {
104 case VT_BOOL:
105 ASSERT3U(res->b, ==, expected);
106 break;
107 case VT_INT:
108 ASSERT3U(res->i, ==, expected);
109 break;
110 default:
111 fail("unhandled val type %u", type);
114 val_putref(res);
117 #define TEST_BOOL_OP0(n, e) test_int_op((n), VT_BOOL, (e), op0(n))
118 #define TEST_BOOL_OP1(n, e, v1) test_int_op((n), VT_BOOL, (e), op1((n), \
119 VAL_ALLOC_BOOL(v1)))
120 #define TEST_BOOL_OP2(n, e, v1, v2) test_int_op((n), VT_BOOL, (e), op2((n), \
121 VAL_ALLOC_BOOL(v1), \
122 VAL_ALLOC_BOOL(v2)))
123 #define TEST_BOOL_OP3(n, e, v1, v2, v3) test_int_op((n), VT_BOOL, (e), op3((n), \
124 VAL_ALLOC_BOOL(v1), \
125 VAL_ALLOC_BOOL(v2), \
126 VAL_ALLOC_BOOL(v3)))
128 #define TEST_INT_OP0(n, e) test_int_op((n), VT_INT, (e), op0(n))
129 #define TEST_INT_OP1(n, e, v1) test_int_op((n), VT_INT, (e), op1((n), \
130 VAL_ALLOC_INT(v1)))
131 #define TEST_INT_OP2(n, e, v1, v2) test_int_op((n), VT_INT, (e), op2((n), \
132 VAL_ALLOC_INT(v1), \
133 VAL_ALLOC_INT(v2)))
134 #define TEST_INT_OP3(n, e, v1, v2, v3) test_int_op((n), VT_INT, (e), op3((n), \
135 VAL_ALLOC_INT(v1), \
136 VAL_ALLOC_INT(v2), \
137 VAL_ALLOC_INT(v3)))
139 static void test_bools(char *or, char *and)
141 int i, j, k;
143 fprintf(stderr, "Testing booleans...\n");
145 TEST_BOOL_OP0(or, false);
146 TEST_BOOL_OP0(and, true);
148 for (i = 0; i < 2; i++) {
149 TEST_BOOL_OP1(or, !!i, !!i);
150 TEST_BOOL_OP1(and, !!i, !!i);
153 for (i = 0; i < 2; i++) {
154 for (j = 0; j < 2; j++) {
155 TEST_BOOL_OP2(or, (!!i) || (!!j), !!i, !!j);
156 TEST_BOOL_OP2(and, (!!i) && (!!j), !!i, !!j);
160 for (i = 0; i < 2; i++) {
161 for (j = 0; j < 2; j++) {
162 for (k = 0; k < 2; k++) {
163 TEST_BOOL_OP3(or, (!!i) || (!!j) || (!!k),
164 !!i, !!j, !!k);
165 TEST_BOOL_OP3(and, (!!i) && (!!j) && (!!k),
166 !!i, !!j, !!k);
172 static void test_ints(void)
174 int i, j, k;
176 fprintf(stderr, "Testing integers...\n");
178 TEST_INT_OP0("+", 0);
179 TEST_INT_OP0("*", 1);
181 for (i = 0; i < 3; i++) {
182 TEST_INT_OP1("+", i, i);
183 TEST_INT_OP1("*", i, i);
186 for (i = 0; i < 3; i++) {
187 for (j = 0; j < 3; j++) {
188 TEST_INT_OP2("+", i + j, i, j);
189 TEST_INT_OP2("*", i * j, i, j);
193 for (i = 0; i < 3; i++) {
194 for (j = 0; j < 3; j++) {
195 for (k = 0; k < 3; k++) {
196 TEST_INT_OP3("+", i + j + k, i, j, k);
197 TEST_INT_OP3("*", i * j * k, i, j, k);
203 void test(void)
205 jeffpc_init(NULL);
207 test_bools("or", "and");
208 test_bools("||", "&&");
209 test_ints();