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