GCC Code Coverage Report


Directory: ../src/
File: /home/joels/Current/lispbm/src/extensions/math_extensions.c
Date: 2025-10-28 15:15:18
Exec Total Coverage
Lines: 124 124 100.0%
Functions: 20 20 100.0%
Branches: 68 68 100.0%

Line Branch Exec Source
1 /*
2 Copyright 2022, 2023, 2025 Joel Svensson svenssonjoel@yahoo.se
3 Copyright 2022, 2023 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
19 #include "extensions.h"
20 #include "lbm_utils.h"
21
22 #include <math.h>
23
24 #ifdef LBM_OPT_MATH_EXTENSIONS_SIZE
25 #pragma GCC optimize ("-Os")
26 #endif
27 #ifdef LBM_OPT_MATH_EXTENSIONS_SIZE_AGGRESSIVE
28 #pragma GCC optimize ("-Oz")
29 #endif
30
31
32 #ifdef __STRICT_ANSI__
33 #define isnanf isnan
34 #define isinff isinf
35 #endif
36
37 // Math
38
39 171 static lbm_value ext_sin(lbm_value *args, lbm_uint argn) {
40
2/2
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 86 times.
171 LBM_CHECK_ARGN_NUMBER(1);
41 86 return lbm_enc_float(sinf(lbm_dec_as_float(args[0])));
42 }
43
44 171 static lbm_value ext_cos(lbm_value *args, lbm_uint argn) {
45
2/2
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 86 times.
171 LBM_CHECK_ARGN_NUMBER(1);
46 86 return lbm_enc_float(cosf(lbm_dec_as_float(args[0])));
47 }
48
49 170 static lbm_value ext_tan(lbm_value *args, lbm_uint argn) {
50
2/2
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 85 times.
170 LBM_CHECK_ARGN_NUMBER(1);
51 85 return lbm_enc_float(tanf(lbm_dec_as_float(args[0])));
52 }
53
54 171 static lbm_value ext_asin(lbm_value *args, lbm_uint argn) {
55
2/2
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 86 times.
171 LBM_CHECK_ARGN_NUMBER(1);
56 86 return lbm_enc_float(asinf(lbm_dec_as_float(args[0])));
57 }
58
59 171 static lbm_value ext_acos(lbm_value *args, lbm_uint argn) {
60
2/2
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 86 times.
171 LBM_CHECK_ARGN_NUMBER(1);
61 86 return lbm_enc_float(acosf(lbm_dec_as_float(args[0])));
62 }
63
64 170 static lbm_value ext_atan(lbm_value *args, lbm_uint argn) {
65
2/2
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 85 times.
170 LBM_CHECK_ARGN_NUMBER(1);
66 85 return lbm_enc_float(atanf(lbm_dec_as_float(args[0])));
67 }
68
69 172 static lbm_value ext_atan2(lbm_value *args, lbm_uint argn) {
70
2/2
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 86 times.
172 LBM_CHECK_ARGN_NUMBER(2);
71 86 return lbm_enc_float(atan2f(lbm_dec_as_float(args[0]), lbm_dec_as_float(args[1])));
72 }
73
74 172 static lbm_value ext_pow(lbm_value *args, lbm_uint argn) {
75
2/2
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 86 times.
172 LBM_CHECK_ARGN_NUMBER(2);
76 86 return lbm_enc_float(powf(lbm_dec_as_float(args[0]), lbm_dec_as_float(args[1])));
77 }
78
79 176 static lbm_value ext_exp(lbm_value *args, lbm_uint argn) {
80
2/2
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 91 times.
176 LBM_CHECK_ARGN_NUMBER(1);
81 91 return lbm_enc_float(expf(lbm_dec_as_float(args[0])));
82 }
83
84 261 static lbm_value ext_sqrt(lbm_value *args, lbm_uint argn) {
85
2/2
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 176 times.
261 LBM_CHECK_ARGN_NUMBER(1);
86 176 return lbm_enc_float(sqrtf(lbm_dec_as_float(args[0])));
87 }
88
89 171 static lbm_value ext_log(lbm_value *args, lbm_uint argn) {
90
2/2
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 86 times.
171 LBM_CHECK_ARGN_NUMBER(1);
91 86 return lbm_enc_float(logf(lbm_dec_as_float(args[0])));
92 }
93
94 254 static lbm_value ext_log10(lbm_value *args, lbm_uint argn) {
95
2/2
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 169 times.
254 LBM_CHECK_ARGN_NUMBER(1);
96 169 return lbm_enc_float(log10f(lbm_dec_as_float(args[0])));
97 }
98
99 171 static lbm_value ext_floor(lbm_value *args, lbm_uint argn) {
100
2/2
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 86 times.
171 LBM_CHECK_ARGN_NUMBER(1);
101 86 return lbm_enc_float(floorf(lbm_dec_as_float(args[0])));
102 }
103
104 171 static lbm_value ext_ceil(lbm_value *args, lbm_uint argn) {
105
2/2
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 86 times.
171 LBM_CHECK_ARGN_NUMBER(1);
106 86 return lbm_enc_float(ceilf(lbm_dec_as_float(args[0])));
107 }
108
109 171 static lbm_value ext_round(lbm_value *args, lbm_uint argn) {
110
2/2
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 86 times.
171 LBM_CHECK_ARGN_NUMBER(1);
111 86 return lbm_enc_float(roundf(lbm_dec_as_float(args[0])));
112 }
113
114 509 static lbm_value ext_deg2rad(lbm_value *args, lbm_uint argn) {
115
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 508 times.
509 LBM_CHECK_NUMBER_ALL();
116
117
2/2
✓ Branch 0 taken 339 times.
✓ Branch 1 taken 169 times.
508 if (argn == 1) {
118 339 return lbm_enc_float(DEG2RAD_f(lbm_dec_as_float(args[0])));
119 } else {
120 169 lbm_value out_list = ENC_SYM_NIL;
121
2/2
✓ Branch 0 taken 254 times.
✓ Branch 1 taken 169 times.
423 for (int i = (int)(argn - 1);i >= 0;i--) {
122 254 out_list = lbm_cons(lbm_enc_float(DEG2RAD_f(lbm_dec_as_float(args[i]))), out_list);
123 }
124 169 return out_list;
125 }
126 }
127
128 256 static lbm_value ext_rad2deg(lbm_value *args, lbm_uint argn) {
129
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 255 times.
256 LBM_CHECK_NUMBER_ALL();
130
131
2/2
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 169 times.
255 if (argn == 1) {
132 86 return lbm_enc_float(RAD2DEG_f(lbm_dec_as_float(args[0])));
133 } else {
134 169 lbm_value out_list = ENC_SYM_NIL;
135
2/2
✓ Branch 0 taken 254 times.
✓ Branch 1 taken 169 times.
423 for (int i = (int)(argn - 1);i >= 0;i--) {
136 254 out_list = lbm_cons(lbm_enc_float(RAD2DEG_f(lbm_dec_as_float(args[i]))), out_list);
137 }
138 169 return out_list;
139 }
140 }
141
142
143 518 static lbm_value ext_is_nan(lbm_value *args, lbm_uint argn) {
144 518 lbm_value res = ENC_SYM_EERROR;
145
2/2
✓ Branch 0 taken 434 times.
✓ Branch 1 taken 84 times.
518 if (argn == 1) {
146 434 res = ENC_SYM_TERROR;
147
2/2
✓ Branch 0 taken 433 times.
✓ Branch 1 taken 1 times.
434 if (lbm_is_number(args[0])) {
148 433 lbm_uint t = lbm_type_of_functional(args[0]);
149
3/3
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 264 times.
✓ Branch 2 taken 84 times.
433 switch(t) {
150 85 case LBM_TYPE_DOUBLE:
151
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 84 times.
85 if (isnan(lbm_dec_double(args[0]))) {
152 1 res = ENC_SYM_TRUE;
153 } else {
154 84 res = ENC_SYM_NIL;
155 }
156 85 break;
157 264 case LBM_TYPE_FLOAT:
158
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 172 times.
264 if (isnanf(lbm_dec_float(args[0]))) {
159 92 res = ENC_SYM_TRUE;
160 } else {
161 172 res = ENC_SYM_NIL;
162 }
163 264 break;
164 84 default:
165 84 res = ENC_SYM_NIL;
166 84 break;
167 }
168 }
169 }
170 518 return res;
171 }
172
173 345 static lbm_value ext_is_inf(lbm_value *args, lbm_uint argn) {
174 345 lbm_value res = ENC_SYM_EERROR;
175
2/2
✓ Branch 0 taken 261 times.
✓ Branch 1 taken 84 times.
345 if (argn == 1) {
176 261 res = ENC_SYM_TERROR;
177
2/2
✓ Branch 0 taken 260 times.
✓ Branch 1 taken 1 times.
261 if (lbm_is_number(args[0])) {
178 260 lbm_uint t = lbm_type_of_functional(args[0]);
179
3/3
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 91 times.
✓ Branch 2 taken 84 times.
260 switch(t) {
180 85 case LBM_TYPE_DOUBLE:
181
4/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 84 times.
85 if (isinf(lbm_dec_double(args[0]))) {
182 1 res = ENC_SYM_TRUE;
183 } else {
184 84 res = ENC_SYM_NIL;
185 }
186 85 break;
187 91 case LBM_TYPE_FLOAT:
188
4/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 87 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 87 times.
91 if (isinff(lbm_dec_float(args[0]))) {
189 4 res = ENC_SYM_TRUE;
190 } else {
191 87 res = ENC_SYM_NIL;
192 }
193 91 break;
194 84 default:
195 84 res = ENC_SYM_NIL;
196 84 break;
197 }
198 }
199 }
200 345 return res;
201 }
202
203
204 66394 void lbm_math_extensions_init(void) {
205
206 66394 lbm_add_extension("sin", ext_sin);
207 66394 lbm_add_extension("cos", ext_cos);
208 66394 lbm_add_extension("tan", ext_tan);
209 66394 lbm_add_extension("asin", ext_asin);
210 66394 lbm_add_extension("acos", ext_acos);
211 66394 lbm_add_extension("atan", ext_atan);
212 66394 lbm_add_extension("atan2", ext_atan2);
213 66394 lbm_add_extension("pow", ext_pow);
214 66394 lbm_add_extension("exp", ext_exp);
215 66394 lbm_add_extension("sqrt", ext_sqrt);
216 66394 lbm_add_extension("log", ext_log);
217 66394 lbm_add_extension("log10", ext_log10);
218 66394 lbm_add_extension("floor", ext_floor);
219 66394 lbm_add_extension("ceil", ext_ceil);
220 66394 lbm_add_extension("round", ext_round);
221 66394 lbm_add_extension("deg2rad", ext_deg2rad);
222 66394 lbm_add_extension("rad2deg", ext_rad2deg);
223 66394 lbm_add_extension("is-nan", ext_is_nan);
224 66394 lbm_add_extension("is-inf", ext_is_inf);
225 66394 }
226