diff --git a/Dict.ark b/Dict.ark index 5b755cd..63bde12 100644 --- a/Dict.ark +++ b/Dict.ark @@ -99,6 +99,7 @@ # @brief Computes the number of (key, value) pairs in a given dictionary # @param _D dictionary +# @deprecated Use the builtin `len` instead # =begin # (let data (dict "key" "value")) # (print (dict:size data)) # 1 @@ -293,13 +294,12 @@ (mut _output "[") (mut _i 0) (while (< _i (len _L)) { - (set _output - (+ - _output - (_valAsJson (@ _L _i)) - (if (= (len _L) (+ 1 _i)) - "" - ", "))) + (set _output (+ + _output + (_valAsJson (@ _L _i)) + (if (= (len _L) (+ 1 _i)) + "" + ", "))) (set _i (+ 1 _i)) }) (+ _output "]") })) @@ -327,13 +327,12 @@ (mut _as_str "") (set _i 0) (while (< _i (len _output)) { - (set _as_str - (+ - _as_str - (@ _output _i) - (if (= (len _output) (+ 1 _i)) - "" - ", "))) + (set _as_str (+ + _as_str + (@ _output _i) + (if (= (len _output) (+ 1 _i)) + "" + ", "))) (set _i (+ 1 _i)) }) (+ "{" _as_str "}") })) diff --git a/List.ark b/List.ark index 409bff6..03867a2 100644 --- a/List.ark +++ b/List.ark @@ -61,6 +61,7 @@ # @brief Function to call the `len` operator on a list # @param _L list to get the size of +# @deprecated Use the builtin `len` instead # =begin # (print (list:size [1 2 3 4])) # 4 # =end diff --git a/Macros.ark b/Macros.ark index bcfe945..aeeaa0f 100644 --- a/Macros.ark +++ b/Macros.ark @@ -1,6 +1,6 @@ # internal, do not use (macro __replace_all_placeholders_with (replacement x ...xs) { - ($if (empty? xs) + ($if ($empty? xs) ($if (= "_" ($repr x)) replacement x) @@ -26,7 +26,7 @@ ($if (= "Symbol" ($type fn1)) (macro call (fn1 arg)) (macro call ((__replace_all_placeholders_with arg ...fn1)))) - ($if (> (len fns) 0) + ($if (> ($len fns) 0) (-> call ...fns) call) }) @@ -48,11 +48,11 @@ # =end # @author https://github.com/SuperFola (macro partial (func ...defargs) { - (macro bloc (__suffix-dup a (- ($argcount func) (len defargs)))) + (macro bloc (__suffix-dup a (- ($argcount func) ($len defargs)))) (fun (bloc) (func ...defargs bloc)) ($undef bloc) }) -(macro __count_placeholders (acc x ...xs) ($if (empty? xs) +(macro __count_placeholders (acc x ...xs) ($if ($empty? xs) ($if (= "_" ($repr x)) (+ 1 acc) acc) @@ -61,14 +61,14 @@ (__count_placeholders acc ...xs)))) (macro __replace_placeholders (replacements x ...xs) { - ($if (empty? xs) + ($if ($empty? xs) ($if (= "_" ($repr x)) - (head replacements) + ($head replacements) x) ($if (= "_" ($repr x)) { - (head replacements) - (__replace_placeholders (tail replacements) ...xs) } + ($head replacements) + (__replace_placeholders ($tail replacements) ...xs) } { x (__replace_placeholders replacements ...xs) })) }) diff --git a/Math.ark b/Math.ark index 8347356..8e7756a 100644 --- a/Math.ark +++ b/Math.ark @@ -255,7 +255,7 @@ (let prime? (fun (n) (if (= 2 n) true - (if (or (= 0 (mod n 2)) (= 1 n)) + (if (or (= 0 (mod n 2)) (= 1 n) (!= 0 (mod n 1))) false { (let k (ceil (+ 1 (sqrt n)))) @@ -276,6 +276,7 @@ # @author https://github.com/Wafelack (let divs (fun (n) { (assert (>= n 1) "divs: n must be greater or equal to 1") + (assert (= 0 (mod n 1)) "divs: n must be an integer") (mut i 1) (mut divisors []) (let top (ceil (/ n 2))) diff --git a/Prelude.ark b/Prelude.ark new file mode 100644 index 0000000..fdd85bc --- /dev/null +++ b/Prelude.ark @@ -0,0 +1,10 @@ +(import std.Dict) +(import std.IO) +(import std.List) +(import std.Macros) +(import std.Math) +(import std.Random) +(import std.Range) +(import std.String) +(import std.Switch) +(import std.Sys) diff --git a/String.ark b/String.ark index e852193..5917cad 100644 --- a/String.ark +++ b/String.ark @@ -245,7 +245,7 @@ # @param _string the string to get a slice of # @param _startingIndex the index in the string where to start slicing # @param _length the length of the slice -# @details The original string is left unmodified. Example: +# @details The original string is left unmodified. # =begin # (let message "hello world, I like goats") # (let slice (string:slice message 6 4)) # => worl @@ -513,3 +513,53 @@ (if (endsWith? _str _suffix) (slice _str 0 (- (len _str) (len _suffix))) _str))) + +# @brief Compute the levenshtein distance between two strings +# @param _str1 string +# @param _str2 string +# =begin +# (print (string:levenshteinDistance "arkscript" "arkscript")) # 0 +# (print (string:levenshteinDistance "arkscript" "Orkscript")) # 1 +# (print (string:levenshteinDistance "arkscript" "0rCscript")) # 2 +# (print (string:levenshteinDistance "arkscript" "OrC")) # 8 +# =end +# @author https://github.com/SuperFola +(let levenshteinDistance (fun (_str1 _str2) { + (let _len1 (+ (len _str1) 1)) + (let _len2 (+ (len _str2) 1)) + (mut _edit_distances (builtin__list:fill _len1 (builtin__list:fill _len2 0))) + + (mut _i 0) + (while (< _i _len1) { + (@@= _edit_distances _i 0 _i) + (set _i (+ 1 _i)) }) + (set _i 0) + (while (< _i _len2) { + (@@= _edit_distances 0 _i _i) + (set _i (+ 1 _i)) }) + + (set _i 1) + (while (< _i _len1) { + (mut _j 1) + (while (< _j _len2) { + (let _dist [ + (+ 1 (@@ _edit_distances (- _i 1) _j)) + (+ 1 (@@ _edit_distances _i (- _j 1))) + (+ + (if (= (@ _str1 (- _i 1)) (@ _str2 (- _j 1))) + 0 + 1) + (@@ _edit_distances (- _i 1) (- _j 1)))]) + (@@= + _edit_distances + _i + _j + (if (and (< (@ _dist 0) (@ _dist 1)) (< (@ _dist 0) (@ _dist 2))) + (@ _dist 0) + (if (and (< (@ _dist 1) (@ _dist 0)) (< (@ _dist 1) (@ _dist 2))) + (@ _dist 1) + (@ _dist 2)))) + (set _j (+ 1 _j)) }) + (set _i (+ 1 _i)) }) + + (@@ _edit_distances (- _len1 1) (- _len2 1)) })) diff --git a/Switch.ark b/Switch.ark index 4417e97..550e8e8 100644 --- a/Switch.ark +++ b/Switch.ark @@ -18,4 +18,4 @@ then (if (= value case) then - ($if (>= (len cases) 2) (switch value ...cases)))) }) + ($if (>= ($len cases) 2) (switch value ...cases)))) }) diff --git a/tests/dict-tests.ark b/tests/dict-tests.ark index 33dd3bd..06a5581 100644 --- a/tests/dict-tests.ark +++ b/tests/dict-tests.ark @@ -25,9 +25,8 @@ (let filter_odd (fun (k v) (= 1 (mod v 2)))) (test:case "comparison" { - # FIXME: the macro processor is using the macro version of `empty?`, even though we have an `$as-is` inside expect - (test:expect ($as-is (empty? (dict)))) - (test:expect ($as-is (not (empty? (dict "a" 2))))) + (test:expect (empty? (dict))) + (test:expect (not (empty? (dict "a" 2)))) (test:expect (not empty)) (test:expect (not (not d))) (test:eq empty (dict)) @@ -68,8 +67,7 @@ (test:eq (dict:size d) 6) (test:eq (dict:size d) (len d)) (test:eq (dict:size (dict)) 0) - # FIXME: the macro processor is using the macro version of `len`, even though we have an `$as-is` inside eq - (test:eq (dict:size (dict)) ($as-is (len (dict)))) + (test:eq (dict:size (dict)) (len (dict))) (test:eq (dict:size d3) 1) (test:eq (dict:size d3) (len d3)) (test:eq (dict:size d4) 1) }) diff --git a/tests/macros-tests.ark b/tests/macros-tests.ark index 2d940ba..864ae61 100644 --- a/tests/macros-tests.ark +++ b/tests/macros-tests.ark @@ -14,6 +14,7 @@ (let test_func1 (partial test_func 1)) (let test_func2 (partial test_func1 2)) (let test_func3 (partial2 test_func 1 _ 3)) +(let test_func4 (partial2 test_func _ 2 _)) (test:suite macros { (test:case "->" { @@ -25,7 +26,9 @@ (test:eq (test_func1 2 3) 6) (test:eq ($argcount test_func1) 2) (test:eq ($argcount test_func2) 1) - (test:eq (test_func3 2) 6) }) + (test:eq ($argcount test_func4) 2) + (test:eq (test_func3 2) 6) + (test:eq (test_func4 1 3) 6) }) (test:case "unless" { (unless false diff --git a/tests/string-tests.ark b/tests/string-tests.ark index 7968697..2737082 100644 --- a/tests/string-tests.ark +++ b/tests/string-tests.ark @@ -162,4 +162,10 @@ (test:eq (string:removeSuffix "TestCase" "Case") "Test") (test:eq (string:removeSuffix "BaseTestCase" "Test") "BaseTestCase") }) + + (test:case "levenshteinDistance" { + (test:eq (string:levenshteinDistance "arkscript" "arkscript") 0) + (test:eq (string:levenshteinDistance "arkscript" "Orkscript") 1) + (test:eq (string:levenshteinDistance "arkscript" "0rCscript") 2) + (test:eq (string:levenshteinDistance "arkscript" "OrC") 8) }) })