GCC Code Coverage Report


Directory: ../src/
File: /home/joels/Current/lispbm/src/fundamental.c
Date: 2025-08-08 18:10:24
Exec Total Coverage
Lines: 855 877 97.5%
Functions: 79 80 98.8%
Branches: 643 703 91.5%

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 140081941 static lbm_uint mul2(lbm_uint a, lbm_uint b) {
109 140081941 lbm_uint retval = ENC_SYM_TERROR;
110
3/4
✓ Branch 0 taken 140081941 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 140081597 times.
✓ Branch 3 taken 344 times.
280163538 if (IS_NUMBER(a) && IS_NUMBER(b)) {
111 lbm_type t;
112
10/10
✓ Branch 0 taken 67532259 times.
✓ Branch 1 taken 72549338 times.
✓ Branch 2 taken 33600532 times.
✓ Branch 3 taken 28 times.
✓ Branch 4 taken 67200756 times.
✓ Branch 5 taken 2804312 times.
✓ Branch 6 taken 67200728 times.
✓ Branch 7 taken 28 times.
✓ Branch 8 taken 282828 times.
✓ Branch 9 taken 2521512 times.
140081597 PROMOTE_SWAP(t, a, b);
113
9/10
✓ Branch 0 taken 560 times.
✓ Branch 1 taken 5601799 times.
✓ Branch 2 taken 896 times.
✓ Branch 3 taken 896 times.
✓ Branch 4 taken 784 times.
✓ Branch 5 taken 134472854 times.
✓ Branch 6 taken 1232 times.
✓ Branch 7 taken 1120 times.
✓ Branch 8 taken 1456 times.
✗ Branch 9 not taken.
140081597 switch (t) {
114 560 case LBM_TYPE_CHAR: retval = lbm_enc_char((uint8_t)(lbm_dec_char(a) * lbm_dec_char(b))); break;
115 #ifdef LBM64
116 2800924 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(a) * lbm_dec_as_i64(b)); break;
117 504 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(a) * lbm_dec_as_u64(b)); break;
118 #else
119 2800875 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 896 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_u32(a) * lbm_dec_as_u32(b)); break;
123 784 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_i32(a) * lbm_dec_as_i32(b)); break;
124 134472854 case LBM_TYPE_FLOAT: retval = lbm_enc_float(lbm_dec_float(a) * lbm_dec_as_float(b)); break;
125 1232 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_u64(a) * lbm_dec_as_u64(b)); break;
126 1120 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_i64(a) * lbm_dec_as_i64(b)); break;
127 1456 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 344 times.
✗ Branch 1 not taken.
344 lbm_set_error_suspect(IS_NUMBER(a) ? b : a);
131 }
132 140081941 return retval;
133 }
134
135 2444 static lbm_uint div2(lbm_uint a, lbm_uint b) {
136 2444 lbm_uint retval = ENC_SYM_TERROR;
137
4/4
✓ Branch 0 taken 2319 times.
✓ Branch 1 taken 125 times.
✓ Branch 2 taken 2195 times.
✓ Branch 3 taken 124 times.
3732 if (IS_NUMBER(a) && IS_NUMBER(b)) {
138 lbm_type t;
139
5/6
✓ Branch 0 taken 116 times.
✓ Branch 1 taken 2079 times.
✓ Branch 2 taken 84 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 56 times.
✓ Branch 5 taken 924 times.
2195 PROMOTE(t, a, b);
140
9/10
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 1157 times.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 253 times.
✓ Branch 6 taken 112 times.
✓ Branch 7 taken 112 times.
✓ Branch 8 taken 169 times.
✗ Branch 9 not taken.
2195 switch (t) {
141
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 56 times.
112 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
2/2
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 308 times.
588 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
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_u64(a) / lbm_dec_as_u64(b)); break;
145 #else
146
2/2
✓ Branch 0 taken 231 times.
✓ Branch 1 taken 338 times.
569 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 56 times.
84 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 56 times.
84 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 194 times.
✓ Branch 1 taken 59 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 194 times.
253 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 56 times.
✓ Branch 1 taken 56 times.
112 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 56 times.
✓ Branch 1 taken 56 times.
112 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 112 times.
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 112 times.
169 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 124 times.
✓ Branch 1 taken 125 times.
249 lbm_set_error_suspect(IS_NUMBER(a) ? b : a);
158 }
159 1537 return retval;
160 }
161
162 17579 static lbm_uint mod2(lbm_uint a, lbm_uint b) {
163 17579 lbm_uint retval = ENC_SYM_TERROR;
164
4/4
✓ Branch 0 taken 17462 times.
✓ Branch 1 taken 117 times.
✓ Branch 2 taken 17348 times.
✓ Branch 3 taken 114 times.
34364 if (IS_NUMBER(a) && IS_NUMBER(b)) {
165 lbm_type t;
166
5/6
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 17318 times.
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 56 times.
✓ Branch 5 taken 8588 times.
17348 PROMOTE(t, a, b);
167
9/10
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 506 times.
✓ Branch 2 taken 16112 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 113 times.
✓ Branch 6 taken 112 times.
✓ Branch 7 taken 112 times.
✓ Branch 8 taken 113 times.
✗ Branch 9 not taken.
17348 switch (t) {
168
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 56 times.
112 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
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 168 times.
280 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
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_u64(a) % lbm_dec_as_u64(b)); break;
172 #else
173
2/2
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 169 times.
226 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 56 times.
84 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 56 times.
84 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 56 times.
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 56 times.
113 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 56 times.
✓ Branch 1 taken 56 times.
112 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 56 times.
✓ Branch 1 taken 56 times.
112 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 56 times.
✓ Branch 1 taken 57 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 56 times.
113 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 114 times.
✓ Branch 1 taken 117 times.
231 lbm_set_error_suspect(IS_NUMBER(a) ? b : a);
185 }
186 17016 return retval;
187 }
188
189 54010003 static lbm_uint sub2(lbm_uint a, lbm_uint b) {
190 54010003 lbm_uint retval = ENC_SYM_TERROR;
191
4/4
✓ Branch 0 taken 54009886 times.
✓ Branch 1 taken 117 times.
✓ Branch 2 taken 54009603 times.
✓ Branch 3 taken 283 times.
108019606 if (IS_NUMBER(a) && IS_NUMBER(b)) {
192 lbm_uint t;
193
5/6
✓ Branch 0 taken 619 times.
✓ Branch 1 taken 54008984 times.
✓ Branch 2 taken 168 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 392 times.
✓ Branch 5 taken 26805167 times.
54009603 PROMOTE(t, a, b);
194
9/10
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 53727825 times.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 280656 times.
✓ Branch 4 taken 168 times.
✓ Branch 5 taken 338 times.
✓ Branch 6 taken 112 times.
✓ Branch 7 taken 168 times.
✓ Branch 8 taken 112 times.
✗ Branch 9 not taken.
54009603 switch (t) {
195 112 case LBM_TYPE_BYTE: retval = lbm_enc_char((uint8_t)(lbm_dec_char(a) - lbm_dec_char(b))); break;
196 #ifdef LBM64
197 26805083 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_as_i64(a) - lbm_dec_as_i64(b)); break;
198 56 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_as_u64(a) - lbm_dec_as_u64(b)); break;
199 #else
200 26922742 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 280656 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_as_u32(a) - lbm_dec_as_u32(b)); break;
204 168 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_as_i32(a) - lbm_dec_as_i32(b)); break;
205 338 case LBM_TYPE_FLOAT: retval = lbm_enc_float(lbm_dec_as_float(a) - lbm_dec_as_float(b)); break;
206 112 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_as_u64(a) - lbm_dec_as_u64(b)); break;
207 168 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_as_i64(a) - lbm_dec_as_i64(b)); break;
208 112 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 283 times.
✓ Branch 1 taken 117 times.
400 lbm_set_error_suspect(IS_NUMBER(a) ? b : a);
212 }
213 54010003 return retval;
214 }
215
216 // a and b must be bytearrays!
217 21145 static bool bytearray_equality(lbm_value a, lbm_value b) {
218 21145 lbm_array_header_t *a_ = (lbm_array_header_t*)lbm_car(a);
219 21145 lbm_array_header_t *b_ = (lbm_array_header_t*)lbm_car(b);
220 21145 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 21145 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21145 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 20809 times.
✓ Branch 5 taken 336 times.
21145 if ((a_ && b_) && a_->size == b_->size) {
225 20809 res = (memcmp((char*)a_->data, (char*)b_->data, a_->size) == 0);
226 }
227 21145 return res;
228 }
229
230 // a and b must be arrays!
231 678 static bool array_struct_equality(lbm_value a, lbm_value b) {
232 678 lbm_array_header_t *a_ = (lbm_array_header_t*)lbm_car(a);
233 678 lbm_array_header_t *b_ = (lbm_array_header_t*)lbm_car(b);
234 678 bool res = false;
235
4/6
✓ Branch 0 taken 678 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 678 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 622 times.
✓ Branch 5 taken 56 times.
678 if ((a_ && b_) && a_->size == b_->size) {
236 622 res = true;
237 622 lbm_value *adata = (lbm_value*)a_->data;
238 622 lbm_value *bdata = (lbm_value*)b_->data;
239 622 lbm_uint size = (lbm_uint)a_->size / (lbm_uint)sizeof(lbm_value);
240
2/2
✓ Branch 0 taken 1529 times.
✓ Branch 1 taken 566 times.
2095 for (lbm_uint i = 0; i < size; i ++ ) {
241 1529 res = struct_eq(adata[i], bdata[i]);
242
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 1473 times.
1529 if (!res) break;
243 }
244 }
245 678 return res;
246 }
247
248 631388 bool struct_eq(lbm_value a, lbm_value b) {
249
250 631388 bool res = false;
251 631388 lbm_type ta = lbm_type_of_functional(a);
252 631388 lbm_type tb = lbm_type_of_functional(b);
253
254
2/2
✓ Branch 0 taken 595911 times.
✓ Branch 1 taken 35477 times.
631388 if (ta == tb) {
255
13/14
✓ Branch 0 taken 129065 times.
✓ Branch 1 taken 255090 times.
✓ Branch 2 taken 1178 times.
✓ Branch 3 taken 10035 times.
✓ Branch 4 taken 151412 times.
✓ Branch 5 taken 3647 times.
✓ Branch 6 taken 7179 times.
✓ Branch 7 taken 13455 times.
✓ Branch 8 taken 1121 times.
✓ Branch 9 taken 1121 times.
✓ Branch 10 taken 785 times.
✓ Branch 11 taken 21145 times.
✓ Branch 12 taken 678 times.
✗ Branch 13 not taken.
595911 switch(ta){
256 129065 case LBM_TYPE_SYMBOL:
257 129065 res = (lbm_dec_sym(a) == lbm_dec_sym(b)); break;
258 255090 case LBM_TYPE_I:
259 255090 res = (lbm_dec_i(a) == lbm_dec_i(b)); break;
260 1178 case LBM_TYPE_U:
261 1178 res = (lbm_dec_u(a) == lbm_dec_u(b)); break;
262 10035 case LBM_TYPE_CHAR:
263 10035 res = (lbm_dec_char(a) == lbm_dec_char(b)); break;
264 151412 case LBM_TYPE_CONS:
265
4/4
✓ Branch 0 taken 151285 times.
✓ Branch 1 taken 127 times.
✓ Branch 2 taken 151215 times.
✓ Branch 3 taken 70 times.
302697 res = ( struct_eq(lbm_car(a),lbm_car(b)) &&
266 302697 struct_eq(lbm_cdr(a),lbm_cdr(b)) ); break;
267 3647 case LBM_TYPE_I32:
268 3647 res = (lbm_dec_i32(a) == lbm_dec_i32(b)); break;
269 7179 case LBM_TYPE_U32:
270 7179 res = (lbm_dec_u32(a) == lbm_dec_u32(b)); break;
271 13455 case LBM_TYPE_FLOAT:
272 13455 res = (lbm_dec_float(a) == lbm_dec_float(b)); break;
273 1121 case LBM_TYPE_I64:
274 1121 res = (lbm_dec_i64(a) == lbm_dec_i64(b)); break;
275 1121 case LBM_TYPE_U64:
276 1121 res = (lbm_dec_u64(a) == lbm_dec_u64(b)); break;
277 785 case LBM_TYPE_DOUBLE:
278 785 res = (lbm_dec_double(a) == lbm_dec_double(b)); break;
279 21145 case LBM_TYPE_ARRAY:
280 21145 res = bytearray_equality(a, b); break;
281 678 case LBM_TYPE_LISPARRAY:
282 678 res = array_struct_equality(a, b); break;
283 }
284 }
285 631388 return res;
286 }
287
288
289 /* returns -1 if a < b; 0 if a = b; 1 if a > b
290 args must be numbers
291 */
292 151933293 static int compare_num(lbm_uint a, lbm_uint b) {
293
294 151933293 int retval = 0;
295
296 lbm_uint t;
297
6/6
✓ Branch 0 taken 2800843 times.
✓ Branch 1 taken 149132450 times.
✓ Branch 2 taken 2800448 times.
✓ Branch 3 taken 28 times.
✓ Branch 4 taken 336 times.
✓ Branch 5 taken 72961326 times.
151933293 PROMOTE(t, a, b);
298
9/10
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 76039466 times.
✓ Branch 2 taken 10577 times.
✓ Branch 3 taken 841054 times.
✓ Branch 4 taken 560113 times.
✓ Branch 5 taken 72801355 times.
✓ Branch 6 taken 560168 times.
✓ Branch 7 taken 1120168 times.
✓ Branch 8 taken 336 times.
✗ Branch 9 not taken.
151933293 switch (t) {
299 56 case LBM_TYPE_CHAR: retval = CMP(lbm_dec_char(a), lbm_dec_char(b)); break;
300 #ifdef LBM64
301 37955594 case LBM_TYPE_I: retval = CMP(lbm_dec_as_i64(a), lbm_dec_as_i64(b)); break;
302 5284 case LBM_TYPE_U: retval = CMP(lbm_dec_as_u64(a), lbm_dec_as_u64(b)); break;
303 #else
304 38083872 case LBM_TYPE_I: retval = CMP(lbm_dec_as_i32(a), lbm_dec_as_i32(b)); break;
305 5293 case LBM_TYPE_U: retval = CMP(lbm_dec_as_u32(a), lbm_dec_as_u32(b)); break;
306 #endif
307 841054 case LBM_TYPE_U32: retval = CMP(lbm_dec_as_u32(a), lbm_dec_as_u32(b)); break;
308 560113 case LBM_TYPE_I32: retval = CMP(lbm_dec_as_i32(a), lbm_dec_as_i32(b)); break;
309 72801355 case LBM_TYPE_FLOAT: retval = CMP(lbm_dec_as_float(a), lbm_dec_as_float(b)); break;
310 560168 case LBM_TYPE_U64: retval = CMP(lbm_dec_as_u64(a), lbm_dec_as_u64(b)); break;
311 1120168 case LBM_TYPE_I64: retval = CMP(lbm_dec_as_i64(a), lbm_dec_as_i64(b)); break;
312 336 case LBM_TYPE_DOUBLE: retval = CMP(lbm_dec_as_double(a), lbm_dec_as_double(b)); break;
313 }
314 151933293 return retval;
315 }
316
317 686 static lbm_value assoc_lookup(lbm_value key, lbm_value assoc) {
318 686 lbm_value curr = assoc;
319 686 lbm_value res = ENC_SYM_NO_MATCH;
320
2/2
✓ Branch 0 taken 1587 times.
✓ Branch 1 taken 56 times.
1643 while (lbm_is_cons(curr)) {
321 1587 lbm_value c = lbm_ref_cell(curr)->car;
322
2/2
✓ Branch 0 taken 1531 times.
✓ Branch 1 taken 56 times.
1587 if (lbm_is_cons(c)) {
323
2/2
✓ Branch 0 taken 574 times.
✓ Branch 1 taken 957 times.
1531 if (struct_eq(lbm_ref_cell(c)->car, key)) {
324 574 res = lbm_ref_cell(c)->cdr;
325 574 break;
326 }
327 } else {
328 56 res = ENC_SYM_EERROR;
329 56 break;
330 }
331 957 curr = lbm_ref_cell(curr)->cdr;
332 }
333 686 return res;
334 }
335
336 672 static lbm_value cossa_lookup(lbm_value key, lbm_value assoc) {
337 672 lbm_value curr = assoc;
338
2/2
✓ Branch 0 taken 1624 times.
✓ Branch 1 taken 56 times.
1680 while (lbm_is_cons(curr)) {
339 1624 lbm_value c = lbm_ref_cell(curr)->car;
340
2/2
✓ Branch 0 taken 1568 times.
✓ Branch 1 taken 56 times.
1624 if (lbm_is_cons(c)) {
341
2/2
✓ Branch 0 taken 560 times.
✓ Branch 1 taken 1008 times.
1568 if (struct_eq(lbm_ref_cell(c)->cdr, key)) {
342 560 return lbm_ref_cell(c)->car;
343 }
344 } else {
345 56 return ENC_SYM_EERROR;
346 }
347 1008 curr = lbm_ref_cell(curr)->cdr;
348 }
349 56 return ENC_SYM_NO_MATCH;
350 }
351
352
353
354 /***************************************************/
355 /* Fundamental operations */
356
357 156507971 static lbm_value fundamental_add(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
358 (void) ctx;
359 156507971 lbm_uint sum = lbm_enc_char(0);
360
2/2
✓ Branch 0 taken 407426989 times.
✓ Branch 1 taken 156400306 times.
563827295 for (lbm_uint i = 0; i < nargs; i ++) {
361 407426989 lbm_value v = args[i];
362
2/2
✓ Branch 0 taken 407426573 times.
✓ Branch 1 taken 401 times.
407426989 if (IS_NUMBER(v)) { // inlining add2 explicitly removes one condition.
363 lbm_type t;
364
10/10
✓ Branch 0 taken 174179925 times.
✓ Branch 1 taken 233246648 times.
✓ Branch 2 taken 95201344 times.
✓ Branch 3 taken 28 times.
✓ Branch 4 taken 162401736 times.
✓ Branch 5 taken 39261548 times.
✓ Branch 6 taken 162401708 times.
✓ Branch 7 taken 28 times.
✓ Branch 8 taken 8091316 times.
✓ Branch 9 taken 31170260 times.
407426573 PROMOTE_SWAP(t, sum, v);
365
9/10
✓ Branch 0 taken 569 times.
✓ Branch 1 taken 53824195 times.
✓ Branch 2 taken 1513 times.
✓ Branch 3 taken 6164170 times.
✓ Branch 4 taken 5603976 times.
✓ Branch 5 taken 325006612 times.
✓ Branch 6 taken 6730760 times.
✓ Branch 7 taken 8971790 times.
✓ Branch 8 taken 1122988 times.
✗ Branch 9 not taken.
407426573 switch (t) {
366 569 case LBM_TYPE_BYTE: sum = lbm_enc_char((uint8_t)(lbm_dec_char(sum) + lbm_dec_char(v))); break;
367 #ifdef LBM64
368 25249300 case LBM_TYPE_I: sum = lbm_enc_i(lbm_dec_i(sum) + lbm_dec_as_i64(v)); break;
369 896 case LBM_TYPE_U: sum = lbm_enc_u(lbm_dec_u(sum) + lbm_dec_as_u64(v)); break;
370 2800560 case LBM_TYPE_U32: sum = lbm_enc_u32(lbm_dec_u32(sum) + lbm_dec_as_u32(v)); break;
371 2800504 case LBM_TYPE_I32: sum = lbm_enc_i32(lbm_dec_i32(sum) + lbm_dec_as_i32(v)); break;
372 162401708 case LBM_TYPE_FLOAT: sum = lbm_enc_float(lbm_dec_float(sum) + lbm_dec_as_float(v)); break;
373 #else
374 28574895 case LBM_TYPE_I: sum = lbm_enc_i(lbm_dec_i(sum) + lbm_dec_as_i32(v)); break;
375 617 case LBM_TYPE_U: sum = lbm_enc_u(lbm_dec_u(sum) + lbm_dec_as_u32(v)); break;
376 3363610 case LBM_TYPE_U32:
377 3363610 sum = lbm_enc_u32(lbm_dec_u32(sum) + lbm_dec_as_u32(v));
378
2/2
✓ Branch 0 taken 582 times.
✓ Branch 1 taken 3363028 times.
3363610 if (lbm_is_symbol(sum)) goto add_end;
379 3363028 break;
380 2803472 case LBM_TYPE_I32:
381 2803472 sum = lbm_enc_i32(lbm_dec_i32(sum) + lbm_dec_as_i32(v));
382
2/2
✓ Branch 0 taken 544 times.
✓ Branch 1 taken 2802928 times.
2803472 if (lbm_is_symbol(sum)) goto add_end;
383 2802928 break;
384 162604904 case LBM_TYPE_FLOAT:
385 162604904 sum = lbm_enc_float(lbm_dec_float(sum) + lbm_dec_as_float(v));
386
2/2
✓ Branch 0 taken 98882 times.
✓ Branch 1 taken 162506022 times.
162604904 if (lbm_is_symbol(sum)) goto add_end;
387 162506022 break;
388 #endif
389 6730760 case LBM_TYPE_U64:
390 6730760 sum = lbm_enc_u64(lbm_dec_u64(sum) + lbm_dec_as_u64(v));
391
2/2
✓ Branch 0 taken 2736 times.
✓ Branch 1 taken 6728024 times.
6730760 if (lbm_is_symbol(sum)) goto add_end;
392 6728024 break;
393 8971790 case LBM_TYPE_I64:
394 8971790 sum = lbm_enc_i64(lbm_dec_i64(sum) + lbm_dec_as_i64(v));
395
2/2
✓ Branch 0 taken 3662 times.
✓ Branch 1 taken 8968128 times.
8971790 if (lbm_is_symbol(sum)) goto add_end;
396 8968128 break;
397 1122988 case LBM_TYPE_DOUBLE:
398 1122988 sum = lbm_enc_double(lbm_dec_double(sum) + lbm_dec_as_double(v));
399
2/2
✓ Branch 0 taken 856 times.
✓ Branch 1 taken 1122132 times.
1122988 if (lbm_is_symbol(sum)) goto add_end;
400 1122132 break;
401 }
402 } else {
403 401 lbm_set_error_suspect(v);
404 401 sum = ENC_SYM_TERROR;
405 401 break; // out of loop
406 }
407 }
408 156400306 add_end:
409 156507969 return sum;
410 }
411
412 54009835 static lbm_value fundamental_sub(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
413 (void) ctx;
414
415 lbm_uint res;
416
417
4/4
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 956 times.
✓ Branch 2 taken 54008711 times.
✓ Branch 3 taken 112 times.
54009835 switch (nargs) {
418 56 case 0:
419 56 res = lbm_enc_char(0);
420 56 break;
421
422 956 case 1:
423 956 res = sub2(lbm_enc_char(0),args[0]);
424 956 break;
425
426 54008711 case 2:
427 54008711 res = sub2(args[0], args[1]);
428 54008711 break;
429
430 112 default:
431 112 res = args[0];
432
2/2
✓ Branch 0 taken 336 times.
✓ Branch 1 taken 56 times.
392 for (lbm_uint i = 1; i < nargs; i ++) {
433 336 res = sub2(res, args[i]);
434
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 280 times.
336 if (lbm_type_of(res) == LBM_TYPE_SYMBOL)
435 56 break;
436 }
437 112 break;
438 }
439 54009835 return res;
440 }
441
442 67813722 static lbm_value fundamental_mul(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
443 (void) ctx;
444
445 67813722 lbm_uint prod = lbm_enc_char(1);
446
2/2
✓ Branch 0 taken 140081941 times.
✓ Branch 1 taken 67765016 times.
207846957 for (lbm_uint i = 0; i < nargs; i ++) {
447 140081941 prod = mul2(prod, args[i]);
448
2/2
✓ Branch 0 taken 48706 times.
✓ Branch 1 taken 140033235 times.
140081941 if (lbm_type_of(prod) == LBM_TYPE_SYMBOL) {
449 48706 break;
450 }
451 }
452 67813722 return prod;
453 }
454
455 2432 static lbm_value fundamental_div(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
456 (void) ctx;
457
458 2432 lbm_uint res = args[0];
459
460
2/2
✓ Branch 0 taken 2316 times.
✓ Branch 1 taken 116 times.
2432 if (nargs >= 2) {
461
2/2
✓ Branch 0 taken 2444 times.
✓ Branch 1 taken 1160 times.
3604 for (lbm_uint i = 1; i < nargs; i ++) {
462 2444 res = div2(res, args[i]);
463
2/2
✓ Branch 0 taken 1156 times.
✓ Branch 1 taken 1288 times.
2444 if (lbm_type_of(res) == LBM_TYPE_SYMBOL) {
464 1156 break;
465 }
466 }
467 } else {
468 116 res = ENC_SYM_EERROR;
469 }
470 2432 return res;
471 }
472
473 17692 static lbm_value fundamental_mod(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
474 (void) ctx;
475
2/2
✓ Branch 0 taken 17579 times.
✓ Branch 1 taken 113 times.
17692 if (nargs == 2) {
476 17579 return mod2(args[0], args[1]);
477 }
478 113 lbm_set_error_reason((char*)lbm_error_str_num_args);
479 113 return ENC_SYM_EERROR;
480 }
481
482 163965 static lbm_value fundamental_eq(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
483 (void) ctx;
484 163965 lbm_uint a = args[0];
485
2/2
✓ Branch 0 taken 164357 times.
✓ Branch 1 taken 115257 times.
279614 for (lbm_uint i = 1; i < nargs; i ++) {
486 164357 lbm_uint b = args[i];
487
2/2
✓ Branch 0 taken 48708 times.
✓ Branch 1 taken 115649 times.
164357 if (!struct_eq(a, b)) return ENC_SYM_NIL;
488 }
489 115257 return ENC_SYM_TRUE;
490 }
491
492 560 static lbm_value fundamental_not_eq(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
493 560 lbm_value r = fundamental_eq(args, nargs, ctx);
494
2/2
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 280 times.
560 return r ? ENC_SYM_NIL : ENC_SYM_TRUE; // Works because ENC_SYM_NIL == 0 and ENC_SYM_TRUE is != 0
495 }
496
497
498 64598556 static lbm_value fundamental_numeq(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
499 (void) ctx;
500
501 64598556 lbm_uint a = args[0];
502 64598556 lbm_value res = ENC_SYM_TERROR;
503
504
2/2
✓ Branch 0 taken 64598432 times.
✓ Branch 1 taken 124 times.
64598556 if (IS_NUMBER(a)) {
505 64598432 res = ENC_SYM_TRUE;
506
2/2
✓ Branch 0 taken 64599606 times.
✓ Branch 1 taken 10119084 times.
74718690 for (lbm_uint i = 1; i < nargs; i ++) {
507 64599606 lbm_uint b = args[i];
508
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 64599492 times.
64599606 if (!IS_NUMBER(b)) {
509 114 res = ENC_SYM_TERROR;
510 114 break;
511 }
512
2/2
✓ Branch 0 taken 54479234 times.
✓ Branch 1 taken 10120258 times.
64599492 if (!(compare_num(a, b) == 0)) {
513 54479234 res = ENC_SYM_NIL;
514 54479234 break;
515 }
516 }
517 }
518 64598556 return res;
519 }
520
521 1120680 static lbm_value fundamental_num_not_eq(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
522 1120680 lbm_value r = fundamental_numeq(args, nargs, ctx);
523 // Needs the more expensive check as r can be ENC_SYM_TERROR.
524
2/2
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 1120400 times.
1120680 if (r == ENC_SYM_NIL) {
525 280 r = ENC_SYM_TRUE;
526
2/2
✓ Branch 0 taken 1120281 times.
✓ Branch 1 taken 119 times.
1120400 } else if (r == ENC_SYM_TRUE) {
527 1120281 r = ENC_SYM_NIL;
528 }
529 1120680 return r;
530 }
531
532 84779240 static lbm_value fundamental_leq(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
533 (void) ctx;
534
535 84779240 lbm_uint a = args[0];
536 84779240 bool r = true;
537
538
2/2
✓ Branch 0 taken 84779116 times.
✓ Branch 1 taken 124 times.
84779240 if (IS_NUMBER(a)) {
539
2/2
✓ Branch 0 taken 84779114 times.
✓ Branch 1 taken 84779002 times.
169558116 for (lbm_uint i = 1; i < nargs; i ++) {
540 84779114 lbm_uint b = args[i];
541
2/2
✓ Branch 0 taken 84779000 times.
✓ Branch 1 taken 114 times.
84779114 if (IS_NUMBER(b)) {
542
3/4
✓ Branch 0 taken 84779000 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10199528 times.
✓ Branch 3 taken 74579472 times.
84779000 r = r && (compare_num(a, b) <= 0);
543 } else {
544 114 lbm_set_error_suspect(b);
545 114 goto leq_type_error;
546 }
547 }
548 } else {
549 124 lbm_set_error_suspect(a);
550 124 goto leq_type_error;
551 }
552
2/2
✓ Branch 0 taken 10199530 times.
✓ Branch 1 taken 74579472 times.
84779002 if (r) {
553 10199530 return ENC_SYM_TRUE;
554 } else {
555 74579472 return ENC_SYM_NIL;
556 }
557 238 leq_type_error:
558 238 return ENC_SYM_TERROR;
559 }
560
561 2555041 static lbm_value fundamental_geq(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
562 (void) ctx;
563
564 2555041 lbm_uint a = args[0];
565 2555041 bool r = true;
566
567
2/2
✓ Branch 0 taken 2554917 times.
✓ Branch 1 taken 124 times.
2555041 if (IS_NUMBER(a)) {
568
2/2
✓ Branch 0 taken 2554915 times.
✓ Branch 1 taken 2554803 times.
5109718 for (lbm_uint i = 1; i < nargs; i ++) {
569 2554915 lbm_uint b = args[i];
570
2/2
✓ Branch 0 taken 2554801 times.
✓ Branch 1 taken 114 times.
2554915 if (IS_NUMBER(b)) {
571
3/4
✓ Branch 0 taken 2554801 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20947 times.
✓ Branch 3 taken 2533854 times.
2554801 r = r && (compare_num(a, b) >= 0);
572 } else {
573 114 lbm_set_error_suspect(b);
574 114 goto geq_type_error;
575 }
576 }
577 } else {
578 124 lbm_set_error_suspect(a);
579 124 goto geq_type_error;
580 }
581
2/2
✓ Branch 0 taken 20949 times.
✓ Branch 1 taken 2533854 times.
2554803 if (r) {
582 20949 return ENC_SYM_TRUE;
583 } else {
584 2533854 return ENC_SYM_NIL;
585 }
586 238 geq_type_error:
587 238 return ENC_SYM_TERROR;
588 }
589
590 2554122 static lbm_value fundamental_lt(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
591 2554122 lbm_value r = fundamental_geq(args, nargs, ctx);
592
2/2
✓ Branch 0 taken 2533742 times.
✓ Branch 1 taken 20380 times.
2554122 if (r == ENC_SYM_NIL) r = ENC_SYM_TRUE;
593
2/2
✓ Branch 0 taken 20261 times.
✓ Branch 1 taken 119 times.
20380 else if (r == ENC_SYM_TRUE) r = ENC_SYM_NIL;
594 2554122 return r;
595 }
596
597 84776246 static lbm_value fundamental_gt(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
598 84776246 lbm_value r = fundamental_leq(args, nargs, ctx);
599
2/2
✓ Branch 0 taken 74579076 times.
✓ Branch 1 taken 10197170 times.
84776246 if (r == ENC_SYM_NIL) r = ENC_SYM_TRUE;
600
2/2
✓ Branch 0 taken 10197051 times.
✓ Branch 1 taken 119 times.
10197170 else if (r == ENC_SYM_TRUE) r = ENC_SYM_NIL;
601 84776246 return r;
602 }
603
604 4069 static lbm_value fundamental_not(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
605 (void) ctx;
606
2/2
✓ Branch 0 taken 3957 times.
✓ Branch 1 taken 112 times.
4069 if (nargs == 1) {
607
2/2
✓ Branch 0 taken 1986 times.
✓ Branch 1 taken 1971 times.
3957 return args[0] ? ENC_SYM_NIL : ENC_SYM_TRUE;
608 }
609 112 return ENC_SYM_EERROR;
610 }
611
612 26490 static lbm_value fundamental_gc(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
613 (void) args;
614 (void) nargs;
615 (void) ctx;
616 26490 lbm_perform_gc();
617 26490 return ENC_SYM_TRUE;
618 }
619
620 6888 static lbm_value fundamental_self(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
621 (void) args;
622 (void) nargs;
623 (void) ctx;
624 6888 return lbm_enc_i(ctx->id);
625 }
626
627 448 static lbm_value fundamental_set_mailbox_size(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
628 448 lbm_value r = ENC_SYM_EERROR;
629
2/2
✓ Branch 0 taken 336 times.
✓ Branch 1 taken 112 times.
448 if (nargs == 1) {
630
2/2
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 56 times.
336 if (IS_NUMBER(args[0])) {
631 280 uint32_t s = lbm_dec_as_u32(args[0]);
632
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 56 times.
280 if (lbm_mailbox_change_size(ctx, s)) {
633 224 r = ENC_SYM_TRUE;
634 } else {
635 56 r = ENC_SYM_NIL;
636 }
637 } else {
638 56 r = ENC_SYM_TERROR;
639 }
640 }
641 448 return r;
642 }
643
644 2794 static lbm_value fundamental_cons(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
645 (void) ctx;
646 2794 lbm_value r = ENC_SYM_EERROR;
647
2/2
✓ Branch 0 taken 2622 times.
✓ Branch 1 taken 172 times.
2794 if (nargs == 2) {
648 2622 lbm_uint a = args[0];
649 2622 lbm_uint b = args[1];
650 2622 r = lbm_cons(a,b);
651 }
652 2794 return r;
653 }
654
655 36349 static lbm_value fundamental_car(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
656 (void) ctx;
657 36349 lbm_value r = ENC_SYM_EERROR;
658
2/2
✓ Branch 0 taken 36235 times.
✓ Branch 1 taken 114 times.
36349 if (nargs == 1) {
659
2/2
✓ Branch 0 taken 35162 times.
✓ Branch 1 taken 1073 times.
36235 if (lbm_is_cons(args[0])) {
660 35162 lbm_cons_t *cell = lbm_ref_cell(args[0]);
661 35162 r = cell->car;
662
2/2
✓ Branch 0 taken 898 times.
✓ Branch 1 taken 175 times.
1073 } else if (lbm_is_symbol_nil(args[0])) {
663 898 r = ENC_SYM_NIL;
664 } else {
665 175 r = ENC_SYM_TERROR;
666 }
667 }
668 36349 return r;
669 }
670
671 46831 static lbm_value fundamental_cdr(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
672 (void) ctx;
673 46831 lbm_value r = ENC_SYM_EERROR;
674
2/2
✓ Branch 0 taken 46717 times.
✓ Branch 1 taken 114 times.
46831 if (nargs == 1) {
675
2/2
✓ Branch 0 taken 45645 times.
✓ Branch 1 taken 1072 times.
46717 if (lbm_is_cons(args[0])) {
676 45645 lbm_cons_t *cell = lbm_ref_cell(args[0]);
677 45645 r = cell->cdr;
678
2/2
✓ Branch 0 taken 898 times.
✓ Branch 1 taken 174 times.
1072 } else if (lbm_is_symbol_nil(args[0])) {
679 898 r = ENC_SYM_NIL;
680 } else {
681 174 r = ENC_SYM_TERROR;
682 }
683 }
684 46831 return r;
685 }
686
687 173359 static lbm_value fundamental_list(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
688 (void) ctx;
689 173359 lbm_value result = ENC_SYM_NIL;
690
2/2
✓ Branch 0 taken 264017 times.
✓ Branch 1 taken 173231 times.
437248 for (lbm_uint i = 1; i <= nargs; i ++) {
691 264017 result = lbm_cons(args[nargs-i], result);
692 // This check may be a mostly useless optimisation.
693 // Only triggers in case of running out of heap here.
694
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 263889 times.
264017 if (lbm_type_of(result) == LBM_TYPE_SYMBOL)
695 128 break;
696 }
697 173359 return result;
698 }
699
700 95302 static lbm_value fundamental_append(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
701 (void) ctx;
702
2/2
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 95245 times.
95302 if (nargs == 0) return ENC_SYM_NIL;
703
4/4
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 95132 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 57 times.
95245 if (nargs == 1 && !lbm_is_list(args[0])) {
704 56 lbm_set_error_suspect(args[0]);
705 56 return ENC_SYM_TERROR;
706 }
707 95189 lbm_value res = args[nargs-1];
708
2/2
✓ Branch 0 taken 119439 times.
✓ Branch 1 taken 95129 times.
214568 for (int i = (int)nargs -2; i >= 0; i --) {
709 119439 lbm_value curr = args[i];
710
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 119379 times.
119439 if (!lbm_is_list(curr)) {
711 60 lbm_set_error_suspect(curr);
712 60 return ENC_SYM_TERROR;
713 }
714 119379 int n = 0;
715
2/2
✓ Branch 0 taken 143917 times.
✓ Branch 1 taken 119379 times.
263296 while (lbm_type_of_functional(curr) == LBM_TYPE_CONS) {
716 143917 n++;
717 143917 curr = lbm_cdr(curr);
718 }
719 119379 curr = args[i];
720
2/2
✓ Branch 0 taken 143917 times.
✓ Branch 1 taken 119379 times.
263296 for (int j = n-1; j >= 0; j --) {
721 143917 res = lbm_cons(lbm_index_list(curr,j),res);
722 }
723 }
724 95129 return(res);
725 }
726
727 3360449 static lbm_value fundamental_undefine(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
728 (void) ctx;
729 3360449 lbm_value *global_env = lbm_get_global_env();
730
3/4
✓ Branch 0 taken 3360449 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3360337 times.
✓ Branch 3 taken 112 times.
3360449 if (nargs == 1 && lbm_is_symbol(args[0])) {
731 3360337 lbm_value key = args[0];
732 3360337 lbm_uint ix_key = lbm_dec_sym(key) & GLOBAL_ENV_MASK;
733 3360337 lbm_value env = global_env[ix_key];
734 3360337 lbm_value res = lbm_env_drop_binding(env, key);
735
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 3360281 times.
3360337 if (res == ENC_SYM_NOT_FOUND) {
736 56 return ENC_SYM_NIL;
737 }
738 3360281 global_env[ix_key] = res;
739 3360281 return ENC_SYM_TRUE;
740
2/4
✓ Branch 0 taken 112 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
112 } else if (nargs == 1 && lbm_is_cons(args[0])) {
741 112 lbm_value curr = args[0];
742
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 112 times.
336 while (lbm_type_of(curr) == LBM_TYPE_CONS) {
743 224 lbm_value key = lbm_car(curr);
744 224 lbm_uint ix_key = lbm_dec_sym(key) & GLOBAL_ENV_MASK;
745 224 lbm_value env = global_env[ix_key];
746 224 lbm_value res = lbm_env_drop_binding(env, key);
747
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 112 times.
224 if (res != ENC_SYM_NOT_FOUND) {
748 112 global_env[ix_key] = res;
749 }
750 224 curr = lbm_cdr(curr);
751 }
752 112 return ENC_SYM_TRUE;
753 }
754 return ENC_SYM_TERROR;
755 }
756
757 157450 static lbm_value fundamental_buf_create(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
758 (void) ctx;
759 157450 lbm_value result = ENC_SYM_EERROR;
760
4/4
✓ Branch 0 taken 45338 times.
✓ Branch 1 taken 112112 times.
✓ Branch 2 taken 45282 times.
✓ Branch 3 taken 56 times.
157450 if (nargs == 1 && IS_NUMBER(args[0])) {
761 45282 lbm_heap_allocate_array(&result, lbm_dec_as_u32(args[0]));
762
5/6
✓ Branch 0 taken 112056 times.
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 112056 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 112000 times.
✓ Branch 5 taken 56 times.
112168 } else if (nargs == 2 && IS_NUMBER(args[1]) && lbm_type_of(args[0]) == LBM_TYPE_DEFRAG_MEM) {
763 112000 lbm_uint *dm = (lbm_uint*)lbm_car(args[0]);
764 112000 return lbm_defrag_mem_alloc(dm, lbm_dec_as_uint(args[1]));
765 }
766 45450 return result;
767 }
768
769 234 static lbm_value fundamental_symbol_to_string(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
770 (void) ctx;
771 234 lbm_value res = ENC_SYM_EERROR;
772
2/2
✓ Branch 0 taken 176 times.
✓ Branch 1 taken 58 times.
234 if (nargs == 1) {
773
2/2
✓ Branch 0 taken 115 times.
✓ Branch 1 taken 61 times.
176 if (lbm_type_of_functional(args[0]) == LBM_TYPE_SYMBOL) {
774 115 lbm_value sym = args[0];
775 115 const char *sym_str = lbm_get_name_by_symbol(lbm_dec_sym(sym));
776
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 115 times.
115 if (sym_str == NULL) return ENC_SYM_NIL;
777 115 size_t len = strlen(sym_str);
778 lbm_value v;
779
1/2
✓ Branch 0 taken 115 times.
✗ Branch 1 not taken.
115 if (lbm_heap_allocate_array(&v, len+1)) {
780 115 lbm_array_header_t *arr = (lbm_array_header_t*)lbm_car(v);
781 115 memset(arr->data,0,len+1);
782 115 memcpy(arr->data,sym_str,len);
783 115 res = v;
784 } else {
785 res = ENC_SYM_MERROR;
786 }
787 } else {
788 61 res = ENC_SYM_TERROR;
789 }
790 }
791 234 return res;
792 }
793
794 233 static lbm_value fundamental_string_to_symbol(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
795 (void) ctx;
796 233 lbm_value result = ENC_SYM_EERROR;
797
2/2
✓ Branch 0 taken 175 times.
✓ Branch 1 taken 58 times.
233 if (nargs == 1) {
798 175 result = ENC_SYM_TERROR;
799 175 lbm_array_header_t *arr = lbm_dec_array_r(args[0]);
800
2/2
✓ Branch 0 taken 115 times.
✓ Branch 1 taken 60 times.
175 if (arr) {
801 // TODO: String to symbol, string should be in LBM_memory..
802 // Some better sanity check is possible here.
803 // Check that array points into lbm_memory.
804 // Additionally check that it is a zero-terminated string.
805 115 char *str = (char *)arr->data;
806 115 lbm_uint sym = ENC_SYM_NIL;
807 115 lbm_str_to_symbol(str,&sym);
808 115 result = lbm_enc_sym(sym);
809 }
810 }
811 233 return result;
812 }
813
814 280 static lbm_value fundamental_symbol_to_uint(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
815 (void) ctx;
816
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 224 times.
280 if (nargs < 1) return ENC_SYM_EERROR;
817 224 lbm_value s = args[0];
818
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 56 times.
224 if (lbm_is_symbol(s))
819 168 return lbm_enc_u(lbm_dec_sym(s));
820
821 56 lbm_set_error_suspect(s);
822 56 return ENC_SYM_TERROR;
823 }
824
825 224 static lbm_value fundamental_uint_to_symbol(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
826 (void) ctx;
827
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 168 times.
224 if (nargs < 1) return ENC_SYM_EERROR;
828 168 lbm_value s = args[0];
829
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 56 times.
168 if (lbm_type_of_functional(s) == LBM_TYPE_U)
830 112 return lbm_enc_sym(lbm_dec_u(s));
831
832 56 lbm_set_error_suspect(s);
833 56 return ENC_SYM_TERROR;
834 }
835
836 224 static lbm_value fundamental_set_car(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
837 (void) ctx;
838 224 lbm_value res = ENC_SYM_EERROR;
839
1/2
✓ Branch 0 taken 224 times.
✗ Branch 1 not taken.
224 if (nargs == 2) {
840
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 56 times.
224 res = lbm_set_car(args[0], args[1]) ? ENC_SYM_TRUE : ENC_SYM_NIL;
841 }
842 224 return res;
843 }
844
845 226 static lbm_value fundamental_set_cdr(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
846 (void) ctx;
847 226 lbm_value res = ENC_SYM_EERROR;
848
1/2
✓ Branch 0 taken 226 times.
✗ Branch 1 not taken.
226 if (nargs == 2) {
849
2/2
✓ Branch 0 taken 170 times.
✓ Branch 1 taken 56 times.
226 res = lbm_set_cdr(args[0],args[1]) ? ENC_SYM_TRUE : ENC_SYM_NIL;
850 }
851 226 return res;
852 }
853
854 1123485 static lbm_value fundamental_set_ix(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
855 (void) ctx;
856 1123485 lbm_value result = ENC_SYM_TERROR;
857
4/4
✓ Branch 0 taken 1123483 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1123482 times.
✓ Branch 3 taken 1 times.
1123485 if (nargs == 3 && IS_NUMBER(args[1])) {
858
2/2
✓ Branch 0 taken 232 times.
✓ Branch 1 taken 1123250 times.
1123482 if (lbm_is_list_rw(args[0])) {
859 232 lbm_value curr = args[0];
860 232 lbm_uint i = 0;
861 232 lbm_int ix_pre = lbm_dec_as_i32(args[1]);
862
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 232 times.
232 if (ix_pre < 0) {
863 lbm_int len = (lbm_int)lbm_list_length(args[0]);
864 ix_pre = len + ix_pre;
865 }
866 232 lbm_uint ix = (lbm_uint)ix_pre;
867
2/2
✓ Branch 0 taken 921 times.
✓ Branch 1 taken 1 times.
922 while (lbm_is_cons_rw(curr)) { // rw as we are going to modify
868 921 lbm_value next = lbm_cdr(curr);
869
2/2
✓ Branch 0 taken 175 times.
✓ Branch 1 taken 746 times.
921 if (i == ix) {
870 175 lbm_set_car(curr, args[2]);
871 175 result = args[0]; // Acts as true and as itself.
872 175 break;
873
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 690 times.
746 } else if (lbm_is_symbol_nil(next)) {
874 56 result = ENC_SYM_NIL; // index out of bounds, no update.
875 56 break;
876 }
877 690 curr = next;
878 690 i++;
879 }
880
1/2
✓ Branch 0 taken 1123250 times.
✗ Branch 1 not taken.
1123250 } else if (lbm_is_lisp_array_rw(args[0])) {
881 1123250 int32_t index = lbm_dec_as_i32(args[1]);
882 1123250 lbm_array_header_t *header = (lbm_array_header_t*)lbm_car(args[0]);
883 1123250 lbm_value *arrdata = (lbm_value*)header->data;
884 1123250 lbm_uint size = header->size / sizeof(lbm_value);
885
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1123249 times.
1123250 if (index < 0) index = (int32_t)size + index;
886
1/2
✓ Branch 0 taken 1123250 times.
✗ Branch 1 not taken.
1123250 if ((uint32_t)index < size) {
887 1123250 arrdata[index] = args[2]; // value
888 1123250 result = args[0];
889 } // index out of range will be eval error.
890 }
891 }
892 1123485 return result;
893 }
894
895 863 static lbm_value fundamental_assoc(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
896 (void) ctx;
897 863 lbm_value result = ENC_SYM_EERROR;
898
2/2
✓ Branch 0 taken 805 times.
✓ Branch 1 taken 58 times.
863 if (nargs == 2) {
899
2/2
✓ Branch 0 taken 686 times.
✓ Branch 1 taken 119 times.
805 if (lbm_is_cons(args[0])) {
900 686 lbm_value r = assoc_lookup(args[1], args[0]);
901
4/4
✓ Branch 0 taken 616 times.
✓ Branch 1 taken 70 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 560 times.
686 if (lbm_is_symbol(r) &&
902 r == ENC_SYM_NO_MATCH) {
903 56 result = ENC_SYM_NIL;
904 } else {
905 630 result = r;
906 }
907
2/2
✓ Branch 0 taken 118 times.
✓ Branch 1 taken 1 times.
119 } else if (lbm_is_symbol(args[0]) &&
908
2/2
✓ Branch 0 taken 61 times.
✓ Branch 1 taken 57 times.
118 args[0] == ENC_SYM_NIL) {
909 61 result = args[0]; /* nil */
910 } /* else error */
911 }
912 863 return result;
913 }
914
915 260156 static lbm_value fundamental_acons(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
916 (void) ctx;
917 260156 lbm_value result = ENC_SYM_TERROR;
918
2/2
✓ Branch 0 taken 259988 times.
✓ Branch 1 taken 168 times.
260156 if (nargs == 3) {
919 259988 lbm_value keyval = lbm_cons(args[0], args[1]);
920 259988 lbm_value new_alist = lbm_cons(keyval, args[2]);
921
922
4/4
✓ Branch 0 taken 259652 times.
✓ Branch 1 taken 336 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 259624 times.
519640 if (lbm_is_symbol(keyval) ||
923 259652 lbm_is_symbol(new_alist) )
924 364 result = ENC_SYM_MERROR;
925 else
926 259624 result = new_alist;
927
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 168 times.
168 } else if (nargs == 2) {
928 result = lbm_cons(args[0], args[1]);
929 }
930 260156 return result;
931 }
932
933 228 static lbm_value set_assoc(lbm_value assoc_list, lbm_value keyval) {
934 228 lbm_value curr = assoc_list;
935 228 lbm_value key = lbm_car(keyval);
936
2/2
✓ Branch 0 taken 448 times.
✓ Branch 1 taken 60 times.
508 while (lbm_is_cons(curr)) {
937
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 280 times.
448 if (struct_eq(key, lbm_caar(curr))) {
938 168 lbm_set_car(curr, keyval);
939 168 return assoc_list;
940 }
941 280 curr = lbm_cdr(curr);
942 }
943 // Assoc-list does not contain key.
944 // Note: Memory errors are implicitly handled by the caller.
945 60 return lbm_cons(keyval, assoc_list);
946 }
947
948 228 static lbm_value fundamental_set_assoc(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
949 (void)ctx;
950 lbm_value keyval;
951
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 60 times.
228 if (nargs == 3) {
952 168 keyval = lbm_cons(args[1], args[2]);
953 // Check if ENC_SYM_MERROR.
954
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 168 times.
168 if (lbm_is_symbol(keyval)) return keyval;
955
2/4
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60 times.
✗ Branch 3 not taken.
60 } else if (nargs == 2 && lbm_is_cons(args[1])) {
956 60 keyval = args[1];
957 } else return ENC_SYM_TERROR;
958 228 return set_assoc(args[0], keyval);
959 }
960
961 840 static lbm_value fundamental_cossa(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
962 (void) ctx;
963 840 lbm_value result = ENC_SYM_EERROR;
964
2/2
✓ Branch 0 taken 784 times.
✓ Branch 1 taken 56 times.
840 if (nargs == 2) {
965
2/2
✓ Branch 0 taken 672 times.
✓ Branch 1 taken 112 times.
784 if (lbm_is_cons(args[0])) {
966 672 lbm_value r = cossa_lookup(args[1], args[0]);
967
4/4
✓ Branch 0 taken 448 times.
✓ Branch 1 taken 224 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 392 times.
672 if (lbm_is_symbol(r) &&
968 r == ENC_SYM_NO_MATCH) {
969 56 result = ENC_SYM_NIL;
970 } else {
971 616 result = r;
972 }
973
1/2
✓ Branch 0 taken 112 times.
✗ Branch 1 not taken.
112 } else if (lbm_is_symbol(args[0]) &&
974
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 56 times.
112 args[0] == ENC_SYM_NIL) {
975 56 result = args[0]; /* nil */
976 } /* else error */
977 }
978 840 return result;
979 }
980
981 63478 static lbm_value fundamental_ix(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
982 (void) ctx;
983 63478 lbm_value result = ENC_SYM_EERROR;
984
4/4
✓ Branch 0 taken 63476 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 63473 times.
✓ Branch 3 taken 3 times.
63478 if (nargs == 2 && IS_NUMBER(args[1])) {
985 63473 result = ENC_SYM_NIL;
986
2/2
✓ Branch 0 taken 45666 times.
✓ Branch 1 taken 17807 times.
63473 if (lbm_is_list(args[0])) {
987 45666 result = lbm_index_list(args[0], lbm_dec_as_i32(args[1]));
988
2/2
✓ Branch 0 taken 17801 times.
✓ Branch 1 taken 6 times.
17807 } else if (lbm_is_lisp_array_r(args[0])) {
989 17801 lbm_array_header_t *header = (lbm_array_header_t*)lbm_car(args[0]);
990 17801 lbm_value *arrdata = (lbm_value*)header->data;
991 17801 lbm_uint size = header->size / sizeof(lbm_value);
992 17801 int32_t index = lbm_dec_as_i32(args[1]);
993
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 17800 times.
17801 if (index < 0) index = (int32_t)size + index;
994
1/2
✓ Branch 0 taken 17801 times.
✗ Branch 1 not taken.
17801 if ((uint32_t)index < size) {
995 17801 result = arrdata[index];
996 }
997 }
998 }
999 63478 return result;
1000 }
1001
1002 592 static lbm_value fundamental_to_i(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1003 (void) ctx;
1004 592 lbm_value result = ENC_SYM_EERROR;
1005
2/2
✓ Branch 0 taken 534 times.
✓ Branch 1 taken 58 times.
592 if (nargs == 1) {
1006 534 result = lbm_enc_i((lbm_int)lbm_dec_as_i64(args[0]));
1007 }
1008 592 return result;
1009 }
1010
1011 672 static lbm_value fundamental_to_i32(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1012 (void) ctx;
1013 672 lbm_value result = ENC_SYM_EERROR;
1014
2/2
✓ Branch 0 taken 616 times.
✓ Branch 1 taken 56 times.
672 if (nargs == 1) {
1015 616 result = lbm_enc_i32(lbm_dec_as_i32(args[0]));
1016 }
1017 672 return result;
1018 }
1019
1020 560 static lbm_value fundamental_to_u(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1021 (void) ctx;
1022 560 lbm_value result = ENC_SYM_EERROR;
1023
2/2
✓ Branch 0 taken 504 times.
✓ Branch 1 taken 56 times.
560 if (nargs == 1) {
1024 504 result = lbm_enc_u((lbm_uint)lbm_dec_as_u64(args[0]));
1025 }
1026 560 return result;
1027 }
1028
1029 560 static lbm_value fundamental_to_u32(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1030 (void) ctx;
1031 560 lbm_value result = ENC_SYM_EERROR;
1032
2/2
✓ Branch 0 taken 504 times.
✓ Branch 1 taken 56 times.
560 if (nargs == 1) {
1033 504 result = lbm_enc_u32(lbm_dec_as_u32(args[0]));
1034 }
1035 560 return result;
1036 }
1037
1038 516 static lbm_value fundamental_to_float(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1039 (void) ctx;
1040 516 lbm_value result = ENC_SYM_EERROR;
1041
2/2
✓ Branch 0 taken 458 times.
✓ Branch 1 taken 58 times.
516 if (nargs == 1) {
1042 458 result = lbm_enc_float(lbm_dec_as_float(args[0]));
1043 }
1044 516 return result;
1045 }
1046
1047 560 static lbm_value fundamental_to_i64(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1048 (void) ctx;
1049 560 lbm_value result = ENC_SYM_EERROR;
1050
2/2
✓ Branch 0 taken 504 times.
✓ Branch 1 taken 56 times.
560 if (nargs == 1) {
1051 504 result = lbm_enc_i64(lbm_dec_as_i64(args[0]));
1052 }
1053 560 return result;
1054 }
1055
1056 560 static lbm_value fundamental_to_u64(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1057 (void) ctx;
1058 560 lbm_value result = ENC_SYM_EERROR;
1059
2/2
✓ Branch 0 taken 504 times.
✓ Branch 1 taken 56 times.
560 if (nargs == 1) {
1060 504 result = lbm_enc_u64(lbm_dec_as_u64(args[0]));
1061 }
1062 560 return result;
1063 }
1064
1065 504 static lbm_value fundamental_to_double(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1066 (void) ctx;
1067 504 lbm_value result = ENC_SYM_EERROR;
1068
2/2
✓ Branch 0 taken 448 times.
✓ Branch 1 taken 56 times.
504 if (nargs == 1) {
1069 448 result = lbm_enc_double(lbm_dec_as_double(args[0]));
1070 }
1071 504 return result;
1072 }
1073
1074 513 static lbm_value fundamental_to_byte(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1075 (void) ctx;
1076 513 lbm_value result = ENC_SYM_EERROR;
1077
2/2
✓ Branch 0 taken 457 times.
✓ Branch 1 taken 56 times.
513 if (nargs == 1) {
1078 457 result = lbm_enc_char(lbm_dec_as_char(args[0]));
1079 }
1080 513 return result;
1081 }
1082
1083 673 static lbm_value fundamental_shl(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1084 (void) ctx;
1085 673 lbm_value retval = ENC_SYM_EERROR;
1086
2/2
✓ Branch 0 taken 617 times.
✓ Branch 1 taken 56 times.
673 if (nargs == 2) {
1087 617 retval = ENC_SYM_TERROR;
1088
4/4
✓ Branch 0 taken 561 times.
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 505 times.
✓ Branch 3 taken 56 times.
617 if (IS_NUMBER(args[0]) && IS_NUMBER(args[1])) {
1089
8/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 56 times.
✓ Branch 4 taken 56 times.
✓ Branch 5 taken 56 times.
✓ Branch 6 taken 56 times.
✓ Branch 7 taken 112 times.
505 switch (lbm_type_of_functional(args[0])) {
1090 1 case LBM_TYPE_CHAR: retval = lbm_enc_char(lbm_dec_char(args[0]) << lbm_dec_as_u32(args[1])); break;
1091 112 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) << lbm_dec_as_u32(args[1])); break;
1092 56 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) << lbm_dec_as_u32(args[1])); break;
1093 56 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_u32(args[0]) << lbm_dec_as_u32(args[1])); break;
1094 56 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_i32(args[0]) << lbm_dec_as_u32(args[1])); break;
1095 56 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_i64(args[0]) << lbm_dec_as_u32(args[1])); break;
1096 56 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_u64(args[0]) << lbm_dec_as_u32(args[1])); break;
1097 }
1098 }
1099 }
1100 673 return retval;
1101 }
1102
1103 673 static lbm_value fundamental_shr(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1104 (void) ctx;
1105 673 lbm_value retval = ENC_SYM_EERROR;
1106
2/2
✓ Branch 0 taken 617 times.
✓ Branch 1 taken 56 times.
673 if (nargs == 2) {
1107 617 retval = ENC_SYM_TERROR;
1108
4/4
✓ Branch 0 taken 561 times.
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 505 times.
✓ Branch 3 taken 56 times.
617 if (IS_NUMBER(args[0]) && IS_NUMBER(args[1])) {
1109
8/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 56 times.
✓ Branch 4 taken 56 times.
✓ Branch 5 taken 56 times.
✓ Branch 6 taken 56 times.
✓ Branch 7 taken 112 times.
505 switch (lbm_type_of_functional(args[0])) {
1110 1 case LBM_TYPE_CHAR: retval = lbm_enc_char(lbm_dec_char(args[0]) >> lbm_dec_as_u32(args[1])); break;
1111 112 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) >> lbm_dec_as_u32(args[1])); break;
1112 56 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) >> lbm_dec_as_u32(args[1])); break;
1113 56 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_u32(args[0]) >> lbm_dec_as_u32(args[1])); break;
1114 56 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_i32(args[0]) >> lbm_dec_as_u32(args[1])); break;
1115 56 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_i64(args[0]) >> lbm_dec_as_u32(args[1])); break;
1116 56 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_u64(args[0]) >> lbm_dec_as_u32(args[1])); break;
1117 }
1118 }
1119 }
1120 673 return retval;
1121 }
1122
1123 673 static lbm_value fundamental_bitwise_and(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1124 (void) ctx;
1125 673 lbm_value retval = ENC_SYM_EERROR;
1126
2/2
✓ Branch 0 taken 617 times.
✓ Branch 1 taken 56 times.
673 if (nargs == 2) {
1127 617 retval = ENC_SYM_TERROR;
1128
4/4
✓ Branch 0 taken 561 times.
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 505 times.
✓ Branch 3 taken 56 times.
617 if (IS_NUMBER(args[0]) && IS_NUMBER(args[1])) {
1129
8/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 56 times.
✓ Branch 4 taken 56 times.
✓ Branch 5 taken 56 times.
✓ Branch 6 taken 56 times.
✓ Branch 7 taken 112 times.
505 switch (lbm_type_of_functional(args[0])) {
1130 1 case LBM_TYPE_CHAR: retval = lbm_enc_char(lbm_dec_char(args[0]) & lbm_dec_as_char(args[1])); break;
1131 #ifdef LBM64
1132 56 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) & lbm_dec_as_i64(args[1])); break;
1133 28 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) & lbm_dec_as_u64(args[1])); break;
1134 #else
1135 56 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) & lbm_dec_as_i32(args[1])); break;
1136 28 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) & lbm_dec_as_u32(args[1])); break;
1137 #endif
1138 56 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_u32(args[0]) & lbm_dec_as_u32(args[1])); break;
1139 56 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_i32(args[0]) & lbm_dec_as_i32(args[1])); break;
1140 56 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_i64(args[0]) & lbm_dec_as_i64(args[1])); break;
1141 56 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_u64(args[0]) & lbm_dec_as_u64(args[1])); break;
1142 }
1143 }
1144 }
1145 673 return retval;
1146 }
1147
1148 673 static lbm_value fundamental_bitwise_or(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1149 (void) ctx;
1150 673 lbm_value retval = ENC_SYM_EERROR;
1151
2/2
✓ Branch 0 taken 617 times.
✓ Branch 1 taken 56 times.
673 if (nargs == 2) {
1152 617 retval = ENC_SYM_TERROR;
1153
4/4
✓ Branch 0 taken 561 times.
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 505 times.
✓ Branch 3 taken 56 times.
617 if (IS_NUMBER(args[0]) && IS_NUMBER(args[1])) {
1154
8/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 56 times.
✓ Branch 4 taken 56 times.
✓ Branch 5 taken 56 times.
✓ Branch 6 taken 56 times.
✓ Branch 7 taken 112 times.
505 switch (lbm_type_of_functional(args[0])) {
1155 1 case LBM_TYPE_CHAR: retval = lbm_enc_char(lbm_dec_char(args[0]) | lbm_dec_as_char(args[1])); break;
1156 #ifdef LBM64
1157 56 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) | lbm_dec_as_i64(args[1])); break;
1158 28 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) | lbm_dec_as_u64(args[1])); break;
1159 #else
1160 56 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) | lbm_dec_as_i32(args[1])); break;
1161 28 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) | lbm_dec_as_u32(args[1])); break;
1162 #endif
1163 56 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_u32(args[0]) | lbm_dec_as_u32(args[1])); break;
1164 56 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_i32(args[0]) | lbm_dec_as_i32(args[1])); break;
1165 56 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_i64(args[0]) | lbm_dec_as_i64(args[1])); break;
1166 56 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_u64(args[0]) | lbm_dec_as_u64(args[1])); break;
1167 }
1168 }
1169 }
1170 673 return retval;
1171 }
1172
1173 673 static lbm_value fundamental_bitwise_xor(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1174 (void) ctx;
1175 673 lbm_value retval = ENC_SYM_EERROR;
1176
2/2
✓ Branch 0 taken 617 times.
✓ Branch 1 taken 56 times.
673 if (nargs == 2) {
1177 617 retval = ENC_SYM_TERROR;
1178
4/4
✓ Branch 0 taken 561 times.
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 505 times.
✓ Branch 3 taken 56 times.
617 if (IS_NUMBER(args[0]) && IS_NUMBER(args[1])) {
1179
8/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 56 times.
✓ Branch 4 taken 56 times.
✓ Branch 5 taken 56 times.
✓ Branch 6 taken 56 times.
✓ Branch 7 taken 112 times.
505 switch (lbm_type_of_functional(args[0])) {
1180 1 case LBM_TYPE_CHAR: retval = lbm_enc_char(lbm_dec_char(args[0]) ^ lbm_dec_as_char(args[1])); break;
1181 #ifdef LBM64
1182 56 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) ^ lbm_dec_as_i64(args[1])); break;
1183 28 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) ^ lbm_dec_as_u64(args[1])); break;
1184 #else
1185 56 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) ^ lbm_dec_as_i32(args[1])); break;
1186 28 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) ^ lbm_dec_as_u32(args[1])); break;
1187 #endif
1188 56 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_u32(args[0]) ^ lbm_dec_as_u32(args[1])); break;
1189 56 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_i32(args[0]) ^ lbm_dec_as_i32(args[1])); break;
1190 56 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_i64(args[0]) ^ lbm_dec_as_i64(args[1])); break;
1191 56 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_u64(args[0]) ^ lbm_dec_as_u64(args[1])); break;
1192 }
1193 }
1194 }
1195 673 return retval;
1196 }
1197
1198 561 static lbm_value fundamental_bitwise_not(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1199 (void) ctx;
1200 561 lbm_value retval = ENC_SYM_EERROR;
1201
2/2
✓ Branch 0 taken 505 times.
✓ Branch 1 taken 56 times.
561 if (nargs == 1) {
1202 505 retval = ENC_SYM_TERROR;
1203
2/2
✓ Branch 0 taken 449 times.
✓ Branch 1 taken 56 times.
505 if (IS_NUMBER(args[0])) {
1204
8/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 56 times.
✓ Branch 4 taken 56 times.
✓ Branch 5 taken 56 times.
✓ Branch 6 taken 56 times.
✓ Branch 7 taken 112 times.
449 switch (lbm_type_of_functional(args[0])) {
1205 1 case LBM_TYPE_CHAR: retval = lbm_enc_char(~lbm_dec_char(args[0])); break;
1206 56 case LBM_TYPE_I: retval = lbm_enc_i(~lbm_dec_i(args[0])); break;
1207 56 case LBM_TYPE_U: retval = lbm_enc_u(~lbm_dec_u(args[0])); break;
1208 56 case LBM_TYPE_U32: retval = lbm_enc_u32(~lbm_dec_u32(args[0])); break;
1209 56 case LBM_TYPE_I32: retval = lbm_enc_i32(~lbm_dec_i32(args[0])); break;
1210 56 case LBM_TYPE_I64: retval = lbm_enc_i64(~lbm_dec_i64(args[0])); break;
1211 56 case LBM_TYPE_U64: retval = lbm_enc_u64(~lbm_dec_u64(args[0])); break;
1212 }
1213 }
1214 }
1215 561 return retval;
1216 }
1217
1218 static lbm_value fundamental_custom_destruct(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1219 (void) ctx;
1220 lbm_value result = ENC_SYM_EERROR;
1221 if (nargs == 1 && (lbm_type_of(args[0]) == LBM_TYPE_CUSTOM)) {
1222 lbm_uint *mem_ptr = (lbm_uint*)lbm_dec_custom(args[0]);
1223 if(!mem_ptr) return ENC_SYM_FATAL_ERROR;
1224 lbm_custom_type_destroy(mem_ptr);
1225 lbm_value tmp = lbm_set_ptr_type(args[0], LBM_TYPE_CONS);
1226 lbm_set_car(tmp, ENC_SYM_NIL);
1227 lbm_set_cdr(tmp, ENC_SYM_NIL);
1228 // The original value will still be of type custom_ptr
1229 result = ENC_SYM_TRUE;
1230 }
1231 return result;
1232 }
1233
1234 33795 static lbm_value fundamental_type_of(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1235 (void) ctx;
1236 33795 lbm_value res = ENC_SYM_EERROR;
1237
2/2
✓ Branch 0 taken 33793 times.
✓ Branch 1 taken 2 times.
33795 if (nargs == 1) {
1238 33793 lbm_value val = args[0];
1239 33793 lbm_type t = lbm_type_of(val);
1240
1241
2/2
✓ Branch 0 taken 19101 times.
✓ Branch 1 taken 14692 times.
33793 if (lbm_is_ptr(val)) {
1242 // Ignore constant or not constant.
1243 19101 t &= LBM_PTR_TO_CONSTANT_MASK;
1244 }
1245
13/16
✓ Branch 0 taken 10532 times.
✓ Branch 1 taken 225 times.
✓ Branch 2 taken 1064 times.
✓ Branch 3 taken 1400 times.
✓ Branch 4 taken 3584 times.
✓ Branch 5 taken 1344 times.
✓ Branch 6 taken 1568 times.
✓ Branch 7 taken 2128 times.
✓ Branch 8 taken 2536 times.
✓ Branch 9 taken 6709 times.
✓ Branch 10 taken 112 times.
✓ Branch 11 taken 2535 times.
✓ Branch 12 taken 56 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
33793 switch(t) {
1246 10532 case LBM_TYPE_CONS: res = ENC_SYM_TYPE_LIST; break;
1247 225 case LBM_TYPE_ARRAY: res = ENC_SYM_TYPE_ARRAY; break;
1248 1064 case LBM_TYPE_I32: res = ENC_SYM_TYPE_I32; break;
1249 1400 case LBM_TYPE_U32: res = ENC_SYM_TYPE_U32; break;
1250 3584 case LBM_TYPE_FLOAT: res = ENC_SYM_TYPE_FLOAT; break;
1251 1344 case LBM_TYPE_I64: res = ENC_SYM_TYPE_I64; break;
1252 1568 case LBM_TYPE_U64: res = ENC_SYM_TYPE_U64; break;
1253 2128 case LBM_TYPE_DOUBLE: res = ENC_SYM_TYPE_DOUBLE; break;
1254 2536 case LBM_TYPE_I: res = ENC_SYM_TYPE_I; break;
1255 6709 case LBM_TYPE_U: res = ENC_SYM_TYPE_U; break;
1256 112 case LBM_TYPE_CHAR: res = ENC_SYM_TYPE_CHAR; break;
1257 2535 case LBM_TYPE_SYMBOL: res = ENC_SYM_TYPE_SYMBOL; break;
1258 56 case LBM_TYPE_LISPARRAY: res = ENC_SYM_TYPE_LISPARRAY; break;
1259 case LBM_TYPE_DEFRAG_MEM: res = ENC_SYM_TYPE_DEFRAG_MEM; break;
1260 case LBM_TYPE_CUSTOM: res = ENC_SYM_TYPE_CUSTOM; break;
1261 }
1262 }
1263 33795 return res;
1264 }
1265
1266 2726 static lbm_value fundamental_list_length(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1267 (void) ctx;
1268 2726 lbm_value result = ENC_SYM_EERROR;
1269
2/2
✓ Branch 0 taken 2668 times.
✓ Branch 1 taken 58 times.
2726 if (nargs == 1) {
1270 2668 result = ENC_SYM_TERROR;
1271
2/2
✓ Branch 0 taken 2321 times.
✓ Branch 1 taken 347 times.
2668 if (lbm_is_list(args[0])) {
1272 2321 int32_t len = (int32_t)lbm_list_length(args[0]);
1273 2321 result = lbm_enc_i(len);
1274
2/2
✓ Branch 0 taken 59 times.
✓ Branch 1 taken 288 times.
347 } else if (lbm_is_array_r(args[0])) {
1275 59 lbm_array_header_t *header = (lbm_array_header_t*)lbm_car(args[0]);
1276 59 result = lbm_enc_i((int)(header->size));
1277
2/2
✓ Branch 0 taken 172 times.
✓ Branch 1 taken 116 times.
288 } else if (lbm_is_lisp_array_r(args[0])) {
1278 172 lbm_array_header_t *header = (lbm_array_header_t*)lbm_car(args[0]);
1279 172 result = lbm_enc_i((int)(header->size / (sizeof(lbm_uint))));
1280 }
1281 }
1282 2726 return result;
1283 }
1284
1285 12188491 static lbm_value fundamental_range(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1286 (void) ctx;
1287 12188491 lbm_value result = ENC_SYM_EERROR;
1288
1289 int32_t start;
1290 int32_t end;
1291 12188491 bool rev = false;
1292
1293
4/4
✓ Branch 0 taken 11603880 times.
✓ Branch 1 taken 584611 times.
✓ Branch 2 taken 11603824 times.
✓ Branch 3 taken 56 times.
12188491 if (nargs == 1 && IS_NUMBER(args[0])) {
1294 11603824 start = 0;
1295 11603824 end = lbm_dec_as_i32(args[0]);
1296
4/4
✓ Branch 0 taken 584555 times.
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 584499 times.
✓ Branch 3 taken 56 times.
1169222 } else if (nargs == 2 &&
1297
2/2
✓ Branch 0 taken 584443 times.
✓ Branch 1 taken 56 times.
1169054 IS_NUMBER(args[0]) &&
1298 584499 IS_NUMBER(args[1])) {
1299 584443 start = lbm_dec_as_i32(args[0]);
1300 584443 end = lbm_dec_as_i32(args[1]);
1301 } else {
1302 224 return result;
1303 }
1304
1305
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 12188211 times.
12188267 if (end == start) return ENC_SYM_NIL;
1306
2/2
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 12188098 times.
12188211 else if (end < start) {
1307 113 int32_t tmp = end;
1308 113 end = start;
1309 113 start = tmp;
1310 113 rev = true;
1311 }
1312
1313 12188211 int num = end - start;
1314
1315
2/2
✓ Branch 0 taken 399030 times.
✓ Branch 1 taken 11789181 times.
12188211 if ((unsigned int)num > lbm_heap_num_free()) {
1316 399030 return ENC_SYM_MERROR;
1317 }
1318
1319 11789181 lbm_value r_list = ENC_SYM_NIL;
1320
2/2
✓ Branch 0 taken 597586619 times.
✓ Branch 1 taken 11789181 times.
609375800 for (int i = end - 1; i >= start; i --) {
1321 597586619 r_list = lbm_cons(lbm_enc_i(i), r_list);
1322 }
1323
2/2
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 11789068 times.
11789181 return rev ? lbm_list_destructive_reverse(r_list) : r_list;
1324 }
1325
1326 560 static lbm_value fundamental_reg_event_handler(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1327 (void) ctx;
1328 560 lbm_value res = ENC_SYM_TERROR;
1329
4/4
✓ Branch 0 taken 504 times.
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 448 times.
✓ Branch 3 taken 56 times.
560 if (nargs == 1 && IS_NUMBER(args[0])) {
1330 448 lbm_set_event_handler_pid((lbm_cid)lbm_dec_i(args[0]));
1331 448 res = ENC_SYM_TRUE;
1332 }
1333 560 return res;
1334 }
1335
1336 68858 static lbm_value fundamental_take(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1337 (void) ctx;
1338 68858 lbm_value res = ENC_SYM_TERROR;
1339
6/6
✓ Branch 0 taken 68802 times.
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 68746 times.
✓ Branch 3 taken 56 times.
✓ Branch 4 taken 68690 times.
✓ Branch 5 taken 56 times.
68858 if (nargs == 2 && IS_NUMBER(args[1]) && lbm_is_list(args[0])) {
1340 68690 int len = lbm_dec_as_i32(args[1]);
1341 68690 res = lbm_list_copy(&len, args[0]);
1342 }
1343 68858 return res;
1344 }
1345
1346 336 static lbm_value fundamental_drop(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1347 (void) ctx;
1348 336 lbm_value res = ENC_SYM_TERROR;
1349
6/6
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 224 times.
✓ Branch 3 taken 56 times.
✓ Branch 4 taken 168 times.
✓ Branch 5 taken 56 times.
336 if (nargs == 2 && IS_NUMBER(args[1]) && lbm_is_list(args[0])) {
1350 168 res = lbm_list_drop(lbm_dec_as_u32(args[1]), args[0]);
1351 }
1352 336 return res;
1353 }
1354 /* (mkarray size) */
1355 563408 static lbm_value fundamental_mkarray(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1356 (void) ctx;
1357 563408 lbm_value res = ENC_SYM_TERROR;
1358
2/4
✓ Branch 0 taken 563408 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 563408 times.
✗ Branch 3 not taken.
563408 if (nargs == 1 && IS_NUMBER(args[0])) {
1359 563408 lbm_heap_allocate_lisp_array(&res, lbm_dec_as_u32(args[0]));
1360 }
1361 // No high-level arrays in defrag mem until we figure out how to do it without overhead.
1362 //else if (nargs == 2 && IS_NUMBER(args[1]) && lbm_type_of(args[0]) == LBM_TYPE_DEFRAG_MEM) {
1363 // lbm_uint *dm = (lbm_uint*)lbm_car(args[0]);
1364 // res = lbm_defrag_mem_alloc_lisparray(dm, lbm_dec_as_u32(args[1]));
1365 //}
1366 563408 return res;
1367 }
1368
1369 // Create an array in a similar way to how list creates a list.
1370 5 static lbm_value fundamental_array(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1371 (void) ctx;
1372 5 lbm_value res = ENC_SYM_TERROR;
1373 5 lbm_heap_allocate_lisp_array(&res, nargs);
1374
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (!lbm_is_symbol_merror(res)) {
1375 5 lbm_array_header_t *header = (lbm_array_header_t*)lbm_car(res);
1376 5 lbm_value *arrdata = (lbm_value*)header->data;
1377
2/2
✓ Branch 0 taken 104 times.
✓ Branch 1 taken 5 times.
109 for (lbm_uint i = 0; i < nargs; i ++) {
1378 104 arrdata[i] = args[i];
1379 }
1380 }
1381 5 return res;
1382 }
1383
1384 337 static lbm_value fundamental_dm_create(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1385 (void) ctx;
1386 337 lbm_value res = ENC_SYM_TERROR;
1387
2/4
✓ Branch 0 taken 337 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 337 times.
✗ Branch 3 not taken.
337 if (argn == 1 && lbm_is_number(args[0])) {
1388 337 lbm_uint n = lbm_dec_as_uint(args[0]);
1389 337 res = lbm_defrag_mem_create(n);
1390 }
1391 337 return res;
1392 }
1393
1394 4172 static lbm_value fundamental_dm_alloc(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1395 (void) ctx;
1396 4172 lbm_value res = ENC_SYM_TERROR;
1397
2/4
✓ Branch 0 taken 4172 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4172 times.
✗ Branch 3 not taken.
4172 if (argn == 2 && lbm_is_number(args[1])) {
1398
1/2
✓ Branch 0 taken 4172 times.
✗ Branch 1 not taken.
4172 if (lbm_type_of(args[0]) == LBM_TYPE_DEFRAG_MEM) {
1399 4172 lbm_uint *dm = (lbm_uint*)lbm_car(args[0]);
1400 4172 res = lbm_defrag_mem_alloc(dm, lbm_dec_as_uint(args[1]));
1401 }
1402 }
1403 // NO high level arrays in Defrag mem until we can do it without overhead in the DM representation!
1404 //else if (argn == 3 && lbm_is_number(args[1]) && args[2] == ENC_SYM_TYPE_LISPARRAY) {
1405 // if (lbm_type_of(args[0]) == LBM_TYPE_DEFRAG_MEM) {
1406 // lbm_uint *dm = (lbm_uint*)lbm_car(args[0]);
1407 // res = lbm_defrag_mem_alloc_lisparray(dm, lbm_dec_as_uint(args[1]));
1408 // }
1409 //}
1410 4172 return res;
1411 }
1412
1413 305 static lbm_value fundamental_is_list(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1414 (void) ctx;
1415 305 lbm_value res = ENC_SYM_TERROR;
1416
2/2
✓ Branch 0 taken 303 times.
✓ Branch 1 taken 2 times.
305 if (argn == 1) {
1417
2/2
✓ Branch 0 taken 186 times.
✓ Branch 1 taken 117 times.
303 res = lbm_is_list(args[0]) ? ENC_SYM_TRUE : ENC_SYM_NIL;
1418 }
1419 305 return res;
1420 }
1421
1422 630 static lbm_value fundamental_is_number(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1423 (void) ctx;
1424 630 lbm_value res = ENC_SYM_TERROR;
1425
2/2
✓ Branch 0 taken 628 times.
✓ Branch 1 taken 2 times.
630 if (argn == 1) {
1426
2/2
✓ Branch 0 taken 398 times.
✓ Branch 1 taken 230 times.
628 res = lbm_is_number(args[0]) ? ENC_SYM_TRUE : ENC_SYM_NIL;
1427 }
1428 630 return res;
1429 }
1430
1431 66 static lbm_value fundamental_int_div(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1432 66 lbm_value res = fundamental_div(args, argn, ctx);
1433
2/3
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40 times.
66 switch (lbm_type_of(res)) {
1434 26 case LBM_TYPE_FLOAT: {
1435 26 res = lbm_enc_i((lbm_int)lbm_dec_float(res));
1436 26 break;
1437 }
1438 case LBM_TYPE_DOUBLE: {
1439 res = lbm_enc_i((lbm_int)lbm_dec_double(res));
1440 break;
1441 }
1442 }
1443
1444 66 return res;
1445 }
1446
1447 112 static lbm_value fundamental_identity(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1448 (void) ctx;
1449 112 lbm_value res = ENC_SYM_TERROR;
1450
1/2
✓ Branch 0 taken 112 times.
✗ Branch 1 not taken.
112 if (argn == 1) {
1451 112 res = args[0];
1452 }
1453 112 return res;
1454 }
1455
1456 3 static lbm_value fundamental_is_string(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1457 (void) ctx;
1458 3 lbm_value res = ENC_SYM_TERROR;
1459
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (argn == 1) {
1460 char *str;
1461
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;
1462 }
1463 3 return res;
1464 }
1465
1466 // Check if a value is a constant (stored in flash)
1467 // Only half true for some shared arrays.. maybe rethink that.
1468 // constant? is true for constant pointers.
1469 // atoms could be considered constant in general but are not by constant?
1470 3 static lbm_value fundamental_is_constant(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1471 (void) ctx;
1472 3 lbm_value res = ENC_SYM_TERROR;
1473
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (argn == 1) {
1474 2 lbm_type t = lbm_type_of(args[0]);
1475
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);
1476 }
1477 1 return res;
1478 }
1479
1480 1962 static lbm_value fundamental_member(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1481 (void)ctx;
1482 1962 lbm_value res = ENC_SYM_TERROR;
1483
3/4
✓ Branch 0 taken 1738 times.
✓ Branch 1 taken 224 times.
✓ Branch 2 taken 1738 times.
✗ Branch 3 not taken.
1962 if (argn == 2 && lbm_is_list(args[1])) {
1484 1738 res = ENC_SYM_NIL;
1485 1738 lbm_value curr = args[1];
1486
1487
2/2
✓ Branch 0 taken 3822 times.
✓ Branch 1 taken 336 times.
4158 while (lbm_is_cons(curr)) {
1488
2/2
✓ Branch 0 taken 1402 times.
✓ Branch 1 taken 2420 times.
3822 if (struct_eq(lbm_car(curr), args[0])) {
1489 1402 res = args[1];
1490 1402 break;
1491 }
1492 2420 curr = lbm_cdr(curr);
1493 }
1494 }
1495 1962 return res;
1496 }
1497
1498
1499 const fundamental_fun fundamental_table[] =
1500 {fundamental_add,
1501 fundamental_sub,
1502 fundamental_mul,
1503 fundamental_div,
1504 fundamental_mod,
1505 fundamental_eq,
1506 fundamental_not_eq,
1507 fundamental_numeq,
1508 fundamental_num_not_eq,
1509 fundamental_lt,
1510 fundamental_gt,
1511 fundamental_leq,
1512 fundamental_geq,
1513 fundamental_not,
1514 fundamental_gc,
1515 fundamental_self,
1516 fundamental_set_mailbox_size,
1517 fundamental_cons,
1518 fundamental_car,
1519 fundamental_cdr,
1520 fundamental_list,
1521 fundamental_append,
1522 fundamental_undefine,
1523 fundamental_buf_create,
1524 fundamental_symbol_to_string,
1525 fundamental_string_to_symbol,
1526 fundamental_symbol_to_uint,
1527 fundamental_uint_to_symbol,
1528 fundamental_set_car,
1529 fundamental_set_cdr,
1530 fundamental_set_ix,
1531 fundamental_assoc,
1532 fundamental_acons,
1533 fundamental_set_assoc,
1534 fundamental_cossa,
1535 fundamental_ix,
1536 fundamental_to_i,
1537 fundamental_to_i32,
1538 fundamental_to_u,
1539 fundamental_to_u32,
1540 fundamental_to_float,
1541 fundamental_to_i64,
1542 fundamental_to_u64,
1543 fundamental_to_double,
1544 fundamental_to_byte,
1545 fundamental_shl,
1546 fundamental_shr,
1547 fundamental_bitwise_and,
1548 fundamental_bitwise_or,
1549 fundamental_bitwise_xor,
1550 fundamental_bitwise_not,
1551 fundamental_custom_destruct,
1552 fundamental_type_of,
1553 fundamental_list_length,
1554 fundamental_range,
1555 fundamental_reg_event_handler,
1556 fundamental_take,
1557 fundamental_drop,
1558 fundamental_mkarray,
1559 fundamental_dm_create,
1560 fundamental_dm_alloc,
1561 fundamental_is_list,
1562 fundamental_is_number,
1563 fundamental_int_div,
1564 fundamental_identity,
1565 fundamental_array,
1566 fundamental_is_string,
1567 fundamental_is_constant,
1568 fundamental_member
1569 };
1570