GCC Code Coverage Report


Directory: ../src/
File: /home/joels/Current/lispbm/src/fundamental.c
Date: 2025-10-27 19:12:55
Exec Total Coverage
Lines: 860 862 99.8%
Functions: 80 80 100.0%
Branches: 629 667 94.3%

Line Branch Exec Source
1 /*
2 Copyright 2019, 2021 - 2025 Joel Svensson svenssonjoel@yahoo.se
3 2022 Benjamin Vedder
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 <http://www.gnu.org/licenses/>.
17 */
18 #include <lbm_types.h>
19 #include "symrepr.h"
20 #include "stack.h"
21 #include "heap.h"
22 #include "eval_cps.h"
23 #include "env.h"
24 #include "lbm_utils.h"
25 #include "lbm_custom_type.h"
26 #include "lbm_constants.h"
27 #include "fundamental.h"
28 #include "lbm_defrag_mem.h"
29 #include "print.h" // printable string?
30
31 #include <stdio.h>
32 #include <math.h>
33
34 #ifdef LBM_OPT_FUNDAMENTALS_SIZE
35 #pragma GCC optimize ("-Os")
36 #endif
37 #ifdef LBM_OPT_FUNDAMENTALS_SIZE_AGGRESSIVE
38 #pragma GCC optimize ("-Oz")
39 #endif
40 /* Type promotion ranks
41
42 32bit LBM:
43 byte < i < u < i32 < u32 < i64 < u64 < float < double
44
45 64bit LBM:
46 byte < i32 < u32 < i < u < i64 < u64 < float < double
47 */
48
49 // PROMOTE_SWAP is for commutative operations
50 // PROMOTE is for non-commutative operations
51
52 #ifndef LBM64
53 #define PROMOTE_SWAP(t, a, b) \
54 if (lbm_type_of_functional(a) < lbm_type_of_functional(b)) { \
55 lbm_value tmp = a; \
56 a = b; \
57 b = tmp; \
58 } \
59 t = lbm_type_of_functional(a);
60 #else
61 #define PROMOTE_SWAP(t, a, b) \
62 if (lbm_type_of_functional(b) == LBM_TYPE_FLOAT && (lbm_type_of_functional(a) < LBM_TYPE_DOUBLE)) { \
63 lbm_value tmp = a; \
64 a = b; \
65 b = tmp; \
66 } if (lbm_type_of_functional(a) == LBM_TYPE_FLOAT && (lbm_type_of_functional(b) < LBM_TYPE_DOUBLE)) { \
67 /* DO NOTHING */ \
68 } else if (lbm_type_of_functional(a) < lbm_type_of_functional(b)) { \
69 lbm_value tmp = a; \
70 a = b; \
71 b = tmp; \
72 } \
73 t = lbm_type_of_functional(a);
74 #endif
75
76 #ifndef LBM64
77 #define PROMOTE(t, a, b) \
78 t = lbm_type_of_functional(a); \
79 lbm_uint t_b = lbm_type_of_functional(b); \
80 if (t < t_b) { \
81 t = t_b; \
82 }
83
84 #else
85 #define PROMOTE(t, a, b) \
86 if (lbm_type_of_functional(b) == LBM_TYPE_FLOAT) { \
87 if (lbm_type_of_functional(a) < LBM_TYPE_DOUBLE) { \
88 t = LBM_TYPE_FLOAT; \
89 } else { \
90 t = lbm_type_of_functional(a); \
91 } \
92 } else if (lbm_type_of_functional(a) < lbm_type_of_functional(b)) { \
93 t = lbm_type_of_functional(b); \
94 } else { \
95 t = lbm_type_of_functional(a); \
96 }
97 #endif
98
99
100 #define IS_NUMBER lbm_is_number
101
102 // Todo: It may be possible perform some of these operations
103 // on encoded values followed by a "correction" of the result values
104 // type bits.
105 // But the checks required to figure out if it is possible to apply the
106 // operation in this way has a cost too...
107
108 70142251 static lbm_uint mul2(lbm_uint a, lbm_uint b) {
109 70142251 lbm_uint retval = ENC_SYM_TERROR;
110
3/4
✓ Branch 0 taken 70142251 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 70142074 times.
✓ Branch 3 taken 177 times.
140284325 if (IS_NUMBER(a) && IS_NUMBER(b)) {
111 lbm_type t;
112
2/2
✓ Branch 0 taken 33960968 times.
✓ Branch 1 taken 36181106 times.
70142074 PROMOTE_SWAP(t, a, b);
113
9/10
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 2866417 times.
✓ Branch 2 taken 392 times.
✓ Branch 3 taken 504 times.
✓ Branch 4 taken 448 times.
✓ Branch 5 taken 67272128 times.
✓ Branch 6 taken 616 times.
✓ Branch 7 taken 560 times.
✓ Branch 8 taken 729 times.
✗ Branch 9 not taken.
70142074 switch (t) {
114 280 case LBM_TYPE_CHAR: retval = lbm_enc_char((uint8_t)(lbm_dec_char(a) * lbm_dec_char(b))); break;
115 #ifdef LBM64
116 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(a) * lbm_dec_as_i64(b)); break;
117 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(a) * lbm_dec_as_u64(b)); break;
118 #else
119 2866417 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(a) * lbm_dec_as_i32(b)); break;
120 392 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(a) * lbm_dec_as_u32(b)); break;
121 #endif
122 504 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_u32(a) * lbm_dec_as_u32(b)); break;
123 448 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_i32(a) * lbm_dec_as_i32(b)); break;
124 67272128 case LBM_TYPE_FLOAT: retval = lbm_enc_float(lbm_dec_float(a) * lbm_dec_as_float(b)); break;
125 616 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_u64(a) * lbm_dec_as_u64(b)); break;
126 560 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_i64(a) * lbm_dec_as_i64(b)); break;
127 729 case LBM_TYPE_DOUBLE: retval = lbm_enc_double(lbm_dec_double(a) * lbm_dec_as_double(b)); break;
128 }
129 } else {
130
1/2
✓ Branch 0 taken 177 times.
✗ Branch 1 not taken.
177 lbm_set_error_suspect(IS_NUMBER(a) ? b : a);
131 }
132 70142251 return retval;
133 }
134
135 1285 static lbm_uint div2(lbm_uint a, lbm_uint b) {
136 1285 lbm_uint retval = ENC_SYM_TERROR;
137
4/4
✓ Branch 0 taken 1216 times.
✓ Branch 1 taken 69 times.
✓ Branch 2 taken 1146 times.
✓ Branch 3 taken 70 times.
1970 if (IS_NUMBER(a) && IS_NUMBER(b)) {
138 lbm_type t;
139
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 1114 times.
1146 PROMOTE(t, a, b);
140
9/10
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 580 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 56 times.
✓ Branch 4 taken 56 times.
✓ Branch 5 taken 144 times.
✓ Branch 6 taken 56 times.
✓ Branch 7 taken 56 times.
✓ Branch 8 taken 86 times.
✗ Branch 9 not taken.
1146 switch (t) {
141
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 28 times.
56 case LBM_TYPE_CHAR: if (lbm_dec_char(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_char((uint8_t)(lbm_dec_char(a) / lbm_dec_char(b))); break;
142 #ifdef LBM64
143 case LBM_TYPE_I: if (lbm_dec_i(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_i(lbm_dec_as_i64(a) / lbm_dec_as_i64(b)); break;
144 case LBM_TYPE_U: if (lbm_dec_as_u32(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_u(lbm_dec_as_u64(a) / lbm_dec_as_u64(b)); break;
145 #else
146
2/2
✓ Branch 0 taken 232 times.
✓ Branch 1 taken 348 times.
580 case LBM_TYPE_I: if (lbm_dec_i(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_i(lbm_dec_as_i32(a) / lbm_dec_as_i32(b)); break;
147
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 28 times.
56 case LBM_TYPE_U: if (lbm_dec_as_u32(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_u(lbm_dec_as_u32(a) / lbm_dec_as_u32(b)); break;
148 #endif
149
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 28 times.
56 case LBM_TYPE_U32: if (lbm_dec_as_u32(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_u32(lbm_dec_as_u32(a) / lbm_dec_as_u32(b)); break;
150
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 28 times.
56 case LBM_TYPE_I32: if (lbm_dec_as_i32(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_i32(lbm_dec_as_i32(a) / lbm_dec_as_i32(b)); break;
151
3/4
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 112 times.
144 case LBM_TYPE_FLOAT: if (lbm_dec_as_float(b) == 0.0f || lbm_dec_as_float(b) == -0.0f) {return ENC_SYM_DIVZERO;} retval = lbm_enc_float(lbm_dec_as_float(a) / lbm_dec_as_float(b)); break;
152
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 28 times.
56 case LBM_TYPE_U64: if (lbm_dec_as_u64(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_u64(lbm_dec_as_u32(a) / lbm_dec_as_u64(b)); break;
153
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 28 times.
56 case LBM_TYPE_I64: if (lbm_dec_as_i64(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_i64(lbm_dec_as_i32(a) / lbm_dec_as_i64(b)); break;
154
3/4
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 57 times.
86 case LBM_TYPE_DOUBLE: if (lbm_dec_as_double(b) == (double)0.0 || lbm_dec_as_double(b) == (double)-0.0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_double(lbm_dec_as_double(a) / lbm_dec_as_double(b)); break;
155 }
156 } else {
157
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 69 times.
139 lbm_set_error_suspect(IS_NUMBER(a) ? b : a);
158 }
159 824 return retval;
160 }
161
162 31989 static lbm_uint mod2(lbm_uint a, lbm_uint b) {
163 31989 lbm_uint retval = ENC_SYM_TERROR;
164
4/4
✓ Branch 0 taken 31928 times.
✓ Branch 1 taken 61 times.
✓ Branch 2 taken 31870 times.
✓ Branch 3 taken 58 times.
63576 if (IS_NUMBER(a) && IS_NUMBER(b)) {
165 lbm_type t;
166
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 31868 times.
31870 PROMOTE(t, a, b);
167
9/10
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 23420 times.
✓ Branch 2 taken 8056 times.
✓ Branch 3 taken 56 times.
✓ Branch 4 taken 56 times.
✓ Branch 5 taken 57 times.
✓ Branch 6 taken 56 times.
✓ Branch 7 taken 56 times.
✓ Branch 8 taken 57 times.
✗ Branch 9 not taken.
31870 switch (t) {
168
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 28 times.
56 case LBM_TYPE_CHAR: if (lbm_dec_char(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_char((uint8_t)(lbm_dec_char(a) % lbm_dec_as_i32(b))); break;
169 #ifdef LBM64
170 case LBM_TYPE_I: if (lbm_dec_i(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_i(lbm_dec_as_i64(a) % lbm_dec_as_i64(b)); break;
171 case LBM_TYPE_U: if (lbm_dec_as_u32(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_u(lbm_dec_as_u64(a) % lbm_dec_as_u64(b)); break;
172 #else
173
2/2
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 23363 times.
23420 case LBM_TYPE_I: if (lbm_dec_i(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_i(lbm_dec_as_i32(a) % lbm_dec_as_i32(b)); break;
174
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 8028 times.
8056 case LBM_TYPE_U: if (lbm_dec_as_u32(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_u(lbm_dec_as_u32(a) % lbm_dec_as_u32(b)); break;
175 #endif
176
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 28 times.
56 case LBM_TYPE_U32: if (lbm_dec_as_u32(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_u32(lbm_dec_as_u32(a) % lbm_dec_as_u32(b)); break;
177
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 28 times.
56 case LBM_TYPE_I32: if (lbm_dec_as_i32(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_i32(lbm_dec_as_i32(a) % lbm_dec_as_i32(b)); break;
178
3/4
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 28 times.
57 case LBM_TYPE_FLOAT: if (lbm_dec_as_float(b) == 0.0f || lbm_dec_as_float(b) == -0.0f) {return ENC_SYM_DIVZERO;} retval = lbm_enc_float(fmodf(lbm_dec_as_float(a), lbm_dec_as_float(b))); break;
179
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 28 times.
56 case LBM_TYPE_U64: if (lbm_dec_as_u64(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_u64(lbm_dec_as_u64(a) % lbm_dec_as_u64(b)); break;
180
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 28 times.
56 case LBM_TYPE_I64: if (lbm_dec_as_i64(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_i64(lbm_dec_as_i64(a) % lbm_dec_as_i64(b)); break;
181
3/4
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 28 times.
57 case LBM_TYPE_DOUBLE: if (lbm_dec_as_double(b) == (double)0.0 || lbm_dec_as_double(b) == (double)-0.0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_double(fmod(lbm_dec_as_double(a), lbm_dec_as_double(b))); break;
182 }
183 } else {
184
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 61 times.
119 lbm_set_error_suspect(IS_NUMBER(a) ? b : a);
185 }
186 31706 return retval;
187 }
188
189 27346255 static lbm_uint sub2(lbm_uint a, lbm_uint b) {
190 27346255 lbm_uint retval = ENC_SYM_TERROR;
191
4/4
✓ Branch 0 taken 27346194 times.
✓ Branch 1 taken 61 times.
✓ Branch 2 taken 27346050 times.
✓ Branch 3 taken 144 times.
54692305 if (IS_NUMBER(a) && IS_NUMBER(b)) {
192 lbm_uint t;
193
2/2
✓ Branch 0 taken 463 times.
✓ Branch 1 taken 27345587 times.
27346050 PROMOTE(t, a, b);
194
9/10
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 27063850 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 281585 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 219 times.
✓ Branch 6 taken 56 times.
✓ Branch 7 taken 84 times.
✓ Branch 8 taken 60 times.
✗ Branch 9 not taken.
27346050 switch (t) {
195 56 case LBM_TYPE_BYTE: retval = lbm_enc_char((uint8_t)(lbm_dec_char(a) - lbm_dec_char(b))); break;
196 #ifdef LBM64
197 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_as_i64(a) - lbm_dec_as_i64(b)); break;
198 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_as_u64(a) - lbm_dec_as_u64(b)); break;
199 #else
200 27063850 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_as_i32(a) - lbm_dec_as_i32(b)); break;
201 56 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_as_u32(a) - lbm_dec_as_u32(b)); break;
202 #endif
203 281585 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_as_u32(a) - lbm_dec_as_u32(b)); break;
204 84 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_as_i32(a) - lbm_dec_as_i32(b)); break;
205 219 case LBM_TYPE_FLOAT: retval = lbm_enc_float(lbm_dec_as_float(a) - lbm_dec_as_float(b)); break;
206 56 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_as_u64(a) - lbm_dec_as_u64(b)); break;
207 84 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_as_i64(a) - lbm_dec_as_i64(b)); break;
208 60 case LBM_TYPE_DOUBLE: retval = lbm_enc_double(lbm_dec_as_double(a) - lbm_dec_as_double(b)); break;
209 }
210 } else {
211
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 61 times.
205 lbm_set_error_suspect(IS_NUMBER(a) ? b : a);
212 }
213 27346255 return retval;
214 }
215
216 // a and b must be bytearrays!
217 20614 static bool bytearray_equality(lbm_value a, lbm_value b) {
218 20614 lbm_array_header_t *a_ = (lbm_array_header_t*)lbm_car(a);
219 20614 lbm_array_header_t *b_ = (lbm_array_header_t*)lbm_car(b);
220 20614 bool res = false;
221 // A NULL array arriving here should be impossible.
222 // if the a and b are not valid arrays at this point, the data
223 // is most likely nonsense - corrupted by cosmic radiation.
224
4/6
✓ Branch 0 taken 20614 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20614 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 20446 times.
✓ Branch 5 taken 168 times.
20614 if ((a_ && b_) && a_->size == b_->size) {
225 20446 res = (memcmp((char*)a_->data, (char*)b_->data, a_->size) == 0);
226 }
227 20614 return res;
228 }
229
230 // a and b must be arrays!
231 342 static bool array_struct_equality(lbm_value a, lbm_value b) {
232 342 lbm_array_header_t *a_ = (lbm_array_header_t*)lbm_car(a);
233 342 lbm_array_header_t *b_ = (lbm_array_header_t*)lbm_car(b);
234 342 bool res = false;
235
4/6
✓ Branch 0 taken 342 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 342 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 314 times.
✓ Branch 5 taken 28 times.
342 if ((a_ && b_) && a_->size == b_->size) {
236 314 res = true;
237 314 lbm_value *adata = (lbm_value*)a_->data;
238 314 lbm_value *bdata = (lbm_value*)b_->data;
239 314 lbm_uint size = (lbm_uint)a_->size / (lbm_uint)sizeof(lbm_value);
240
2/2
✓ Branch 0 taken 773 times.
✓ Branch 1 taken 286 times.
1059 for (lbm_uint i = 0; i < size; i ++ ) {
241 773 res = struct_eq(adata[i], bdata[i]);
242
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 745 times.
773 if (!res) break;
243 }
244 }
245 342 return res;
246 }
247
248 // ////////////////////////////////////////////////////////////
249 // Added pointer comparison before recurring on arrays and lists.
250 // struct_eq can exhaust stack! but the pointer check makes it
251 // a highly unlikely event occurring normally.
252 //
253 // To run out of C stack now you would have to
254 // create in memory two identical structures that are
255 // large and pointer-wise unique but structuraly identical.
256 //
257 // Unknowns that impact this is argument is that
258 // the stack depth is unknown to me (it is a result of the integrator's choices).
259 469742 bool struct_eq(lbm_value a, lbm_value b) {
260
261 469742 bool res = false;
262 469742 lbm_type ta = lbm_type_of_functional(a);
263 469742 lbm_type tb = lbm_type_of_functional(b);
264
265
2/2
✓ Branch 0 taken 391263 times.
✓ Branch 1 taken 78479 times.
469742 if (ta == tb) {
266
13/14
✓ Branch 0 taken 72239 times.
✓ Branch 1 taken 202023 times.
✓ Branch 2 taken 590 times.
✓ Branch 3 taken 5023 times.
✓ Branch 4 taken 76748 times.
✓ Branch 5 taken 1827 times.
✓ Branch 6 taken 3596 times.
✓ Branch 7 taken 6743 times.
✓ Branch 8 taken 561 times.
✓ Branch 9 taken 561 times.
✓ Branch 10 taken 396 times.
✓ Branch 11 taken 20614 times.
✓ Branch 12 taken 342 times.
✗ Branch 13 not taken.
391263 switch(ta){
267 72239 case LBM_TYPE_SYMBOL:
268 72239 res = (lbm_dec_sym(a) == lbm_dec_sym(b)); break;
269 202023 case LBM_TYPE_I:
270 202023 res = (lbm_dec_i(a) == lbm_dec_i(b)); break;
271 590 case LBM_TYPE_U:
272 590 res = (lbm_dec_u(a) == lbm_dec_u(b)); break;
273 5023 case LBM_TYPE_CHAR:
274 5023 res = (lbm_dec_char(a) == lbm_dec_char(b)); break;
275 76748 case LBM_TYPE_CONS:
276
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 76734 times.
76748 if (a == b) { // quick path if pointers equal (pointers equal => structural equal)
277 14 res = true;
278 14 break;
279 }
280
4/4
✓ Branch 0 taken 76677 times.
✓ Branch 1 taken 57 times.
✓ Branch 2 taken 76649 times.
✓ Branch 3 taken 28 times.
153411 res = ( struct_eq(lbm_car(a),lbm_car(b)) &&
281 153411 struct_eq(lbm_cdr(a),lbm_cdr(b)) ); break;
282 1827 case LBM_TYPE_I32:
283 1827 res = (lbm_dec_i32(a) == lbm_dec_i32(b)); break;
284 3596 case LBM_TYPE_U32:
285 3596 res = (lbm_dec_u32(a) == lbm_dec_u32(b)); break;
286 6743 case LBM_TYPE_FLOAT:
287 6743 res = (lbm_dec_float(a) == lbm_dec_float(b)); break;
288 561 case LBM_TYPE_I64:
289 561 res = (lbm_dec_i64(a) == lbm_dec_i64(b)); break;
290 561 case LBM_TYPE_U64:
291 561 res = (lbm_dec_u64(a) == lbm_dec_u64(b)); break;
292 396 case LBM_TYPE_DOUBLE:
293 396 res = (lbm_dec_double(a) == lbm_dec_double(b)); break;
294 20614 case LBM_TYPE_ARRAY:
295 20614 res = bytearray_equality(a, b); break;
296 342 case LBM_TYPE_LISPARRAY:
297
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 342 times.
342 if (a == b) { // quick path if pointers equal (pointers equal => structural equal)
298 res = true;
299 break;
300 }
301 342 res = array_struct_equality(a, b); break;
302 }
303 }
304 469742 return res;
305 }
306
307
308 /* returns -1 if a < b; 0 if a = b; 1 if a > b
309 args must be numbers
310 */
311 76367068 static int compare_num(lbm_uint a, lbm_uint b) {
312
313 76367068 int retval = 0;
314
315 lbm_uint t;
316
2/2
✓ Branch 0 taken 370 times.
✓ Branch 1 taken 76366698 times.
76367068 PROMOTE(t, a, b);
317
9/10
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 38279675 times.
✓ Branch 2 taken 5293 times.
✓ Branch 3 taken 560889 times.
✓ Branch 4 taken 280059 times.
✓ Branch 5 taken 36400775 times.
✓ Branch 6 taken 280084 times.
✓ Branch 7 taken 560086 times.
✓ Branch 8 taken 179 times.
✗ Branch 9 not taken.
76367068 switch (t) {
318 28 case LBM_TYPE_CHAR: retval = CMP(lbm_dec_char(a), lbm_dec_char(b)); break;
319 #ifdef LBM64
320 case LBM_TYPE_I: retval = CMP(lbm_dec_as_i64(a), lbm_dec_as_i64(b)); break;
321 case LBM_TYPE_U: retval = CMP(lbm_dec_as_u64(a), lbm_dec_as_u64(b)); break;
322 #else
323 38279675 case LBM_TYPE_I: retval = CMP(lbm_dec_as_i32(a), lbm_dec_as_i32(b)); break;
324 5293 case LBM_TYPE_U: retval = CMP(lbm_dec_as_u32(a), lbm_dec_as_u32(b)); break;
325 #endif
326 560889 case LBM_TYPE_U32: retval = CMP(lbm_dec_as_u32(a), lbm_dec_as_u32(b)); break;
327 280059 case LBM_TYPE_I32: retval = CMP(lbm_dec_as_i32(a), lbm_dec_as_i32(b)); break;
328 36400775 case LBM_TYPE_FLOAT: retval = CMP(lbm_dec_as_float(a), lbm_dec_as_float(b)); break;
329 280084 case LBM_TYPE_U64: retval = CMP(lbm_dec_as_u64(a), lbm_dec_as_u64(b)); break;
330 560086 case LBM_TYPE_I64: retval = CMP(lbm_dec_as_i64(a), lbm_dec_as_i64(b)); break;
331 179 case LBM_TYPE_DOUBLE: retval = CMP(lbm_dec_as_double(a), lbm_dec_as_double(b)); break;
332 }
333 76367068 return retval;
334 }
335
336 362 static lbm_value assoc_lookup(lbm_value key, lbm_value assoc) {
337 362 lbm_value curr = assoc;
338 362 lbm_value res = ENC_SYM_NO_MATCH;
339
2/2
✓ Branch 0 taken 827 times.
✓ Branch 1 taken 28 times.
855 while (lbm_is_cons(curr)) {
340 827 lbm_value c = lbm_ref_cell(curr)->car;
341
2/2
✓ Branch 0 taken 799 times.
✓ Branch 1 taken 28 times.
827 if (lbm_is_cons(c)) {
342
2/2
✓ Branch 0 taken 306 times.
✓ Branch 1 taken 493 times.
799 if (struct_eq(lbm_ref_cell(c)->car, key)) {
343 306 res = lbm_ref_cell(c)->cdr;
344 306 break;
345 }
346 } else {
347 28 res = ENC_SYM_EERROR;
348 28 break;
349 }
350 493 curr = lbm_ref_cell(curr)->cdr;
351 }
352 362 return res;
353 }
354
355 338 static lbm_value cossa_lookup(lbm_value key, lbm_value assoc) {
356 338 lbm_value curr = assoc;
357
2/2
✓ Branch 0 taken 816 times.
✓ Branch 1 taken 28 times.
844 while (lbm_is_cons(curr)) {
358 816 lbm_value c = lbm_ref_cell(curr)->car;
359
2/2
✓ Branch 0 taken 788 times.
✓ Branch 1 taken 28 times.
816 if (lbm_is_cons(c)) {
360
2/2
✓ Branch 0 taken 282 times.
✓ Branch 1 taken 506 times.
788 if (struct_eq(lbm_ref_cell(c)->cdr, key)) {
361 282 return lbm_ref_cell(c)->car;
362 }
363 } else {
364 28 return ENC_SYM_EERROR;
365 }
366 506 curr = lbm_ref_cell(curr)->cdr;
367 }
368 28 return ENC_SYM_NO_MATCH;
369 }
370
371
372
373 /***************************************************/
374 /* Fundamental operations */
375
376 78032526 static lbm_value fundamental_add(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
377 (void) ctx;
378 78032526 lbm_uint sum = lbm_enc_char(0);
379
2/2
✓ Branch 0 taken 202133456 times.
✓ Branch 1 taken 77927497 times.
280060953 for (lbm_uint i = 0; i < nargs; i ++) {
380 202133456 lbm_value v = args[i];
381
2/2
✓ Branch 0 taken 202133249 times.
✓ Branch 1 taken 207 times.
202133456 if (IS_NUMBER(v)) { // inlining add2 explicitly removes one condition.
382 lbm_type t;
383
2/2
✓ Branch 0 taken 78314068 times.
✓ Branch 1 taken 123819181 times.
202133249 PROMOTE_SWAP(t, sum, v);
384
9/10
✓ Branch 0 taken 289 times.
✓ Branch 1 taken 24944852 times.
✓ Branch 2 taken 617 times.
✓ Branch 3 taken 3363610 times.
✓ Branch 4 taken 2803472 times.
✓ Branch 5 taken 162604906 times.
✓ Branch 6 taken 3366604 times.
✓ Branch 7 taken 4487334 times.
✓ Branch 8 taken 561565 times.
✗ Branch 9 not taken.
202133249 switch (t) {
385 289 case LBM_TYPE_BYTE: sum = lbm_enc_char((uint8_t)(lbm_dec_char(sum) + lbm_dec_char(v))); break;
386 #ifdef LBM64
387 case LBM_TYPE_I: sum = lbm_enc_i(lbm_dec_i(sum) + lbm_dec_as_i64(v)); break;
388 case LBM_TYPE_U: sum = lbm_enc_u(lbm_dec_u(sum) + lbm_dec_as_u64(v)); break;
389 case LBM_TYPE_U32: sum = lbm_enc_u32(lbm_dec_u32(sum) + lbm_dec_as_u32(v)); break;
390 case LBM_TYPE_I32: sum = lbm_enc_i32(lbm_dec_i32(sum) + lbm_dec_as_i32(v)); break;
391 case LBM_TYPE_FLOAT: sum = lbm_enc_float(lbm_dec_float(sum) + lbm_dec_as_float(v)); break;
392 #else
393 24944852 case LBM_TYPE_I: sum = lbm_enc_i(lbm_dec_i(sum) + lbm_dec_as_i32(v)); break;
394 617 case LBM_TYPE_U: sum = lbm_enc_u(lbm_dec_u(sum) + lbm_dec_as_u32(v)); break;
395 3363610 case LBM_TYPE_U32:
396 3363610 sum = lbm_enc_u32(lbm_dec_u32(sum) + lbm_dec_as_u32(v));
397
2/2
✓ Branch 0 taken 582 times.
✓ Branch 1 taken 3363028 times.
3363610 if (lbm_is_symbol(sum)) goto add_end;
398 3363028 break;
399 2803472 case LBM_TYPE_I32:
400 2803472 sum = lbm_enc_i32(lbm_dec_i32(sum) + lbm_dec_as_i32(v));
401
2/2
✓ Branch 0 taken 544 times.
✓ Branch 1 taken 2802928 times.
2803472 if (lbm_is_symbol(sum)) goto add_end;
402 2802928 break;
403 162604906 case LBM_TYPE_FLOAT:
404 162604906 sum = lbm_enc_float(lbm_dec_float(sum) + lbm_dec_as_float(v));
405
2/2
✓ Branch 0 taken 98882 times.
✓ Branch 1 taken 162506024 times.
162604906 if (lbm_is_symbol(sum)) goto add_end;
406 162506024 break;
407 #endif
408 3366604 case LBM_TYPE_U64:
409 3366604 sum = lbm_enc_u64(lbm_dec_u64(sum) + lbm_dec_as_u64(v));
410
2/2
✓ Branch 0 taken 1860 times.
✓ Branch 1 taken 3364744 times.
3366604 if (lbm_is_symbol(sum)) goto add_end;
411 3364744 break;
412 4487334 case LBM_TYPE_I64:
413 4487334 sum = lbm_enc_i64(lbm_dec_i64(sum) + lbm_dec_as_i64(v));
414
2/2
✓ Branch 0 taken 2430 times.
✓ Branch 1 taken 4484904 times.
4487334 if (lbm_is_symbol(sum)) goto add_end;
415 4484904 break;
416 561565 case LBM_TYPE_DOUBLE:
417 561565 sum = lbm_enc_double(lbm_dec_double(sum) + lbm_dec_as_double(v));
418
2/2
✓ Branch 0 taken 524 times.
✓ Branch 1 taken 561041 times.
561565 if (lbm_is_symbol(sum)) goto add_end;
419 561041 break;
420 }
421 } else {
422 207 lbm_set_error_suspect(v);
423 207 sum = ENC_SYM_TERROR;
424 207 break; // out of loop
425 }
426 }
427 77927497 add_end:
428 78032526 return sum;
429 }
430
431 27346169 static lbm_value fundamental_sub(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
432 (void) ctx;
433
434 lbm_uint res;
435
436
4/4
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 491 times.
✓ Branch 2 taken 27345593 times.
✓ Branch 3 taken 57 times.
27346169 switch (nargs) {
437 28 case 0:
438 28 res = lbm_enc_char(0);
439 28 break;
440
441 491 case 1:
442 491 res = sub2(lbm_enc_char(0),args[0]);
443 491 break;
444
445 27345593 case 2:
446 27345593 res = sub2(args[0], args[1]);
447 27345593 break;
448
449 57 default:
450 57 res = args[0];
451
2/2
✓ Branch 0 taken 171 times.
✓ Branch 1 taken 28 times.
199 for (lbm_uint i = 1; i < nargs; i ++) {
452 171 res = sub2(res, args[i]);
453
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 142 times.
171 if (lbm_type_of(res) == LBM_TYPE_SYMBOL)
454 29 break;
455 }
456 57 break;
457 }
458 27346169 return res;
459 }
460
461 33960331 static lbm_value fundamental_mul(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
462 (void) ctx;
463
464 33960331 lbm_uint prod = lbm_enc_char(1);
465
2/2
✓ Branch 0 taken 70142251 times.
✓ Branch 1 taken 33911792 times.
104054043 for (lbm_uint i = 0; i < nargs; i ++) {
466 70142251 prod = mul2(prod, args[i]);
467
2/2
✓ Branch 0 taken 48539 times.
✓ Branch 1 taken 70093712 times.
70142251 if (lbm_type_of(prod) == LBM_TYPE_SYMBOL) {
468 48539 break;
469 }
470 }
471 33960331 return prod;
472 }
473
474 1271 static lbm_value fundamental_div(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
475 (void) ctx;
476
477 1271 lbm_uint res = args[0];
478
479
2/2
✓ Branch 0 taken 1211 times.
✓ Branch 1 taken 60 times.
1271 if (nargs >= 2) {
480
2/2
✓ Branch 0 taken 1285 times.
✓ Branch 1 taken 611 times.
1896 for (lbm_uint i = 1; i < nargs; i ++) {
481 1285 res = div2(res, args[i]);
482
2/2
✓ Branch 0 taken 600 times.
✓ Branch 1 taken 685 times.
1285 if (lbm_type_of(res) == LBM_TYPE_SYMBOL) {
483 600 break;
484 }
485 }
486 } else {
487 60 res = ENC_SYM_EERROR;
488 }
489 1271 return res;
490 }
491
492 32046 static lbm_value fundamental_mod(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
493 (void) ctx;
494
2/2
✓ Branch 0 taken 31989 times.
✓ Branch 1 taken 57 times.
32046 if (nargs == 2) {
495 31989 return mod2(args[0], args[1]);
496 }
497 57 lbm_set_error_reason((char*)lbm_error_str_num_args);
498 57 return ENC_SYM_EERROR;
499 }
500
501 159753 static lbm_value fundamental_eq(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
502 (void) ctx;
503 159753 lbm_uint a = args[0];
504
2/2
✓ Branch 0 taken 159949 times.
✓ Branch 1 taken 74574 times.
234523 for (lbm_uint i = 1; i < nargs; i ++) {
505 159949 lbm_uint b = args[i];
506
2/2
✓ Branch 0 taken 85179 times.
✓ Branch 1 taken 74770 times.
159949 if (!struct_eq(a, b)) return ENC_SYM_NIL;
507 }
508 74574 return ENC_SYM_TRUE;
509 }
510
511 280 static lbm_value fundamental_not_eq(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
512 280 lbm_value r = fundamental_eq(args, nargs, ctx);
513
2/2
✓ Branch 0 taken 140 times.
✓ Branch 1 taken 140 times.
280 return r ? ENC_SYM_NIL : ENC_SYM_TRUE; // Works because ENC_SYM_NIL == 0 and ENC_SYM_TRUE is != 0
514 }
515
516
517 32531076 static lbm_value fundamental_numeq(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
518 (void) ctx;
519
520 32531076 lbm_uint a = args[0];
521 32531076 lbm_value res = ENC_SYM_TERROR;
522
523
2/2
✓ Branch 0 taken 32531008 times.
✓ Branch 1 taken 68 times.
32531076 if (IS_NUMBER(a)) {
524 32531008 res = ENC_SYM_TRUE;
525
2/2
✓ Branch 0 taken 32531593 times.
✓ Branch 1 taken 5077518 times.
37609111 for (lbm_uint i = 1; i < nargs; i ++) {
526 32531593 lbm_uint b = args[i];
527
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 32531535 times.
32531593 if (!IS_NUMBER(b)) {
528 58 res = ENC_SYM_TERROR;
529 58 break;
530 }
531
2/2
✓ Branch 0 taken 27453432 times.
✓ Branch 1 taken 5078103 times.
32531535 if (!(compare_num(a, b) == 0)) {
532 27453432 res = ENC_SYM_NIL;
533 27453432 break;
534 }
535 }
536 }
537 32531076 return res;
538 }
539
540 560349 static lbm_value fundamental_num_not_eq(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
541 560349 lbm_value r = fundamental_numeq(args, nargs, ctx);
542 // Needs the more expensive check as r can be ENC_SYM_TERROR.
543
2/2
✓ Branch 0 taken 143 times.
✓ Branch 1 taken 560206 times.
560349 if (r == ENC_SYM_NIL) {
544 143 r = ENC_SYM_TRUE;
545
2/2
✓ Branch 0 taken 560143 times.
✓ Branch 1 taken 63 times.
560206 } else if (r == ENC_SYM_TRUE) {
546 560143 r = ENC_SYM_NIL;
547 }
548 560349 return r;
549 }
550
551 42399791 static lbm_value fundamental_leq(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
552 (void) ctx;
553
554 42399791 lbm_uint a = args[0];
555 42399791 bool r = true;
556
557
2/2
✓ Branch 0 taken 42399723 times.
✓ Branch 1 taken 68 times.
42399791 if (IS_NUMBER(a)) {
558
2/2
✓ Branch 0 taken 42399720 times.
✓ Branch 1 taken 42399665 times.
84799385 for (lbm_uint i = 1; i < nargs; i ++) {
559 42399720 lbm_uint b = args[i];
560
2/2
✓ Branch 0 taken 42399662 times.
✓ Branch 1 taken 58 times.
42399720 if (IS_NUMBER(b)) {
561
3/4
✓ Branch 0 taken 42399662 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5101801 times.
✓ Branch 3 taken 37297861 times.
42399662 r = r && (compare_num(a, b) <= 0);
562 } else {
563 58 lbm_set_error_suspect(b);
564 58 goto leq_type_error;
565 }
566 }
567 } else {
568 68 lbm_set_error_suspect(a);
569 68 goto leq_type_error;
570 }
571
2/2
✓ Branch 0 taken 5101804 times.
✓ Branch 1 taken 37297861 times.
42399665 if (r) {
572 5101804 return ENC_SYM_TRUE;
573 } else {
574 37297861 return ENC_SYM_NIL;
575 }
576 126 leq_type_error:
577 126 return ENC_SYM_TERROR;
578 }
579
580 1435999 static lbm_value fundamental_geq(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
581 (void) ctx;
582
583 1435999 lbm_uint a = args[0];
584 1435999 bool r = true;
585
586
2/2
✓ Branch 0 taken 1435931 times.
✓ Branch 1 taken 68 times.
1435999 if (IS_NUMBER(a)) {
587
2/2
✓ Branch 0 taken 1435929 times.
✓ Branch 1 taken 1435873 times.
2871802 for (lbm_uint i = 1; i < nargs; i ++) {
588 1435929 lbm_uint b = args[i];
589
2/2
✓ Branch 0 taken 1435871 times.
✓ Branch 1 taken 58 times.
1435929 if (IS_NUMBER(b)) {
590
3/4
✓ Branch 0 taken 1435871 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 77146 times.
✓ Branch 3 taken 1358725 times.
1435871 r = r && (compare_num(a, b) >= 0);
591 } else {
592 58 lbm_set_error_suspect(b);
593 58 goto geq_type_error;
594 }
595 }
596 } else {
597 68 lbm_set_error_suspect(a);
598 68 goto geq_type_error;
599 }
600
2/2
✓ Branch 0 taken 77148 times.
✓ Branch 1 taken 1358725 times.
1435873 if (r) {
601 77148 return ENC_SYM_TRUE;
602 } else {
603 1358725 return ENC_SYM_NIL;
604 }
605 126 geq_type_error:
606 126 return ENC_SYM_TERROR;
607 }
608
609 1435519 static lbm_value fundamental_lt(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
610 1435519 lbm_value r = fundamental_geq(args, nargs, ctx);
611
2/2
✓ Branch 0 taken 1358669 times.
✓ Branch 1 taken 76850 times.
1435519 if (r == ENC_SYM_NIL) r = ENC_SYM_TRUE;
612
2/2
✓ Branch 0 taken 76787 times.
✓ Branch 1 taken 63 times.
76850 else if (r == ENC_SYM_TRUE) r = ENC_SYM_NIL;
613 1435519 return r;
614 }
615
616 42388189 static lbm_value fundamental_gt(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
617 42388189 lbm_value r = fundamental_leq(args, nargs, ctx);
618
2/2
✓ Branch 0 taken 37289593 times.
✓ Branch 1 taken 5098596 times.
42388189 if (r == ENC_SYM_NIL) r = ENC_SYM_TRUE;
619
2/2
✓ Branch 0 taken 5098533 times.
✓ Branch 1 taken 63 times.
5098596 else if (r == ENC_SYM_TRUE) r = ENC_SYM_NIL;
620 42388189 return r;
621 }
622
623 2394 static lbm_value fundamental_not(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
624 (void) ctx;
625
2/2
✓ Branch 0 taken 2338 times.
✓ Branch 1 taken 56 times.
2394 if (nargs == 1) {
626
2/2
✓ Branch 0 taken 1212 times.
✓ Branch 1 taken 1126 times.
2338 return args[0] ? ENC_SYM_NIL : ENC_SYM_TRUE;
627 }
628 56 return ENC_SYM_EERROR;
629 }
630
631 13246 static lbm_value fundamental_gc(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
632 (void) args;
633 (void) nargs;
634 (void) ctx;
635 13246 lbm_perform_gc();
636 13246 return ENC_SYM_TRUE;
637 }
638
639 3444 static lbm_value fundamental_self(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
640 (void) args;
641 (void) nargs;
642 (void) ctx;
643 3444 return lbm_enc_i(ctx->id);
644 }
645
646 224 static lbm_value fundamental_set_mailbox_size(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
647 224 lbm_value r = ENC_SYM_EERROR;
648
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 56 times.
224 if (nargs == 1) {
649
2/2
✓ Branch 0 taken 140 times.
✓ Branch 1 taken 28 times.
168 if (IS_NUMBER(args[0])) {
650 140 uint32_t s = lbm_dec_as_u32(args[0]);
651
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 28 times.
140 if (lbm_mailbox_change_size(ctx, s)) {
652 112 r = ENC_SYM_TRUE;
653 } else {
654 28 r = ENC_SYM_NIL;
655 }
656 } else {
657 28 r = ENC_SYM_TERROR;
658 }
659 }
660 224 return r;
661 }
662
663 32765 static lbm_value fundamental_cons(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
664 (void) ctx;
665 32765 lbm_value r = ENC_SYM_EERROR;
666
2/2
✓ Branch 0 taken 32677 times.
✓ Branch 1 taken 88 times.
32765 if (nargs == 2) {
667 32677 lbm_uint a = args[0];
668 32677 lbm_uint b = args[1];
669 32677 r = lbm_cons(a,b);
670 }
671 32765 return r;
672 }
673
674 89432 static lbm_value fundamental_car(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
675 (void) ctx;
676 89432 lbm_value r = ENC_SYM_EERROR;
677
2/2
✓ Branch 0 taken 89374 times.
✓ Branch 1 taken 58 times.
89432 if (nargs == 1) {
678
2/2
✓ Branch 0 taken 88830 times.
✓ Branch 1 taken 544 times.
89374 if (lbm_is_cons(args[0])) {
679 88830 lbm_cons_t *cell = lbm_ref_cell(args[0]);
680 88830 r = cell->car;
681
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 92 times.
544 } else if (lbm_is_symbol_nil(args[0])) {
682 452 r = ENC_SYM_NIL;
683 } else {
684 92 r = ENC_SYM_TERROR;
685 }
686 }
687 89432 return r;
688 }
689
690 84382 static lbm_value fundamental_cdr(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
691 (void) ctx;
692 84382 lbm_value r = ENC_SYM_EERROR;
693
2/2
✓ Branch 0 taken 84324 times.
✓ Branch 1 taken 58 times.
84382 if (nargs == 1) {
694
2/2
✓ Branch 0 taken 83784 times.
✓ Branch 1 taken 540 times.
84324 if (lbm_is_cons(args[0])) {
695 83784 lbm_cons_t *cell = lbm_ref_cell(args[0]);
696 83784 r = cell->cdr;
697
2/2
✓ Branch 0 taken 450 times.
✓ Branch 1 taken 90 times.
540 } else if (lbm_is_symbol_nil(args[0])) {
698 450 r = ENC_SYM_NIL;
699 } else {
700 90 r = ENC_SYM_TERROR;
701 }
702 }
703 84382 return r;
704 }
705
706 108397 static lbm_value fundamental_list(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
707 (void) ctx;
708 108397 lbm_value result = ENC_SYM_NIL;
709
2/2
✓ Branch 0 taken 154161 times.
✓ Branch 1 taken 108313 times.
262474 for (lbm_uint i = 1; i <= nargs; i ++) {
710 154161 result = lbm_cons(args[nargs-i], result);
711 // This check may be a mostly useless optimisation.
712 // Only triggers in case of running out of heap here.
713
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 154077 times.
154161 if (lbm_type_of(result) == LBM_TYPE_SYMBOL)
714 84 break;
715 }
716 108397 return result;
717 }
718
719 59957 static lbm_value fundamental_append(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
720 (void) ctx;
721
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 59928 times.
59957 if (nargs == 0) return ENC_SYM_NIL;
722
4/4
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 59871 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 29 times.
59928 if (nargs == 1 && !lbm_is_list(args[0])) {
723 28 lbm_set_error_suspect(args[0]);
724 28 return ENC_SYM_TERROR;
725 }
726 59900 lbm_value res = args[nargs-1];
727
2/2
✓ Branch 0 taken 86248 times.
✓ Branch 1 taken 59868 times.
146116 for (int i = (int)nargs -2; i >= 0; i --) {
728 86248 lbm_value curr = args[i];
729
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 86216 times.
86248 if (!lbm_is_list(curr)) {
730 32 lbm_set_error_suspect(curr);
731 32 return ENC_SYM_TERROR;
732 }
733 86216 int n = 0;
734
2/2
✓ Branch 0 taken 105689 times.
✓ Branch 1 taken 86216 times.
191905 while (lbm_type_of_functional(curr) == LBM_TYPE_CONS) {
735 105689 n++;
736 105689 curr = lbm_cdr(curr);
737 }
738 86216 curr = args[i];
739
2/2
✓ Branch 0 taken 105689 times.
✓ Branch 1 taken 86216 times.
191905 for (int j = n-1; j >= 0; j --) {
740 105689 res = lbm_cons(lbm_index_list(curr,j),res);
741 }
742 }
743 59868 return(res);
744 }
745
746 1680229 static lbm_value fundamental_undefine(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
747 (void) ctx;
748 1680229 lbm_value *global_env = lbm_get_global_env();
749
4/4
✓ Branch 0 taken 1680227 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1680170 times.
✓ Branch 3 taken 57 times.
1680229 if (nargs == 1 && lbm_is_symbol(args[0])) {
750 1680170 lbm_value key = args[0];
751 1680170 lbm_uint ix_key = lbm_dec_sym(key) & GLOBAL_ENV_MASK;
752 1680170 lbm_value env = global_env[ix_key];
753 1680170 lbm_value res = lbm_env_drop_binding(env, key);
754
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 1680142 times.
1680170 if (res == ENC_SYM_NOT_FOUND) {
755 28 return ENC_SYM_NIL;
756 }
757 1680142 global_env[ix_key] = res;
758 1680142 return ENC_SYM_TRUE;
759
3/4
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 57 times.
✗ Branch 3 not taken.
59 } else if (nargs == 1 && lbm_is_cons(args[0])) {
760 57 lbm_value curr = args[0];
761
2/2
✓ Branch 0 taken 115 times.
✓ Branch 1 taken 57 times.
172 while (lbm_type_of(curr) == LBM_TYPE_CONS) {
762 115 lbm_value key = lbm_car(curr);
763 115 lbm_uint ix_key = lbm_dec_sym(key) & GLOBAL_ENV_MASK;
764 115 lbm_value env = global_env[ix_key];
765 115 lbm_value res = lbm_env_drop_binding(env, key);
766
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 59 times.
115 if (res != ENC_SYM_NOT_FOUND) {
767 56 global_env[ix_key] = res;
768 }
769 115 curr = lbm_cdr(curr);
770 }
771 57 return ENC_SYM_TRUE;
772 }
773 2 return ENC_SYM_TERROR;
774 }
775
776 80639 static lbm_value fundamental_buf_create(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
777 (void) ctx;
778 80639 lbm_value result = ENC_SYM_EERROR;
779
4/4
✓ Branch 0 taken 24581 times.
✓ Branch 1 taken 56058 times.
✓ Branch 2 taken 24553 times.
✓ Branch 3 taken 28 times.
80639 if (nargs == 1 && IS_NUMBER(args[0])) {
780 24553 lbm_heap_allocate_array(&result, lbm_dec_as_u32(args[0]));
781
6/6
✓ Branch 0 taken 56030 times.
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 56029 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 56000 times.
✓ Branch 5 taken 29 times.
56086 } else if (nargs == 2 && IS_NUMBER(args[1]) && lbm_type_of(args[0]) == LBM_TYPE_DEFRAG_MEM) {
782 56000 lbm_uint *dm = (lbm_uint*)lbm_car(args[0]);
783 56000 return lbm_defrag_mem_alloc(dm, lbm_dec_as_uint(args[1]));
784 }
785 24639 return result;
786 }
787
788 10159 static lbm_value fundamental_symbol_to_string(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
789 (void) ctx;
790 10159 lbm_value res = ENC_SYM_EERROR;
791
2/2
✓ Branch 0 taken 10129 times.
✓ Branch 1 taken 30 times.
10159 if (nargs == 1) {
792
2/2
✓ Branch 0 taken 10096 times.
✓ Branch 1 taken 33 times.
10129 if (lbm_type_of_functional(args[0]) == LBM_TYPE_SYMBOL) {
793 10096 lbm_value sym = args[0];
794 10096 const char *sym_str = lbm_get_name_by_symbol(lbm_dec_sym(sym));
795
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10096 times.
10096 if (sym_str == NULL) return ENC_SYM_NIL;
796 10096 size_t len = strlen(sym_str);
797 lbm_value v;
798
2/2
✓ Branch 0 taken 10071 times.
✓ Branch 1 taken 25 times.
10096 if (lbm_heap_allocate_array(&v, len+1)) {
799 10071 lbm_array_header_t *arr = (lbm_array_header_t*)lbm_car(v);
800 10071 memset(arr->data,0,len+1);
801 10071 memcpy(arr->data,sym_str,len);
802 10071 res = v;
803 } else {
804 25 res = ENC_SYM_MERROR;
805 }
806 } else {
807 33 res = ENC_SYM_TERROR;
808 }
809 }
810 10159 return res;
811 }
812
813 136 static lbm_value fundamental_string_to_symbol(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
814 (void) ctx;
815 136 lbm_value result = ENC_SYM_EERROR;
816
2/2
✓ Branch 0 taken 106 times.
✓ Branch 1 taken 30 times.
136 if (nargs == 1) {
817 106 result = ENC_SYM_TERROR;
818 106 lbm_array_header_t *arr = lbm_dec_array_r(args[0]);
819
2/2
✓ Branch 0 taken 74 times.
✓ Branch 1 taken 32 times.
106 if (arr) {
820 // TODO: String to symbol, string should be in LBM_memory..
821 // Some better sanity check is possible here.
822 // Check that array points into lbm_memory.
823 // Additionally check that it is a zero-terminated string.
824 74 char *str = (char *)arr->data;
825 74 lbm_uint sym = ENC_SYM_NIL;
826 74 lbm_str_to_symbol(str,&sym);
827 74 result = lbm_enc_sym(sym);
828 }
829 }
830 136 return result;
831 }
832
833 140 static lbm_value fundamental_symbol_to_uint(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
834 (void) ctx;
835
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 112 times.
140 if (nargs < 1) return ENC_SYM_EERROR;
836 112 lbm_value s = args[0];
837
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 28 times.
112 if (lbm_is_symbol(s))
838 84 return lbm_enc_u(lbm_dec_sym(s));
839
840 28 lbm_set_error_suspect(s);
841 28 return ENC_SYM_TERROR;
842 }
843
844 112 static lbm_value fundamental_uint_to_symbol(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
845 (void) ctx;
846
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 84 times.
112 if (nargs < 1) return ENC_SYM_EERROR;
847 84 lbm_value s = args[0];
848
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 28 times.
84 if (lbm_type_of_functional(s) == LBM_TYPE_U)
849 56 return lbm_enc_sym(lbm_dec_u(s));
850
851 28 lbm_set_error_suspect(s);
852 28 return ENC_SYM_TERROR;
853 }
854
855 119 static lbm_value fundamental_set_car(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
856 (void) ctx;
857 119 lbm_value res = ENC_SYM_EERROR;
858
2/2
✓ Branch 0 taken 118 times.
✓ Branch 1 taken 1 times.
119 if (nargs == 2) {
859
2/2
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 28 times.
118 res = lbm_set_car(args[0], args[1]) ? ENC_SYM_TRUE : ENC_SYM_NIL;
860 }
861 119 return res;
862 }
863
864 123 static lbm_value fundamental_set_cdr(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
865 (void) ctx;
866 123 lbm_value res = ENC_SYM_EERROR;
867
2/2
✓ Branch 0 taken 122 times.
✓ Branch 1 taken 1 times.
123 if (nargs == 2) {
868
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 28 times.
122 res = lbm_set_cdr(args[0],args[1]) ? ENC_SYM_TRUE : ENC_SYM_NIL;
869 }
870 123 return res;
871 }
872
873 561775 static lbm_value fundamental_set_ix(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
874 (void) ctx;
875 561775 lbm_value result = ENC_SYM_TERROR;
876
4/4
✓ Branch 0 taken 561773 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 561772 times.
✓ Branch 3 taken 1 times.
561775 if (nargs == 3 && IS_NUMBER(args[1])) {
877
2/2
✓ Branch 0 taken 124 times.
✓ Branch 1 taken 561648 times.
561772 if (lbm_is_list_rw(args[0])) {
878 124 lbm_value curr = args[0];
879 124 lbm_uint i = 0;
880 124 lbm_int ix_pre = lbm_dec_as_i32(args[1]);
881
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 123 times.
124 if (ix_pre < 0) {
882 1 lbm_int len = (lbm_int)lbm_list_length(args[0]);
883 1 ix_pre = len + ix_pre;
884 }
885 124 lbm_uint ix = (lbm_uint)ix_pre;
886
2/2
✓ Branch 0 taken 487 times.
✓ Branch 1 taken 1 times.
488 while (lbm_is_cons_rw(curr)) { // rw as we are going to modify
887 487 lbm_value next = lbm_cdr(curr);
888
2/2
✓ Branch 0 taken 95 times.
✓ Branch 1 taken 392 times.
487 if (i == ix) {
889 95 lbm_set_car(curr, args[2]);
890 95 result = args[0]; // Acts as true and as itself.
891 95 break;
892
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 364 times.
392 } else if (lbm_is_symbol_nil(next)) {
893 28 result = ENC_SYM_NIL; // index out of bounds, no update.
894 28 break;
895 }
896 364 curr = next;
897 364 i++;
898 }
899
2/2
✓ Branch 0 taken 561647 times.
✓ Branch 1 taken 1 times.
561648 } else if (lbm_is_lisp_array_rw(args[0])) {
900 561647 int32_t index = lbm_dec_as_i32(args[1]);
901 561647 lbm_array_header_t *header = (lbm_array_header_t*)lbm_car(args[0]);
902 561647 lbm_value *arrdata = (lbm_value*)header->data;
903 561647 lbm_uint size = header->size / sizeof(lbm_value);
904
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 561646 times.
561647 if (index < 0) index = (int32_t)size + index;
905
2/2
✓ Branch 0 taken 561646 times.
✓ Branch 1 taken 1 times.
561647 if ((uint32_t)index < size) {
906 561646 arrdata[index] = args[2]; // value
907 561646 result = args[0];
908 } // index out of range will be eval error.
909 }
910 }
911 561775 return result;
912 }
913
914 455 static lbm_value fundamental_assoc(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
915 (void) ctx;
916 455 lbm_value result = ENC_SYM_EERROR;
917
2/2
✓ Branch 0 taken 425 times.
✓ Branch 1 taken 30 times.
455 if (nargs == 2) {
918
2/2
✓ Branch 0 taken 362 times.
✓ Branch 1 taken 63 times.
425 if (lbm_is_cons(args[0])) {
919 362 lbm_value r = assoc_lookup(args[1], args[0]);
920
4/4
✓ Branch 0 taken 314 times.
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 286 times.
362 if (lbm_is_symbol(r) &&
921 r == ENC_SYM_NO_MATCH) {
922 28 result = ENC_SYM_NIL;
923 } else {
924 334 result = r;
925 }
926
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 1 times.
63 } else if (lbm_is_symbol(args[0]) &&
927
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 29 times.
62 args[0] == ENC_SYM_NIL) {
928 33 result = args[0]; /* nil */
929 } /* else error */
930 }
931 455 return result;
932 }
933
934 130087 static lbm_value fundamental_acons(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
935 (void) ctx;
936 130087 lbm_value result = ENC_SYM_TERROR;
937
2/2
✓ Branch 0 taken 130002 times.
✓ Branch 1 taken 85 times.
130087 if (nargs == 3) {
938 130002 lbm_value keyval = lbm_cons(args[0], args[1]);
939 130002 lbm_value new_alist = lbm_cons(keyval, args[2]);
940
941
4/4
✓ Branch 0 taken 129834 times.
✓ Branch 1 taken 168 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 129820 times.
259836 if (lbm_is_symbol(keyval) ||
942 129834 lbm_is_symbol(new_alist) )
943 182 result = ENC_SYM_MERROR;
944 else
945 129820 result = new_alist;
946
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 84 times.
85 } else if (nargs == 2) {
947 1 result = lbm_cons(args[0], args[1]);
948 }
949 130087 return result;
950 }
951
952 116 static lbm_value set_assoc(lbm_value assoc_list, lbm_value keyval) {
953 116 lbm_value curr = assoc_list;
954 116 lbm_value key = lbm_car(keyval);
955
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 32 times.
256 while (lbm_is_cons(curr)) {
956
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 140 times.
224 if (struct_eq(key, lbm_caar(curr))) {
957 84 lbm_set_car(curr, keyval);
958 84 return assoc_list;
959 }
960 140 curr = lbm_cdr(curr);
961 }
962 // Assoc-list does not contain key.
963 // Note: Memory errors are implicitly handled by the caller.
964 32 return lbm_cons(keyval, assoc_list);
965 }
966
967 118 static lbm_value fundamental_set_assoc(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
968 (void)ctx;
969 lbm_value keyval;
970
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 34 times.
118 if (nargs == 3) {
971 84 keyval = lbm_cons(args[1], args[2]);
972 // Check if ENC_SYM_MERROR.
973
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 if (lbm_is_symbol(keyval)) return keyval;
974
4/4
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 1 times.
34 } else if (nargs == 2 && lbm_is_cons(args[1])) {
975 32 keyval = args[1];
976 2 } else return ENC_SYM_TERROR;
977 116 return set_assoc(args[0], keyval);
978 }
979
980 422 static lbm_value fundamental_cossa(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
981 (void) ctx;
982 422 lbm_value result = ENC_SYM_EERROR;
983
2/2
✓ Branch 0 taken 394 times.
✓ Branch 1 taken 28 times.
422 if (nargs == 2) {
984
2/2
✓ Branch 0 taken 338 times.
✓ Branch 1 taken 56 times.
394 if (lbm_is_cons(args[0])) {
985 338 lbm_value r = cossa_lookup(args[1], args[0]);
986
4/4
✓ Branch 0 taken 226 times.
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 198 times.
338 if (lbm_is_symbol(r) &&
987 r == ENC_SYM_NO_MATCH) {
988 28 result = ENC_SYM_NIL;
989 } else {
990 310 result = r;
991 }
992
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 } else if (lbm_is_symbol(args[0]) &&
993
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 28 times.
56 args[0] == ENC_SYM_NIL) {
994 28 result = args[0]; /* nil */
995 } /* else error */
996 }
997 422 return result;
998 }
999
1000 33915 static lbm_value fundamental_ix(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1001 (void) ctx;
1002 33915 lbm_value result = ENC_SYM_EERROR;
1003
4/4
✓ Branch 0 taken 33913 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 33910 times.
✓ Branch 3 taken 3 times.
33915 if (nargs == 2 && IS_NUMBER(args[1])) {
1004 33910 result = ENC_SYM_NIL;
1005
2/2
✓ Branch 0 taken 22969 times.
✓ Branch 1 taken 10941 times.
33910 if (lbm_is_list(args[0])) {
1006 22969 result = lbm_index_list(args[0], lbm_dec_as_i32(args[1]));
1007
2/2
✓ Branch 0 taken 10935 times.
✓ Branch 1 taken 6 times.
10941 } else if (lbm_is_lisp_array_r(args[0])) {
1008 10935 lbm_array_header_t *header = (lbm_array_header_t*)lbm_car(args[0]);
1009 10935 lbm_value *arrdata = (lbm_value*)header->data;
1010 10935 lbm_uint size = header->size / sizeof(lbm_value);
1011 10935 int32_t index = lbm_dec_as_i32(args[1]);
1012
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 10934 times.
10935 if (index < 0) index = (int32_t)size + index;
1013
1/2
✓ Branch 0 taken 10935 times.
✗ Branch 1 not taken.
10935 if ((uint32_t)index < size) {
1014 10935 result = arrdata[index];
1015 }
1016 }
1017 }
1018 33915 return result;
1019 }
1020
1021 313 static lbm_value fundamental_to_i(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1022 (void) ctx;
1023 313 lbm_value result = ENC_SYM_EERROR;
1024
2/2
✓ Branch 0 taken 283 times.
✓ Branch 1 taken 30 times.
313 if (nargs == 1) {
1025 283 result = lbm_enc_i((lbm_int)lbm_dec_as_i64(args[0]));
1026 }
1027 313 return result;
1028 }
1029
1030 280 static lbm_value fundamental_to_i32(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1031 (void) ctx;
1032 280 lbm_value result = ENC_SYM_EERROR;
1033
2/2
✓ Branch 0 taken 252 times.
✓ Branch 1 taken 28 times.
280 if (nargs == 1) {
1034 252 result = lbm_enc_i32(lbm_dec_as_i32(args[0]));
1035 }
1036 280 return result;
1037 }
1038
1039 280 static lbm_value fundamental_to_u(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1040 (void) ctx;
1041 280 lbm_value result = ENC_SYM_EERROR;
1042
2/2
✓ Branch 0 taken 252 times.
✓ Branch 1 taken 28 times.
280 if (nargs == 1) {
1043 252 result = lbm_enc_u((lbm_uint)lbm_dec_as_u64(args[0]));
1044 }
1045 280 return result;
1046 }
1047
1048 280 static lbm_value fundamental_to_u32(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1049 (void) ctx;
1050 280 lbm_value result = ENC_SYM_EERROR;
1051
2/2
✓ Branch 0 taken 252 times.
✓ Branch 1 taken 28 times.
280 if (nargs == 1) {
1052 252 result = lbm_enc_u32(lbm_dec_as_u32(args[0]));
1053 }
1054 280 return result;
1055 }
1056
1057 265 static lbm_value fundamental_to_float(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1058 (void) ctx;
1059 265 lbm_value result = ENC_SYM_EERROR;
1060
2/2
✓ Branch 0 taken 235 times.
✓ Branch 1 taken 30 times.
265 if (nargs == 1) {
1061 235 result = lbm_enc_float(lbm_dec_as_float(args[0]));
1062 }
1063 265 return result;
1064 }
1065
1066 280 static lbm_value fundamental_to_i64(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1067 (void) ctx;
1068 280 lbm_value result = ENC_SYM_EERROR;
1069
2/2
✓ Branch 0 taken 252 times.
✓ Branch 1 taken 28 times.
280 if (nargs == 1) {
1070 252 result = lbm_enc_i64(lbm_dec_as_i64(args[0]));
1071 }
1072 280 return result;
1073 }
1074
1075 280 static lbm_value fundamental_to_u64(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1076 (void) ctx;
1077 280 lbm_value result = ENC_SYM_EERROR;
1078
2/2
✓ Branch 0 taken 252 times.
✓ Branch 1 taken 28 times.
280 if (nargs == 1) {
1079 252 result = lbm_enc_u64(lbm_dec_as_u64(args[0]));
1080 }
1081 280 return result;
1082 }
1083
1084 254 static lbm_value fundamental_to_double(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1085 (void) ctx;
1086 254 lbm_value result = ENC_SYM_EERROR;
1087
2/2
✓ Branch 0 taken 226 times.
✓ Branch 1 taken 28 times.
254 if (nargs == 1) {
1088 226 result = lbm_enc_double(lbm_dec_as_double(args[0]));
1089 }
1090 254 return result;
1091 }
1092
1093 261 static lbm_value fundamental_to_byte(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1094 (void) ctx;
1095 261 lbm_value result = ENC_SYM_EERROR;
1096
2/2
✓ Branch 0 taken 233 times.
✓ Branch 1 taken 28 times.
261 if (nargs == 1) {
1097 233 result = lbm_enc_char(lbm_dec_as_char(args[0]));
1098 }
1099 261 return result;
1100 }
1101
1102 338 static lbm_value fundamental_shl(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1103 (void) ctx;
1104 338 lbm_value retval = ENC_SYM_EERROR;
1105
2/2
✓ Branch 0 taken 310 times.
✓ Branch 1 taken 28 times.
338 if (nargs == 2) {
1106 310 retval = ENC_SYM_TERROR;
1107
4/4
✓ Branch 0 taken 282 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 254 times.
✓ Branch 3 taken 28 times.
310 if (IS_NUMBER(args[0]) && IS_NUMBER(args[1])) {
1108
8/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 57 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 28 times.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 28 times.
✓ Branch 6 taken 28 times.
✓ Branch 7 taken 56 times.
254 switch (lbm_type_of_functional(args[0])) {
1109 1 case LBM_TYPE_CHAR: retval = lbm_enc_char(lbm_dec_char(args[0]) << lbm_dec_as_u32(args[1])); break;
1110 57 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) << lbm_dec_as_u32(args[1])); break;
1111 28 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) << lbm_dec_as_u32(args[1])); break;
1112 28 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_u32(args[0]) << lbm_dec_as_u32(args[1])); break;
1113 28 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_i32(args[0]) << lbm_dec_as_u32(args[1])); break;
1114 28 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_i64(args[0]) << lbm_dec_as_u32(args[1])); break;
1115 28 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_u64(args[0]) << lbm_dec_as_u32(args[1])); break;
1116 }
1117 }
1118 }
1119 338 return retval;
1120 }
1121
1122 338 static lbm_value fundamental_shr(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1123 (void) ctx;
1124 338 lbm_value retval = ENC_SYM_EERROR;
1125
2/2
✓ Branch 0 taken 310 times.
✓ Branch 1 taken 28 times.
338 if (nargs == 2) {
1126 310 retval = ENC_SYM_TERROR;
1127
4/4
✓ Branch 0 taken 282 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 254 times.
✓ Branch 3 taken 28 times.
310 if (IS_NUMBER(args[0]) && IS_NUMBER(args[1])) {
1128
8/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 57 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 28 times.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 28 times.
✓ Branch 6 taken 28 times.
✓ Branch 7 taken 56 times.
254 switch (lbm_type_of_functional(args[0])) {
1129 1 case LBM_TYPE_CHAR: retval = lbm_enc_char(lbm_dec_char(args[0]) >> lbm_dec_as_u32(args[1])); break;
1130 57 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) >> lbm_dec_as_u32(args[1])); break;
1131 28 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) >> lbm_dec_as_u32(args[1])); break;
1132 28 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_u32(args[0]) >> lbm_dec_as_u32(args[1])); break;
1133 28 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_i32(args[0]) >> lbm_dec_as_u32(args[1])); break;
1134 28 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_i64(args[0]) >> lbm_dec_as_u32(args[1])); break;
1135 28 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_u64(args[0]) >> lbm_dec_as_u32(args[1])); break;
1136 }
1137 }
1138 }
1139 338 return retval;
1140 }
1141
1142 338 static lbm_value fundamental_bitwise_and(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1143 (void) ctx;
1144 338 lbm_value retval = ENC_SYM_EERROR;
1145
2/2
✓ Branch 0 taken 310 times.
✓ Branch 1 taken 28 times.
338 if (nargs == 2) {
1146 310 retval = ENC_SYM_TERROR;
1147
4/4
✓ Branch 0 taken 282 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 254 times.
✓ Branch 3 taken 28 times.
310 if (IS_NUMBER(args[0]) && IS_NUMBER(args[1])) {
1148
8/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 57 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 28 times.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 28 times.
✓ Branch 6 taken 28 times.
✓ Branch 7 taken 56 times.
254 switch (lbm_type_of_functional(args[0])) {
1149 1 case LBM_TYPE_CHAR: retval = lbm_enc_char(lbm_dec_char(args[0]) & lbm_dec_as_char(args[1])); break;
1150 #ifdef LBM64
1151 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) & lbm_dec_as_i64(args[1])); break;
1152 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) & lbm_dec_as_u64(args[1])); break;
1153 #else
1154 57 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) & lbm_dec_as_i32(args[1])); break;
1155 28 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) & lbm_dec_as_u32(args[1])); break;
1156 #endif
1157 28 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_u32(args[0]) & lbm_dec_as_u32(args[1])); break;
1158 28 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_i32(args[0]) & lbm_dec_as_i32(args[1])); break;
1159 28 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_i64(args[0]) & lbm_dec_as_i64(args[1])); break;
1160 28 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_u64(args[0]) & lbm_dec_as_u64(args[1])); break;
1161 }
1162 }
1163 }
1164 338 return retval;
1165 }
1166
1167 338 static lbm_value fundamental_bitwise_or(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1168 (void) ctx;
1169 338 lbm_value retval = ENC_SYM_EERROR;
1170
2/2
✓ Branch 0 taken 310 times.
✓ Branch 1 taken 28 times.
338 if (nargs == 2) {
1171 310 retval = ENC_SYM_TERROR;
1172
4/4
✓ Branch 0 taken 282 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 254 times.
✓ Branch 3 taken 28 times.
310 if (IS_NUMBER(args[0]) && IS_NUMBER(args[1])) {
1173
8/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 57 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 28 times.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 28 times.
✓ Branch 6 taken 28 times.
✓ Branch 7 taken 56 times.
254 switch (lbm_type_of_functional(args[0])) {
1174 1 case LBM_TYPE_CHAR: retval = lbm_enc_char(lbm_dec_char(args[0]) | lbm_dec_as_char(args[1])); break;
1175 #ifdef LBM64
1176 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) | lbm_dec_as_i64(args[1])); break;
1177 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) | lbm_dec_as_u64(args[1])); break;
1178 #else
1179 57 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) | lbm_dec_as_i32(args[1])); break;
1180 28 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) | lbm_dec_as_u32(args[1])); break;
1181 #endif
1182 28 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_u32(args[0]) | lbm_dec_as_u32(args[1])); break;
1183 28 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_i32(args[0]) | lbm_dec_as_i32(args[1])); break;
1184 28 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_i64(args[0]) | lbm_dec_as_i64(args[1])); break;
1185 28 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_u64(args[0]) | lbm_dec_as_u64(args[1])); break;
1186 }
1187 }
1188 }
1189 338 return retval;
1190 }
1191
1192 338 static lbm_value fundamental_bitwise_xor(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1193 (void) ctx;
1194 338 lbm_value retval = ENC_SYM_EERROR;
1195
2/2
✓ Branch 0 taken 310 times.
✓ Branch 1 taken 28 times.
338 if (nargs == 2) {
1196 310 retval = ENC_SYM_TERROR;
1197
4/4
✓ Branch 0 taken 282 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 254 times.
✓ Branch 3 taken 28 times.
310 if (IS_NUMBER(args[0]) && IS_NUMBER(args[1])) {
1198
8/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 57 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 28 times.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 28 times.
✓ Branch 6 taken 28 times.
✓ Branch 7 taken 56 times.
254 switch (lbm_type_of_functional(args[0])) {
1199 1 case LBM_TYPE_CHAR: retval = lbm_enc_char(lbm_dec_char(args[0]) ^ lbm_dec_as_char(args[1])); break;
1200 #ifdef LBM64
1201 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) ^ lbm_dec_as_i64(args[1])); break;
1202 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) ^ lbm_dec_as_u64(args[1])); break;
1203 #else
1204 57 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) ^ lbm_dec_as_i32(args[1])); break;
1205 28 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) ^ lbm_dec_as_u32(args[1])); break;
1206 #endif
1207 28 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_u32(args[0]) ^ lbm_dec_as_u32(args[1])); break;
1208 28 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_i32(args[0]) ^ lbm_dec_as_i32(args[1])); break;
1209 28 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_i64(args[0]) ^ lbm_dec_as_i64(args[1])); break;
1210 28 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_u64(args[0]) ^ lbm_dec_as_u64(args[1])); break;
1211 }
1212 }
1213 }
1214 338 return retval;
1215 }
1216
1217 282 static lbm_value fundamental_bitwise_not(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1218 (void) ctx;
1219 282 lbm_value retval = ENC_SYM_EERROR;
1220
2/2
✓ Branch 0 taken 254 times.
✓ Branch 1 taken 28 times.
282 if (nargs == 1) {
1221 254 retval = ENC_SYM_TERROR;
1222
2/2
✓ Branch 0 taken 226 times.
✓ Branch 1 taken 28 times.
254 if (IS_NUMBER(args[0])) {
1223
8/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 29 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 28 times.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 28 times.
✓ Branch 6 taken 28 times.
✓ Branch 7 taken 56 times.
226 switch (lbm_type_of_functional(args[0])) {
1224 1 case LBM_TYPE_CHAR: retval = lbm_enc_char(~lbm_dec_char(args[0])); break;
1225 29 case LBM_TYPE_I: retval = lbm_enc_i(~lbm_dec_i(args[0])); break;
1226 28 case LBM_TYPE_U: retval = lbm_enc_u(~lbm_dec_u(args[0])); break;
1227 28 case LBM_TYPE_U32: retval = lbm_enc_u32(~lbm_dec_u32(args[0])); break;
1228 28 case LBM_TYPE_I32: retval = lbm_enc_i32(~lbm_dec_i32(args[0])); break;
1229 28 case LBM_TYPE_I64: retval = lbm_enc_i64(~lbm_dec_i64(args[0])); break;
1230 28 case LBM_TYPE_U64: retval = lbm_enc_u64(~lbm_dec_u64(args[0])); break;
1231 }
1232 }
1233 }
1234 282 return retval;
1235 }
1236
1237 4 static lbm_value fundamental_custom_destruct(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1238 (void) ctx;
1239 4 lbm_value result = ENC_SYM_EERROR;
1240
4/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1 times.
4 if (nargs == 1 && (lbm_type_of(args[0]) == LBM_TYPE_CUSTOM)) {
1241 2 lbm_uint *mem_ptr = (lbm_uint*)lbm_dec_custom(args[0]);
1242
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(!mem_ptr) return ENC_SYM_FATAL_ERROR;
1243 2 lbm_custom_type_destroy(mem_ptr);
1244 2 lbm_value tmp = lbm_set_ptr_type(args[0], LBM_TYPE_CONS);
1245 2 lbm_set_car(tmp, ENC_SYM_NIL);
1246 2 lbm_set_cdr(tmp, ENC_SYM_NIL);
1247 // The original value will still be of type custom_ptr
1248 2 result = ENC_SYM_TRUE;
1249 }
1250 4 return result;
1251 }
1252
1253 16955 static lbm_value fundamental_type_of(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1254 (void) ctx;
1255 16955 lbm_value res = ENC_SYM_EERROR;
1256
2/2
✓ Branch 0 taken 16953 times.
✓ Branch 1 taken 2 times.
16955 if (nargs == 1) {
1257 16953 lbm_value val = args[0];
1258 16953 lbm_type t = lbm_type_of(val);
1259
1260
2/2
✓ Branch 0 taken 11212 times.
✓ Branch 1 taken 5741 times.
16953 if (lbm_is_ptr(val)) {
1261 // Ignore constant or not constant.
1262 11212 t &= LBM_PTR_TO_CONSTANT_MASK;
1263 }
1264
15/16
✓ Branch 0 taken 5297 times.
✓ Branch 1 taken 114 times.
✓ Branch 2 taken 644 times.
✓ Branch 3 taken 812 times.
✓ Branch 4 taken 1793 times.
✓ Branch 5 taken 672 times.
✓ Branch 6 taken 784 times.
✓ Branch 7 taken 1065 times.
✓ Branch 8 taken 1165 times.
✓ Branch 9 taken 3245 times.
✓ Branch 10 taken 56 times.
✓ Branch 11 taken 1275 times.
✓ Branch 12 taken 28 times.
✓ Branch 13 taken 1 times.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
16953 switch(t) {
1265 5297 case LBM_TYPE_CONS: res = ENC_SYM_TYPE_LIST; break;
1266 114 case LBM_TYPE_ARRAY: res = ENC_SYM_TYPE_ARRAY; break;
1267 644 case LBM_TYPE_I32: res = ENC_SYM_TYPE_I32; break;
1268 812 case LBM_TYPE_U32: res = ENC_SYM_TYPE_U32; break;
1269 1793 case LBM_TYPE_FLOAT: res = ENC_SYM_TYPE_FLOAT; break;
1270 672 case LBM_TYPE_I64: res = ENC_SYM_TYPE_I64; break;
1271 784 case LBM_TYPE_U64: res = ENC_SYM_TYPE_U64; break;
1272 1065 case LBM_TYPE_DOUBLE: res = ENC_SYM_TYPE_DOUBLE; break;
1273 1165 case LBM_TYPE_I: res = ENC_SYM_TYPE_I; break;
1274 3245 case LBM_TYPE_U: res = ENC_SYM_TYPE_U; break;
1275 56 case LBM_TYPE_CHAR: res = ENC_SYM_TYPE_CHAR; break;
1276 1275 case LBM_TYPE_SYMBOL: res = ENC_SYM_TYPE_SYMBOL; break;
1277 28 case LBM_TYPE_LISPARRAY: res = ENC_SYM_TYPE_LISPARRAY; break;
1278 1 case LBM_TYPE_DEFRAG_MEM: res = ENC_SYM_TYPE_DEFRAG_MEM; break;
1279 2 case LBM_TYPE_CUSTOM: res = ENC_SYM_TYPE_CUSTOM; break;
1280 }
1281 }
1282 16955 return res;
1283 }
1284
1285 2412 static lbm_value fundamental_list_length(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1286 (void) ctx;
1287 2412 lbm_value result = ENC_SYM_EERROR;
1288
2/2
✓ Branch 0 taken 2382 times.
✓ Branch 1 taken 30 times.
2412 if (nargs == 1) {
1289 2382 result = ENC_SYM_TERROR;
1290
2/2
✓ Branch 0 taken 1193 times.
✓ Branch 1 taken 1189 times.
2382 if (lbm_is_list(args[0])) {
1291 1193 int32_t len = (int32_t)lbm_list_length(args[0]);
1292 1193 result = lbm_enc_i(len);
1293
2/2
✓ Branch 0 taken 1040 times.
✓ Branch 1 taken 149 times.
1189 } else if (lbm_is_array_r(args[0])) {
1294 1040 lbm_array_header_t *header = (lbm_array_header_t*)lbm_car(args[0]);
1295 1040 result = lbm_enc_i((int)(header->size));
1296
2/2
✓ Branch 0 taken 88 times.
✓ Branch 1 taken 61 times.
149 } else if (lbm_is_lisp_array_r(args[0])) {
1297 88 lbm_array_header_t *header = (lbm_array_header_t*)lbm_car(args[0]);
1298 88 result = lbm_enc_i((int)(header->size / (sizeof(lbm_uint))));
1299 }
1300 }
1301 2412 return result;
1302 }
1303
1304 6092979 static lbm_value fundamental_range(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1305 (void) ctx;
1306 6092979 lbm_value result = ENC_SYM_EERROR;
1307
1308 int32_t start;
1309 int32_t end;
1310 6092979 bool rev = false;
1311
1312
4/4
✓ Branch 0 taken 5802490 times.
✓ Branch 1 taken 290489 times.
✓ Branch 2 taken 5802462 times.
✓ Branch 3 taken 28 times.
6092979 if (nargs == 1 && IS_NUMBER(args[0])) {
1313 5802462 start = 0;
1314 5802462 end = lbm_dec_as_i32(args[0]);
1315
4/4
✓ Branch 0 taken 290461 times.
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 290433 times.
✓ Branch 3 taken 28 times.
580978 } else if (nargs == 2 &&
1316
2/2
✓ Branch 0 taken 290405 times.
✓ Branch 1 taken 28 times.
580894 IS_NUMBER(args[0]) &&
1317 290433 IS_NUMBER(args[1])) {
1318 290405 start = lbm_dec_as_i32(args[0]);
1319 290405 end = lbm_dec_as_i32(args[1]);
1320 } else {
1321 112 return result;
1322 }
1323
1324
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 6092839 times.
6092867 if (end == start) return ENC_SYM_NIL;
1325
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 6092783 times.
6092839 else if (end < start) {
1326 56 int32_t tmp = end;
1327 56 end = start;
1328 56 start = tmp;
1329 56 rev = true;
1330 }
1331
1332 6092839 int num = end - start;
1333
1334
2/2
✓ Branch 0 taken 199266 times.
✓ Branch 1 taken 5893573 times.
6092839 if ((unsigned int)num > lbm_heap_num_free()) {
1335 199266 return ENC_SYM_MERROR;
1336 }
1337
1338 5893573 lbm_value r_list = ENC_SYM_NIL;
1339
2/2
✓ Branch 0 taken 298446951 times.
✓ Branch 1 taken 5893573 times.
304340524 for (int i = end - 1; i >= start; i --) {
1340 298446951 r_list = lbm_cons(lbm_enc_i(i), r_list);
1341 }
1342
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 5893517 times.
5893573 return rev ? lbm_list_destructive_reverse(r_list) : r_list;
1343 }
1344
1345 280 static lbm_value fundamental_reg_event_handler(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1346 (void) ctx;
1347 280 lbm_value res = ENC_SYM_TERROR;
1348
4/4
✓ Branch 0 taken 252 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 224 times.
✓ Branch 3 taken 28 times.
280 if (nargs == 1 && IS_NUMBER(args[0])) {
1349 224 lbm_set_event_handler_pid((lbm_cid)lbm_dec_i(args[0]));
1350 224 res = ENC_SYM_TRUE;
1351 }
1352 280 return res;
1353 }
1354
1355 34550 static lbm_value fundamental_take(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1356 (void) ctx;
1357 34550 lbm_value res = ENC_SYM_TERROR;
1358
6/6
✓ Branch 0 taken 34522 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 34494 times.
✓ Branch 3 taken 28 times.
✓ Branch 4 taken 34466 times.
✓ Branch 5 taken 28 times.
34550 if (nargs == 2 && IS_NUMBER(args[1]) && lbm_is_list(args[0])) {
1359 34466 int len = lbm_dec_as_i32(args[1]);
1360 34466 res = lbm_list_copy(&len, args[0]);
1361 }
1362 34550 return res;
1363 }
1364
1365 168 static lbm_value fundamental_drop(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1366 (void) ctx;
1367 168 lbm_value res = ENC_SYM_TERROR;
1368
6/6
✓ Branch 0 taken 140 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 28 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 28 times.
168 if (nargs == 2 && IS_NUMBER(args[1]) && lbm_is_list(args[0])) {
1369 84 res = lbm_list_drop(lbm_dec_as_u32(args[1]), args[0]);
1370 }
1371 168 return res;
1372 }
1373 /* (mkarray size) */
1374 281709 static lbm_value fundamental_mkarray(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1375 (void) ctx;
1376 281709 lbm_value res = ENC_SYM_TERROR;
1377
2/4
✓ Branch 0 taken 281709 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 281709 times.
✗ Branch 3 not taken.
281709 if (nargs == 1 && IS_NUMBER(args[0])) {
1378 281709 lbm_heap_allocate_lisp_array(&res, lbm_dec_as_u32(args[0]));
1379 }
1380 // No high-level arrays in defrag mem until we figure out how to do it without overhead.
1381 //else if (nargs == 2 && IS_NUMBER(args[1]) && lbm_type_of(args[0]) == LBM_TYPE_DEFRAG_MEM) {
1382 // lbm_uint *dm = (lbm_uint*)lbm_car(args[0]);
1383 // res = lbm_defrag_mem_alloc_lisparray(dm, lbm_dec_as_u32(args[1]));
1384 //}
1385 281709 return res;
1386 }
1387
1388 // Create an array in a similar way to how list creates a list.
1389 5 static lbm_value fundamental_array(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1390 (void) ctx;
1391 5 lbm_value res = ENC_SYM_TERROR;
1392 5 lbm_heap_allocate_lisp_array(&res, nargs);
1393
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (!lbm_is_symbol_merror(res)) {
1394 5 lbm_array_header_t *header = (lbm_array_header_t*)lbm_car(res);
1395 5 lbm_value *arrdata = (lbm_value*)header->data;
1396
2/2
✓ Branch 0 taken 104 times.
✓ Branch 1 taken 5 times.
109 for (lbm_uint i = 0; i < nargs; i ++) {
1397 104 arrdata[i] = args[i];
1398 }
1399 }
1400 5 return res;
1401 }
1402
1403 169 static lbm_value fundamental_dm_create(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1404 (void) ctx;
1405 169 lbm_value res = ENC_SYM_TERROR;
1406
2/4
✓ Branch 0 taken 169 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 169 times.
✗ Branch 3 not taken.
169 if (argn == 1 && lbm_is_number(args[0])) {
1407 169 lbm_uint n = lbm_dec_as_uint(args[0]);
1408 169 res = lbm_defrag_mem_create(n);
1409 }
1410 169 return res;
1411 }
1412
1413 2184 static lbm_value fundamental_dm_alloc(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1414 (void) ctx;
1415 2184 lbm_value res = ENC_SYM_TERROR;
1416
2/4
✓ Branch 0 taken 2184 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2184 times.
✗ Branch 3 not taken.
2184 if (argn == 2 && lbm_is_number(args[1])) {
1417
1/2
✓ Branch 0 taken 2184 times.
✗ Branch 1 not taken.
2184 if (lbm_type_of(args[0]) == LBM_TYPE_DEFRAG_MEM) {
1418 2184 lbm_uint *dm = (lbm_uint*)lbm_car(args[0]);
1419 2184 res = lbm_defrag_mem_alloc(dm, lbm_dec_as_uint(args[1]));
1420 }
1421 }
1422 // NO high level arrays in Defrag mem until we can do it without overhead in the DM representation!
1423 //else if (argn == 3 && lbm_is_number(args[1]) && args[2] == ENC_SYM_TYPE_LISPARRAY) {
1424 // if (lbm_type_of(args[0]) == LBM_TYPE_DEFRAG_MEM) {
1425 // lbm_uint *dm = (lbm_uint*)lbm_car(args[0]);
1426 // res = lbm_defrag_mem_alloc_lisparray(dm, lbm_dec_as_uint(args[1]));
1427 // }
1428 //}
1429 2184 return res;
1430 }
1431
1432 167 static lbm_value fundamental_is_list(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1433 (void) ctx;
1434 167 lbm_value res = ENC_SYM_TERROR;
1435
2/2
✓ Branch 0 taken 165 times.
✓ Branch 1 taken 2 times.
167 if (argn == 1) {
1436
2/2
✓ Branch 0 taken 104 times.
✓ Branch 1 taken 61 times.
165 res = lbm_is_list(args[0]) ? ENC_SYM_TRUE : ENC_SYM_NIL;
1437 }
1438 167 return res;
1439 }
1440
1441 331 static lbm_value fundamental_is_number(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1442 (void) ctx;
1443 331 lbm_value res = ENC_SYM_TERROR;
1444
2/2
✓ Branch 0 taken 329 times.
✓ Branch 1 taken 2 times.
331 if (argn == 1) {
1445
2/2
✓ Branch 0 taken 211 times.
✓ Branch 1 taken 118 times.
329 res = lbm_is_number(args[0]) ? ENC_SYM_TRUE : ENC_SYM_NIL;
1446 }
1447 331 return res;
1448 }
1449
1450 77 static lbm_value fundamental_int_div(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1451 77 lbm_value res = fundamental_div(args, argn, ctx);
1452
3/3
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 49 times.
77 switch (lbm_type_of(res)) {
1453 27 case LBM_TYPE_FLOAT: {
1454 27 res = lbm_enc_i((lbm_int)lbm_dec_float(res));
1455 27 break;
1456 }
1457 1 case LBM_TYPE_DOUBLE: {
1458 1 res = lbm_enc_i((lbm_int)lbm_dec_double(res));
1459 1 break;
1460 }
1461 }
1462
1463 77 return res;
1464 }
1465
1466 56 static lbm_value fundamental_identity(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1467 (void) ctx;
1468 56 lbm_value res = ENC_SYM_TERROR;
1469
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 if (argn == 1) {
1470 56 res = args[0];
1471 }
1472 56 return res;
1473 }
1474
1475 3 static lbm_value fundamental_is_string(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1476 (void) ctx;
1477 3 lbm_value res = ENC_SYM_TERROR;
1478
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (argn == 1) {
1479 char *str;
1480
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 res = lbm_value_is_printable_string(args[0], &str) ? ENC_SYM_TRUE : ENC_SYM_NIL;
1481 }
1482 3 return res;
1483 }
1484
1485 // Check if a value is a constant (stored in flash)
1486 // Only half true for some shared arrays.. maybe rethink that.
1487 // constant? is true for constant pointers.
1488 // atoms could be considered constant in general but are not by constant?
1489 3 static lbm_value fundamental_is_constant(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1490 (void) ctx;
1491 3 lbm_value res = ENC_SYM_TERROR;
1492
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (argn == 1) {
1493 2 lbm_type t = lbm_type_of(args[0]);
1494
3/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
2 return (((args[0] & LBM_PTR_BIT) && (t & LBM_PTR_TO_CONSTANT_BIT)) ? ENC_SYM_TRUE : ENC_SYM_NIL);
1495 }
1496 1 return res;
1497 }
1498
1499 982 static lbm_value fundamental_member(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1500 (void)ctx;
1501 982 lbm_value res = ENC_SYM_TERROR;
1502
3/4
✓ Branch 0 taken 870 times.
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 870 times.
✗ Branch 3 not taken.
982 if (argn == 2 && lbm_is_list(args[1])) {
1503 870 res = ENC_SYM_NIL;
1504 870 lbm_value curr = args[1];
1505
1506
2/2
✓ Branch 0 taken 1918 times.
✓ Branch 1 taken 168 times.
2086 while (lbm_is_cons(curr)) {
1507
2/2
✓ Branch 0 taken 702 times.
✓ Branch 1 taken 1216 times.
1918 if (struct_eq(lbm_car(curr), args[0])) {
1508 702 res = args[1];
1509 702 break;
1510 }
1511 1216 curr = lbm_cdr(curr);
1512 }
1513 }
1514 982 return res;
1515 }
1516
1517
1518 const fundamental_fun fundamental_table[] =
1519 {fundamental_add,
1520 fundamental_sub,
1521 fundamental_mul,
1522 fundamental_div,
1523 fundamental_mod,
1524 fundamental_eq,
1525 fundamental_not_eq,
1526 fundamental_numeq,
1527 fundamental_num_not_eq,
1528 fundamental_lt,
1529 fundamental_gt,
1530 fundamental_leq,
1531 fundamental_geq,
1532 fundamental_not,
1533 fundamental_gc,
1534 fundamental_self,
1535 fundamental_set_mailbox_size,
1536 fundamental_cons,
1537 fundamental_car,
1538 fundamental_cdr,
1539 fundamental_list,
1540 fundamental_append,
1541 fundamental_undefine,
1542 fundamental_buf_create,
1543 fundamental_symbol_to_string,
1544 fundamental_string_to_symbol,
1545 fundamental_symbol_to_uint,
1546 fundamental_uint_to_symbol,
1547 fundamental_set_car,
1548 fundamental_set_cdr,
1549 fundamental_set_ix,
1550 fundamental_assoc,
1551 fundamental_acons,
1552 fundamental_set_assoc,
1553 fundamental_cossa,
1554 fundamental_ix,
1555 fundamental_to_i,
1556 fundamental_to_i32,
1557 fundamental_to_u,
1558 fundamental_to_u32,
1559 fundamental_to_float,
1560 fundamental_to_i64,
1561 fundamental_to_u64,
1562 fundamental_to_double,
1563 fundamental_to_byte,
1564 fundamental_shl,
1565 fundamental_shr,
1566 fundamental_bitwise_and,
1567 fundamental_bitwise_or,
1568 fundamental_bitwise_xor,
1569 fundamental_bitwise_not,
1570 fundamental_custom_destruct,
1571 fundamental_type_of,
1572 fundamental_list_length,
1573 fundamental_range,
1574 fundamental_reg_event_handler,
1575 fundamental_take,
1576 fundamental_drop,
1577 fundamental_mkarray,
1578 fundamental_dm_create,
1579 fundamental_dm_alloc,
1580 fundamental_is_list,
1581 fundamental_is_number,
1582 fundamental_int_div,
1583 fundamental_identity,
1584 fundamental_array,
1585 fundamental_is_string,
1586 fundamental_is_constant,
1587 fundamental_member
1588 };
1589