GCC Code Coverage Report


Directory: ../src/
File: /home/joels/Current/lispbm/src/fundamental.c
Date: 2025-10-28 15:15:18
Exec Total Coverage
Lines: 881 883 99.8%
Functions: 80 80 100.0%
Branches: 672 713 94.2%

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 210224131 static lbm_uint mul2(lbm_uint a, lbm_uint b) {
109 210224131 lbm_uint retval = ENC_SYM_TERROR;
110
3/4
✓ Branch 0 taken 210224131 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 210223618 times.
✓ Branch 3 taken 513 times.
420447749 if (IS_NUMBER(a) && IS_NUMBER(b)) {
111 lbm_type t;
112
11/11
✓ Branch 0 taken 67561533 times.
✓ Branch 1 taken 106517285 times.
✓ Branch 2 taken 36144800 times.
✓ Branch 3 taken 33600532 times.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 67200756 times.
✓ Branch 6 taken 2804312 times.
✓ Branch 7 taken 67200728 times.
✓ Branch 8 taken 28 times.
✓ Branch 9 taken 282828 times.
✓ Branch 10 taken 2521512 times.
277424346 PROMOTE_SWAP(t, a, b);
113
9/10
✓ Branch 0 taken 840 times.
✓ Branch 1 taken 8468163 times.
✓ Branch 2 taken 1288 times.
✓ Branch 3 taken 1400 times.
✓ Branch 4 taken 1232 times.
✓ Branch 5 taken 201744982 times.
✓ Branch 6 taken 1848 times.
✓ Branch 7 taken 1680 times.
✓ Branch 8 taken 2185 times.
✗ Branch 9 not taken.
210223618 switch (t) {
114 840 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 5667239 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(a) * lbm_dec_as_i32(b)); break;
120 784 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(a) * lbm_dec_as_u32(b)); break;
121 #endif
122 1400 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_u32(a) * lbm_dec_as_u32(b)); break;
123 1232 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_i32(a) * lbm_dec_as_i32(b)); break;
124 201744982 case LBM_TYPE_FLOAT: retval = lbm_enc_float(lbm_dec_float(a) * lbm_dec_as_float(b)); break;
125 1848 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_u64(a) * lbm_dec_as_u64(b)); break;
126 1680 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_i64(a) * lbm_dec_as_i64(b)); break;
127 2185 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 513 times.
✗ Branch 1 not taken.
513 lbm_set_error_suspect(IS_NUMBER(a) ? b : a);
131 }
132 210224131 return retval;
133 }
134
135 3637 static lbm_uint div2(lbm_uint a, lbm_uint b) {
136 3637 lbm_uint retval = ENC_SYM_TERROR;
137
4/4
✓ Branch 0 taken 3456 times.
✓ Branch 1 taken 181 times.
✓ Branch 2 taken 3274 times.
✓ Branch 3 taken 182 times.
5554 if (IS_NUMBER(a) && IS_NUMBER(b)) {
138 lbm_type t;
139
6/7
✓ Branch 0 taken 116 times.
✓ Branch 1 taken 2122 times.
✓ Branch 2 taken 1036 times.
✓ Branch 3 taken 84 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 56 times.
✓ Branch 6 taken 924 times.
3274 PROMOTE(t, a, b);
140
9/10
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 1700 times.
✓ Branch 2 taken 168 times.
✓ Branch 3 taken 140 times.
✓ Branch 4 taken 140 times.
✓ Branch 5 taken 368 times.
✓ Branch 6 taken 168 times.
✓ Branch 7 taken 168 times.
✓ Branch 8 taken 254 times.
✗ Branch 9 not taken.
3274 switch (t) {
141
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 84 times.
168 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 456 times.
✓ Branch 1 taken 656 times.
1112 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 56 times.
✓ Branch 1 taken 56 times.
112 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 56 times.
✓ Branch 1 taken 84 times.
140 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 56 times.
✓ Branch 1 taken 84 times.
140 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 280 times.
✓ Branch 1 taken 88 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 280 times.
368 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 84 times.
✓ Branch 1 taken 84 times.
168 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 84 times.
✓ Branch 1 taken 84 times.
168 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 169 times.
✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 169 times.
254 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 182 times.
✓ Branch 1 taken 181 times.
363 lbm_set_error_suspect(IS_NUMBER(a) ? b : a);
158 }
159 2280 return retval;
160 }
161
162 49557 static lbm_uint mod2(lbm_uint a, lbm_uint b) {
163 49557 lbm_uint retval = ENC_SYM_TERROR;
164
4/4
✓ Branch 0 taken 49384 times.
✓ Branch 1 taken 173 times.
✓ Branch 2 taken 49214 times.
✓ Branch 3 taken 170 times.
97928 if (IS_NUMBER(a) && IS_NUMBER(b)) {
165 lbm_type t;
166
6/7
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 40512 times.
✓ Branch 2 taken 8672 times.
✓ Branch 3 taken 28 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 56 times.
✓ Branch 6 taken 8588 times.
49214 PROMOTE(t, a, b);
167
9/10
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 23924 times.
✓ Branch 2 taken 24168 times.
✓ Branch 3 taken 140 times.
✓ Branch 4 taken 140 times.
✓ Branch 5 taken 169 times.
✓ Branch 6 taken 168 times.
✓ Branch 7 taken 168 times.
✓ Branch 8 taken 169 times.
✗ Branch 9 not taken.
49214 switch (t) {
168
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 84 times.
168 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 113 times.
✓ Branch 1 taken 23531 times.
23644 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 56 times.
✓ Branch 1 taken 16056 times.
16112 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 56 times.
✓ Branch 1 taken 84 times.
140 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 56 times.
✓ Branch 1 taken 84 times.
140 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 84 times.
✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 84 times.
169 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 84 times.
✓ Branch 1 taken 84 times.
168 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 84 times.
✓ Branch 1 taken 84 times.
168 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 84 times.
✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 84 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(fmod(lbm_dec_as_double(a), lbm_dec_as_double(b))); break;
182 }
183 } else {
184
2/2
✓ Branch 0 taken 170 times.
✓ Branch 1 taken 173 times.
343 lbm_set_error_suspect(IS_NUMBER(a) ? b : a);
185 }
186 48714 return retval;
187 }
188
189 80956888 static lbm_uint sub2(lbm_uint a, lbm_uint b) {
190 80956888 lbm_uint retval = ENC_SYM_TERROR;
191
4/4
✓ Branch 0 taken 80956715 times.
✓ Branch 1 taken 173 times.
✓ Branch 2 taken 80956291 times.
✓ Branch 3 taken 424 times.
161913179 if (IS_NUMBER(a) && IS_NUMBER(b)) {
192 lbm_uint t;
193
6/7
✓ Branch 0 taken 632 times.
✓ Branch 1 taken 54152097 times.
✓ Branch 2 taken 26803562 times.
✓ Branch 3 taken 168 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 392 times.
✓ Branch 6 taken 26805058 times.
80956291 PROMOTE(t, a, b);
194
9/10
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 80392307 times.
✓ Branch 2 taken 168 times.
✓ Branch 3 taken 562235 times.
✓ Branch 4 taken 252 times.
✓ Branch 5 taken 569 times.
✓ Branch 6 taken 168 times.
✓ Branch 7 taken 252 times.
✓ Branch 8 taken 172 times.
✗ Branch 9 not taken.
80956291 switch (t) {
195 168 case LBM_TYPE_BYTE: retval = lbm_enc_char((uint8_t)(lbm_dec_char(a) - lbm_dec_char(b))); break;
196 #ifdef LBM64
197 26804974 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 53587333 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_as_i32(a) - lbm_dec_as_i32(b)); break;
201 112 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_as_u32(a) - lbm_dec_as_u32(b)); break;
202 #endif
203 562235 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_as_u32(a) - lbm_dec_as_u32(b)); break;
204 252 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_as_i32(a) - lbm_dec_as_i32(b)); break;
205 569 case LBM_TYPE_FLOAT: retval = lbm_enc_float(lbm_dec_as_float(a) - lbm_dec_as_float(b)); break;
206 168 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_as_u64(a) - lbm_dec_as_u64(b)); break;
207 252 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_as_i64(a) - lbm_dec_as_i64(b)); break;
208 172 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 424 times.
✓ Branch 1 taken 173 times.
597 lbm_set_error_suspect(IS_NUMBER(a) ? b : a);
212 }
213 80956888 return retval;
214 }
215
216 // a and b must be bytearrays!
217 41726 static bool bytearray_equality(lbm_value a, lbm_value b) {
218 41726 lbm_array_header_t *a_ = (lbm_array_header_t*)lbm_car(a);
219 41726 lbm_array_header_t *b_ = (lbm_array_header_t*)lbm_car(b);
220 41726 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 41726 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 41726 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 41222 times.
✓ Branch 5 taken 504 times.
41726 if ((a_ && b_) && a_->size == b_->size) {
225 41222 res = (memcmp((char*)a_->data, (char*)b_->data, a_->size) == 0);
226 }
227 41726 return res;
228 }
229
230 // a and b must be arrays!
231 1014 static bool array_struct_equality(lbm_value a, lbm_value b) {
232 1014 lbm_array_header_t *a_ = (lbm_array_header_t*)lbm_car(a);
233 1014 lbm_array_header_t *b_ = (lbm_array_header_t*)lbm_car(b);
234 1014 bool res = false;
235
4/6
✓ Branch 0 taken 1014 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1014 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 930 times.
✓ Branch 5 taken 84 times.
1014 if ((a_ && b_) && a_->size == b_->size) {
236 930 res = true;
237 930 lbm_value *adata = (lbm_value*)a_->data;
238 930 lbm_value *bdata = (lbm_value*)b_->data;
239 930 lbm_uint size = (lbm_uint)a_->size / (lbm_uint)sizeof(lbm_value);
240
2/2
✓ Branch 0 taken 2285 times.
✓ Branch 1 taken 846 times.
3131 for (lbm_uint i = 0; i < size; i ++ ) {
241 2285 res = struct_eq(adata[i], bdata[i]);
242
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 2201 times.
2285 if (!res) break;
243 }
244 }
245 1014 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 949104 bool struct_eq(lbm_value a, lbm_value b) {
260
261 949104 bool res = false;
262 949104 lbm_type ta = lbm_type_of_functional(a);
263 949104 lbm_type tb = lbm_type_of_functional(b);
264
265
2/2
✓ Branch 0 taken 835546 times.
✓ Branch 1 taken 113558 times.
949104 if (ta == tb) {
266
13/14
✓ Branch 0 taken 199446 times.
✓ Branch 1 taken 308503 times.
✓ Branch 2 taken 1766 times.
✓ Branch 3 taken 15047 times.
✓ Branch 4 taken 227084 times.
✓ Branch 5 taken 5467 times.
✓ Branch 6 taken 10764 times.
✓ Branch 7 taken 20187 times.
✓ Branch 8 taken 1681 times.
✓ Branch 9 taken 1681 times.
✓ Branch 10 taken 1180 times.
✓ Branch 11 taken 41726 times.
✓ Branch 12 taken 1014 times.
✗ Branch 13 not taken.
835546 switch(ta){
267 199446 case LBM_TYPE_SYMBOL:
268 199446 res = (lbm_dec_sym(a) == lbm_dec_sym(b)); break;
269 308503 case LBM_TYPE_I:
270 308503 res = (lbm_dec_i(a) == lbm_dec_i(b)); break;
271 1766 case LBM_TYPE_U:
272 1766 res = (lbm_dec_u(a) == lbm_dec_u(b)); break;
273 15047 case LBM_TYPE_CHAR:
274 15047 res = (lbm_dec_char(a) == lbm_dec_char(b)); break;
275 227084 case LBM_TYPE_CONS:
276
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 227070 times.
227084 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 226901 times.
✓ Branch 1 taken 169 times.
✓ Branch 2 taken 226817 times.
✓ Branch 3 taken 84 times.
453971 res = ( struct_eq(lbm_car(a),lbm_car(b)) &&
281 453971 struct_eq(lbm_cdr(a),lbm_cdr(b)) ); break;
282 5467 case LBM_TYPE_I32:
283 5467 res = (lbm_dec_i32(a) == lbm_dec_i32(b)); break;
284 10764 case LBM_TYPE_U32:
285 10764 res = (lbm_dec_u32(a) == lbm_dec_u32(b)); break;
286 20187 case LBM_TYPE_FLOAT:
287 20187 res = (lbm_dec_float(a) == lbm_dec_float(b)); break;
288 1681 case LBM_TYPE_I64:
289 1681 res = (lbm_dec_i64(a) == lbm_dec_i64(b)); break;
290 1681 case LBM_TYPE_U64:
291 1681 res = (lbm_dec_u64(a) == lbm_dec_u64(b)); break;
292 1180 case LBM_TYPE_DOUBLE:
293 1180 res = (lbm_dec_double(a) == lbm_dec_double(b)); break;
294 41726 case LBM_TYPE_ARRAY:
295 41726 res = bytearray_equality(a, b); break;
296 1014 case LBM_TYPE_LISPARRAY:
297
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1014 times.
1014 if (a == b) { // quick path if pointers equal (pointers equal => structural equal)
298 res = true;
299 break;
300 }
301 1014 res = array_struct_equality(a, b); break;
302 }
303 }
304 949104 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 227889603 static int compare_num(lbm_uint a, lbm_uint b) {
312
313 227889603 int retval = 0;
314
315 lbm_uint t;
316
7/7
✓ Branch 0 taken 2800846 times.
✓ Branch 1 taken 149329237 times.
✓ Branch 2 taken 75759520 times.
✓ Branch 3 taken 2800448 times.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 336 times.
✓ Branch 6 taken 72961217 times.
227889603 PROMOTE(t, a, b);
317
9/10
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 113908536 times.
✓ Branch 2 taken 15861 times.
✓ Branch 3 taken 1401785 times.
✓ Branch 4 taken 840171 times.
✓ Branch 5 taken 109202145 times.
✓ Branch 6 taken 840252 times.
✓ Branch 7 taken 1680254 times.
✓ Branch 8 taken 515 times.
✗ Branch 9 not taken.
227889603 switch (t) {
318 84 case LBM_TYPE_CHAR: retval = CMP(lbm_dec_char(a), lbm_dec_char(b)); break;
319 #ifdef LBM64
320 37955485 case LBM_TYPE_I: retval = CMP(lbm_dec_as_i64(a), lbm_dec_as_i64(b)); break;
321 5284 case LBM_TYPE_U: retval = CMP(lbm_dec_as_u64(a), lbm_dec_as_u64(b)); break;
322 #else
323 75953051 case LBM_TYPE_I: retval = CMP(lbm_dec_as_i32(a), lbm_dec_as_i32(b)); break;
324 10577 case LBM_TYPE_U: retval = CMP(lbm_dec_as_u32(a), lbm_dec_as_u32(b)); break;
325 #endif
326 1401785 case LBM_TYPE_U32: retval = CMP(lbm_dec_as_u32(a), lbm_dec_as_u32(b)); break;
327 840171 case LBM_TYPE_I32: retval = CMP(lbm_dec_as_i32(a), lbm_dec_as_i32(b)); break;
328 109202145 case LBM_TYPE_FLOAT: retval = CMP(lbm_dec_as_float(a), lbm_dec_as_float(b)); break;
329 840252 case LBM_TYPE_U64: retval = CMP(lbm_dec_as_u64(a), lbm_dec_as_u64(b)); break;
330 1680254 case LBM_TYPE_I64: retval = CMP(lbm_dec_as_i64(a), lbm_dec_as_i64(b)); break;
331 515 case LBM_TYPE_DOUBLE: retval = CMP(lbm_dec_as_double(a), lbm_dec_as_double(b)); break;
332 }
333 227889603 return retval;
334 }
335
336 1034 static lbm_value assoc_lookup(lbm_value key, lbm_value assoc) {
337 1034 lbm_value curr = assoc;
338 1034 lbm_value res = ENC_SYM_NO_MATCH;
339
2/2
✓ Branch 0 taken 2395 times.
✓ Branch 1 taken 84 times.
2479 while (lbm_is_cons(curr)) {
340 2395 lbm_value c = lbm_ref_cell(curr)->car;
341
2/2
✓ Branch 0 taken 2311 times.
✓ Branch 1 taken 84 times.
2395 if (lbm_is_cons(c)) {
342
2/2
✓ Branch 0 taken 866 times.
✓ Branch 1 taken 1445 times.
2311 if (struct_eq(lbm_ref_cell(c)->car, key)) {
343 866 res = lbm_ref_cell(c)->cdr;
344 866 break;
345 }
346 } else {
347 84 res = ENC_SYM_EERROR;
348 84 break;
349 }
350 1445 curr = lbm_ref_cell(curr)->cdr;
351 }
352 1034 return res;
353 }
354
355 1010 static lbm_value cossa_lookup(lbm_value key, lbm_value assoc) {
356 1010 lbm_value curr = assoc;
357
2/2
✓ Branch 0 taken 2440 times.
✓ Branch 1 taken 84 times.
2524 while (lbm_is_cons(curr)) {
358 2440 lbm_value c = lbm_ref_cell(curr)->car;
359
2/2
✓ Branch 0 taken 2356 times.
✓ Branch 1 taken 84 times.
2440 if (lbm_is_cons(c)) {
360
2/2
✓ Branch 0 taken 842 times.
✓ Branch 1 taken 1514 times.
2356 if (struct_eq(lbm_ref_cell(c)->cdr, key)) {
361 842 return lbm_ref_cell(c)->car;
362 }
363 } else {
364 84 return ENC_SYM_EERROR;
365 }
366 1514 curr = lbm_ref_cell(curr)->cdr;
367 }
368 84 return ENC_SYM_NO_MATCH;
369 }
370
371
372
373 /***************************************************/
374 /* Fundamental operations */
375
376 234830835 static lbm_value fundamental_add(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
377 (void) ctx;
378 234830835 lbm_uint sum = lbm_enc_char(0);
379
2/2
✓ Branch 0 taken 611046035 times.
✓ Branch 1 taken 234618151 times.
845664186 for (lbm_uint i = 0; i < nargs; i ++) {
380 611046035 lbm_value v = args[i];
381
2/2
✓ Branch 0 taken 611045433 times.
✓ Branch 1 taken 599 times.
611046035 if (IS_NUMBER(v)) { // inlining add2 explicitly removes one condition.
382 lbm_type t;
383
11/11
✓ Branch 0 taken 174589447 times.
✓ Branch 1 taken 312771994 times.
✓ Branch 2 taken 123683992 times.
✓ Branch 3 taken 95201344 times.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 162401736 times.
✓ Branch 6 taken 39261548 times.
✓ Branch 7 taken 162401708 times.
✓ Branch 8 taken 28 times.
✓ Branch 9 taken 8091316 times.
✓ Branch 10 taken 31170260 times.
773447141 PROMOTE_SWAP(t, sum, v);
384
9/10
✓ Branch 0 taken 849 times.
✓ Branch 1 taken 80254668 times.
✓ Branch 2 taken 2129 times.
✓ Branch 3 taken 9527780 times.
✓ Branch 4 taken 8407448 times.
✓ Branch 5 taken 487611518 times.
✓ Branch 6 taken 10097364 times.
✓ Branch 7 taken 13459124 times.
✓ Branch 8 taken 1684553 times.
✗ Branch 9 not taken.
611045433 switch (t) {
385 849 case LBM_TYPE_BYTE: sum = lbm_enc_char((uint8_t)(lbm_dec_char(sum) + lbm_dec_char(v))); break;
386 #ifdef LBM64
387 25249300 case LBM_TYPE_I: sum = lbm_enc_i(lbm_dec_i(sum) + lbm_dec_as_i64(v)); break;
388 896 case LBM_TYPE_U: sum = lbm_enc_u(lbm_dec_u(sum) + lbm_dec_as_u64(v)); break;
389 2800560 case LBM_TYPE_U32: sum = lbm_enc_u32(lbm_dec_u32(sum) + lbm_dec_as_u32(v)); break;
390 2800504 case LBM_TYPE_I32: sum = lbm_enc_i32(lbm_dec_i32(sum) + lbm_dec_as_i32(v)); break;
391 162401708 case LBM_TYPE_FLOAT: sum = lbm_enc_float(lbm_dec_float(sum) + lbm_dec_as_float(v)); break;
392 #else
393 55005368 case LBM_TYPE_I: sum = lbm_enc_i(lbm_dec_i(sum) + lbm_dec_as_i32(v)); break;
394 1233 case LBM_TYPE_U: sum = lbm_enc_u(lbm_dec_u(sum) + lbm_dec_as_u32(v)); break;
395 6727220 case LBM_TYPE_U32:
396 6727220 sum = lbm_enc_u32(lbm_dec_u32(sum) + lbm_dec_as_u32(v));
397
2/2
✓ Branch 0 taken 1164 times.
✓ Branch 1 taken 6726056 times.
6727220 if (lbm_is_symbol(sum)) goto add_end;
398 6726056 break;
399 5606944 case LBM_TYPE_I32:
400 5606944 sum = lbm_enc_i32(lbm_dec_i32(sum) + lbm_dec_as_i32(v));
401
2/2
✓ Branch 0 taken 1088 times.
✓ Branch 1 taken 5605856 times.
5606944 if (lbm_is_symbol(sum)) goto add_end;
402 5605856 break;
403 325209810 case LBM_TYPE_FLOAT:
404 325209810 sum = lbm_enc_float(lbm_dec_float(sum) + lbm_dec_as_float(v));
405
2/2
✓ Branch 0 taken 197764 times.
✓ Branch 1 taken 325012046 times.
325209810 if (lbm_is_symbol(sum)) goto add_end;
406 325012046 break;
407 #endif
408 10097364 case LBM_TYPE_U64:
409 10097364 sum = lbm_enc_u64(lbm_dec_u64(sum) + lbm_dec_as_u64(v));
410
2/2
✓ Branch 0 taken 4596 times.
✓ Branch 1 taken 10092768 times.
10097364 if (lbm_is_symbol(sum)) goto add_end;
411 10092768 break;
412 13459124 case LBM_TYPE_I64:
413 13459124 sum = lbm_enc_i64(lbm_dec_i64(sum) + lbm_dec_as_i64(v));
414
2/2
✓ Branch 0 taken 6092 times.
✓ Branch 1 taken 13453032 times.
13459124 if (lbm_is_symbol(sum)) goto add_end;
415 13453032 break;
416 1684553 case LBM_TYPE_DOUBLE:
417 1684553 sum = lbm_enc_double(lbm_dec_double(sum) + lbm_dec_as_double(v));
418
2/2
✓ Branch 0 taken 1380 times.
✓ Branch 1 taken 1683173 times.
1684553 if (lbm_is_symbol(sum)) goto add_end;
419 1683173 break;
420 }
421 } else {
422 599 lbm_set_error_suspect(v);
423 599 sum = ENC_SYM_TERROR;
424 599 break; // out of loop
425 }
426 }
427 234618151 add_end:
428 234830834 return sum;
429 }
430
431 80956634 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 84 times.
✓ Branch 1 taken 1444 times.
✓ Branch 2 taken 80954937 times.
✓ Branch 3 taken 169 times.
80956634 switch (nargs) {
437 84 case 0:
438 84 res = lbm_enc_char(0);
439 84 break;
440
441 1444 case 1:
442 1444 res = sub2(lbm_enc_char(0),args[0]);
443 1444 break;
444
445 80954937 case 2:
446 80954937 res = sub2(args[0], args[1]);
447 80954937 break;
448
449 169 default:
450 169 res = args[0];
451
2/2
✓ Branch 0 taken 507 times.
✓ Branch 1 taken 84 times.
591 for (lbm_uint i = 1; i < nargs; i ++) {
452 507 res = sub2(res, args[i]);
453
2/2
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 422 times.
507 if (lbm_type_of(res) == LBM_TYPE_SYMBOL)
454 85 break;
455 }
456 169 break;
457 }
458 80956634 return res;
459 }
460
461 101774018 static lbm_value fundamental_mul(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
462 (void) ctx;
463
464 101774018 lbm_uint prod = lbm_enc_char(1);
465
2/2
✓ Branch 0 taken 210224131 times.
✓ Branch 1 taken 101676781 times.
311900912 for (lbm_uint i = 0; i < nargs; i ++) {
466 210224131 prod = mul2(prod, args[i]);
467
2/2
✓ Branch 0 taken 97237 times.
✓ Branch 1 taken 210126894 times.
210224131 if (lbm_type_of(prod) == LBM_TYPE_SYMBOL) {
468 97237 break;
469 }
470 }
471 101774018 return prod;
472 }
473
474 3623 static lbm_value fundamental_div(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
475 (void) ctx;
476
477 3623 lbm_uint res = args[0];
478
479
2/2
✓ Branch 0 taken 3451 times.
✓ Branch 1 taken 172 times.
3623 if (nargs >= 2) {
480
2/2
✓ Branch 0 taken 3637 times.
✓ Branch 1 taken 1731 times.
5368 for (lbm_uint i = 1; i < nargs; i ++) {
481 3637 res = div2(res, args[i]);
482
2/2
✓ Branch 0 taken 1720 times.
✓ Branch 1 taken 1917 times.
3637 if (lbm_type_of(res) == LBM_TYPE_SYMBOL) {
483 1720 break;
484 }
485 }
486 } else {
487 172 res = ENC_SYM_EERROR;
488 }
489 3623 return res;
490 }
491
492 49726 static lbm_value fundamental_mod(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
493 (void) ctx;
494
2/2
✓ Branch 0 taken 49557 times.
✓ Branch 1 taken 169 times.
49726 if (nargs == 2) {
495 49557 return mod2(args[0], args[1]);
496 }
497 169 lbm_set_error_reason((char*)lbm_error_str_num_args);
498 169 return ENC_SYM_EERROR;
499 }
500
501 322203 static lbm_value fundamental_eq(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
502 (void) ctx;
503 322203 lbm_uint a = args[0];
504
2/2
✓ Branch 0 taken 322791 times.
✓ Branch 1 taken 188958 times.
511749 for (lbm_uint i = 1; i < nargs; i ++) {
505 322791 lbm_uint b = args[i];
506
2/2
✓ Branch 0 taken 133245 times.
✓ Branch 1 taken 189546 times.
322791 if (!struct_eq(a, b)) return ENC_SYM_NIL;
507 }
508 188958 return ENC_SYM_TRUE;
509 }
510
511 840 static lbm_value fundamental_not_eq(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
512 840 lbm_value r = fundamental_eq(args, nargs, ctx);
513
2/2
✓ Branch 0 taken 420 times.
✓ Branch 1 taken 420 times.
840 return r ? ENC_SYM_NIL : ENC_SYM_TRUE; // Works because ENC_SYM_NIL == 0 and ENC_SYM_TRUE is != 0
514 }
515
516
517 96730076 static lbm_value fundamental_numeq(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
518 (void) ctx;
519
520 96730076 lbm_uint a = args[0];
521 96730076 lbm_value res = ENC_SYM_TERROR;
522
523
2/2
✓ Branch 0 taken 96729896 times.
✓ Branch 1 taken 180 times.
96730076 if (IS_NUMBER(a)) {
524 96729896 res = ENC_SYM_TRUE;
525
2/2
✓ Branch 0 taken 96731657 times.
✓ Branch 1 taken 15196434 times.
111928091 for (lbm_uint i = 1; i < nargs; i ++) {
526 96731657 lbm_uint b = args[i];
527
2/2
✓ Branch 0 taken 170 times.
✓ Branch 1 taken 96731487 times.
96731657 if (!IS_NUMBER(b)) {
528 170 res = ENC_SYM_TERROR;
529 170 break;
530 }
531
2/2
✓ Branch 0 taken 81533292 times.
✓ Branch 1 taken 15198195 times.
96731487 if (!(compare_num(a, b) == 0)) {
532 81533292 res = ENC_SYM_NIL;
533 81533292 break;
534 }
535 }
536 }
537 96730076 return res;
538 }
539
540 1681021 static lbm_value fundamental_num_not_eq(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
541 1681021 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 423 times.
✓ Branch 1 taken 1680598 times.
1681021 if (r == ENC_SYM_NIL) {
544 423 r = ENC_SYM_TRUE;
545
2/2
✓ Branch 0 taken 1680423 times.
✓ Branch 1 taken 175 times.
1680598 } else if (r == ENC_SYM_TRUE) {
546 1680423 r = ENC_SYM_NIL;
547 }
548 1681021 return r;
549 }
550
551 127178908 static lbm_value fundamental_leq(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
552 (void) ctx;
553
554 127178908 lbm_uint a = args[0];
555 127178908 bool r = true;
556
557
2/2
✓ Branch 0 taken 127178728 times.
✓ Branch 1 taken 180 times.
127178908 if (IS_NUMBER(a)) {
558
2/2
✓ Branch 0 taken 127178725 times.
✓ Branch 1 taken 127178558 times.
254357283 for (lbm_uint i = 1; i < nargs; i ++) {
559 127178725 lbm_uint b = args[i];
560
2/2
✓ Branch 0 taken 127178555 times.
✓ Branch 1 taken 170 times.
127178725 if (IS_NUMBER(b)) {
561
3/4
✓ Branch 0 taken 127178555 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15301306 times.
✓ Branch 3 taken 111877249 times.
127178555 r = r && (compare_num(a, b) <= 0);
562 } else {
563 170 lbm_set_error_suspect(b);
564 170 goto leq_type_error;
565 }
566 }
567 } else {
568 180 lbm_set_error_suspect(a);
569 180 goto leq_type_error;
570 }
571
2/2
✓ Branch 0 taken 15301309 times.
✓ Branch 1 taken 111877249 times.
127178558 if (r) {
572 15301309 return ENC_SYM_TRUE;
573 } else {
574 111877249 return ENC_SYM_NIL;
575 }
576 350 leq_type_error:
577 350 return ENC_SYM_TERROR;
578 }
579
580 3979913 static lbm_value fundamental_geq(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
581 (void) ctx;
582
583 3979913 lbm_uint a = args[0];
584 3979913 bool r = true;
585
586
2/2
✓ Branch 0 taken 3979733 times.
✓ Branch 1 taken 180 times.
3979913 if (IS_NUMBER(a)) {
587
2/2
✓ Branch 0 taken 3979731 times.
✓ Branch 1 taken 3979563 times.
7959294 for (lbm_uint i = 1; i < nargs; i ++) {
588 3979731 lbm_uint b = args[i];
589
2/2
✓ Branch 0 taken 3979561 times.
✓ Branch 1 taken 170 times.
3979731 if (IS_NUMBER(b)) {
590
3/4
✓ Branch 0 taken 3979561 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 98038 times.
✓ Branch 3 taken 3881523 times.
3979561 r = r && (compare_num(a, b) >= 0);
591 } else {
592 170 lbm_set_error_suspect(b);
593 170 goto geq_type_error;
594 }
595 }
596 } else {
597 180 lbm_set_error_suspect(a);
598 180 goto geq_type_error;
599 }
600
2/2
✓ Branch 0 taken 98040 times.
✓ Branch 1 taken 3881523 times.
3979563 if (r) {
601 98040 return ENC_SYM_TRUE;
602 } else {
603 3881523 return ENC_SYM_NIL;
604 }
605 350 geq_type_error:
606 350 return ENC_SYM_TERROR;
607 }
608
609 3978537 static lbm_value fundamental_lt(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
610 3978537 lbm_value r = fundamental_geq(args, nargs, ctx);
611
2/2
✓ Branch 0 taken 3881355 times.
✓ Branch 1 taken 97182 times.
3978537 if (r == ENC_SYM_NIL) r = ENC_SYM_TRUE;
612
2/2
✓ Branch 0 taken 97007 times.
✓ Branch 1 taken 175 times.
97182 else if (r == ENC_SYM_TRUE) r = ENC_SYM_NIL;
613 3978537 return r;
614 }
615
616 127164333 static lbm_value fundamental_gt(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
617 127164333 lbm_value r = fundamental_leq(args, nargs, ctx);
618
2/2
✓ Branch 0 taken 111868585 times.
✓ Branch 1 taken 15295748 times.
127164333 if (r == ENC_SYM_NIL) r = ENC_SYM_TRUE;
619
2/2
✓ Branch 0 taken 15295573 times.
✓ Branch 1 taken 175 times.
15295748 else if (r == ENC_SYM_TRUE) r = ENC_SYM_NIL;
620 127164333 return r;
621 }
622
623 6382 static lbm_value fundamental_not(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
624 (void) ctx;
625
2/2
✓ Branch 0 taken 6214 times.
✓ Branch 1 taken 168 times.
6382 if (nargs == 1) {
626
2/2
✓ Branch 0 taken 3177 times.
✓ Branch 1 taken 3037 times.
6214 return args[0] ? ENC_SYM_NIL : ENC_SYM_TRUE;
627 }
628 168 return ENC_SYM_EERROR;
629 }
630
631 39734 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 39734 lbm_perform_gc();
636 39734 return ENC_SYM_TRUE;
637 }
638
639 10332 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 10332 return lbm_enc_i(ctx->id);
644 }
645
646 672 static lbm_value fundamental_set_mailbox_size(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
647 672 lbm_value r = ENC_SYM_EERROR;
648
2/2
✓ Branch 0 taken 504 times.
✓ Branch 1 taken 168 times.
672 if (nargs == 1) {
649
2/2
✓ Branch 0 taken 420 times.
✓ Branch 1 taken 84 times.
504 if (IS_NUMBER(args[0])) {
650 420 uint32_t s = lbm_dec_as_u32(args[0]);
651
2/2
✓ Branch 0 taken 336 times.
✓ Branch 1 taken 84 times.
420 if (lbm_mailbox_change_size(ctx, s)) {
652 336 r = ENC_SYM_TRUE;
653 } else {
654 84 r = ENC_SYM_NIL;
655 }
656 } else {
657 84 r = ENC_SYM_TERROR;
658 }
659 }
660 672 return r;
661 }
662
663 35509 static lbm_value fundamental_cons(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
664 (void) ctx;
665 35509 lbm_value r = ENC_SYM_EERROR;
666
2/2
✓ Branch 0 taken 35253 times.
✓ Branch 1 taken 256 times.
35509 if (nargs == 2) {
667 35253 lbm_uint a = args[0];
668 35253 lbm_uint b = args[1];
669 35253 r = lbm_cons(a,b);
670 }
671 35509 return r;
672 }
673
674 125455 static lbm_value fundamental_car(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
675 (void) ctx;
676 125455 lbm_value r = ENC_SYM_EERROR;
677
2/2
✓ Branch 0 taken 125285 times.
✓ Branch 1 taken 170 times.
125455 if (nargs == 1) {
678
2/2
✓ Branch 0 taken 123677 times.
✓ Branch 1 taken 1608 times.
125285 if (lbm_is_cons(args[0])) {
679 123677 lbm_cons_t *cell = lbm_ref_cell(args[0]);
680 123677 r = cell->car;
681
2/2
✓ Branch 0 taken 1348 times.
✓ Branch 1 taken 260 times.
1608 } else if (lbm_is_symbol_nil(args[0])) {
682 1348 r = ENC_SYM_NIL;
683 } else {
684 260 r = ENC_SYM_TERROR;
685 }
686 }
687 125455 return r;
688 }
689
690 130877 static lbm_value fundamental_cdr(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
691 (void) ctx;
692 130877 lbm_value r = ENC_SYM_EERROR;
693
2/2
✓ Branch 0 taken 130707 times.
✓ Branch 1 taken 170 times.
130877 if (nargs == 1) {
694
2/2
✓ Branch 0 taken 129103 times.
✓ Branch 1 taken 1604 times.
130707 if (lbm_is_cons(args[0])) {
695 129103 lbm_cons_t *cell = lbm_ref_cell(args[0]);
696 129103 r = cell->cdr;
697
2/2
✓ Branch 0 taken 1346 times.
✓ Branch 1 taken 258 times.
1604 } else if (lbm_is_symbol_nil(args[0])) {
698 1346 r = ENC_SYM_NIL;
699 } else {
700 258 r = ENC_SYM_TERROR;
701 }
702 }
703 130877 return r;
704 }
705
706 281605 static lbm_value fundamental_list(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
707 (void) ctx;
708 281605 lbm_value result = ENC_SYM_NIL;
709
2/2
✓ Branch 0 taken 417701 times.
✓ Branch 1 taken 281393 times.
699094 for (lbm_uint i = 1; i <= nargs; i ++) {
710 417701 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 212 times.
✓ Branch 1 taken 417489 times.
417701 if (lbm_type_of(result) == LBM_TYPE_SYMBOL)
714 212 break;
715 }
716 281605 return result;
717 }
718
719 155209 static lbm_value fundamental_append(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
720 (void) ctx;
721
2/2
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 155124 times.
155209 if (nargs == 0) return ENC_SYM_NIL;
722
4/4
✓ Branch 0 taken 169 times.
✓ Branch 1 taken 154955 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 85 times.
155124 if (nargs == 1 && !lbm_is_list(args[0])) {
723 84 lbm_set_error_suspect(args[0]);
724 84 return ENC_SYM_TERROR;
725 }
726 155040 lbm_value res = args[nargs-1];
727
2/2
✓ Branch 0 taken 205636 times.
✓ Branch 1 taken 154952 times.
360588 for (int i = (int)nargs -2; i >= 0; i --) {
728 205636 lbm_value curr = args[i];
729
2/2
✓ Branch 0 taken 88 times.
✓ Branch 1 taken 205548 times.
205636 if (!lbm_is_list(curr)) {
730 88 lbm_set_error_suspect(curr);
731 88 return ENC_SYM_TERROR;
732 }
733 205548 int n = 0;
734
2/2
✓ Branch 0 taken 249433 times.
✓ Branch 1 taken 205548 times.
454981 while (lbm_type_of_functional(curr) == LBM_TYPE_CONS) {
735 249433 n++;
736 249433 curr = lbm_cdr(curr);
737 }
738 205548 curr = args[i];
739
2/2
✓ Branch 0 taken 249433 times.
✓ Branch 1 taken 205548 times.
454981 for (int j = n-1; j >= 0; j --) {
740 249433 res = lbm_cons(lbm_index_list(curr,j),res);
741 }
742 }
743 154952 return(res);
744 }
745
746 5040677 static lbm_value fundamental_undefine(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
747 (void) ctx;
748 5040677 lbm_value *global_env = lbm_get_global_env();
749
4/4
✓ Branch 0 taken 5040675 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 5040506 times.
✓ Branch 3 taken 169 times.
5040677 if (nargs == 1 && lbm_is_symbol(args[0])) {
750 5040506 lbm_value key = args[0];
751 5040506 lbm_uint ix_key = lbm_dec_sym(key) & GLOBAL_ENV_MASK;
752 5040506 lbm_value env = global_env[ix_key];
753 5040506 lbm_value res = lbm_env_drop_binding(env, key);
754
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 5040422 times.
5040506 if (res == ENC_SYM_NOT_FOUND) {
755 84 return ENC_SYM_NIL;
756 }
757 5040422 global_env[ix_key] = res;
758 5040422 return ENC_SYM_TRUE;
759
3/4
✓ Branch 0 taken 169 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 169 times.
✗ Branch 3 not taken.
171 } else if (nargs == 1 && lbm_is_cons(args[0])) {
760 169 lbm_value curr = args[0];
761
2/2
✓ Branch 0 taken 339 times.
✓ Branch 1 taken 169 times.
508 while (lbm_type_of(curr) == LBM_TYPE_CONS) {
762 339 lbm_value key = lbm_car(curr);
763 339 lbm_uint ix_key = lbm_dec_sym(key) & GLOBAL_ENV_MASK;
764 339 lbm_value env = global_env[ix_key];
765 339 lbm_value res = lbm_env_drop_binding(env, key);
766
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 171 times.
339 if (res != ENC_SYM_NOT_FOUND) {
767 168 global_env[ix_key] = res;
768 }
769 339 curr = lbm_cdr(curr);
770 }
771 169 return ENC_SYM_TRUE;
772 }
773 2 return ENC_SYM_TERROR;
774 }
775
776 238138 static lbm_value fundamental_buf_create(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
777 (void) ctx;
778 238138 lbm_value result = ENC_SYM_EERROR;
779
4/4
✓ Branch 0 taken 69968 times.
✓ Branch 1 taken 168170 times.
✓ Branch 2 taken 69884 times.
✓ Branch 3 taken 84 times.
238138 if (nargs == 1 && IS_NUMBER(args[0])) {
780 69884 lbm_heap_allocate_array(&result, lbm_dec_as_u32(args[0]));
781
6/6
✓ Branch 0 taken 168086 times.
✓ Branch 1 taken 168 times.
✓ Branch 2 taken 168085 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 168000 times.
✓ Branch 5 taken 85 times.
168254 } else if (nargs == 2 && IS_NUMBER(args[1]) && lbm_type_of(args[0]) == LBM_TYPE_DEFRAG_MEM) {
782 168000 lbm_uint *dm = (lbm_uint*)lbm_car(args[0]);
783 168000 return lbm_defrag_mem_alloc(dm, lbm_dec_as_uint(args[1]));
784 }
785 70138 return result;
786 }
787
788 10383 static lbm_value fundamental_symbol_to_string(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
789 (void) ctx;
790 10383 lbm_value res = ENC_SYM_EERROR;
791
2/2
✓ Branch 0 taken 10297 times.
✓ Branch 1 taken 86 times.
10383 if (nargs == 1) {
792
2/2
✓ Branch 0 taken 10208 times.
✓ Branch 1 taken 89 times.
10297 if (lbm_type_of_functional(args[0]) == LBM_TYPE_SYMBOL) {
793 10208 lbm_value sym = args[0];
794 10208 const char *sym_str = lbm_get_name_by_symbol(lbm_dec_sym(sym));
795
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10208 times.
10208 if (sym_str == NULL) return ENC_SYM_NIL;
796 10208 size_t len = strlen(sym_str);
797 lbm_value v;
798
2/2
✓ Branch 0 taken 10183 times.
✓ Branch 1 taken 25 times.
10208 if (lbm_heap_allocate_array(&v, len+1)) {
799 10183 lbm_array_header_t *arr = (lbm_array_header_t*)lbm_car(v);
800 10183 memset(arr->data,0,len+1);
801 10183 memcpy(arr->data,sym_str,len);
802 10183 res = v;
803 } else {
804 25 res = ENC_SYM_MERROR;
805 }
806 } else {
807 89 res = ENC_SYM_TERROR;
808 }
809 }
810 10383 return res;
811 }
812
813 360 static lbm_value fundamental_string_to_symbol(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
814 (void) ctx;
815 360 lbm_value result = ENC_SYM_EERROR;
816
2/2
✓ Branch 0 taken 274 times.
✓ Branch 1 taken 86 times.
360 if (nargs == 1) {
817 274 result = ENC_SYM_TERROR;
818 274 lbm_array_header_t *arr = lbm_dec_array_r(args[0]);
819
2/2
✓ Branch 0 taken 186 times.
✓ Branch 1 taken 88 times.
274 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 186 char *str = (char *)arr->data;
825 186 lbm_uint sym = ENC_SYM_NIL;
826 186 lbm_str_to_symbol(str,&sym);
827 186 result = lbm_enc_sym(sym);
828 }
829 }
830 360 return result;
831 }
832
833 420 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 84 times.
✓ Branch 1 taken 336 times.
420 if (nargs < 1) return ENC_SYM_EERROR;
836 336 lbm_value s = args[0];
837
2/2
✓ Branch 0 taken 252 times.
✓ Branch 1 taken 84 times.
336 if (lbm_is_symbol(s))
838 252 return lbm_enc_u(lbm_dec_sym(s));
839
840 84 lbm_set_error_suspect(s);
841 84 return ENC_SYM_TERROR;
842 }
843
844 336 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 84 times.
✓ Branch 1 taken 252 times.
336 if (nargs < 1) return ENC_SYM_EERROR;
847 252 lbm_value s = args[0];
848
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 84 times.
252 if (lbm_type_of_functional(s) == LBM_TYPE_U)
849 168 return lbm_enc_sym(lbm_dec_u(s));
850
851 84 lbm_set_error_suspect(s);
852 84 return ENC_SYM_TERROR;
853 }
854
855 343 static lbm_value fundamental_set_car(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
856 (void) ctx;
857 343 lbm_value res = ENC_SYM_EERROR;
858
2/2
✓ Branch 0 taken 342 times.
✓ Branch 1 taken 1 times.
343 if (nargs == 2) {
859
2/2
✓ Branch 0 taken 258 times.
✓ Branch 1 taken 84 times.
342 res = lbm_set_car(args[0], args[1]) ? ENC_SYM_TRUE : ENC_SYM_NIL;
860 }
861 343 return res;
862 }
863
864 347 static lbm_value fundamental_set_cdr(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
865 (void) ctx;
866 347 lbm_value res = ENC_SYM_EERROR;
867
2/2
✓ Branch 0 taken 346 times.
✓ Branch 1 taken 1 times.
347 if (nargs == 2) {
868
2/2
✓ Branch 0 taken 262 times.
✓ Branch 1 taken 84 times.
346 res = lbm_set_cdr(args[0],args[1]) ? ENC_SYM_TRUE : ENC_SYM_NIL;
869 }
870 347 return res;
871 }
872
873 1685247 static lbm_value fundamental_set_ix(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
874 (void) ctx;
875 1685247 lbm_value result = ENC_SYM_TERROR;
876
4/4
✓ Branch 0 taken 1685245 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1685244 times.
✓ Branch 3 taken 1 times.
1685247 if (nargs == 3 && IS_NUMBER(args[1])) {
877
2/2
✓ Branch 0 taken 348 times.
✓ Branch 1 taken 1684896 times.
1685244 if (lbm_is_list_rw(args[0])) {
878 348 lbm_value curr = args[0];
879 348 lbm_uint i = 0;
880 348 lbm_int ix_pre = lbm_dec_as_i32(args[1]);
881
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 347 times.
348 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 348 lbm_uint ix = (lbm_uint)ix_pre;
886
2/2
✓ Branch 0 taken 1383 times.
✓ Branch 1 taken 1 times.
1384 while (lbm_is_cons_rw(curr)) { // rw as we are going to modify
887 1383 lbm_value next = lbm_cdr(curr);
888
2/2
✓ Branch 0 taken 263 times.
✓ Branch 1 taken 1120 times.
1383 if (i == ix) {
889 263 lbm_set_car(curr, args[2]);
890 263 result = args[0]; // Acts as true and as itself.
891 263 break;
892
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 1036 times.
1120 } else if (lbm_is_symbol_nil(next)) {
893 84 result = ENC_SYM_NIL; // index out of bounds, no update.
894 84 break;
895 }
896 1036 curr = next;
897 1036 i++;
898 }
899
2/2
✓ Branch 0 taken 1684895 times.
✓ Branch 1 taken 1 times.
1684896 } else if (lbm_is_lisp_array_rw(args[0])) {
900 1684895 int32_t index = lbm_dec_as_i32(args[1]);
901 1684895 lbm_array_header_t *header = (lbm_array_header_t*)lbm_car(args[0]);
902 1684895 lbm_value *arrdata = (lbm_value*)header->data;
903 1684895 lbm_uint size = header->size / sizeof(lbm_value);
904
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1684894 times.
1684895 if (index < 0) index = (int32_t)size + index;
905
2/2
✓ Branch 0 taken 1684894 times.
✓ Branch 1 taken 1 times.
1684895 if ((uint32_t)index < size) {
906 1684894 arrdata[index] = args[2]; // value
907 1684894 result = args[0];
908 } // index out of range will be eval error.
909 }
910 }
911 1685247 return result;
912 }
913
914 1295 static lbm_value fundamental_assoc(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
915 (void) ctx;
916 1295 lbm_value result = ENC_SYM_EERROR;
917
2/2
✓ Branch 0 taken 1209 times.
✓ Branch 1 taken 86 times.
1295 if (nargs == 2) {
918
2/2
✓ Branch 0 taken 1034 times.
✓ Branch 1 taken 175 times.
1209 if (lbm_is_cons(args[0])) {
919 1034 lbm_value r = assoc_lookup(args[1], args[0]);
920
4/4
✓ Branch 0 taken 930 times.
✓ Branch 1 taken 104 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 846 times.
1034 if (lbm_is_symbol(r) &&
921 r == ENC_SYM_NO_MATCH) {
922 84 result = ENC_SYM_NIL;
923 } else {
924 950 result = r;
925 }
926
2/2
✓ Branch 0 taken 174 times.
✓ Branch 1 taken 1 times.
175 } else if (lbm_is_symbol(args[0]) &&
927
2/2
✓ Branch 0 taken 89 times.
✓ Branch 1 taken 85 times.
174 args[0] == ENC_SYM_NIL) {
928 89 result = args[0]; /* nil */
929 } /* else error */
930 }
931 1295 return result;
932 }
933
934 390239 static lbm_value fundamental_acons(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
935 (void) ctx;
936 390239 lbm_value result = ENC_SYM_TERROR;
937
2/2
✓ Branch 0 taken 389986 times.
✓ Branch 1 taken 253 times.
390239 if (nargs == 3) {
938 389986 lbm_value keyval = lbm_cons(args[0], args[1]);
939 389986 lbm_value new_alist = lbm_cons(keyval, args[2]);
940
941
4/4
✓ Branch 0 taken 389482 times.
✓ Branch 1 taken 504 times.
✓ Branch 2 taken 42 times.
✓ Branch 3 taken 389440 times.
779468 if (lbm_is_symbol(keyval) ||
942 389482 lbm_is_symbol(new_alist) )
943 546 result = ENC_SYM_MERROR;
944 else
945 389440 result = new_alist;
946
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 252 times.
253 } else if (nargs == 2) {
947 1 result = lbm_cons(args[0], args[1]);
948 }
949 390239 return result;
950 }
951
952 340 static lbm_value set_assoc(lbm_value assoc_list, lbm_value keyval) {
953 340 lbm_value curr = assoc_list;
954 340 lbm_value key = lbm_car(keyval);
955
2/2
✓ Branch 0 taken 672 times.
✓ Branch 1 taken 88 times.
760 while (lbm_is_cons(curr)) {
956
2/2
✓ Branch 0 taken 252 times.
✓ Branch 1 taken 420 times.
672 if (struct_eq(key, lbm_caar(curr))) {
957 252 lbm_set_car(curr, keyval);
958 252 return assoc_list;
959 }
960 420 curr = lbm_cdr(curr);
961 }
962 // Assoc-list does not contain key.
963 // Note: Memory errors are implicitly handled by the caller.
964 88 return lbm_cons(keyval, assoc_list);
965 }
966
967 342 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 252 times.
✓ Branch 1 taken 90 times.
342 if (nargs == 3) {
971 252 keyval = lbm_cons(args[1], args[2]);
972 // Check if ENC_SYM_MERROR.
973
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 252 times.
252 if (lbm_is_symbol(keyval)) return keyval;
974
4/4
✓ Branch 0 taken 89 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 88 times.
✓ Branch 3 taken 1 times.
90 } else if (nargs == 2 && lbm_is_cons(args[1])) {
975 88 keyval = args[1];
976 2 } else return ENC_SYM_TERROR;
977 340 return set_assoc(args[0], keyval);
978 }
979
980 1262 static lbm_value fundamental_cossa(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
981 (void) ctx;
982 1262 lbm_value result = ENC_SYM_EERROR;
983
2/2
✓ Branch 0 taken 1178 times.
✓ Branch 1 taken 84 times.
1262 if (nargs == 2) {
984
2/2
✓ Branch 0 taken 1010 times.
✓ Branch 1 taken 168 times.
1178 if (lbm_is_cons(args[0])) {
985 1010 lbm_value r = cossa_lookup(args[1], args[0]);
986
4/4
✓ Branch 0 taken 674 times.
✓ Branch 1 taken 336 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 590 times.
1010 if (lbm_is_symbol(r) &&
987 r == ENC_SYM_NO_MATCH) {
988 84 result = ENC_SYM_NIL;
989 } else {
990 926 result = r;
991 }
992
1/2
✓ Branch 0 taken 168 times.
✗ Branch 1 not taken.
168 } else if (lbm_is_symbol(args[0]) &&
993
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 84 times.
168 args[0] == ENC_SYM_NIL) {
994 84 result = args[0]; /* nil */
995 } /* else error */
996 }
997 1262 return result;
998 }
999
1000 97347 static lbm_value fundamental_ix(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1001 (void) ctx;
1002 97347 lbm_value result = ENC_SYM_EERROR;
1003
4/4
✓ Branch 0 taken 97345 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 97342 times.
✓ Branch 3 taken 3 times.
97347 if (nargs == 2 && IS_NUMBER(args[1])) {
1004 97342 result = ENC_SYM_NIL;
1005
2/2
✓ Branch 0 taken 68609 times.
✓ Branch 1 taken 28733 times.
97342 if (lbm_is_list(args[0])) {
1006 68609 result = lbm_index_list(args[0], lbm_dec_as_i32(args[1]));
1007
2/2
✓ Branch 0 taken 28727 times.
✓ Branch 1 taken 6 times.
28733 } else if (lbm_is_lisp_array_r(args[0])) {
1008 28727 lbm_array_header_t *header = (lbm_array_header_t*)lbm_car(args[0]);
1009 28727 lbm_value *arrdata = (lbm_value*)header->data;
1010 28727 lbm_uint size = header->size / sizeof(lbm_value);
1011 28727 int32_t index = lbm_dec_as_i32(args[1]);
1012
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 28726 times.
28727 if (index < 0) index = (int32_t)size + index;
1013
1/2
✓ Branch 0 taken 28727 times.
✗ Branch 1 not taken.
28727 if ((uint32_t)index < size) {
1014 28727 result = arrdata[index];
1015 }
1016 }
1017 }
1018 97347 return result;
1019 }
1020
1021 873 static lbm_value fundamental_to_i(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1022 (void) ctx;
1023 873 lbm_value result = ENC_SYM_EERROR;
1024
2/2
✓ Branch 0 taken 787 times.
✓ Branch 1 taken 86 times.
873 if (nargs == 1) {
1025 787 result = lbm_enc_i((lbm_int)lbm_dec_as_i64(args[0]));
1026 }
1027 873 return result;
1028 }
1029
1030 952 static lbm_value fundamental_to_i32(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1031 (void) ctx;
1032 952 lbm_value result = ENC_SYM_EERROR;
1033
2/2
✓ Branch 0 taken 868 times.
✓ Branch 1 taken 84 times.
952 if (nargs == 1) {
1034 868 result = lbm_enc_i32(lbm_dec_as_i32(args[0]));
1035 }
1036 952 return result;
1037 }
1038
1039 840 static lbm_value fundamental_to_u(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1040 (void) ctx;
1041 840 lbm_value result = ENC_SYM_EERROR;
1042
2/2
✓ Branch 0 taken 756 times.
✓ Branch 1 taken 84 times.
840 if (nargs == 1) {
1043 756 result = lbm_enc_u((lbm_uint)lbm_dec_as_u64(args[0]));
1044 }
1045 840 return result;
1046 }
1047
1048 840 static lbm_value fundamental_to_u32(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1049 (void) ctx;
1050 840 lbm_value result = ENC_SYM_EERROR;
1051
2/2
✓ Branch 0 taken 756 times.
✓ Branch 1 taken 84 times.
840 if (nargs == 1) {
1052 756 result = lbm_enc_u32(lbm_dec_as_u32(args[0]));
1053 }
1054 840 return result;
1055 }
1056
1057 769 static lbm_value fundamental_to_float(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1058 (void) ctx;
1059 769 lbm_value result = ENC_SYM_EERROR;
1060
2/2
✓ Branch 0 taken 683 times.
✓ Branch 1 taken 86 times.
769 if (nargs == 1) {
1061 683 result = lbm_enc_float(lbm_dec_as_float(args[0]));
1062 }
1063 769 return result;
1064 }
1065
1066 840 static lbm_value fundamental_to_i64(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1067 (void) ctx;
1068 840 lbm_value result = ENC_SYM_EERROR;
1069
2/2
✓ Branch 0 taken 756 times.
✓ Branch 1 taken 84 times.
840 if (nargs == 1) {
1070 756 result = lbm_enc_i64(lbm_dec_as_i64(args[0]));
1071 }
1072 840 return result;
1073 }
1074
1075 840 static lbm_value fundamental_to_u64(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1076 (void) ctx;
1077 840 lbm_value result = ENC_SYM_EERROR;
1078
2/2
✓ Branch 0 taken 756 times.
✓ Branch 1 taken 84 times.
840 if (nargs == 1) {
1079 756 result = lbm_enc_u64(lbm_dec_as_u64(args[0]));
1080 }
1081 840 return result;
1082 }
1083
1084 758 static lbm_value fundamental_to_double(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1085 (void) ctx;
1086 758 lbm_value result = ENC_SYM_EERROR;
1087
2/2
✓ Branch 0 taken 674 times.
✓ Branch 1 taken 84 times.
758 if (nargs == 1) {
1088 674 result = lbm_enc_double(lbm_dec_as_double(args[0]));
1089 }
1090 758 return result;
1091 }
1092
1093 765 static lbm_value fundamental_to_byte(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1094 (void) ctx;
1095 765 lbm_value result = ENC_SYM_EERROR;
1096
2/2
✓ Branch 0 taken 681 times.
✓ Branch 1 taken 84 times.
765 if (nargs == 1) {
1097 681 result = lbm_enc_char(lbm_dec_as_char(args[0]));
1098 }
1099 765 return result;
1100 }
1101
1102 1010 static lbm_value fundamental_shl(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1103 (void) ctx;
1104 1010 lbm_value retval = ENC_SYM_EERROR;
1105
2/2
✓ Branch 0 taken 926 times.
✓ Branch 1 taken 84 times.
1010 if (nargs == 2) {
1106 926 retval = ENC_SYM_TERROR;
1107
4/4
✓ Branch 0 taken 842 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 758 times.
✓ Branch 3 taken 84 times.
926 if (IS_NUMBER(args[0]) && IS_NUMBER(args[1])) {
1108
8/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 169 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 84 times.
✓ Branch 6 taken 84 times.
✓ Branch 7 taken 168 times.
758 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 169 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) << lbm_dec_as_u32(args[1])); break;
1111 84 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) << lbm_dec_as_u32(args[1])); break;
1112 84 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_u32(args[0]) << lbm_dec_as_u32(args[1])); break;
1113 84 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_i32(args[0]) << lbm_dec_as_u32(args[1])); break;
1114 84 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_i64(args[0]) << lbm_dec_as_u32(args[1])); break;
1115 84 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_u64(args[0]) << lbm_dec_as_u32(args[1])); break;
1116 }
1117 }
1118 }
1119 1010 return retval;
1120 }
1121
1122 1010 static lbm_value fundamental_shr(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1123 (void) ctx;
1124 1010 lbm_value retval = ENC_SYM_EERROR;
1125
2/2
✓ Branch 0 taken 926 times.
✓ Branch 1 taken 84 times.
1010 if (nargs == 2) {
1126 926 retval = ENC_SYM_TERROR;
1127
4/4
✓ Branch 0 taken 842 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 758 times.
✓ Branch 3 taken 84 times.
926 if (IS_NUMBER(args[0]) && IS_NUMBER(args[1])) {
1128
8/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 169 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 84 times.
✓ Branch 6 taken 84 times.
✓ Branch 7 taken 168 times.
758 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 169 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) >> lbm_dec_as_u32(args[1])); break;
1131 84 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) >> lbm_dec_as_u32(args[1])); break;
1132 84 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_u32(args[0]) >> lbm_dec_as_u32(args[1])); break;
1133 84 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_i32(args[0]) >> lbm_dec_as_u32(args[1])); break;
1134 84 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_i64(args[0]) >> lbm_dec_as_u32(args[1])); break;
1135 84 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_u64(args[0]) >> lbm_dec_as_u32(args[1])); break;
1136 }
1137 }
1138 }
1139 1010 return retval;
1140 }
1141
1142 1010 static lbm_value fundamental_bitwise_and(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1143 (void) ctx;
1144 1010 lbm_value retval = ENC_SYM_EERROR;
1145
2/2
✓ Branch 0 taken 926 times.
✓ Branch 1 taken 84 times.
1010 if (nargs == 2) {
1146 926 retval = ENC_SYM_TERROR;
1147
4/4
✓ Branch 0 taken 842 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 758 times.
✓ Branch 3 taken 84 times.
926 if (IS_NUMBER(args[0]) && IS_NUMBER(args[1])) {
1148
8/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 169 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 84 times.
✓ Branch 6 taken 84 times.
✓ Branch 7 taken 168 times.
758 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 56 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) & lbm_dec_as_i64(args[1])); break;
1152 28 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) & lbm_dec_as_u64(args[1])); break;
1153 #else
1154 113 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) & lbm_dec_as_i32(args[1])); break;
1155 56 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) & lbm_dec_as_u32(args[1])); break;
1156 #endif
1157 84 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_u32(args[0]) & lbm_dec_as_u32(args[1])); break;
1158 84 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_i32(args[0]) & lbm_dec_as_i32(args[1])); break;
1159 84 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_i64(args[0]) & lbm_dec_as_i64(args[1])); break;
1160 84 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_u64(args[0]) & lbm_dec_as_u64(args[1])); break;
1161 }
1162 }
1163 }
1164 1010 return retval;
1165 }
1166
1167 1010 static lbm_value fundamental_bitwise_or(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1168 (void) ctx;
1169 1010 lbm_value retval = ENC_SYM_EERROR;
1170
2/2
✓ Branch 0 taken 926 times.
✓ Branch 1 taken 84 times.
1010 if (nargs == 2) {
1171 926 retval = ENC_SYM_TERROR;
1172
4/4
✓ Branch 0 taken 842 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 758 times.
✓ Branch 3 taken 84 times.
926 if (IS_NUMBER(args[0]) && IS_NUMBER(args[1])) {
1173
8/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 169 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 84 times.
✓ Branch 6 taken 84 times.
✓ Branch 7 taken 168 times.
758 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 56 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) | lbm_dec_as_i64(args[1])); break;
1177 28 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) | lbm_dec_as_u64(args[1])); break;
1178 #else
1179 113 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) | lbm_dec_as_i32(args[1])); break;
1180 56 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) | lbm_dec_as_u32(args[1])); break;
1181 #endif
1182 84 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_u32(args[0]) | lbm_dec_as_u32(args[1])); break;
1183 84 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_i32(args[0]) | lbm_dec_as_i32(args[1])); break;
1184 84 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_i64(args[0]) | lbm_dec_as_i64(args[1])); break;
1185 84 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_u64(args[0]) | lbm_dec_as_u64(args[1])); break;
1186 }
1187 }
1188 }
1189 1010 return retval;
1190 }
1191
1192 1010 static lbm_value fundamental_bitwise_xor(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1193 (void) ctx;
1194 1010 lbm_value retval = ENC_SYM_EERROR;
1195
2/2
✓ Branch 0 taken 926 times.
✓ Branch 1 taken 84 times.
1010 if (nargs == 2) {
1196 926 retval = ENC_SYM_TERROR;
1197
4/4
✓ Branch 0 taken 842 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 758 times.
✓ Branch 3 taken 84 times.
926 if (IS_NUMBER(args[0]) && IS_NUMBER(args[1])) {
1198
8/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 169 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 84 times.
✓ Branch 6 taken 84 times.
✓ Branch 7 taken 168 times.
758 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 56 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) ^ lbm_dec_as_i64(args[1])); break;
1202 28 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) ^ lbm_dec_as_u64(args[1])); break;
1203 #else
1204 113 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) ^ lbm_dec_as_i32(args[1])); break;
1205 56 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) ^ lbm_dec_as_u32(args[1])); break;
1206 #endif
1207 84 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_u32(args[0]) ^ lbm_dec_as_u32(args[1])); break;
1208 84 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_i32(args[0]) ^ lbm_dec_as_i32(args[1])); break;
1209 84 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_i64(args[0]) ^ lbm_dec_as_i64(args[1])); break;
1210 84 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_u64(args[0]) ^ lbm_dec_as_u64(args[1])); break;
1211 }
1212 }
1213 }
1214 1010 return retval;
1215 }
1216
1217 842 static lbm_value fundamental_bitwise_not(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1218 (void) ctx;
1219 842 lbm_value retval = ENC_SYM_EERROR;
1220
2/2
✓ Branch 0 taken 758 times.
✓ Branch 1 taken 84 times.
842 if (nargs == 1) {
1221 758 retval = ENC_SYM_TERROR;
1222
2/2
✓ Branch 0 taken 674 times.
✓ Branch 1 taken 84 times.
758 if (IS_NUMBER(args[0])) {
1223
8/8
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 85 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 84 times.
✓ Branch 6 taken 84 times.
✓ Branch 7 taken 168 times.
674 switch (lbm_type_of_functional(args[0])) {
1224 1 case LBM_TYPE_CHAR: retval = lbm_enc_char(~lbm_dec_char(args[0])); break;
1225 85 case LBM_TYPE_I: retval = lbm_enc_i(~lbm_dec_i(args[0])); break;
1226 84 case LBM_TYPE_U: retval = lbm_enc_u(~lbm_dec_u(args[0])); break;
1227 84 case LBM_TYPE_U32: retval = lbm_enc_u32(~lbm_dec_u32(args[0])); break;
1228 84 case LBM_TYPE_I32: retval = lbm_enc_i32(~lbm_dec_i32(args[0])); break;
1229 84 case LBM_TYPE_I64: retval = lbm_enc_i64(~lbm_dec_i64(args[0])); break;
1230 84 case LBM_TYPE_U64: retval = lbm_enc_u64(~lbm_dec_u64(args[0])); break;
1231 }
1232 }
1233 }
1234 842 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 50651 static lbm_value fundamental_type_of(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1254 (void) ctx;
1255 50651 lbm_value res = ENC_SYM_EERROR;
1256
2/2
✓ Branch 0 taken 50649 times.
✓ Branch 1 taken 2 times.
50651 if (nargs == 1) {
1257 50649 lbm_value val = args[0];
1258 50649 lbm_type t = lbm_type_of(val);
1259
1260
2/2
✓ Branch 0 taken 30252 times.
✓ Branch 1 taken 20397 times.
50649 if (lbm_is_ptr(val)) {
1261 // Ignore constant or not constant.
1262 30252 t &= LBM_PTR_TO_CONSTANT_MASK;
1263 }
1264
15/16
✓ Branch 0 taken 15769 times.
✓ Branch 1 taken 338 times.
✓ Branch 2 taken 1708 times.
✓ Branch 3 taken 2212 times.
✓ Branch 4 taken 5377 times.
✓ Branch 5 taken 2016 times.
✓ Branch 6 taken 2352 times.
✓ Branch 7 taken 3193 times.
✓ Branch 8 taken 3685 times.
✓ Branch 9 taken 9949 times.
✓ Branch 10 taken 168 times.
✓ Branch 11 taken 3795 times.
✓ Branch 12 taken 84 times.
✓ Branch 13 taken 1 times.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
50649 switch(t) {
1265 15769 case LBM_TYPE_CONS: res = ENC_SYM_TYPE_LIST; break;
1266 338 case LBM_TYPE_ARRAY: res = ENC_SYM_TYPE_ARRAY; break;
1267 1708 case LBM_TYPE_I32: res = ENC_SYM_TYPE_I32; break;
1268 2212 case LBM_TYPE_U32: res = ENC_SYM_TYPE_U32; break;
1269 5377 case LBM_TYPE_FLOAT: res = ENC_SYM_TYPE_FLOAT; break;
1270 2016 case LBM_TYPE_I64: res = ENC_SYM_TYPE_I64; break;
1271 2352 case LBM_TYPE_U64: res = ENC_SYM_TYPE_U64; break;
1272 3193 case LBM_TYPE_DOUBLE: res = ENC_SYM_TYPE_DOUBLE; break;
1273 3685 case LBM_TYPE_I: res = ENC_SYM_TYPE_I; break;
1274 9949 case LBM_TYPE_U: res = ENC_SYM_TYPE_U; break;
1275 168 case LBM_TYPE_CHAR: res = ENC_SYM_TYPE_CHAR; break;
1276 3795 case LBM_TYPE_SYMBOL: res = ENC_SYM_TYPE_SYMBOL; break;
1277 84 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 50651 return res;
1283 }
1284
1285 5100 static lbm_value fundamental_list_length(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1286 (void) ctx;
1287 5100 lbm_value result = ENC_SYM_EERROR;
1288
2/2
✓ Branch 0 taken 5014 times.
✓ Branch 1 taken 86 times.
5100 if (nargs == 1) {
1289 5014 result = ENC_SYM_TERROR;
1290
2/2
✓ Branch 0 taken 3489 times.
✓ Branch 1 taken 1525 times.
5014 if (lbm_is_list(args[0])) {
1291 3489 int32_t len = (int32_t)lbm_list_length(args[0]);
1292 3489 result = lbm_enc_i(len);
1293
2/2
✓ Branch 0 taken 1096 times.
✓ Branch 1 taken 429 times.
1525 } else if (lbm_is_array_r(args[0])) {
1294 1096 lbm_array_header_t *header = (lbm_array_header_t*)lbm_car(args[0]);
1295 1096 result = lbm_enc_i((int)(header->size));
1296
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 173 times.
429 } else if (lbm_is_lisp_array_r(args[0])) {
1297 256 lbm_array_header_t *header = (lbm_array_header_t*)lbm_car(args[0]);
1298 256 result = lbm_enc_i((int)(header->size / (sizeof(lbm_uint))));
1299 }
1300 }
1301 5100 return result;
1302 }
1303
1304 18282238 static lbm_value fundamental_range(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1305 (void) ctx;
1306 18282238 lbm_value result = ENC_SYM_EERROR;
1307
1308 int32_t start;
1309 int32_t end;
1310 18282238 bool rev = false;
1311
1312
4/4
✓ Branch 0 taken 17406354 times.
✓ Branch 1 taken 875884 times.
✓ Branch 2 taken 17406270 times.
✓ Branch 3 taken 84 times.
18282238 if (nargs == 1 && IS_NUMBER(args[0])) {
1313 17406270 start = 0;
1314 17406270 end = lbm_dec_as_i32(args[0]);
1315
4/4
✓ Branch 0 taken 875800 times.
✓ Branch 1 taken 168 times.
✓ Branch 2 taken 875716 times.
✓ Branch 3 taken 84 times.
1751768 } else if (nargs == 2 &&
1316
2/2
✓ Branch 0 taken 875632 times.
✓ Branch 1 taken 84 times.
1751516 IS_NUMBER(args[0]) &&
1317 875716 IS_NUMBER(args[1])) {
1318 875632 start = lbm_dec_as_i32(args[0]);
1319 875632 end = lbm_dec_as_i32(args[1]);
1320 } else {
1321 336 return result;
1322 }
1323
1324
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 18281818 times.
18281902 if (end == start) return ENC_SYM_NIL;
1325
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 18281650 times.
18281818 else if (end < start) {
1326 168 int32_t tmp = end;
1327 168 end = start;
1328 168 start = tmp;
1329 168 rev = true;
1330 }
1331
1332 18281818 int num = end - start;
1333
1334
2/2
✓ Branch 0 taken 598426 times.
✓ Branch 1 taken 17683392 times.
18281818 if ((unsigned int)num > lbm_heap_num_free()) {
1335 598426 return ENC_SYM_MERROR;
1336 }
1337
1338 17683392 lbm_value r_list = ENC_SYM_NIL;
1339
2/2
✓ Branch 0 taken 896200575 times.
✓ Branch 1 taken 17683392 times.
913883967 for (int i = end - 1; i >= start; i --) {
1340 896200575 r_list = lbm_cons(lbm_enc_i(i), r_list);
1341 }
1342
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 17683224 times.
17683392 return rev ? lbm_list_destructive_reverse(r_list) : r_list;
1343 }
1344
1345 840 static lbm_value fundamental_reg_event_handler(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1346 (void) ctx;
1347 840 lbm_value res = ENC_SYM_TERROR;
1348
4/4
✓ Branch 0 taken 756 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 672 times.
✓ Branch 3 taken 84 times.
840 if (nargs == 1 && IS_NUMBER(args[0])) {
1349 672 lbm_set_event_handler_pid((lbm_cid)lbm_dec_i(args[0]));
1350 672 res = ENC_SYM_TRUE;
1351 }
1352 840 return res;
1353 }
1354
1355 103458 static lbm_value fundamental_take(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1356 (void) ctx;
1357 103458 lbm_value res = ENC_SYM_TERROR;
1358
6/6
✓ Branch 0 taken 103374 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 103290 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 103206 times.
✓ Branch 5 taken 84 times.
103458 if (nargs == 2 && IS_NUMBER(args[1]) && lbm_is_list(args[0])) {
1359 103206 int len = lbm_dec_as_i32(args[1]);
1360 103206 res = lbm_list_copy(&len, args[0]);
1361 }
1362 103458 return res;
1363 }
1364
1365 504 static lbm_value fundamental_drop(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1366 (void) ctx;
1367 504 lbm_value res = ENC_SYM_TERROR;
1368
6/6
✓ Branch 0 taken 420 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 336 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 252 times.
✓ Branch 5 taken 84 times.
504 if (nargs == 2 && IS_NUMBER(args[1]) && lbm_is_list(args[0])) {
1369 252 res = lbm_list_drop(lbm_dec_as_u32(args[1]), args[0]);
1370 }
1371 504 return res;
1372 }
1373 /* (mkarray size) */
1374 845117 static lbm_value fundamental_mkarray(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1375 (void) ctx;
1376 845117 lbm_value res = ENC_SYM_TERROR;
1377
2/4
✓ Branch 0 taken 845117 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 845117 times.
✗ Branch 3 not taken.
845117 if (nargs == 1 && IS_NUMBER(args[0])) {
1378 845117 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 845117 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 505 static lbm_value fundamental_dm_create(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1404 (void) ctx;
1405 505 lbm_value res = ENC_SYM_TERROR;
1406
2/4
✓ Branch 0 taken 505 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505 times.
✗ Branch 3 not taken.
505 if (argn == 1 && lbm_is_number(args[0])) {
1407 505 lbm_uint n = lbm_dec_as_uint(args[0]);
1408 505 res = lbm_defrag_mem_create(n);
1409 }
1410 505 return res;
1411 }
1412
1413 6356 static lbm_value fundamental_dm_alloc(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1414 (void) ctx;
1415 6356 lbm_value res = ENC_SYM_TERROR;
1416
2/4
✓ Branch 0 taken 6356 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6356 times.
✗ Branch 3 not taken.
6356 if (argn == 2 && lbm_is_number(args[1])) {
1417
1/2
✓ Branch 0 taken 6356 times.
✗ Branch 1 not taken.
6356 if (lbm_type_of(args[0]) == LBM_TYPE_DEFRAG_MEM) {
1418 6356 lbm_uint *dm = (lbm_uint*)lbm_car(args[0]);
1419 6356 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 6356 return res;
1430 }
1431
1432 448 static lbm_value fundamental_is_list(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1433 (void) ctx;
1434 448 lbm_value res = ENC_SYM_TERROR;
1435
2/2
✓ Branch 0 taken 446 times.
✓ Branch 1 taken 2 times.
448 if (argn == 1) {
1436
2/2
✓ Branch 0 taken 273 times.
✓ Branch 1 taken 173 times.
446 res = lbm_is_list(args[0]) ? ENC_SYM_TRUE : ENC_SYM_NIL;
1437 }
1438 448 return res;
1439 }
1440
1441 947 static lbm_value fundamental_is_number(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1442 (void) ctx;
1443 947 lbm_value res = ENC_SYM_TERROR;
1444
2/2
✓ Branch 0 taken 945 times.
✓ Branch 1 taken 2 times.
947 if (argn == 1) {
1445
2/2
✓ Branch 0 taken 603 times.
✓ Branch 1 taken 342 times.
945 res = lbm_is_number(args[0]) ? ENC_SYM_TRUE : ENC_SYM_NIL;
1446 }
1447 947 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 168 static lbm_value fundamental_identity(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1467 (void) ctx;
1468 168 lbm_value res = ENC_SYM_TERROR;
1469
1/2
✓ Branch 0 taken 168 times.
✗ Branch 1 not taken.
168 if (argn == 1) {
1470 168 res = args[0];
1471 }
1472 168 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 2942 static lbm_value fundamental_member(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1500 (void)ctx;
1501 2942 lbm_value res = ENC_SYM_TERROR;
1502
3/4
✓ Branch 0 taken 2606 times.
✓ Branch 1 taken 336 times.
✓ Branch 2 taken 2606 times.
✗ Branch 3 not taken.
2942 if (argn == 2 && lbm_is_list(args[1])) {
1503 2606 res = ENC_SYM_NIL;
1504 2606 lbm_value curr = args[1];
1505
1506
2/2
✓ Branch 0 taken 5726 times.
✓ Branch 1 taken 504 times.
6230 while (lbm_is_cons(curr)) {
1507
2/2
✓ Branch 0 taken 2102 times.
✓ Branch 1 taken 3624 times.
5726 if (struct_eq(lbm_car(curr), args[0])) {
1508 2102 res = args[1];
1509 2102 break;
1510 }
1511 3624 curr = lbm_cdr(curr);
1512 }
1513 }
1514 2942 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