• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ArkScript-lang / Ark / 14640812317

24 Apr 2025 11:46AM UTC coverage: 83.196% (+2.8%) from 80.417%
14640812317

Pull #530

github

web-flow
Merge 718abfdf5 into 32828a045
Pull Request #530: Feat/inst locations

290 of 380 new or added lines in 20 files covered. (76.32%)

7 existing lines in 3 files now uncovered.

6560 of 7885 relevant lines covered (83.2%)

79291.33 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

19.49
/src/arkreactor/Builtins/Mathematics.cpp
1
#define _USE_MATH_DEFINES
2
#include <cmath>
3
#include <fmt/core.h>
4
#include <random>
5

6
#include <Ark/Builtins/Builtins.hpp>
7

8
#include <Ark/TypeChecker.hpp>
9
#include <Ark/VM/VM.hpp>
10

11
namespace Ark::internal::Builtins::Mathematics
12
{
13
    /**
14
     * @name math:exp
15
     * @brief Calculate e^number
16
     * @param value the Number
17
     * =begin
18
     * (math:exp 1)  # 2.7182...
19
     * =end
20
     * @author https://github.com/SuperFola
21
     */
22
    Value exponential(std::vector<Value>& n, VM* vm [[maybe_unused]])
7✔
23
    {
7✔
24
        if (!types::check(n, ValueType::Number))
7✔
NEW
25
            throw types::TypeCheckingError(
×
26
                "math:exp",
×
27
                { { types::Contract { { types::Typedef("value", ValueType::Number) } } } },
×
28
                n);
×
29

30
        return Value(std::exp(n[0].number()));
7✔
31
    }
×
32

33
    /**
34
     * @name math:ln
35
     * @brief Calculate the logarithm of a number
36
     * @param value the Number
37
     * =begin
38
     * (math:ln 1)  # 0
39
     * =end
40
     * @author https://github.com/SuperFola
41
     */
42
    Value logarithm(std::vector<Value>& n, VM* vm [[maybe_unused]])
17✔
43
    {
17✔
44
        if (!types::check(n, ValueType::Number))
17✔
NEW
45
            throw types::TypeCheckingError(
×
46
                "math:ln",
×
47
                { { types::Contract { { types::Typedef("value", ValueType::Number) } } } },
×
48
                n);
×
49

50
        if (n[0].number() <= 0.0)
17✔
51
            throw std::runtime_error(fmt::format("math:ln: value {} must be greater than 0", n[0].number()));
×
52

53
        return Value(std::log(n[0].number()));
17✔
54
    }
×
55

56
    /**
57
     * @name math:ceil
58
     * @brief Get the smallest possible integer greater than the number
59
     * @param value the Number
60
     * =begin
61
     * (math:ceil 0.2)  # 1
62
     * =end
63
     * @author https://github.com/SuperFola
64
     */
65
    Value ceil_(std::vector<Value>& n, VM* vm [[maybe_unused]])
3✔
66
    {
3✔
67
        if (!types::check(n, ValueType::Number))
3✔
NEW
68
            throw types::TypeCheckingError(
×
69
                "math:ceil",
×
70
                { { types::Contract { { types::Typedef("value", ValueType::Number) } } } },
×
71
                n);
×
72

73
        return Value(std::ceil(n[0].number()));
3✔
74
    }
×
75

76
    /**
77
     * @name math:floor
78
     * @brief Get the smallest possible integer equal to the given number
79
     * @param value the Number
80
     * =begin
81
     * (math:floor 1.7)  # 1
82
     * =end
83
     * @author https://github.com/SuperFola
84
     */
85
    Value floor_(std::vector<Value>& n, VM* vm [[maybe_unused]])
14✔
86
    {
14✔
87
        if (!types::check(n, ValueType::Number))
14✔
NEW
88
            throw types::TypeCheckingError(
×
89
                "math:floor",
×
90
                { { types::Contract { { types::Typedef("value", ValueType::Number) } } } },
×
91
                n);
×
92

93
        return Value(std::floor(n[0].number()));
14✔
94
    }
×
95

96
    /**
97
     * @name math:round
98
     * @brief Get the smallest possible integer equal to or greater than the given number
99
     * @param value the Number
100
     * =begin
101
     * (math:round 0.2)  # 0
102
     * (math:round 0.6)  # 1
103
     * =end
104
     * @author https://github.com/SuperFola
105
     */
106
    Value round_(std::vector<Value>& n, VM* vm [[maybe_unused]])
5✔
107
    {
5✔
108
        if (!types::check(n, ValueType::Number))
5✔
NEW
109
            throw types::TypeCheckingError(
×
110
                "math:round",
×
111
                { { types::Contract { { types::Typedef("value", ValueType::Number) } } } },
×
112
                n);
×
113

114
        return Value(std::round(n[0].number()));
5✔
115
    }
×
116

117
    /**
118
     * @name math:NaN?
119
     * @brief Check if a Number is NaN
120
     * @param value the Number
121
     * =begin
122
     * (math:NaN? 2)  # false
123
     * (math:NaN? nan)  # true
124
     * =end
125
     * @author https://github.com/SuperFola
126
     */
127
    Value isnan_(std::vector<Value>& n, VM* vm [[maybe_unused]])
×
128
    {
×
129
        if (!types::check(n, ValueType::Any))
×
NEW
130
            throw types::TypeCheckingError(
×
131
                "math:NaN?",
×
132
                { { types::Contract { { types::Typedef("value", ValueType::Any) } } } },
×
133
                n);
×
134

135
        if (n[0].valueType() != ValueType::Number)
×
136
            return falseSym;
×
137

138
        return std::isnan(n[0].number()) ? trueSym : falseSym;
×
139
    }
×
140

141
    /**
142
     * @name math:Inf?
143
     * @brief Check if a Number if Inf
144
     * @param value the Number
145
     * =begin
146
     * (math:Inf? 1)  # false
147
     * (math:Inf? nan)  # false
148
     * =end
149
     * @author https://github.com/SuperFola
150
     */
151
    Value isinf_(std::vector<Value>& n, VM* vm [[maybe_unused]])
3✔
152
    {
3✔
153
        if (!types::check(n, ValueType::Any))
3✔
NEW
154
            throw types::TypeCheckingError(
×
155
                "math:Inf?",
×
156
                { { types::Contract { { types::Typedef("value", ValueType::Any) } } } },
×
157
                n);
×
158

159
        if (n[0].valueType() != ValueType::Number)
3✔
160
            return falseSym;
×
161

162
        return std::isinf(n[0].number()) ? trueSym : falseSym;
3✔
163
    }
3✔
164

165
    /**
166
     * @name math:cos
167
     * @brief Calculate the cosinus of a number
168
     * @param value the Number (radians)
169
     * =begin
170
     * (math:cos 0)  # 1
171
     * (math:cos math:pi)  # -1
172
     * =end
173
     * @author https://github.com/SuperFola
174
     */
175
    Value cos_(std::vector<Value>& n, VM* vm [[maybe_unused]])
×
176
    {
×
177
        if (!types::check(n, ValueType::Number))
×
NEW
178
            throw types::TypeCheckingError(
×
179
                "math:cos",
×
180
                { { types::Contract { { types::Typedef("value", ValueType::Number) } } } },
×
181
                n);
×
182

183
        return Value(std::cos(n[0].number()));
×
184
    }
×
185

186
    /**
187
     * @name math:sin
188
     * @brief Calculate the sinus of a number
189
     * @param value the Number (radians)
190
     * =begin
191
     * (math:sin 0)  # 0
192
     * (math:cos (/ math:pi 2))  # 1
193
     * =end
194
     * @author https://github.com/SuperFola
195
     */
196
    Value sin_(std::vector<Value>& n, VM* vm [[maybe_unused]])
×
197
    {
×
198
        if (!types::check(n, ValueType::Number))
×
NEW
199
            throw types::TypeCheckingError(
×
200
                "math:sin",
×
201
                { { types::Contract { { types::Typedef("value", ValueType::Number) } } } },
×
202
                n);
×
203

204
        return Value(std::sin(n[0].number()));
×
205
    }
×
206

207
    /**
208
     * @name math:tan
209
     * @brief Calculate the tangent of a number
210
     * @param value the Number (radians)
211
     * =begin
212
     * (math:tan 0)  # 0
213
     * (math:cos (/ math:pi 4))  # 1
214
     * =end
215
     * @author https://github.com/SuperFola
216
     */
217
    Value tan_(std::vector<Value>& n, VM* vm [[maybe_unused]])
×
218
    {
×
219
        if (!types::check(n, ValueType::Number))
×
NEW
220
            throw types::TypeCheckingError(
×
221
                "math:tan",
×
222
                { { types::Contract { { types::Typedef("value", ValueType::Number) } } } },
×
223
                n);
×
224

225
        return Value(std::tan(n[0].number()));
×
226
    }
×
227

228
    /**
229
     * @name math:arccos
230
     * @brief Calculate the arc cosinus of a number
231
     * @param value the Number
232
     * =begin
233
     * (math:arccos 1)  # 0
234
     * =end
235
     * @author https://github.com/SuperFola
236
     */
237
    Value acos_(std::vector<Value>& n, VM* vm [[maybe_unused]])
×
238
    {
×
239
        if (!types::check(n, ValueType::Number))
×
NEW
240
            throw types::TypeCheckingError(
×
241
                "math:arccos",
×
242
                { { types::Contract { { types::Typedef("value", ValueType::Number) } } } },
×
243
                n);
×
244

245
        return Value(std::acos(n[0].number()));
×
246
    }
×
247

248
    /**
249
     * @name math:arcsin
250
     * @brief Calculate the arc sinus of a number
251
     * @param value the Number
252
     * =begin
253
     * (math:arcsin 1)  # 1.570796326794897 (/ math:pi 2)
254
     * =end
255
     * @author https://github.com/SuperFola
256
     */
257
    Value asin_(std::vector<Value>& n, VM* vm [[maybe_unused]])
×
258
    {
×
259
        if (!types::check(n, ValueType::Number))
×
NEW
260
            throw types::TypeCheckingError(
×
261
                "math:arcsin",
×
262
                { { types::Contract { { types::Typedef("value", ValueType::Number) } } } },
×
263
                n);
×
264

265
        return Value(std::asin(n[0].number()));
×
266
    }
×
267

268
    /**
269
     * @name math:arctan
270
     * @brief Calculate the arc tangent of a number
271
     * @param value the Number
272
     * =begin
273
     * (math:arctan 0)  # 0
274
     * =end
275
     * @author https://github.com/SuperFola
276
     */
277
    Value atan_(std::vector<Value>& n, VM* vm [[maybe_unused]])
×
278
    {
×
279
        if (!types::check(n, ValueType::Number))
×
NEW
280
            throw types::TypeCheckingError(
×
281
                "math:arctan",
×
282
                { { types::Contract { { types::Typedef("value", ValueType::Number) } } } },
×
283
                n);
×
284

285
        return Value(std::atan(n[0].number()));
×
286
    }
×
287

288
    /**
289
     * @name math:cosh
290
     * @brief Calculate the hyperbolic cosinus of a number
291
     * @param value the Number
292
     * @author https://github.com/Gryfenfer97
293
     */
294
    Value cosh_(std::vector<Value>& n, VM* vm [[maybe_unused]])
×
295
    {
×
296
        if (!types::check(n, ValueType::Number))
×
NEW
297
            throw types::TypeCheckingError(
×
298
                "math:cosh",
×
299
                { { types::Contract { { types::Typedef("value", ValueType::Number) } } } },
×
300
                n);
×
301

302
        return Value(std::cosh(n[0].number()));
×
303
    }
×
304

305
    /**
306
     * @name math:sinh
307
     * @brief Calculate the hyperbolic sinus of a number
308
     * @param value the Number
309
     * @author https://github.com/Gryfenfer97
310
     */
311
    Value sinh_(std::vector<Value>& n, VM* vm [[maybe_unused]])
×
312
    {
×
313
        if (!types::check(n, ValueType::Number))
×
NEW
314
            throw types::TypeCheckingError(
×
315
                "math:sinh",
×
316
                { { types::Contract { { types::Typedef("value", ValueType::Number) } } } },
×
317
                n);
×
318

319
        return Value(std::sinh(n[0].number()));
×
320
    }
×
321

322
    /**
323
     * @name math:tanh
324
     * @brief Calculate the hyperbolic tangent of a number
325
     * @param value the Number
326
     * @author https://github.com/Gryfenfer97
327
     */
328
    Value tanh_(std::vector<Value>& n, VM* vm [[maybe_unused]])
×
329
    {
×
330
        if (!types::check(n, ValueType::Number))
×
NEW
331
            throw types::TypeCheckingError(
×
332
                "math:tanh",
×
333
                { { types::Contract { { types::Typedef("value", ValueType::Number) } } } },
×
334
                n);
×
335

336
        return Value(std::tanh(n[0].number()));
×
337
    }
×
338

339
    /**
340
     * @name math:acosh
341
     * @brief Calculate the hyperbolic arc cosinus of a number
342
     * @param value the Number
343
     * @author https://github.com/Gryfenfer97
344
     */
345
    Value acosh_(std::vector<Value>& n, VM* vm [[maybe_unused]])
×
346
    {
×
347
        if (!types::check(n, ValueType::Number))
×
NEW
348
            throw types::TypeCheckingError(
×
349
                "math:acosh",
×
350
                { { types::Contract { { types::Typedef("value", ValueType::Number) } } } },
×
351
                n);
×
352

353
        return Value(std::acosh(n[0].number()));
×
354
    }
×
355

356
    /**
357
     * @name math:asinh
358
     * @brief Calculate the hyperbolic arc sinus of a number
359
     * @param value the Number
360
     * @author https://github.com/Gryfenfer97
361
     */
362
    Value asinh_(std::vector<Value>& n, VM* vm [[maybe_unused]])
×
363
    {
×
364
        if (!types::check(n, ValueType::Number))
×
NEW
365
            throw types::TypeCheckingError(
×
366
                "math:asinh",
×
367
                { { types::Contract { { types::Typedef("value", ValueType::Number) } } } },
×
368
                n);
×
369

370
        return Value(std::asinh(n[0].number()));
×
371
    }
×
372

373
    /**
374
     * @name math:atanh
375
     * @brief Calculate the hyperbolic arc tangent of a number
376
     * @param value the Number
377
     * @author https://github.com/Gryfenfer97
378
     */
379
    Value atanh_(std::vector<Value>& n, VM* vm [[maybe_unused]])
×
380
    {
×
381
        if (!types::check(n, ValueType::Number))
×
NEW
382
            throw types::TypeCheckingError(
×
383
                "math:atanh",
×
384
                { { types::Contract { { types::Typedef("value", ValueType::Number) } } } },
×
385
                n);
×
386

387
        return Value(std::atanh(n[0].number()));
×
388
    }
×
389

390
    /**
391
     * @name random
392
     * @brief Compute a random number in [-2147483648, 2147483647] or in a custom range passed to the function
393
     * @param min optional inclusive lower bound
394
     * @param max optional inclusive upper bound. Must be present if `min` is passed
395
     * =begin
396
     * (print (random))  # a number in [-2147483648, 2147483647]
397
     * (print (random 0 10))  # a number between 0 and 10
398
     * =end
399
     * @author https://github.com/SuperFola
400
     */
401
    Value random(std::vector<Value>& n, VM* vm [[maybe_unused]])
100✔
402
    {
100✔
403
        static std::mt19937 gen { std::random_device()() };
100✔
404

405
        if (n.size() == 2 && !types::check(n, ValueType::Number, ValueType::Number))
100✔
NEW
406
            throw types::TypeCheckingError(
×
407
                "random",
×
408
                { { types::Contract {
×
409
                    { types::Typedef("min", ValueType::Number), types::Typedef("max", ValueType::Number) } } } },
×
410
                n);
×
411

412
        if (n.size() == 2)
100✔
413
        {
414
            const auto inclusive_min = static_cast<int>(n[0].number()),
100✔
415
                       inclusive_max = static_cast<int>(n[1].number());
100✔
416

417
            std::uniform_int_distribution<> distrib(inclusive_min, inclusive_max);
100✔
418
            return Value(distrib(gen));
100✔
419
        }
100✔
420

421
        const auto x = static_cast<int>(gen());
×
422
        return Value(x);
×
423
    }
100✔
424
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc