about summary refs log tree commit diff
diff options
context:
space:
mode:
authorsterni <sternenseemann@systemli.org>2023-08-05T13·39+0200
committersterni <sternenseemann@systemli.org>2023-08-09T12·12+0000
commit984ea69386a47e753c4129e2a6230aa60b4584cd (patch)
treebab3642e070d41d5901c1c73a839ff1c03b7313a
parentdbdb2575cfd12b7b41fbf12547592d00819c7546 (diff)
refactor(users/sterni/nix): move generic number operation into num r/6477
We omit type checks for performance reasons in most places currently, so
the library grouping is important in showing people what to use for what
sort of input. The moved functions make sense to use with floats as
well, so we'll move them to the num library. Some of the remaining
functions could theoretically be adapted and moved, but aren't for now.

Change-Id: Ifdecaa60be594f4438b2a58b9ea6445e2da080e3
Reviewed-on: https://cl.tvl.fyi/c/depot/+/9007
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
-rw-r--r--users/sterni/nix/char/tests/default.nix6
-rw-r--r--users/sterni/nix/int/default.nix28
-rw-r--r--users/sterni/nix/int/tests/default.nix6
-rw-r--r--users/sterni/nix/num/default.nix16
-rw-r--r--users/sterni/nix/num/tests/default.nix26
-rw-r--r--users/sterni/nix/utf8/default.nix27
6 files changed, 64 insertions, 45 deletions
diff --git a/users/sterni/nix/char/tests/default.nix b/users/sterni/nix/char/tests/default.nix
index 313df474514c..cb17b74c578f 100644
--- a/users/sterni/nix/char/tests/default.nix
+++ b/users/sterni/nix/char/tests/default.nix
@@ -10,7 +10,7 @@ let
   inherit (depot.users.sterni.nix)
     char
     string
-    int
+    num
     fun
     ;
 
@@ -18,10 +18,10 @@ let
 
   testAllCharConversion = it "tests conversion of all chars" [
     (assertEq "char.chr converts to char.allChars"
-      (builtins.genList (fun.rl char.chr (int.add 1)) 255)
+      (builtins.genList (fun.rl char.chr (num.add 1)) 255)
       charList)
     (assertEq "char.ord converts from char.allChars"
-      (builtins.genList (int.add 1) 255)
+      (builtins.genList (num.add 1) 255)
       (builtins.map char.ord charList))
   ];
 
diff --git a/users/sterni/nix/int/default.nix b/users/sterni/nix/int/default.nix
index a39a9477e211..e1d7e1fe7e4f 100644
--- a/users/sterni/nix/int/default.nix
+++ b/users/sterni/nix/int/default.nix
@@ -2,31 +2,22 @@
 
 let
 
-  # TODO(sterni): implement nix.float and figure out which of these
-  #               functions can be split out into a common nix.num
-  #               library.
-
   inherit (depot.users.sterni.nix)
     string
+    num
     ;
 
   inherit (builtins)
     bitOr
     bitAnd
     bitXor
-    mul
-    div
-    add
-    sub
     ;
 
-  abs = i: if i < 0 then -i else i;
-
   exp = base: pow:
     if pow > 0
     then base * (exp base (pow - 1))
     else if pow < 0
-    then 1.0 / exp base (abs pow)
+    then 1.0 / exp base (num.abs pow)
     else 1;
 
   bitShiftR = bit: count:
@@ -52,7 +43,7 @@ let
     in
     if int == 0
     then "0"
