GCC Code Coverage Report


Directory: ../src/
File: /home/joels/Current/lispbm/src/fundamental.c
Date: 2024-11-05 17:11:09
Exec Total Coverage
Lines: 842 860 97.9%
Functions: 76 77 98.7%
Branches: 575 639 90.0%

Line Branch Exec Source
1 /*
2 Copyright 2019, 2021 - 2024 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
30 #include <stdio.h>
31 #include <math.h>
32
33 /* Type promotion ranks
34
35 32bit LBM:
36 byte < i < u < i32 < u32 < i64 < u64 < float < double
37
38 64bit LBM:
39 byte < i32 < u32 < i < u < i64 < u64 < float < double
40 */
41
42 // PROMOTE_SWAP is for commutative operations
43 // PROMOTE is for non-commutative operations
44
45 #ifndef LBM64
46 #define PROMOTE_SWAP(t, a, b) \
47 if (lbm_type_of_functional(a) < lbm_type_of_functional(b)) { \
48 lbm_value tmp = a; \
49 a = b; \
50 b = tmp; \
51 } \
52 t = lbm_type_of_functional(a);
53 #else
54 #define PROMOTE_SWAP(t, a, b) \
55 if (lbm_type_of_functional(b) == LBM_TYPE_FLOAT && (lbm_type_of_functional(a) < LBM_TYPE_DOUBLE)) { \
56 lbm_value tmp = a; \
57 a = b; \
58 b = tmp; \
59 } if (lbm_type_of_functional(a) == LBM_TYPE_FLOAT && (lbm_type_of_functional(b) < LBM_TYPE_DOUBLE)) { \
60 /* DO NOTHING */ \
61 } else if (lbm_type_of_functional(a) < lbm_type_of_functional(b)) { \
62 lbm_value tmp = a; \
63 a = b; \
64 b = tmp; \
65 } \
66 t = lbm_type_of_functional(a);
67 #endif
68
69 #ifndef LBM64
70 #define PROMOTE(t, a, b) \
71 t = lbm_type_of_functional(a); \
72 lbm_uint t_b = lbm_type_of_functional(b); \
73 if (t < t_b) { \
74 t = t_b; \
75 }
76
77 #else
78 #define PROMOTE(t, a, b) \
79 if (lbm_type_of_functional(b) == LBM_TYPE_FLOAT) { \
80 if (lbm_type_of_functional(a) < LBM_TYPE_DOUBLE) { \
81 t = LBM_TYPE_FLOAT; \
82 } else { \
83 t = lbm_type_of_functional(a); \
84 } \
85 } else if (lbm_type_of_functional(a) < lbm_type_of_functional(b)) { \
86 t = lbm_type_of_functional(b); \
87 } else { \
88 t = lbm_type_of_functional(a); \
89 }
90 #endif
91
92
93 #define IS_NUMBER lbm_is_number
94
95 // Todo: It may be possible perform some of these operations
96 // on encoded values followed by a "correction" of the result values
97 // type bits.
98 // But the checks required to figure out if it is possible to apply the
99 // operation in this way has a cost too...
100
101 2805236 static lbm_uint mul2(lbm_uint a, lbm_uint b) {
102 2805236 lbm_uint retval = ENC_SYM_TERROR;
103
3/4
✓ Branch 1 taken 2805236 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2805068 times.
✓ Branch 5 taken 168 times.
2805236 if (IS_NUMBER(a) && IS_NUMBER(b)) {
104 lbm_type t;
105
2/2
✓ Branch 2 taken 283304 times.
✓ Branch 3 taken 2521764 times.
2805068 PROMOTE_SWAP(t, a, b);
106
9/10
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 2800812 times.
✓ Branch 2 taken 392 times.
✓ Branch 3 taken 504 times.
✓ Branch 4 taken 448 times.
✓ Branch 5 taken 728 times.
✓ Branch 6 taken 616 times.
✓ Branch 7 taken 560 times.
✓ Branch 8 taken 728 times.
✗ Branch 9 not taken.
2805068 switch (t) {
107 280 case LBM_TYPE_CHAR: retval = lbm_enc_char((uint8_t)(lbm_dec_char(a) * lbm_dec_char(b))); break;
108 #ifdef LBM64
109 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(a) * lbm_dec_as_i64(b)); break;
110 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(a) * lbm_dec_as_u64(b)); break;
111 #else
112 2800812 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(a) * lbm_dec_as_i32(b)); break;
113 392 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(a) * lbm_dec_as_u32(b)); break;
114 #endif
115 504 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_u32(a) * lbm_dec_as_u32(b)); break;
116 448 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_i32(a) * lbm_dec_as_i32(b)); break;
117 728 case LBM_TYPE_FLOAT: retval = lbm_enc_float(lbm_dec_float(a) * lbm_dec_as_float(b)); break;
118 616 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_u64(a) * lbm_dec_as_u64(b)); break;
119 560 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_i64(a) * lbm_dec_as_i64(b)); break;
120 728 case LBM_TYPE_DOUBLE: retval = lbm_enc_double(lbm_dec_double(a) * lbm_dec_as_double(b)); break;
121 }
122 2805068 } else {
123
1/2
✓ Branch 1 taken 168 times.
✗ Branch 2 not taken.
168 lbm_set_error_suspect(IS_NUMBER(a) ? b : a);
124 }
125 2805236 return retval;
126 }
127
128 1176 static lbm_uint div2(lbm_uint a, lbm_uint b) {
129 1176 lbm_uint retval = ENC_SYM_TERROR;
130
4/4
✓ Branch 1 taken 1120 times.
✓ Branch 2 taken 56 times.
✓ Branch 4 taken 1064 times.
✓ Branch 5 taken 56 times.
1176 if (IS_NUMBER(a) && IS_NUMBER(b)) {
131 lbm_type t;
132
2/2
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 1036 times.
1064 PROMOTE(t, a, b);
133
9/10
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 532 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 56 times.
✓ Branch 4 taken 56 times.
✓ Branch 5 taken 112 times.
✓ Branch 6 taken 56 times.
✓ Branch 7 taken 56 times.
✓ Branch 8 taken 84 times.
✗ Branch 9 not taken.
1064 switch (t) {
134
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 28 times.
56 case LBM_TYPE_CHAR: if (lbm_dec_char(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_char((uint8_t)(lbm_dec_char(a) / lbm_dec_char(b))); break;
135 #ifdef LBM64
136 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;
137 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;
138 #else
139
2/2
✓ Branch 1 taken 224 times.
✓ Branch 2 taken 308 times.
532 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;
140
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 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;
141 #endif
142
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 28 times.
56 case LBM_TYPE_U32: if (lbm_dec_as_u32(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_u32(lbm_dec_as_u32(a) / lbm_dec_as_u32(b)); break;
143
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 28 times.
56 case LBM_TYPE_I32: if (lbm_dec_as_i32(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_i32(lbm_dec_as_i32(a) / lbm_dec_as_i32(b)); break;
144
3/4
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 28 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 84 times.
112 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;
145
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 28 times.
56 case LBM_TYPE_U64: if (lbm_dec_as_u64(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_u64(lbm_dec_as_u32(a) / lbm_dec_as_u64(b)); break;
146
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 28 times.
56 case LBM_TYPE_I64: if (lbm_dec_as_i64(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_i64(lbm_dec_as_i32(a) / lbm_dec_as_i64(b)); break;
147
3/4
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 28 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 56 times.
84 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;
148 }
149 616 } else {
150
2/2
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 56 times.
112 lbm_set_error_suspect(IS_NUMBER(a) ? b : a);
151 }
152 728 return retval;
153 }
154
155 784 static lbm_uint mod2(lbm_uint a, lbm_uint b) {
156 784 lbm_uint retval = ENC_SYM_TERROR;
157
4/4
✓ Branch 1 taken 728 times.
✓ Branch 2 taken 56 times.
✓ Branch 4 taken 672 times.
✓ Branch 5 taken 56 times.
784 if (IS_NUMBER(a) && IS_NUMBER(b)) {
158 lbm_type t;
159
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 672 times.
672 PROMOTE(t, a, b);
160
9/10
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 224 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 56 times.
✓ Branch 8 taken 56 times.
✗ Branch 9 not taken.
672 switch (t) {
161
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 28 times.
56 case LBM_TYPE_CHAR: if (lbm_dec_char(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_char((uint8_t)(lbm_dec_char(a) % lbm_dec_as_i32(b))); break;
162 #ifdef LBM64
163 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;
164 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;
165 #else
166
2/2
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 168 times.
224 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;
167
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 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;
168 #endif
169
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 28 times.
56 case LBM_TYPE_U32: if (lbm_dec_as_u32(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_u32(lbm_dec_as_u32(a) % lbm_dec_as_u32(b)); break;
170
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 28 times.
56 case LBM_TYPE_I32: if (lbm_dec_as_i32(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_i32(lbm_dec_as_i32(a) % lbm_dec_as_i32(b)); break;
171
3/4
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 28 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 28 times.
56 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;
172
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 28 times.
56 case LBM_TYPE_U64: if (lbm_dec_as_u64(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_u64(lbm_dec_as_u64(a) % lbm_dec_as_u64(b)); break;
173
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 28 times.
56 case LBM_TYPE_I64: if (lbm_dec_as_i64(b) == 0) {return ENC_SYM_DIVZERO;} retval = lbm_enc_i64(lbm_dec_as_i64(a) % lbm_dec_as_i64(b)); break;
174
3/4
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 28 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 28 times.
56 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;
175 }
176 392 } else {
177
2/2
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 56 times.
112 lbm_set_error_suspect(IS_NUMBER(a) ? b : a);
178 }
179 504 return retval;
180 }
181
182 21203849 static lbm_uint sub2(lbm_uint a, lbm_uint b) {
183 21203849 lbm_uint retval = ENC_SYM_TERROR;
184
4/4
✓ Branch 1 taken 21203793 times.
✓ Branch 2 taken 56 times.
✓ Branch 4 taken 21203653 times.
✓ Branch 5 taken 140 times.
21203849 if (IS_NUMBER(a) && IS_NUMBER(b)) {
185 lbm_uint t;
186
2/2
✓ Branch 2 taken 448 times.
✓ Branch 3 taken 21203205 times.
21203653 PROMOTE(t, a, b);
187
9/10
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 20922443 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 280566 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 252 times.
✓ Branch 6 taken 56 times.
✓ Branch 7 taken 84 times.
✓ Branch 8 taken 56 times.
✗ Branch 9 not taken.
21203653 switch (t) {
188 56 case LBM_TYPE_BYTE: retval = lbm_enc_char((uint8_t)(lbm_dec_char(a) - lbm_dec_char(b))); break;
189 #ifdef LBM64
190 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_as_i64(a) - lbm_dec_as_i64(b)); break;
191 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_as_u64(a) - lbm_dec_as_u64(b)); break;
192 #else
193 20922443 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_as_i32(a) - lbm_dec_as_i32(b)); break;
194 56 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_as_u32(a) - lbm_dec_as_u32(b)); break;
195 #endif
196 280566 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_as_u32(a) - lbm_dec_as_u32(b)); break;
197 84 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_as_i32(a) - lbm_dec_as_i32(b)); break;
198 252 case LBM_TYPE_FLOAT: retval = lbm_enc_float(lbm_dec_as_float(a) - lbm_dec_as_float(b)); break;
199 56 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_as_u64(a) - lbm_dec_as_u64(b)); break;
200 84 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_as_i64(a) - lbm_dec_as_i64(b)); break;
201 56 case LBM_TYPE_DOUBLE: retval = lbm_enc_double(lbm_dec_as_double(a) - lbm_dec_as_double(b)); break;
202 }
203 21203653 } else {
204
2/2
✓ Branch 1 taken 140 times.
✓ Branch 2 taken 56 times.
196 lbm_set_error_suspect(IS_NUMBER(a) ? b : a);
205 }
206 21203849 return retval;
207 }
208
209 // a and b must be bytearrays!
210 10136 static bool bytearray_equality(lbm_value a, lbm_value b) {
211 10136 lbm_array_header_t *a_ = (lbm_array_header_t*)lbm_car(a);
212 10136 lbm_array_header_t *b_ = (lbm_array_header_t*)lbm_car(b);
213
214 // A NULL array arriving here should be impossible.
215 // if the a and b are not valid arrays at this point, the data
216 // is most likely nonsense - corrupted by cosmic radiation.
217 10136 bool res = a_->size == b_->size;
218
2/2
✓ Branch 0 taken 9968 times.
✓ Branch 1 taken 168 times.
10136 if (res) {
219 9968 res = (memcmp((char*)a_->data, (char*)b_->data, a_->size) == 0);
220 }
221 10136 return res;
222 }
223
224 // a and b must be arrays!
225 196 static bool array_struct_equality(lbm_value a, lbm_value b) {
226 196 lbm_array_header_t *a_ = (lbm_array_header_t*)lbm_car(a);
227 196 lbm_array_header_t *b_ = (lbm_array_header_t*)lbm_car(b);
228 196 lbm_value *adata = (lbm_value*)a_->data;
229 196 lbm_value *bdata = (lbm_value*)b_->data;
230 196 bool res = a_->size == b_->size;
231
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 28 times.
196 if (res) {
232 168 lbm_uint size = (lbm_uint)a_->size / (lbm_uint)sizeof(lbm_value);
233
2/2
✓ Branch 0 taken 448 times.
✓ Branch 1 taken 140 times.
588 for (lbm_uint i = 0; i < size; i ++ ) {
234 448 res = struct_eq(adata[i], bdata[i]);
235
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 420 times.
448 if (!res) break;
236 }
237 }
238 196 return res;
239 }
240
241 230596 bool struct_eq(lbm_value a, lbm_value b) {
242
243 230596 bool res = false;
244 230596 lbm_type ta = lbm_type_of_functional(a);
245 230596 lbm_type tb = lbm_type_of_functional(b);
246
247
2/2
✓ Branch 0 taken 16128 times.
✓ Branch 1 taken 214468 times.
230596 if (ta == tb) {
248
13/14
✓ Branch 0 taken 59184 times.
✓ Branch 1 taken 51924 times.
✓ Branch 2 taken 588 times.
✓ Branch 3 taken 4592 times.
✓ Branch 4 taken 73652 times.
✓ Branch 5 taken 1820 times.
✓ Branch 6 taken 3584 times.
✓ Branch 7 taken 7280 times.
✓ Branch 8 taken 560 times.
✓ Branch 9 taken 560 times.
✓ Branch 10 taken 392 times.
✓ Branch 11 taken 10136 times.
✓ Branch 12 taken 196 times.
✗ Branch 13 not taken.
214468 switch(ta){
249 59184 case LBM_TYPE_SYMBOL:
250 59184 res = (lbm_dec_sym(a) == lbm_dec_sym(b)); break;
251 51924 case LBM_TYPE_I:
252 51924 res = (lbm_dec_i(a) == lbm_dec_i(b)); break;
253 588 case LBM_TYPE_U:
254 588 res = (lbm_dec_u(a) == lbm_dec_u(b)); break;
255 4592 case LBM_TYPE_CHAR:
256 4592 res = (lbm_dec_char(a) == lbm_dec_char(b)); break;
257 73652 case LBM_TYPE_CONS:
258
3/4
✓ Branch 3 taken 73624 times.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 73624 times.
✗ Branch 6 not taken.
147276 res = ( struct_eq(lbm_car(a),lbm_car(b)) &&
259 147276 struct_eq(lbm_cdr(a),lbm_cdr(b)) ); break;
260 1820 case LBM_TYPE_I32:
261 1820 res = (lbm_dec_i32(a) == lbm_dec_i32(b)); break;
262 3584 case LBM_TYPE_U32:
263 3584 res = (lbm_dec_u32(a) == lbm_dec_u32(b)); break;
264 7280 case LBM_TYPE_FLOAT:
265 7280 res = (lbm_dec_float(a) == lbm_dec_float(b)); break;
266 560 case LBM_TYPE_I64:
267 560 res = (lbm_dec_i64(a) == lbm_dec_i64(b)); break;
268 560 case LBM_TYPE_U64:
269 560 res = (lbm_dec_u64(a) == lbm_dec_u64(b)); break;
270 392 case LBM_TYPE_DOUBLE:
271 392 res = (lbm_dec_double(a) == lbm_dec_double(b)); break;
272 10136 case LBM_TYPE_ARRAY:
273 10136 res = bytearray_equality(a, b); break;
274 196 case LBM_TYPE_LISPARRAY:
275 196 res = array_struct_equality(a, b); break;
276 }
277 16128 }
278 230596 return res;
279 }
280
281
282 /* returns -1 if a < b; 0 if a = b; 1 if a > b
283 args must be numbers
284 */
285 33434994 static int compare_num(lbm_uint a, lbm_uint b) {
286
287 33434994 int retval = 0;
288
289 lbm_uint t;
290
2/2
✓ Branch 2 taken 364 times.
✓ Branch 3 taken 33434630 times.
33434994 PROMOTE(t, a, b);
291
9/10
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 31752866 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 560728 times.
✓ Branch 4 taken 280056 times.
✓ Branch 5 taken 896 times.
✓ Branch 6 taken 280084 times.
✓ Branch 7 taken 560084 times.
✓ Branch 8 taken 168 times.
✗ Branch 9 not taken.
33434994 switch (t) {
292 28 case LBM_TYPE_CHAR: retval = CMP(lbm_dec_char(a), lbm_dec_char(b)); break;
293 #ifdef LBM64
294 case LBM_TYPE_I: retval = CMP(lbm_dec_as_i64(a), lbm_dec_as_i64(b)); break;
295 case LBM_TYPE_U: retval = CMP(lbm_dec_as_u64(a), lbm_dec_as_u64(b)); break;
296 #else
297 31752866 case LBM_TYPE_I: retval = CMP(lbm_dec_as_i32(a), lbm_dec_as_i32(b)); break;
298 84 case LBM_TYPE_U: retval = CMP(lbm_dec_as_u32(a), lbm_dec_as_u32(b)); break;
299 #endif
300 560728 case LBM_TYPE_U32: retval = CMP(lbm_dec_as_u32(a), lbm_dec_as_u32(b)); break;
301 280056 case LBM_TYPE_I32: retval = CMP(lbm_dec_as_i32(a), lbm_dec_as_i32(b)); break;
302 896 case LBM_TYPE_FLOAT: retval = CMP(lbm_dec_as_float(a), lbm_dec_as_float(b)); break;
303 280084 case LBM_TYPE_U64: retval = CMP(lbm_dec_as_u64(a), lbm_dec_as_u64(b)); break;
304 560084 case LBM_TYPE_I64: retval = CMP(lbm_dec_as_i64(a), lbm_dec_as_i64(b)); break;
305 168 case LBM_TYPE_DOUBLE: retval = CMP(lbm_dec_as_double(a), lbm_dec_as_double(b)); break;
306 }
307 33434994 return retval;
308 }
309
310 /* (array-create size) */
311 24102 static void array_create(lbm_value *args, lbm_uint nargs, lbm_value *result) {
312 24102 *result = ENC_SYM_EERROR;
313
4/4
✓ Branch 0 taken 24046 times.
✓ Branch 1 taken 56 times.
✓ Branch 3 taken 24018 times.
✓ Branch 4 taken 28 times.
24102 if (nargs == 1 && IS_NUMBER(args[0])) {
314 24018 lbm_heap_allocate_array(result, lbm_dec_as_u32(args[0]));
315 }
316 24102 }
317
318 364 static lbm_value assoc_lookup(lbm_value key, lbm_value assoc) {
319 364 lbm_value curr = assoc;
320 364 lbm_value res = ENC_SYM_NO_MATCH;
321
2/2
✓ Branch 1 taken 812 times.
✓ Branch 2 taken 28 times.
840 while (lbm_is_cons(curr)) {
322 812 lbm_value c = lbm_ref_cell(curr)->car;
323
2/2
✓ Branch 1 taken 784 times.
✓ Branch 2 taken 28 times.
812 if (lbm_is_cons(c)) {
324
2/2
✓ Branch 2 taken 308 times.
✓ Branch 3 taken 476 times.
784 if (struct_eq(lbm_ref_cell(c)->car, key)) {
325 308 res = lbm_ref_cell(c)->cdr;
326 308 break;
327 }
328 } else {
329 28 res = ENC_SYM_EERROR;
330 28 break;
331 }
332 476 curr = lbm_ref_cell(curr)->cdr;
333 }
334 364 return res;
335 }
336
337 336 static lbm_value cossa_lookup(lbm_value key, lbm_value assoc) {
338 336 lbm_value curr = assoc;
339
2/2
✓ Branch 1 taken 812 times.
✓ Branch 2 taken 28 times.
840 while (lbm_is_cons(curr)) {
340 812 lbm_value c = lbm_ref_cell(curr)->car;
341
2/2
✓ Branch 1 taken 784 times.
✓ Branch 2 taken 28 times.
812 if (lbm_is_cons(c)) {
342
2/2
✓ Branch 2 taken 280 times.
✓ Branch 3 taken 504 times.
784 if (struct_eq(lbm_ref_cell(c)->cdr, key)) {
343 280 return lbm_ref_cell(c)->car;
344 }
345 } else {
346 28 return ENC_SYM_EERROR;
347 }
348 504 curr = lbm_ref_cell(curr)->cdr;
349 }
350 28 return ENC_SYM_NO_MATCH;
351 }
352
353
354
355 /***************************************************/
356 /* Fundamental operations */
357
358 7495106 static lbm_value fundamental_add(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
359 (void) ctx;
360 7495106 lbm_uint sum = lbm_enc_char(0);
361
2/2
✓ Branch 0 taken 38656850 times.
✓ Branch 1 taken 7489880 times.
46146730 for (lbm_uint i = 0; i < nargs; i ++) {
362 38656850 lbm_value v = args[i];
363
2/2
✓ Branch 1 taken 38656654 times.
✓ Branch 2 taken 196 times.
38656850 if (IS_NUMBER(v)) { // inlining add2 explicitly removes one condition.
364 lbm_type t;
365
2/2
✓ Branch 2 taken 7787674 times.
✓ Branch 3 taken 30868980 times.
38656654 PROMOTE_SWAP(t, sum, v);
366
9/10
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 24054728 times.
✓ Branch 2 taken 616 times.
✓ Branch 3 taken 3364152 times.
✓ Branch 4 taken 2814532 times.
✓ Branch 5 taken 1876 times.
✓ Branch 6 taken 3368402 times.
✓ Branch 7 taken 4490244 times.
✓ Branch 8 taken 561824 times.
✗ Branch 9 not taken.
38656654 switch (t) {
367 280 case LBM_TYPE_BYTE: sum = lbm_enc_char((uint8_t)(lbm_dec_char(sum) + lbm_dec_char(v))); break;
368 #ifdef LBM64
369 case LBM_TYPE_I: sum = lbm_enc_i(lbm_dec_i(sum) + lbm_dec_as_i64(v)); break;
370 case LBM_TYPE_U: sum = lbm_enc_u(lbm_dec_u(sum) + lbm_dec_as_u64(v)); break;
371 #else
372 24054728 case LBM_TYPE_I: sum = lbm_enc_i(lbm_dec_i(sum) + lbm_dec_as_i32(v)); break;
373 616 case LBM_TYPE_U: sum = lbm_enc_u(lbm_dec_u(sum) + lbm_dec_as_u32(v)); break;
374 #endif
375 3364152 case LBM_TYPE_U32: sum = lbm_enc_u32(lbm_dec_u32(sum) + lbm_dec_as_u32(v)); break;
376 2814532 case LBM_TYPE_I32: sum = lbm_enc_i32(lbm_dec_i32(sum) + lbm_dec_as_i32(v)); break;
377 1876 case LBM_TYPE_FLOAT: sum = lbm_enc_float(lbm_dec_float(sum) + lbm_dec_as_float(v)); break;
378 // extra check only in the cases that require it. (on 32bit, some wasted cycles on 64 bit)
379 3368402 case LBM_TYPE_U64:
380 3368402 sum = lbm_enc_u64(lbm_dec_u64(sum) + lbm_dec_as_u64(v));
381
2/2
✓ Branch 1 taken 1566 times.
✓ Branch 2 taken 3366836 times.
3368402 if (lbm_is_symbol_merror(sum)) goto add_end;
382 3366836 break;
383 4490244 case LBM_TYPE_I64:
384 4490244 sum = lbm_enc_i64(lbm_dec_i64(sum) + lbm_dec_as_i64(v));
385
2/2
✓ Branch 1 taken 2940 times.
✓ Branch 2 taken 4487304 times.
4490244 if (lbm_is_symbol_merror(sum)) goto add_end;
386 4487304 break;
387 561824 case LBM_TYPE_DOUBLE:
388 561824 sum = lbm_enc_double(lbm_dec_double(sum) + lbm_dec_as_double(v));
389
2/2
✓ Branch 1 taken 524 times.
✓ Branch 2 taken 561300 times.
561824 if (lbm_is_symbol_merror(sum)) goto add_end;
390 561300 break;
391 }
392 38651624 } else {
393 196 lbm_set_error_suspect(v);
394 196 sum = ENC_SYM_TERROR;
395 196 break; // out of loop
396 }
397 }
398 7489880 add_end:
399 7495106 return sum;
400 }
401
402 21203765 static lbm_value fundamental_sub(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
403 (void) ctx;
404
405 lbm_uint res;
406
407
4/4
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 476 times.
✓ Branch 2 taken 21203205 times.
✓ Branch 3 taken 56 times.
21203765 switch (nargs) {
408 28 case 0:
409 28 res = lbm_enc_char(0);
410 28 break;
411
412 476 case 1:
413 476 res = sub2(lbm_enc_char(0),args[0]);
414 476 break;
415
416 21203205 case 2:
417 21203205 res = sub2(args[0], args[1]);
418 21203205 break;
419
420 56 default:
421 56 res = args[0];
422
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 28 times.
196 for (lbm_uint i = 1; i < nargs; i ++) {
423 168 res = sub2(res, args[i]);
424
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 140 times.
168 if (lbm_type_of(res) == LBM_TYPE_SYMBOL)
425 28 break;
426 }
427 56 break;
428 }
429 21203765 return res;
430 }
431
432 282660 static lbm_value fundamental_mul(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
433 (void) ctx;
434
435 282660 lbm_uint prod = lbm_enc_char(1);
436
2/2
✓ Branch 0 taken 2805236 times.
✓ Branch 1 taken 282492 times.
3087728 for (lbm_uint i = 0; i < nargs; i ++) {
437 2805236 prod = mul2(prod, args[i]);
438
2/2
✓ Branch 1 taken 168 times.
✓ Branch 2 taken 2805068 times.
2805236 if (lbm_type_of(prod) == LBM_TYPE_SYMBOL) {
439 168 break;
440 }
441 }
442 282660 return prod;
443 }
444
445 1176 static lbm_value fundamental_div(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
446 (void) ctx;
447
448 1176 lbm_uint res = args[0];
449
450
2/2
✓ Branch 0 taken 1120 times.
✓ Branch 1 taken 56 times.
1176 if (nargs >= 2) {
451
2/2
✓ Branch 0 taken 1176 times.
✓ Branch 1 taken 560 times.
1736 for (lbm_uint i = 1; i < nargs; i ++) {
452 1176 res = div2(res, args[i]);
453
2/2
✓ Branch 1 taken 560 times.
✓ Branch 2 taken 616 times.
1176 if (lbm_type_of(res) == LBM_TYPE_SYMBOL) {
454 560 break;
455 }
456 }
457 } else {
458 56 res = ENC_SYM_EERROR;
459 }
460 1176 return res;
461 }
462
463 840 static lbm_value fundamental_mod(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
464 (void) ctx;
465
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 784 times.
840 if (nargs != 2) {
466 56 lbm_set_error_reason((char*)lbm_error_str_num_args);
467 56 return ENC_SYM_EERROR;
468 }
469 784 lbm_value res = args[0];
470 784 lbm_value arg2 = args[1];
471 784 res = mod2(res, arg2);
472 784 return res;
473 }
474
475 75732 static lbm_value fundamental_eq(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
476 (void) ctx;
477
478 75732 lbm_uint a = args[0];
479 75732 bool r = true;
480
481
2/2
✓ Branch 0 taken 75900 times.
✓ Branch 1 taken 53080 times.
128980 for (lbm_uint i = 1; i < nargs; i ++) {
482 75900 lbm_uint b = args[i];
483
3/4
✓ Branch 0 taken 75900 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 53248 times.
✓ Branch 4 taken 22652 times.
75900 r = r && struct_eq(a, b);
484
2/2
✓ Branch 0 taken 22652 times.
✓ Branch 1 taken 53248 times.
75900 if (!r) break;
485 }
486
2/2
✓ Branch 0 taken 53080 times.
✓ Branch 1 taken 22652 times.
75732 return r ? ENC_SYM_TRUE : ENC_SYM_NIL;
487 }
488
489 280 static lbm_value fundamental_not_eq(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
490 280 lbm_value r = fundamental_eq(args, nargs, ctx);
491
2/2
✓ Branch 0 taken 140 times.
✓ Branch 1 taken 140 times.
280 return r ? ENC_SYM_NIL : ENC_SYM_TRUE; // Works because ENC_SYM_NIL == 0 and ENC_SYM_TRUE is != 0
492 }
493
494
495 23697658 static lbm_value fundamental_numeq(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
496 (void) ctx;
497
498 23697658 lbm_uint a = args[0];
499 23697658 bool r = true;
500 23697658 bool ok = true;
501
502 23697658 lbm_value res = ENC_SYM_TERROR;
503
504
2/2
✓ Branch 1 taken 23697602 times.
✓ Branch 2 taken 56 times.
23697658 if (IS_NUMBER(a)) {
505
2/2
✓ Branch 0 taken 23698134 times.
✓ Branch 1 taken 2259014 times.
25957148 for (lbm_uint i = 1; i < nargs; i ++) {
506 23698134 lbm_uint b = args[i];
507
2/2
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 23698078 times.
23698134 if (!IS_NUMBER(b)) {
508 56 ok = false;
509 56 break;
510 }
511
3/4
✓ Branch 0 taken 23698078 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 2259546 times.
✓ Branch 4 taken 21438532 times.
23698078 r = r && (compare_num(a, b) == 0);
512
2/2
✓ Branch 0 taken 21438532 times.
✓ Branch 1 taken 2259546 times.
23698078 if (!r) break;
513 }
514
2/2
✓ Branch 0 taken 23697546 times.
✓ Branch 1 taken 56 times.
23697602 if (ok) {
515
2/2
✓ Branch 0 taken 2259014 times.
✓ Branch 1 taken 21438532 times.
23697546 res = r ? ENC_SYM_TRUE : ENC_SYM_NIL;
516 }
517 }
518 23697658 return res;
519 }
520
521 560336 static lbm_value fundamental_num_not_eq(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
522 560336 lbm_value r = fundamental_numeq(args, nargs, ctx);
523
2/2
✓ Branch 0 taken 140 times.
✓ Branch 1 taken 560196 times.
560336 if (r == ENC_SYM_NIL) {
524 140 r = ENC_SYM_TRUE;
525
2/2
✓ Branch 0 taken 560140 times.
✓ Branch 1 taken 56 times.
560196 } else if (r == ENC_SYM_TRUE) {
526 560140 r = ENC_SYM_NIL;
527 }
528 560336 return r;
529 }
530
531 8784384 static lbm_value fundamental_leq(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
532 (void) ctx;
533
534 8784384 lbm_uint a = args[0];
535 8784384 lbm_uint b = ENC_SYM_NIL;
536 8784384 bool r = true;
537 8784384 bool ok = true;
538
539
2/2
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 8784328 times.
8784384 if (!IS_NUMBER(a)) {
540 56 lbm_set_error_suspect(a);
541 56 return ENC_SYM_TERROR;
542 }
543
2/2
✓ Branch 0 taken 8784328 times.
✓ Branch 1 taken 8784272 times.
17568600 for (lbm_uint i = 1; i < nargs; i ++) {
544 8784328 b = args[i];
545
2/2
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 8784272 times.
8784328 if (!IS_NUMBER(b)) {
546 56 ok = false;
547 56 break;
548 }
549
3/4
✓ Branch 0 taken 8784272 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 5099752 times.
✓ Branch 4 taken 3684520 times.
8784272 r = r && (compare_num(a, b) <= 0);
550 }
551
2/2
✓ Branch 0 taken 8784272 times.
✓ Branch 1 taken 56 times.
8784328 if (ok) {
552
2/2
✓ Branch 0 taken 5099752 times.
✓ Branch 1 taken 3684520 times.
8784272 if (r) {
553 5099752 return ENC_SYM_TRUE;
554 } else {
555 3684520 return ENC_SYM_NIL;
556 }
557 }
558 56 lbm_set_error_suspect(b);
559 56 return ENC_SYM_TERROR;
560 }
561
562 952756 static lbm_value fundamental_geq(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
563 (void) ctx;
564
565 952756 lbm_uint a = args[0];
566 952756 lbm_uint b = ENC_SYM_NIL;
567 952756 bool r = true;
568 952756 bool ok = true;
569
570
2/2
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 952700 times.
952756 if (!IS_NUMBER(a)) {
571 56 lbm_set_error_suspect(a);
572 56 return ENC_SYM_TERROR;
573 }
574
2/2
✓ Branch 0 taken 952700 times.
✓ Branch 1 taken 952644 times.
1905344 for (lbm_uint i = 1; i < nargs; i ++) {
575 952700 b = args[i];
576
2/2
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 952644 times.
952700 if (!IS_NUMBER(b)) {
577 56 ok = false;
578 56 break;
579 }
580
3/4
✓ Branch 0 taken 952644 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 9996 times.
✓ Branch 4 taken 942648 times.
952644 r = r && (compare_num(a, b) >= 0);
581 }
582
2/2
✓ Branch 0 taken 952644 times.
✓ Branch 1 taken 56 times.
952700 if (ok) {
583
2/2
✓ Branch 0 taken 9996 times.
✓ Branch 1 taken 942648 times.
952644 if (r) {
584 9996 return ENC_SYM_TRUE;
585 } else {
586 942648 return ENC_SYM_NIL;
587 }
588 }
589 56 lbm_set_error_suspect(b);
590 56 return ENC_SYM_TERROR;
591 }
592
593 952616 static lbm_value fundamental_lt(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
594 952616 lbm_value r = fundamental_geq(args, nargs, ctx);
595
2/2
✓ Branch 0 taken 942620 times.
✓ Branch 1 taken 9996 times.
952616 if (r == ENC_SYM_NIL) r = ENC_SYM_TRUE;
596
2/2
✓ Branch 0 taken 9940 times.
✓ Branch 1 taken 56 times.
9996 else if (r == ENC_SYM_TRUE) r = ENC_SYM_NIL;
597 952616 return r;
598 }
599
600 8782900 static lbm_value fundamental_gt(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
601 8782900 lbm_value r = fundamental_leq(args, nargs, ctx);
602
2/2
✓ Branch 0 taken 3684324 times.
✓ Branch 1 taken 5098576 times.
8782900 if (r == ENC_SYM_NIL) r = ENC_SYM_TRUE;
603
2/2
✓ Branch 0 taken 5098520 times.
✓ Branch 1 taken 56 times.
5098576 else if (r == ENC_SYM_TRUE) r = ENC_SYM_NIL;
604 8782900 return r;
605 }
606
607 1960 static lbm_value fundamental_not(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
608 (void) ctx;
609 1960 lbm_value r = ENC_SYM_EERROR;
610
2/2
✓ Branch 0 taken 1904 times.
✓ Branch 1 taken 56 times.
1960 if (nargs == 1) {
611
2/2
✓ Branch 0 taken 952 times.
✓ Branch 1 taken 952 times.
1904 r = args[0] ? ENC_SYM_NIL : ENC_SYM_TRUE;
612 }
613 1960 return r;
614 }
615
616 13160 static lbm_value fundamental_gc(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
617 (void) args;
618 (void) nargs;
619 (void) ctx;
620 13160 lbm_perform_gc();
621 13160 return ENC_SYM_TRUE;
622 }
623
624 3444 static lbm_value fundamental_self(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
625 (void) args;
626 (void) nargs;
627 (void) ctx;
628 3444 return lbm_enc_i(ctx->id);
629 }
630
631 224 static lbm_value fundamental_set_mailbox_size(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
632 224 lbm_value r = ENC_SYM_EERROR;
633
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 56 times.
224 if (nargs == 1) {
634
2/2
✓ Branch 1 taken 140 times.
✓ Branch 2 taken 28 times.
168 if (IS_NUMBER(args[0])) {
635 140 uint32_t s = lbm_dec_as_u32(args[0]);
636
2/2
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 28 times.
140 if (lbm_mailbox_change_size(ctx, s)) {
637 112 r = ENC_SYM_TRUE;
638 } else {
639 28 r = ENC_SYM_NIL;
640 }
641 } else {
642 28 r = ENC_SYM_TERROR;
643 }
644 }
645 224 return r;
646 }
647
648 2801762 static lbm_value fundamental_cons(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
649 (void) ctx;
650 2801762 lbm_value r = ENC_SYM_EERROR;
651
2/2
✓ Branch 0 taken 2801678 times.
✓ Branch 1 taken 84 times.
2801762 if (nargs == 2) {
652 2801678 lbm_uint a = args[0];
653 2801678 lbm_uint b = args[1];
654 2801678 r = lbm_cons(a,b);
655 }
656 2801762 return r;
657 }
658
659 16016 static lbm_value fundamental_car(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
660 (void) ctx;
661 16016 lbm_value r = ENC_SYM_EERROR;
662
2/2
✓ Branch 0 taken 15960 times.
✓ Branch 1 taken 56 times.
16016 if (nargs == 1) {
663
2/2
✓ Branch 1 taken 15848 times.
✓ Branch 2 taken 112 times.
15960 if (lbm_is_cons(args[0])) {
664 15848 lbm_cons_t *cell = lbm_ref_cell(args[0]);
665 15848 r = cell->car;
666
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 84 times.
112 } else if (lbm_is_symbol_nil(args[0])) {
667 28 r = ENC_SYM_NIL;
668 } else {
669 84 r = ENC_SYM_TERROR;
670 }
671 }
672 16016 return r;
673 }
674
675 21504 static lbm_value fundamental_cdr(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
676 (void) ctx;
677 21504 lbm_value r = ENC_SYM_EERROR;
678
2/2
✓ Branch 0 taken 21448 times.
✓ Branch 1 taken 56 times.
21504 if (nargs == 1) {
679
2/2
✓ Branch 1 taken 21336 times.
✓ Branch 2 taken 112 times.
21448 if (lbm_is_cons(args[0])) {
680 21336 lbm_cons_t *cell = lbm_ref_cell(args[0]);
681 21336 r = cell->cdr;
682
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 84 times.
112 } else if (lbm_is_symbol_nil(args[0])) {
683 28 r = ENC_SYM_NIL;
684 } else {
685 84 r = ENC_SYM_TERROR;
686 }
687 }
688 21504 return r;
689 }
690
691 78260 static lbm_value fundamental_list(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
692 (void) ctx;
693 78260 lbm_value result = ENC_SYM_NIL;
694
2/2
✓ Branch 0 taken 111710 times.
✓ Branch 1 taken 78204 times.
189914 for (lbm_uint i = 1; i <= nargs; i ++) {
695 111710 result = lbm_cons(args[nargs-i], result);
696
2/2
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 111654 times.
111710 if (lbm_type_of(result) == LBM_TYPE_SYMBOL)
697 56 break;
698 }
699 78260 return result;
700 }
701
702 47646 static lbm_value fundamental_append(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
703 (void) ctx;
704
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 47618 times.
47646 if (nargs == 0) return ENC_SYM_NIL;
705
4/4
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 47562 times.
✓ Branch 3 taken 28 times.
✓ Branch 4 taken 28 times.
47618 if (nargs == 1 && !lbm_is_list(args[0])) {
706 28 lbm_set_error_suspect(args[0]);
707 28 return ENC_SYM_TERROR;
708 }
709 47590 lbm_value res = args[nargs-1];
710
2/2
✓ Branch 0 taken 59854 times.
✓ Branch 1 taken 47562 times.
107416 for (int i = (int)nargs -2; i >= 0; i --) {
711 59854 lbm_value curr = args[i];
712
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 59826 times.
59854 if (!lbm_is_list(curr)) {
713 28 lbm_set_error_suspect(curr);
714 28 return ENC_SYM_TERROR;
715 }
716 59826 int n = 0;
717
2/2
✓ Branch 1 taken 71996 times.
✓ Branch 2 taken 59826 times.
131822 while (lbm_type_of_functional(curr) == LBM_TYPE_CONS) {
718 71996 n++;
719 71996 curr = lbm_cdr(curr);
720 }
721 59826 curr = args[i];
722
2/2
✓ Branch 0 taken 71996 times.
✓ Branch 1 taken 59826 times.
131822 for (int j = n-1; j >= 0; j --) {
723 71996 res = lbm_cons(lbm_index_list(curr,j),res);
724 }
725 }
726 47562 return(res);
727 }
728
729 1680224 static lbm_value fundamental_undefine(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
730 (void) ctx;
731 1680224 lbm_value *global_env = lbm_get_global_env();
732
3/4
✓ Branch 0 taken 1680224 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 1680168 times.
✓ Branch 4 taken 56 times.
1680224 if (nargs == 1 && lbm_is_symbol(args[0])) {
733 1680168 lbm_value key = args[0];
734 1680168 lbm_uint ix_key = lbm_dec_sym(key) & GLOBAL_ENV_MASK;
735 1680168 lbm_value env = global_env[ix_key];
736 1680168 lbm_value res = lbm_env_drop_binding(env, key);
737
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 1680140 times.
1680168 if (res == ENC_SYM_NOT_FOUND) {
738 28 return ENC_SYM_NIL;
739 }
740 1680140 global_env[ix_key] = res;
741 1680140 return ENC_SYM_TRUE;
742
2/4
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 56 times.
✗ Branch 4 not taken.
56 } else if (nargs == 1 && lbm_is_cons(args[0])) {
743 56 lbm_value curr = args[0];
744
2/2
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 56 times.
168 while (lbm_type_of(curr) == LBM_TYPE_CONS) {
745 112 lbm_value key = lbm_car(curr);
746 112 lbm_uint ix_key = lbm_dec_sym(key) & GLOBAL_ENV_MASK;
747 112 lbm_value env = global_env[ix_key];
748 112 lbm_value res = lbm_env_drop_binding(env, key);
749
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 56 times.
112 if (res != ENC_SYM_NOT_FOUND) {
750 56 global_env[ix_key] = res;
751 }
752 112 curr = lbm_cdr(curr);
753 }
754 56 return ENC_SYM_TRUE;
755 }
756 return ENC_SYM_TERROR;
757 }
758
759 24102 static lbm_value fundamental_buf_create(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
760 (void) ctx;
761 24102 lbm_value result = ENC_SYM_EERROR;
762 24102 array_create(args, nargs, &result);
763 24102 return result;
764 }
765
766 112 static lbm_value fundamental_symbol_to_string(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
767 (void) ctx;
768 112 lbm_value res = ENC_SYM_EERROR;
769
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 28 times.
112 if (nargs == 1) {
770
2/2
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 28 times.
84 if (lbm_type_of_functional(args[0]) == LBM_TYPE_SYMBOL) {
771 56 lbm_value sym = args[0];
772 56 const char *sym_str = lbm_get_name_by_symbol(lbm_dec_sym(sym));
773
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 if (sym_str == NULL) return ENC_SYM_NIL;
774 56 size_t len = strlen(sym_str);
775 lbm_value v;
776
1/2
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
56 if (lbm_heap_allocate_array(&v, len+1)) {
777 56 lbm_array_header_t *arr = (lbm_array_header_t*)lbm_car(v);
778 56 memset(arr->data,0,len+1);
779 56 memcpy(arr->data,sym_str,len);
780 56 res = v;
781 } else {
782 res = ENC_SYM_MERROR;
783 }
784 } else {
785 28 res = ENC_SYM_TERROR;
786 }
787 }
788 112 return res;
789 }
790
791 112 static lbm_value fundamental_string_to_symbol(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
792 (void) ctx;
793 112 lbm_value result = ENC_SYM_EERROR;
794
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 28 times.
112 if (nargs == 1) {
795 84 result = ENC_SYM_TERROR;
796
2/2
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 28 times.
84 if (lbm_is_array_r(args[0])) {
797 56 lbm_array_header_t *arr = (lbm_array_header_t *)lbm_car(args[0]);
798 // TODO: String to symbol, string should be in LBM_memory..
799 // Some better sanity check is possible here.
800 // Check that array points into lbm_memory.
801 // Additionally check that it is a zero-terminated string.
802 56 char *str = (char *)arr->data;
803 56 lbm_uint sym = ENC_SYM_NIL;
804 56 lbm_str_to_symbol(str,&sym);
805 56 result = lbm_enc_sym(sym);
806 }
807 }
808 112 return result;
809 }
810
811 140 static lbm_value fundamental_symbol_to_uint(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
812 (void) ctx;
813
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 112 times.
140 if (nargs < 1) return ENC_SYM_EERROR;
814 112 lbm_value s = args[0];
815
2/2
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 28 times.
112 if (lbm_type_of_functional(s) == LBM_TYPE_SYMBOL)
816 84 return lbm_enc_u(lbm_dec_sym(s));
817
818 28 lbm_set_error_suspect(s);
819 28 return ENC_SYM_TERROR;
820 }
821
822 112 static lbm_value fundamental_uint_to_symbol(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
823 (void) ctx;
824
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 84 times.
112 if (nargs < 1) return ENC_SYM_EERROR;
825 84 lbm_value s = args[0];
826
2/2
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 28 times.
84 if (lbm_type_of_functional(s) == LBM_TYPE_U)
827 56 return lbm_enc_sym(lbm_dec_u(s));
828
829 28 lbm_set_error_suspect(s);
830 28 return ENC_SYM_TERROR;
831 }
832
833 112 static lbm_value fundamental_set_car(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
834 (void) ctx;
835 112 lbm_value res = ENC_SYM_EERROR;
836
1/2
✓ Branch 0 taken 112 times.
✗ Branch 1 not taken.
112 if (nargs == 2) {
837
2/2
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 28 times.
112 res = lbm_set_car(args[0], args[1]) ? ENC_SYM_TRUE : ENC_SYM_NIL;
838 }
839 112 return res;
840 }
841
842 112 static lbm_value fundamental_set_cdr(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
843 (void) ctx;
844 112 lbm_value res = ENC_SYM_EERROR;
845
1/2
✓ Branch 0 taken 112 times.
✗ Branch 1 not taken.
112 if (nargs == 2) {
846
2/2
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 28 times.
112 res = lbm_set_cdr(args[0],args[1]) ? ENC_SYM_TRUE : ENC_SYM_NIL;
847 }
848 112 return res;
849 }
850
851 280 static lbm_value fundamental_set_ix(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
852 (void) ctx;
853 280 lbm_value result = ENC_SYM_TERROR;
854
2/4
✓ Branch 0 taken 280 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 280 times.
✗ Branch 4 not taken.
280 if (nargs == 3 && IS_NUMBER(args[1])) {
855
2/2
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 168 times.
280 if (lbm_is_list_rw(args[0])) {
856 112 lbm_value curr = args[0];
857 112 lbm_uint i = 0;
858 112 lbm_int ix_pre = lbm_dec_as_i32(args[1]);
859
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
112 if (ix_pre < 0) {
860 lbm_int len = (lbm_int)lbm_list_length(args[0]);
861 ix_pre = len + ix_pre;
862 }
863 112 lbm_uint ix = (lbm_uint)ix_pre;
864
1/2
✓ Branch 1 taken 448 times.
✗ Branch 2 not taken.
448 while (lbm_is_cons_rw(curr)) { // rw as we are going to modify
865 448 lbm_value next = lbm_cdr(curr);
866
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 364 times.
448 if (i == ix) {
867 84 lbm_set_car(curr, args[2]);
868 84 result = args[0]; // Acts as true and as itself.
869 84 break;
870
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 336 times.
364 } else if (lbm_is_symbol_nil(next)) {
871 28 result = ENC_SYM_NIL; // index out of bounds, no update.
872 28 break;
873 }
874 336 curr = next;
875 336 i++;
876 }
877
1/2
✓ Branch 1 taken 168 times.
✗ Branch 2 not taken.
168 } else if (lbm_is_lisp_array_rw(args[0])) {
878 168 lbm_value index = lbm_dec_as_u32(args[1]);
879 168 lbm_value val = args[2];
880 168 lbm_array_header_t *header = (lbm_array_header_t*)lbm_car(args[0]);
881 168 lbm_value *arrdata = (lbm_value*)header->data;
882 168 lbm_uint size = header->size / sizeof(lbm_value);
883
1/2
✓ Branch 0 taken 168 times.
✗ Branch 1 not taken.
168 if (index < size) {
884 168 arrdata[index] = val;
885 168 result = args[0];
886 } // index out of range will be eval error.
887 }
888 }
889 280 return result;
890 }
891
892 448 static lbm_value fundamental_assoc(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
893 (void) ctx;
894 448 lbm_value result = ENC_SYM_EERROR;
895
2/2
✓ Branch 0 taken 420 times.
✓ Branch 1 taken 28 times.
448 if (nargs == 2) {
896
2/2
✓ Branch 1 taken 364 times.
✓ Branch 2 taken 56 times.
420 if (lbm_is_cons(args[0])) {
897 364 lbm_value r = assoc_lookup(args[1], args[0]);
898
4/4
✓ Branch 1 taken 336 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 28 times.
✓ Branch 4 taken 308 times.
364 if (lbm_is_symbol(r) &&
899 r == ENC_SYM_NO_MATCH) {
900 28 result = ENC_SYM_NIL;
901 } else {
902 336 result = r;
903 }
904
1/2
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
56 } else if (lbm_is_symbol(args[0]) &&
905
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 28 times.
56 args[0] == ENC_SYM_NIL) {
906 28 result = args[0]; /* nil */
907 } /* else error */
908 }
909 448 return result;
910 }
911
912 130076 static lbm_value fundamental_acons(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
913 (void) ctx;
914 130076 lbm_value result = ENC_SYM_EERROR;
915
2/2
✓ Branch 0 taken 129992 times.
✓ Branch 1 taken 84 times.
130076 if (nargs == 3) {
916 129992 lbm_value keyval = lbm_cons(args[0], args[1]);
917 129992 lbm_value new_alist = lbm_cons(keyval, args[2]);
918
919
4/4
✓ Branch 1 taken 129824 times.
✓ Branch 2 taken 168 times.
✓ Branch 3 taken 14 times.
✓ Branch 4 taken 129810 times.
259816 if (lbm_is_symbol(keyval) ||
920 129824 lbm_is_symbol(new_alist) )
921 182 result = ENC_SYM_MERROR;
922 else
923 129810 result = new_alist;
924
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 } else if (nargs == 2) {
925 result = lbm_cons(args[0], args[1]);
926 }
927 130076 return result;
928 }
929
930 112 static lbm_value fundamental_set_assoc(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
931 (void) ctx;
932 112 lbm_value result = ENC_SYM_EERROR;
933
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 28 times.
112 if (nargs == 3) {
934 84 result = lbm_env_set_functional(args[0], args[1], args[2]);
935
2/4
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 28 times.
✗ Branch 4 not taken.
28 } else if (nargs == 2 && lbm_is_cons(args[1])) {
936 28 lbm_value x = lbm_car(args[1]);
937 28 lbm_value xs = lbm_cdr(args[1]);
938 28 result = lbm_env_set(args[0], x, xs);
939 }
940 112 return result;
941 }
942
943 420 static lbm_value fundamental_cossa(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
944 (void) ctx;
945 420 lbm_value result = ENC_SYM_EERROR;
946
2/2
✓ Branch 0 taken 392 times.
✓ Branch 1 taken 28 times.
420 if (nargs == 2) {
947
2/2
✓ Branch 1 taken 336 times.
✓ Branch 2 taken 56 times.
392 if (lbm_is_cons(args[0])) {
948 336 lbm_value r = cossa_lookup(args[1], args[0]);
949
4/4
✓ Branch 1 taken 224 times.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 28 times.
✓ Branch 4 taken 196 times.
336 if (lbm_is_symbol(r) &&
950 r == ENC_SYM_NO_MATCH) {
951 28 result = ENC_SYM_NIL;
952 } else {
953 308 result = r;
954 }
955
1/2
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
56 } else if (lbm_is_symbol(args[0]) &&
956
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 28 times.
56 args[0] == ENC_SYM_NIL) {
957 28 result = args[0]; /* nil */
958 } /* else error */
959 }
960 420 return result;
961 }
962
963 22988 static lbm_value fundamental_ix(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
964 (void) ctx;
965 22988 lbm_value result = ENC_SYM_EERROR;
966
2/4
✓ Branch 0 taken 22988 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 22988 times.
✗ Branch 4 not taken.
22988 if (nargs == 2 && IS_NUMBER(args[1])) {
967
2/2
✓ Branch 1 taken 22820 times.
✓ Branch 2 taken 168 times.
22988 if (lbm_is_list(args[0])) {
968 22820 result = lbm_index_list(args[0], lbm_dec_as_i32(args[1]));
969
1/2
✓ Branch 1 taken 168 times.
✗ Branch 2 not taken.
168 } else if (lbm_is_lisp_array_r(args[0])) {
970 168 lbm_array_header_t *header = (lbm_array_header_t*)lbm_car(args[0]);
971 168 lbm_value *arrdata = (lbm_value*)header->data;
972 168 lbm_uint size = header->size / sizeof(lbm_value);
973 168 lbm_uint index = lbm_dec_as_u32(args[1]);
974
1/2
✓ Branch 0 taken 168 times.
✗ Branch 1 not taken.
168 if (index < size) {
975 168 result = arrdata[index];
976 } // index out of range will be eval error.
977 }
978 }
979 22988 return result;
980 }
981
982 280 static lbm_value fundamental_to_i(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
983 (void) ctx;
984 280 lbm_value result = ENC_SYM_EERROR;
985
2/2
✓ Branch 0 taken 252 times.
✓ Branch 1 taken 28 times.
280 if (nargs == 1) {
986 252 result = lbm_enc_i((lbm_int)lbm_dec_as_i64(args[0]));
987 }
988 280 return result;
989 }
990
991 280 static lbm_value fundamental_to_i32(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
992 (void) ctx;
993 280 lbm_value result = ENC_SYM_EERROR;
994
2/2
✓ Branch 0 taken 252 times.
✓ Branch 1 taken 28 times.
280 if (nargs == 1) {
995 252 result = lbm_enc_i32(lbm_dec_as_i32(args[0]));
996 }
997 280 return result;
998 }
999
1000 280 static lbm_value fundamental_to_u(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1001 (void) ctx;
1002 280 lbm_value result = ENC_SYM_EERROR;
1003
2/2
✓ Branch 0 taken 252 times.
✓ Branch 1 taken 28 times.
280 if (nargs == 1) {
1004 252 result = lbm_enc_u((lbm_uint)lbm_dec_as_u64(args[0]));
1005 }
1006 280 return result;
1007 }
1008
1009 280 static lbm_value fundamental_to_u32(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1010 (void) ctx;
1011 280 lbm_value result = ENC_SYM_EERROR;
1012
2/2
✓ Branch 0 taken 252 times.
✓ Branch 1 taken 28 times.
280 if (nargs == 1) {
1013 252 result = lbm_enc_u32(lbm_dec_as_u32(args[0]));
1014 }
1015 280 return result;
1016 }
1017
1018 252 static lbm_value fundamental_to_float(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1019 (void) ctx;
1020 252 lbm_value result = ENC_SYM_EERROR;
1021
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 28 times.
252 if (nargs == 1) {
1022 224 result = lbm_enc_float(lbm_dec_as_float(args[0]));
1023 }
1024 252 return result;
1025 }
1026
1027 280 static lbm_value fundamental_to_i64(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1028 (void) ctx;
1029 280 lbm_value result = ENC_SYM_EERROR;
1030
2/2
✓ Branch 0 taken 252 times.
✓ Branch 1 taken 28 times.
280 if (nargs == 1) {
1031 252 result = lbm_enc_i64(lbm_dec_as_i64(args[0]));
1032 }
1033 280 return result;
1034 }
1035
1036 280 static lbm_value fundamental_to_u64(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1037 (void) ctx;
1038 280 lbm_value result = ENC_SYM_EERROR;
1039
2/2
✓ Branch 0 taken 252 times.
✓ Branch 1 taken 28 times.
280 if (nargs == 1) {
1040 252 result = lbm_enc_u64(lbm_dec_as_u64(args[0]));
1041 }
1042 280 return result;
1043 }
1044
1045 252 static lbm_value fundamental_to_double(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1046 (void) ctx;
1047 252 lbm_value result = ENC_SYM_EERROR;
1048
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 28 times.
252 if (nargs == 1) {
1049 224 result = lbm_enc_double(lbm_dec_as_double(args[0]));
1050 }
1051 252 return result;
1052 }
1053
1054 252 static lbm_value fundamental_to_byte(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1055 (void) ctx;
1056 252 lbm_value result = ENC_SYM_EERROR;
1057
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 28 times.
252 if (nargs == 1) {
1058 224 result = lbm_enc_char(lbm_dec_as_char(args[0]));
1059 }
1060 252 return result;
1061 }
1062
1063 336 static lbm_value fundamental_shl(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1064 (void) ctx;
1065 336 lbm_value retval = ENC_SYM_EERROR;
1066
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 308 times.
336 if (nargs == 2) {
1067 308 retval = ENC_SYM_TERROR;
1068
4/4
✓ Branch 1 taken 280 times.
✓ Branch 2 taken 28 times.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 252 times.
308 if (!(IS_NUMBER(args[0]) && IS_NUMBER(args[1]))) {
1069 56 return retval;
1070 }
1071
7/7
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 28 times.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 28 times.
✓ Branch 6 taken 28 times.
✓ Branch 7 taken 56 times.
252 switch (lbm_type_of_functional(args[0])) {
1072 56 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) << lbm_dec_as_u32(args[1])); break;
1073 28 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) << lbm_dec_as_u32(args[1])); break;
1074 28 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_u32(args[0]) << lbm_dec_as_u32(args[1])); break;
1075 28 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_i32(args[0]) << lbm_dec_as_u32(args[1])); break;
1076 28 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_i64(args[0]) << lbm_dec_as_u32(args[1])); break;
1077 28 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_u64(args[0]) << lbm_dec_as_u32(args[1])); break;
1078 }
1079 28 }
1080 280 return retval;
1081 }
1082
1083 336 static lbm_value fundamental_shr(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1084 (void) ctx;
1085 336 lbm_value retval = ENC_SYM_EERROR;
1086
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 308 times.
336 if (nargs == 2) {
1087 308 retval = ENC_SYM_TERROR;
1088
4/4
✓ Branch 1 taken 280 times.
✓ Branch 2 taken 28 times.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 252 times.
308 if (!(IS_NUMBER(args[0]) && IS_NUMBER(args[1]))) {
1089 56 return retval;
1090 }
1091
7/7
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 28 times.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 28 times.
✓ Branch 6 taken 28 times.
✓ Branch 7 taken 56 times.
252 switch (lbm_type_of_functional(args[0])) {
1092 56 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) >> lbm_dec_as_u32(args[1])); break;
1093 28 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) >> lbm_dec_as_u32(args[1])); break;
1094 28 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_u32(args[0]) >> lbm_dec_as_u32(args[1])); break;
1095 28 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_i32(args[0]) >> lbm_dec_as_u32(args[1])); break;
1096 28 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_i64(args[0]) >> lbm_dec_as_u32(args[1])); break;
1097 28 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_u64(args[0]) >> lbm_dec_as_u32(args[1])); break;
1098 }
1099 28 }
1100 280 return retval;
1101 }
1102
1103 336 static lbm_value fundamental_bitwise_and(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1104 (void) ctx;
1105 336 lbm_value retval = ENC_SYM_EERROR;
1106
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 308 times.
336 if (nargs == 2) {
1107 308 retval = ENC_SYM_TERROR;
1108
4/4
✓ Branch 1 taken 280 times.
✓ Branch 2 taken 28 times.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 252 times.
308 if (!(IS_NUMBER(args[0]) && IS_NUMBER(args[1]))) {
1109 56 return retval;
1110 }
1111
7/7
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 28 times.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 28 times.
✓ Branch 6 taken 28 times.
✓ Branch 7 taken 56 times.
252 switch (lbm_type_of_functional(args[0])) {
1112 #ifdef LBM64
1113 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) & lbm_dec_as_i64(args[1])); break;
1114 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) & lbm_dec_as_u64(args[1])); break;
1115 #else
1116 56 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) & lbm_dec_as_i32(args[1])); break;
1117 28 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) & lbm_dec_as_u32(args[1])); break;
1118 #endif
1119 28 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_u32(args[0]) & lbm_dec_as_u32(args[1])); break;
1120 28 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_i32(args[0]) & lbm_dec_as_i32(args[1])); break;
1121 28 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_i64(args[0]) & lbm_dec_as_i64(args[1])); break;
1122 28 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_u64(args[0]) & lbm_dec_as_u64(args[1])); break;
1123 }
1124 28 }
1125 280 return retval;
1126 }
1127
1128 336 static lbm_value fundamental_bitwise_or(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1129 (void) ctx;
1130 336 lbm_value retval = ENC_SYM_EERROR;
1131
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 308 times.
336 if (nargs == 2) {
1132 308 retval = ENC_SYM_TERROR;
1133
4/4
✓ Branch 1 taken 280 times.
✓ Branch 2 taken 28 times.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 252 times.
308 if (!(IS_NUMBER(args[0]) && IS_NUMBER(args[1]))) {
1134 56 return retval;
1135 }
1136
7/7
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 28 times.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 28 times.
✓ Branch 6 taken 28 times.
✓ Branch 7 taken 56 times.
252 switch (lbm_type_of_functional(args[0])) {
1137 #ifdef LBM64
1138 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) | lbm_dec_as_i64(args[1])); break;
1139 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) | lbm_dec_as_u64(args[1])); break;
1140 #else
1141 56 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) | lbm_dec_as_i32(args[1])); break;
1142 28 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) | lbm_dec_as_u32(args[1])); break;
1143 #endif
1144 28 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_u32(args[0]) | lbm_dec_as_u32(args[1])); break;
1145 28 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_i32(args[0]) | lbm_dec_as_i32(args[1])); break;
1146 28 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_i64(args[0]) | lbm_dec_as_i64(args[1])); break;
1147 28 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_u64(args[0]) | lbm_dec_as_u64(args[1])); break;
1148 }
1149 28 }
1150 280 return retval;
1151 }
1152
1153 336 static lbm_value fundamental_bitwise_xor(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1154 (void) ctx;
1155 336 lbm_value retval = ENC_SYM_EERROR;
1156
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 308 times.
336 if (nargs == 2) {
1157 308 retval = ENC_SYM_TERROR;
1158
4/4
✓ Branch 1 taken 280 times.
✓ Branch 2 taken 28 times.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 252 times.
308 if (!(IS_NUMBER(args[0]) && IS_NUMBER(args[1]))) {
1159 56 return retval;
1160 }
1161
7/7
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 28 times.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 28 times.
✓ Branch 6 taken 28 times.
✓ Branch 7 taken 56 times.
252 switch (lbm_type_of_functional(args[0])) {
1162 #ifdef LBM64
1163 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) ^ lbm_dec_as_i64(args[1])); break;
1164 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) ^ lbm_dec_as_u64(args[1])); break;
1165 #else
1166 56 case LBM_TYPE_I: retval = lbm_enc_i(lbm_dec_i(args[0]) ^ lbm_dec_as_i32(args[1])); break;
1167 28 case LBM_TYPE_U: retval = lbm_enc_u(lbm_dec_u(args[0]) ^ lbm_dec_as_u32(args[1])); break;
1168 #endif
1169 28 case LBM_TYPE_U32: retval = lbm_enc_u32(lbm_dec_u32(args[0]) ^ lbm_dec_as_u32(args[1])); break;
1170 28 case LBM_TYPE_I32: retval = lbm_enc_i32(lbm_dec_i32(args[0]) ^ lbm_dec_as_i32(args[1])); break;
1171 28 case LBM_TYPE_I64: retval = lbm_enc_i64(lbm_dec_i64(args[0]) ^ lbm_dec_as_i64(args[1])); break;
1172 28 case LBM_TYPE_U64: retval = lbm_enc_u64(lbm_dec_u64(args[0]) ^ lbm_dec_as_u64(args[1])); break;
1173 }
1174 28 }
1175 280 return retval;
1176 }
1177
1178 280 static lbm_value fundamental_bitwise_not(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1179 (void) ctx;
1180 280 lbm_value retval = ENC_SYM_EERROR;
1181
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 252 times.
280 if (nargs == 1) {
1182 252 retval = ENC_SYM_TERROR;
1183
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 224 times.
252 if (!(IS_NUMBER(args[0]))) {
1184 28 return retval;
1185 }
1186
7/7
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 28 times.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 28 times.
✓ Branch 6 taken 28 times.
✓ Branch 7 taken 56 times.
224 switch (lbm_type_of_functional(args[0])) {
1187 28 case LBM_TYPE_I: retval = lbm_enc_i(~lbm_dec_i(args[0])); break;
1188 28 case LBM_TYPE_U: retval = lbm_enc_u(~lbm_dec_u(args[0])); break;
1189 28 case LBM_TYPE_U32: retval = lbm_enc_u32(~lbm_dec_u32(args[0])); break;
1190 28 case LBM_TYPE_I32: retval = lbm_enc_i32(~lbm_dec_i32(args[0])); break;
1191 28 case LBM_TYPE_I64: retval = lbm_enc_i64(~lbm_dec_i64(args[0])); break;
1192 28 case LBM_TYPE_U64: retval = lbm_enc_u64(~lbm_dec_u64(args[0])); break;
1193 }
1194 28 }
1195 252 return retval;
1196 }
1197
1198 28 static lbm_value fundamental_custom_destruct(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1199 (void) ctx;
1200 28 lbm_value result = ENC_SYM_EERROR;
1201
2/4
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 28 times.
✗ Branch 4 not taken.
28 if (nargs == 1 && (lbm_type_of(args[0]) == LBM_TYPE_CUSTOM)) {
1202 28 lbm_uint *mem_ptr = (lbm_uint*)lbm_dec_custom(args[0]);
1203
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 if(!mem_ptr) return ENC_SYM_FATAL_ERROR;
1204 28 lbm_custom_type_destroy(mem_ptr);
1205 28 lbm_value tmp = lbm_set_ptr_type(args[0], LBM_TYPE_CONS);
1206 28 lbm_set_car(tmp, ENC_SYM_NIL);
1207 28 lbm_set_cdr(tmp, ENC_SYM_NIL);
1208 /* The original value will still be of type custom_ptr */
1209 28 result = ENC_SYM_TRUE;
1210 }
1211 28 return result;
1212 }
1213
1214 14448 static lbm_value fundamental_type_of(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1215 (void) ctx;
1216 14448 lbm_value res = ENC_SYM_EERROR;
1217
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14448 times.
14448 if (nargs == 1) {
1218 14448 lbm_value val = args[0];
1219 14448 lbm_type t = lbm_type_of(val);
1220
1221
2/2
✓ Branch 1 taken 11144 times.
✓ Branch 2 taken 3304 times.
14448 if (lbm_is_ptr(val)) {
1222 // Ignore constant or not constant.
1223 11144 t &= LBM_PTR_TO_CONSTANT_MASK;
1224 }
1225
13/16
✓ Branch 0 taken 5236 times.
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 644 times.
✓ Branch 3 taken 812 times.
✓ Branch 4 taken 1792 times.
✓ Branch 5 taken 672 times.
✓ Branch 6 taken 784 times.
✓ Branch 7 taken 1064 times.
✓ Branch 8 taken 1148 times.
✓ Branch 9 taken 840 times.
✓ Branch 10 taken 56 times.
✓ Branch 11 taken 1260 times.
✓ Branch 12 taken 28 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
14448 switch(t) {
1226 5236 case LBM_TYPE_CONS: res = ENC_SYM_TYPE_LIST; break;
1227 112 case LBM_TYPE_ARRAY: res = ENC_SYM_TYPE_ARRAY; break;
1228 644 case LBM_TYPE_I32: res = ENC_SYM_TYPE_I32; break;
1229 812 case LBM_TYPE_U32: res = ENC_SYM_TYPE_U32; break;
1230 1792 case LBM_TYPE_FLOAT: res = ENC_SYM_TYPE_FLOAT; break;
1231 672 case LBM_TYPE_I64: res = ENC_SYM_TYPE_I64; break;
1232 784 case LBM_TYPE_U64: res = ENC_SYM_TYPE_U64; break;
1233 1064 case LBM_TYPE_DOUBLE: res = ENC_SYM_TYPE_DOUBLE; break;
1234 1148 case LBM_TYPE_I: res = ENC_SYM_TYPE_I; break;
1235 840 case LBM_TYPE_U: res = ENC_SYM_TYPE_U; break;
1236 56 case LBM_TYPE_CHAR: res = ENC_SYM_TYPE_CHAR; break;
1237 1260 case LBM_TYPE_SYMBOL: res = ENC_SYM_TYPE_SYMBOL; break;
1238 28 case LBM_TYPE_LISPARRAY: res = ENC_SYM_TYPE_LISPARRAY; break;
1239 case LBM_TYPE_DEFRAG_MEM: res = ENC_SYM_TYPE_DEFRAG_MEM; break;
1240 case LBM_TYPE_CUSTOM: res = ENC_SYM_TYPE_CUSTOM; break;
1241 }
1242 }
1243 14448 return res;
1244 }
1245
1246 812 static lbm_value fundamental_list_length(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1247 (void) ctx;
1248 812 lbm_value result = ENC_SYM_EERROR;
1249
2/2
✓ Branch 0 taken 784 times.
✓ Branch 1 taken 28 times.
812 if (nargs == 1) {
1250 784 result = ENC_SYM_TERROR;
1251
2/2
✓ Branch 1 taken 672 times.
✓ Branch 2 taken 112 times.
784 if (lbm_is_list(args[0])) {
1252 672 int32_t len = (int32_t)lbm_list_length(args[0]);
1253 672 result = lbm_enc_i(len);
1254
2/2
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 84 times.
112 } else if (lbm_is_array_r(args[0])) {
1255 28 lbm_array_header_t *header = (lbm_array_header_t*)lbm_car(args[0]);
1256 28 result = lbm_enc_i((int)(header->size));
1257
2/2
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 28 times.
84 } else if (lbm_is_lisp_array_r(args[0])) {
1258 56 lbm_array_header_t *header = (lbm_array_header_t*)lbm_car(args[0]);
1259 56 result = lbm_enc_i((int)(header->size / (sizeof(lbm_uint))));
1260 }
1261 }
1262 812 return result;
1263 }
1264
1265 6090724 static lbm_value fundamental_range(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1266 (void) ctx;
1267 6090724 lbm_value result = ENC_SYM_EERROR;
1268
1269 int32_t start;
1270 int32_t end;
1271 6090724 bool rev = false;
1272
1273
4/4
✓ Branch 0 taken 5801938 times.
✓ Branch 1 taken 288786 times.
✓ Branch 3 taken 5801910 times.
✓ Branch 4 taken 28 times.
6090724 if (nargs == 1 && IS_NUMBER(args[0])) {
1274 5801910 start = 0;
1275 5801910 end = lbm_dec_as_i32(args[0]);
1276
4/4
✓ Branch 0 taken 288758 times.
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 288730 times.
✓ Branch 3 taken 28 times.
577572 } else if (nargs == 2 &&
1277
2/2
✓ Branch 1 taken 288702 times.
✓ Branch 2 taken 28 times.
577488 IS_NUMBER(args[0]) &&
1278 288730 IS_NUMBER(args[1])) {
1279 288702 start = lbm_dec_as_i32(args[0]);
1280 288702 end = lbm_dec_as_i32(args[1]);
1281 } else {
1282 112 return result;
1283 }
1284
1285
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 6090584 times.
6090612 if (end == start) return ENC_SYM_NIL;
1286
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 6090528 times.
6090584 else if (end < start) {
1287 56 int32_t tmp = end;
1288 56 end = start;
1289 56 start = tmp;
1290 56 rev = true;
1291 }
1292
1293 6090584 int num = end - start;
1294
1295
2/2
✓ Branch 1 taken 197180 times.
✓ Branch 2 taken 5893404 times.
6090584 if ((unsigned int)num > lbm_heap_num_free()) {
1296 197180 return ENC_SYM_MERROR;
1297 }
1298
1299 5893404 lbm_value r_list = ENC_SYM_NIL;
1300
2/2
✓ Branch 0 taken 298510395 times.
✓ Branch 1 taken 5893404 times.
304403799 for (int i = end - 1; i >= start; i --) {
1301 298510395 r_list = lbm_cons(lbm_enc_i(i), r_list);
1302 }
1303
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 5893348 times.
5893404 return rev ? lbm_list_destructive_reverse(r_list) : r_list;
1304 }
1305
1306 280 static lbm_value fundamental_reg_event_handler(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1307 (void) ctx;
1308 280 lbm_value res = ENC_SYM_TERROR;
1309
4/4
✓ Branch 0 taken 252 times.
✓ Branch 1 taken 28 times.
✓ Branch 3 taken 224 times.
✓ Branch 4 taken 28 times.
280 if (nargs == 1 && IS_NUMBER(args[0])) {
1310 224 lbm_set_event_handler_pid((lbm_cid)lbm_dec_i(args[0]));
1311 224 res = ENC_SYM_TRUE;
1312 }
1313 280 return res;
1314 }
1315
1316 34532 static lbm_value fundamental_take(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1317 (void) ctx;
1318 34532 lbm_value res = ENC_SYM_TERROR;
1319
6/6
✓ Branch 0 taken 34504 times.
✓ Branch 1 taken 28 times.
✓ Branch 3 taken 34476 times.
✓ Branch 4 taken 28 times.
✓ Branch 6 taken 34448 times.
✓ Branch 7 taken 28 times.
34532 if (nargs == 2 && IS_NUMBER(args[1]) && lbm_is_list(args[0])) {
1320 34448 int len = lbm_dec_as_i32(args[1]);
1321 34448 res = lbm_list_copy(&len, args[0]);
1322 }
1323 34532 return res;
1324 }
1325
1326 168 static lbm_value fundamental_drop(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1327 (void) ctx;
1328 168 lbm_value res = ENC_SYM_TERROR;
1329
6/6
✓ Branch 0 taken 140 times.
✓ Branch 1 taken 28 times.
✓ Branch 3 taken 112 times.
✓ Branch 4 taken 28 times.
✓ Branch 6 taken 84 times.
✓ Branch 7 taken 28 times.
168 if (nargs == 2 && IS_NUMBER(args[1]) && lbm_is_list(args[0])) {
1330 84 res = lbm_list_drop(lbm_dec_as_u32(args[1]), args[0]);
1331 }
1332 168 return res;
1333 }
1334 /* (mkarray size) */
1335 112 static lbm_value fundamental_mkarray(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1336 (void) ctx;
1337 112 lbm_value res = ENC_SYM_TERROR;
1338
2/4
✓ Branch 0 taken 112 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 112 times.
✗ Branch 4 not taken.
112 if (nargs == 1 && IS_NUMBER(args[0])) {
1339 112 lbm_heap_allocate_lisp_array(&res, lbm_dec_as_u32(args[0]));
1340 }
1341 112 return res;
1342 }
1343
1344 28 static lbm_value fundamental_array_to_list(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1345 (void) ctx;
1346 28 lbm_value res = ENC_SYM_TERROR;
1347
2/4
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 28 times.
✗ Branch 4 not taken.
28 if (nargs == 1 && lbm_is_lisp_array_r(args[0])) {
1348 28 lbm_array_header_t *header = (lbm_array_header_t*)lbm_car(args[0]);
1349 28 lbm_value *arrdata = (lbm_value*)header->data;
1350 28 lbm_uint size = (header->size / sizeof(lbm_uint));
1351 28 res = lbm_heap_allocate_list(size);
1352
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
28 if (lbm_is_symbol(res)) return res;
1353 28 lbm_value curr = res;
1354 28 lbm_uint ix = 0;
1355
2/2
✓ Branch 1 taken 280 times.
✓ Branch 2 taken 28 times.
308 while (lbm_is_cons(curr)) {
1356 280 lbm_set_car(curr, arrdata[ix]);
1357 280 ix ++;
1358 280 curr = lbm_cdr(curr);
1359 }
1360 }
1361 28 return res;
1362 }
1363
1364 476 static lbm_value fundamental_list_to_array(lbm_value *args, lbm_uint nargs, eval_context_t *ctx) {
1365 (void) ctx;
1366 476 lbm_value res = ENC_SYM_TERROR;
1367
4/4
✓ Branch 0 taken 448 times.
✓ Branch 1 taken 28 times.
✓ Branch 3 taken 420 times.
✓ Branch 4 taken 28 times.
476 if (nargs == 1 && lbm_is_list(args[0])) {
1368 420 lbm_int len = (lbm_int)lbm_list_length(args[0]);
1369
2/2
✓ Branch 0 taken 392 times.
✓ Branch 1 taken 28 times.
420 if ( len > 0 ) {
1370 392 lbm_heap_allocate_lisp_array(&res, (lbm_uint)len);
1371
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 392 times.
392 if (lbm_is_symbol(res)) return res;
1372 392 lbm_value curr = args[0];
1373 392 int ix = 0;
1374 392 lbm_array_header_t *header = (lbm_array_header_t*)lbm_car(res);
1375 392 lbm_value *arrdata = (lbm_value*)header->data;
1376
2/2
✓ Branch 1 taken 1344 times.
✓ Branch 2 taken 392 times.
1736 while (lbm_is_cons(curr)) {
1377 1344 arrdata[ix] = lbm_car(curr);
1378 1344 ix ++;
1379 1344 curr = lbm_cdr(curr);
1380 }
1381 } else {
1382 28 res = ENC_SYM_NIL; // could be a unique array-empty symbol
1383 }
1384 }
1385 476 return res;
1386 }
1387
1388 140 static lbm_value fundamental_dm_create(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1389 (void) ctx;
1390 140 lbm_value res = ENC_SYM_TERROR;
1391
2/4
✓ Branch 0 taken 140 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 140 times.
✗ Branch 4 not taken.
140 if (argn == 1 && lbm_is_number(args[0])) {
1392 140 lbm_uint n = lbm_dec_as_uint(args[0]);
1393 140 res = lbm_defrag_mem_create(n);
1394 }
1395 140 return res;
1396 }
1397
1398 2184 static lbm_value fundamental_dm_alloc(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1399 (void) ctx;
1400 2184 lbm_value res = ENC_SYM_TERROR;
1401
2/4
✓ Branch 0 taken 2184 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 2184 times.
✗ Branch 4 not taken.
2184 if (argn == 2 && lbm_is_number(args[1])) {
1402
1/2
✓ Branch 1 taken 2184 times.
✗ Branch 2 not taken.
2184 if (lbm_type_of(args[0]) == LBM_TYPE_DEFRAG_MEM) {
1403 2184 lbm_uint *dm = (lbm_uint*)lbm_car(args[0]);
1404 2184 res = lbm_defrag_mem_alloc(dm, lbm_dec_as_uint(args[1]));
1405 }
1406 }
1407 2184 return res;
1408 }
1409
1410 140 static lbm_value fundamental_is_list(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1411 (void) ctx;
1412 140 lbm_value res = ENC_SYM_TERROR;
1413
1/2
✓ Branch 0 taken 140 times.
✗ Branch 1 not taken.
140 if (argn == 1) {
1414
2/2
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 56 times.
140 res = lbm_is_list_rw(args[0]) ? ENC_SYM_TRUE : ENC_SYM_NIL;
1415 }
1416 140 return res;
1417 }
1418
1419 308 static lbm_value fundamental_is_number(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1420 (void) ctx;
1421 308 lbm_value res = ENC_SYM_TERROR;
1422
1/2
✓ Branch 0 taken 308 times.
✗ Branch 1 not taken.
308 if (argn == 1) {
1423
2/2
✓ Branch 1 taken 196 times.
✓ Branch 2 taken 112 times.
308 res = lbm_is_number(args[0]) ? ENC_SYM_TRUE : ENC_SYM_NIL;
1424 }
1425 308 return res;
1426 }
1427
1428 static lbm_value fundamental_int_div(lbm_value *args, lbm_uint argn, eval_context_t *ctx) {
1429 lbm_value res = fundamental_div(args, argn, ctx);
1430 switch (lbm_type_of(res)) {
1431 case LBM_TYPE_FLOAT: {
1432 res = lbm_enc_i((lbm_int)lbm_dec_float(res));
1433 break;
1434 }
1435 case LBM_TYPE_DOUBLE: {
1436 res = lbm_enc_i((lbm_int)lbm_dec_double(res));
1437 break;
1438 }
1439 }
1440
1441 return res;
1442 }
1443
1444 const fundamental_fun fundamental_table[] =
1445 {fundamental_add,
1446 fundamental_sub,
1447 fundamental_mul,
1448 fundamental_div,
1449 fundamental_mod,
1450 fundamental_eq,
1451 fundamental_not_eq,
1452 fundamental_numeq,
1453 fundamental_num_not_eq,
1454 fundamental_lt,
1455 fundamental_gt,
1456 fundamental_leq,
1457 fundamental_geq,
1458 fundamental_not,
1459 fundamental_gc,
1460 fundamental_self,
1461 fundamental_set_mailbox_size,
1462 fundamental_cons,
1463 fundamental_car,
1464 fundamental_cdr,
1465 fundamental_list,
1466 fundamental_append,
1467 fundamental_undefine,
1468 fundamental_buf_create,
1469 fundamental_symbol_to_string,
1470 fundamental_string_to_symbol,
1471 fundamental_symbol_to_uint,
1472 fundamental_uint_to_symbol,
1473 fundamental_set_car,
1474 fundamental_set_cdr,
1475 fundamental_set_ix,
1476 fundamental_assoc,
1477 fundamental_acons,
1478 fundamental_set_assoc,
1479 fundamental_cossa,
1480 fundamental_ix,
1481 fundamental_to_i,
1482 fundamental_to_i32,
1483 fundamental_to_u,
1484 fundamental_to_u32,
1485 fundamental_to_float,
1486 fundamental_to_i64,
1487 fundamental_to_u64,
1488 fundamental_to_double,
1489 fundamental_to_byte,
1490 fundamental_shl,
1491 fundamental_shr,
1492 fundamental_bitwise_and,
1493 fundamental_bitwise_or,
1494 fundamental_bitwise_xor,
1495 fundamental_bitwise_not,
1496 fundamental_custom_destruct,
1497 fundamental_type_of,
1498 fundamental_list_length,
1499 fundamental_range,
1500 fundamental_reg_event_handler,
1501 fundamental_take,
1502 fundamental_drop,
1503 fundamental_mkarray,
1504 fundamental_array_to_list,
1505 fundamental_list_to_array,
1506 fundamental_dm_create,
1507 fundamental_dm_alloc,
1508 fundamental_is_list,
1509 fundamental_is_number,
1510 fundamental_int_div,
1511 };
1512