GCC Code Coverage Report


Directory: ../src/
File: /home/joels/Current/lispbm/src/extensions/math_extensions.c
Date: 2025-08-08 18:10:24
Exec Total Coverage
Lines: 121 124 97.6%
Functions: 20 20 100.0%
Branches: 63 68 92.6%

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