-    else "${sign}${go (abs int)}";
+    else "${sign}${go (num.abs int)}";
 
   fromHexMap = builtins.listToAttrs
     (lib.imap0 (i: c: { name = c; value = i; })
@@ -94,26 +85,17 @@ let
   odd = x: bitAnd x 1 == 1;
   even = x: bitAnd x 1 == 0;
 
-  # div and mod behave like quot and rem in Haskell,
-  # i. e. they truncate towards 0
+  inherit (builtins) div;
   mod = a: b: let res = a / b; in a - (res * b);
 
-  inRange = a: b: x: x >= a && x <= b;
-
-  sum = builtins.foldl' (a: b: a + b) 0;
-
 in
 {
   inherit
     maxBound
     minBound
-    abs
     exp
     odd
     even
-    add
-    sub
-    mul
     div
     mod
     bitShiftR
@@ -123,7 +105,5 @@ in
     bitXor
     toHex
     fromHex
-    inRange
-    sum
     ;
 }
diff --git a/users/sterni/nix/int/tests/default.nix b/users/sterni/nix/int/tests/default.nix
index 8d2263b42117..bc694ac90a02 100644
--- a/users/sterni/nix/int/tests/default.nix
+++ b/users/sterni/nix/int/tests/default.nix
@@ -15,9 +15,6 @@ let
     ;
 
   testBounds = it "checks minBound and maxBound" [
-    # this is gonna blow up in my face because
-    # integer overflow is undefined behavior in
-    # C++, so most likely anything could happen?
     (assertEq "maxBound is the maxBound" true
       (int.maxBound + 1 < int.maxBound))
     (assertEq "minBound is the minBound" true
@@ -321,7 +318,6 @@ let
   testBasic = it "checks basic int operations" [
     (assertEq "122 is even" (int.even 122 && !(int.odd 122)) true)
     (assertEq "123 is odd" (int.odd 123 && !(int.even 123)) true)
-    (assertEq "abs -4959" (int.abs (-4959)) 4959)
   ];
 
   expNumbers = [
@@ -374,7 +370,7 @@ let
   checkShiftLMulExp = n:
     assertEq "${toString n} >> 6 == ${toString n} * 2 ^ 6"
       (int.bitShiftL n 5)
-      (int.mul n (int.exp 2 5));
+      (n * (int.exp 2 5));
 
   testBit = it "checks bitwise operations" (lib.flatten [
     (builtins.map checkShift shifts)
diff --git a/users/sterni/nix/num/default.nix b/users/sterni/nix/num/default.nix
new file mode 100644
index 000000000000..640493083722
--- /dev/null
+++ b/users/sterni/nix/num/default.nix
@@ -0,0 +1,16 @@
+{ ... }:
+
+rec {
+  inherit (builtins)
+    mul
+    div
+    add
+    sub
+    ;
+
+  abs = i: if i < 0 then -i else i;
+
+  inRange = a: b: x: x >= a && x <= b;
+
+  sum = builtins.foldl' (a: b: a + b) 0;
+}
diff --git a/users/sterni/nix/num/tests/default.nix b/users/sterni/nix/num/tests/default.nix
new file mode 100644
index 000000000000..ca5f861debe8
--- /dev/null
+++ b/users/sterni/nix/num/tests/default.nix
@@ -0,0 +1,26 @@
+{ depot, ... }:
+
+let
+
+  inherit (depot.nix.runTestsuite)
+    runTestsuite
+    it
+    assertEq
+    ;
+
+  inherit (depot.users.sterni.nix)
+    num
+    ;
+
+  testsBasic = it "tests basic operations" [
+    (assertEq "abs -4959" (num.abs (-4959)) 4959)
+    (assertEq "sum" (num.sum [ 123 321 1.5 ]) (123 + 321 + 1.5))
+    (assertEq "inRange"
+      (builtins.map (num.inRange 1.0 5) [ 0 0.5 3 4 4.5 5.5 5 6 ])
+      [ false false true true true false true false ])
+  ];
+in
+
+runTestsuite "nix.num" [
+  testsBasic
+]
diff --git a/users/sterni/nix/utf8/default.nix b/users/sterni/nix/utf8/default.nix
index 71c846c0421e..e76695f128b2 100644
--- a/users/sterni/nix/utf8/default.nix
+++ b/users/sterni/nix/utf8/default.nix
@@ -6,6 +6,7 @@ let
     char
     flow
     fun
+    num
     int
     string
     util
@@ -46,17 +47,17 @@ let
     # byte position as an index starting with 0
     pos:
     let
-      defaultRange = int.inRange 128 191;
+      defaultRange = num.inRange 128 191;
 
       secondBytePredicate = flow.switch first [
-        [ (int.inRange 194 223) defaultRange ] # C2..DF
-        [ 224 (int.inRange 160 191) ] # E0
-        [ (int.inRange 225 236) defaultRange ] # E1..EC
-        [ 237 (int.inRange 128 159) ] # ED
-        [ (int.inRange 238 239) defaultRange ] # EE..EF
-        [ 240 (int.inRange 144 191) ] # F0
-        [ (int.inRange 241 243) defaultRange ] # F1..F3
-        [ 244 (int.inRange 128 143) ] # F4
+        [ (num.inRange 194 223) defaultRange ] # C2..DF
+        [ 224 (num.inRange 160 191) ] # E0
+        [ (num.inRange 225 236) defaultRange ] # E1..EC
+        [ 237 (num.inRange 128 159) ] # ED
+        [ (num.inRange 238 239) defaultRange ] # EE..EF
+        [ 240 (num.inRange 144 191) ] # F0
+        [ (num.inRange 241 243) defaultRange ] # F1..F3
+        [ 244 (num.inRange 128 143) ] # F4
         [ (fun.const true) null ]
       ];
 
@@ -225,10 +226,10 @@ let
       # Note that this doesn't check if the Unicode codepoint is allowed,
       # but rather allows all theoretically UTF-8-encodeable ones.
       count = flow.switch cp [
-        [ (int.inRange 0 127) 1 ] # 00000000 0xxxxxxx
-        [ (int.inRange 128 2047) 2 ] # 00000yyy yyxxxxxx
-        [ (int.inRange 2048 65535) 3 ] # zzzzyyyy yyxxxxxx
-        [ (int.inRange 65536 1114111) 4 ] # 000uuuuu zzzzyyyy yyxxxxxx,
+        [ (num.inRange 0 127) 1 ] # 00000000 0xxxxxxx
+        [ (num.inRange 128 2047) 2 ] # 00000yyy yyxxxxxx
+        [ (num.inRange 2048 65535) 3 ] # zzzzyyyy yyxxxxxx
+        [ (num.inRange 65536 1114111) 4 ] # 000uuuuu zzzzyyyy yyxxxxxx,
         # capped at U+10FFFF
 
         [ (fun.const true) (builtins.throw invalidCodepointMsg) ]