From a38ef23e17dc3a9ac7aebd3b8b950e0dd0db4cde Mon Sep 17 00:00:00 2001 From: Pekka Laiho Date: Sun, 18 Oct 2020 10:24:18 +0700 Subject: [PATCH] add functions: loop, coinflip, rand --- README.md | 3 +++ src/Lib/Math.php | 10 ++++++++++ src/LispFactory.php | 9 +++++++++ 3 files changed, 22 insertions(+) diff --git a/README.md b/README.md index ce3318a..54eec2d 100644 --- a/README.md +++ b/README.md @@ -141,6 +141,7 @@ quote | `(quote (1 2 3))` | `(1 2 3)` | Return the argument without evaluation. Name | Example | Example result | Description ----- | ------- | -------------- | ----------- doc | `(doc +)` | `"Return the sum of all arguments."` | Show description of a built-in function. +loop | `(loop (fn (a) (do (print a) (coinflip))) "hello ")` | `hello hello hello false` | Call the given function repeatedly in a loop until it returns false. read | `(read "(+ 1 2 3)")` | `(+ 1 2 3)` | Read a string as code and return the expression. print | `(print "hello world")` | `"hello world"null` | Print expression on the screen. Print returns null (which is shown due to the extra print in repl). Give optional second argument as `true` to show strings in readable format. error | `(error "invalid value")` | `error: invalid value` | Throw an exception with message as argument. @@ -266,6 +267,8 @@ floor | `(floor 2.5)` | `2` | Get the next lowest integer. ceil | `(ceil 2.5)` | `3` | Get the next highest integer. pow | `(pow 2 4)` | `16` | Raise the first argument to the power of the second argument. sqrt | `(sqrt 2)` | `1.41` | Calculate the square root. +coinflip | `(coinflip)` | `true` | Return true or false with equal probability. +rand | `(rand 5 10)` | `8` | Return a random integer between given min and max values. ### String functions diff --git a/src/Lib/Math.php b/src/Lib/Math.php index f7cacb7..f1f92b3 100644 --- a/src/Lib/Math.php +++ b/src/Lib/Math.php @@ -99,5 +99,15 @@ class Math implements ILib $env->set('sqrt', new CoreFunc('sqrt', 'Return the square root of the arguemnt.', 1, 1, fn ($a) => sqrt($a) )); + + // Random number generator + + $env->set('coinflip', new CoreFunc('coinflip', 'Return true or false with equal probability.', 0, 0, + fn () => boolval(mt_rand(0, 1)) + )); + + $env->set('rand', new CoreFunc('rand', 'Return a random integer between given min and max values.', 2, 2, + fn ($min, $max) => mt_rand($min, $max) + )); } } diff --git a/src/LispFactory.php b/src/LispFactory.php index b562b5c..cb870bf 100644 --- a/src/LispFactory.php +++ b/src/LispFactory.php @@ -24,6 +24,15 @@ class LispFactory } )); + $env->set('loop', new CoreFunc('loop', 'Call the given function repeatedly in a loop until it returns false.', 1, -1, + function (Func $f, ...$args) { + do { + $result = $f->call($args); + } while ($result); + return $result; + } + )); + $env->set('read', new CoreFunc('read', 'Read string as code.', 1, 1, fn (string $a) => $reader->read($tokenizer->tokenize($a)) ));