Skip to content

Commit d0fbbad

Browse files
committed
feat(builtins): turning random into a builtin
1 parent 2a28726 commit d0fbbad

File tree

12 files changed

+57
-21
lines changed

12 files changed

+57
-21
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
- compile time argument count check for `and` and `or`
3737
- basic dead code elimination in the AST optimizer
3838
- new operator `@@` to get elements in list of lists / list of strings
39+
- new builtin `random`, returning a random number between INT_MIN and INT_MAX, or in a custom range
3940

4041
### Changed
4142
- instructions are on 4 bytes: 1 byte for the instruction, 1 byte of padding, 2 bytes for an immediate argument

README.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,7 @@ Also, it has:
5353
## More or less game
5454

5555
```clojure
56-
(import std.random)
57-
(import std.Math)
58-
59-
(let number (mod (math:abs (random)) 10000))
56+
(let number (random 0 10000))
6057

6158
(let game (fun () {
6259
(let impl (fun (tries) {

examples/games/more-or-less.ark

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
(import random)
2-
(import std.Math)
3-
4-
(let number (mod (math:abs (random)) 10000))
1+
(let number (random 0 10000))
52

63
(let game (fun () {
74
(let impl (fun (tries) {

include/Ark/Builtins/Builtins.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ namespace Ark::internal::Builtins
108108
Value acosh_(std::vector<Value>& n, VM* vm); // math:acosh, 1 argument
109109
Value asinh_(std::vector<Value>& n, VM* vm); // math:asinh, 1 argument
110110
Value atanh_(std::vector<Value>& n, VM* vm); // math:atanh, 1 argument
111+
112+
Value random(std::vector<Value>& n, VM* vm); // random, 0-2 args
111113
}
112114

113115
namespace Async

src/arkreactor/Builtins/Builtins.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ namespace Ark::internal::Builtins
8787
{ "math:acosh", Value(Mathematics::acosh_) },
8888
{ "math:asinh", Value(Mathematics::asinh_) },
8989
{ "math:atanh", Value(Mathematics::atanh_) },
90+
{ "random", Value(Mathematics::random) },
9091

9192
// Async
9293
{ "async", Value(Async::async) },

src/arkreactor/Builtins/Mathematics.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#define _USE_MATH_DEFINES
22
#include <cmath>
33
#include <fmt/core.h>
4+
#include <random>
45

56
#include <Ark/Builtins/Builtins.hpp>
67

@@ -385,4 +386,39 @@ namespace Ark::internal::Builtins::Mathematics
385386

386387
return Value(std::atanh(n[0].number()));
387388
}
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]])
402+
{
403+
static std::mt19937 gen { std::random_device()() };
404+
405+
if (n.size() == 2 && !types::check(n, ValueType::Number, ValueType::Number))
406+
types::generateError(
407+
"random",
408+
{ { types::Contract {
409+
{ types::Typedef("min", ValueType::Number), types::Typedef("max", ValueType::Number) } } } },
410+
n);
411+
412+
if (n.size() == 2)
413+
{
414+
const auto inclusive_min = static_cast<int>(n[0].number()),
415+
inclusive_max = static_cast<int>(n[1].number());
416+
417+
std::uniform_int_distribution<> distrib(inclusive_min, inclusive_max);
418+
return Value(distrib(gen));
419+
}
420+
421+
const auto x = static_cast<int>(gen());
422+
return Value(x);
423+
}
388424
}

tests/fuzzing/arkscript.dict

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,4 @@
8080
"math:arccos"
8181
"math:arcsin"
8282
"math:arctan"
83+
"random"

tests/fuzzing/corpus-cmin-tmin/examples_games_more-or-less.ark

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
(import random)
2-
(import std.Math)
3-
4-
(let number (mod (math:abs (random)) 10000))
1+
(let number (random 0 10000))
52

63
(let game (fun () {
74
(let impl (fun (tries) {

tests/fuzzing/corpus-cmin/examples_games_more-or-less.ark

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
(import random)
2-
(import std.Math)
3-
4-
(let number (mod (math:abs (random)) 10000))
1+
(let number (random 0 10000))
52

63
(let game (fun () {
74
(let impl (fun (tries) {

0 commit comments

Comments
 (0)