aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--stdlib/source/lux/data/number/i16.lux20
-rw-r--r--stdlib/source/lux/data/number/i32.lux20
-rw-r--r--stdlib/source/lux/data/number/i64.lux29
-rw-r--r--stdlib/source/lux/data/number/i8.lux20
-rw-r--r--stdlib/source/lux/target/jvm/constant.lux21
-rw-r--r--stdlib/source/lux/target/jvm/constant/pool.lux3
-rw-r--r--stdlib/source/lux/tool/compiler/phase/generation/jvm/structure.lux4
-rw-r--r--stdlib/source/test/lux/data.lux6
-rw-r--r--stdlib/source/test/lux/data/number/i16.lux39
-rw-r--r--stdlib/source/test/lux/data/number/i32.lux39
-rw-r--r--stdlib/source/test/lux/data/number/i64.lux8
-rw-r--r--stdlib/source/test/lux/data/number/i8.lux39
12 files changed, 228 insertions, 20 deletions
diff --git a/stdlib/source/lux/data/number/i16.lux b/stdlib/source/lux/data/number/i16.lux
new file mode 100644
index 000000000..23f64afc5
--- /dev/null
+++ b/stdlib/source/lux/data/number/i16.lux
@@ -0,0 +1,20 @@
+(.module:
+ [lux (#- i64)
+ [abstract
+ [equivalence (#+ Equivalence)]]
+ [data
+ ["." maybe]]
+ [type (#+ :by-example)]]
+ [//
+ ["." i64 (#+ Sub)]])
+
+(def: sub (maybe.assume (i64.sub 16)))
+
+(def: #export I16 (:by-example [size]
+ {(Sub size)
+ sub}
+ (I64 size)))
+
+(def: #export i16 (-> I64 I16) (get@ #i64.narrow sub))
+(def: #export i64 (-> I16 I64) (get@ #i64.wide sub))
+(def: #export equivalence (Equivalence I16) (get@ #i64.equivalence sub))
diff --git a/stdlib/source/lux/data/number/i32.lux b/stdlib/source/lux/data/number/i32.lux
new file mode 100644
index 000000000..7f4452880
--- /dev/null
+++ b/stdlib/source/lux/data/number/i32.lux
@@ -0,0 +1,20 @@
+(.module:
+ [lux (#- i64)
+ [abstract
+ [equivalence (#+ Equivalence)]]
+ [data
+ ["." maybe]]
+ [type (#+ :by-example)]]
+ [//
+ ["." i64 (#+ Sub)]])
+
+(def: sub (maybe.assume (i64.sub 32)))
+
+(def: #export I32 (:by-example [size]
+ {(Sub size)
+ sub}
+ (I64 size)))
+
+(def: #export i32 (-> I64 I32) (get@ #i64.narrow sub))
+(def: #export i64 (-> I32 I64) (get@ #i64.wide sub))
+(def: #export equivalence (Equivalence I32) (get@ #i64.equivalence sub))
diff --git a/stdlib/source/lux/data/number/i64.lux b/stdlib/source/lux/data/number/i64.lux
index 9d431769b..2b736b005 100644
--- a/stdlib/source/lux/data/number/i64.lux
+++ b/stdlib/source/lux/data/number/i64.lux
@@ -33,10 +33,14 @@
(All [s] (-> (I64 s) (I64 s)))
(xor (:coerce I64 -1)))
+(type: #export Mask I64)
+
(def: #export (mask bits)
- (-> Nat I64)
+ (-> Nat Mask)
(|> 1 .i64 (..left-shift (n/% ..width bits)) .dec))
+(def: #export sign Mask (|> 1 .i64 (..left-shift 63)))
+
(def: (add-shift shift value)
(-> Nat Nat Nat)
(|> value (logic-right-shift shift) (n/+ value)))
@@ -112,3 +116,26 @@
(def: identity (.i64 (..not 0)))
(def: compose ..and)
)
+
+(type: #export (Sub size)
+ {#narrow (-> I64 (I64 size))
+ #wide (-> (I64 size) I64)
+ #equivalence (Equivalence (I64 size))})
+
+(def: #export (sub width)
+ (Ex [size] (-> Nat (Maybe (Sub size))))
+ (if (.and (n/> 0 width)
+ (n/< ..width width))
+ (let [top (dec width)
+ shift (n/- width ..width)
+ sign (: Mask (|> 1 .i64 (..left-shift top)))
+ number (..mask (dec width))]
+ (#.Some {#narrow (function (narrow value)
+ (..or (|> value (..and ..sign) (..logic-right-shift shift))
+ (|> value (..and number))))
+ #wide (function (wide value)
+ (|> (..or (|> value (..and sign) (..left-shift shift))
+ (|> value (..clear top)))
+ .i64))
+ #equivalence ..equivalence}))
+ #.None))
diff --git a/stdlib/source/lux/data/number/i8.lux b/stdlib/source/lux/data/number/i8.lux
new file mode 100644
index 000000000..483f6a6a1
--- /dev/null
+++ b/stdlib/source/lux/data/number/i8.lux
@@ -0,0 +1,20 @@
+(.module:
+ [lux (#- i64)
+ [abstract
+ [equivalence (#+ Equivalence)]]
+ [data
+ ["." maybe]]
+ [type (#+ :by-example)]]
+ [//
+ ["." i64 (#+ Sub)]])
+
+(def: sub (maybe.assume (i64.sub 8)))
+
+(def: #export I8 (:by-example [size]
+ {(Sub size)
+ sub}
+ (I64 size)))
+
+(def: #export i8 (-> I64 I8) (get@ #i64.narrow sub))
+(def: #export i64 (-> I8 I64) (get@ #i64.wide sub))
+(def: #export equivalence (Equivalence I8) (get@ #i64.equivalence sub))
diff --git a/stdlib/source/lux/target/jvm/constant.lux b/stdlib/source/lux/target/jvm/constant.lux
index 80addbcbe..d900b9690 100644
--- a/stdlib/source/lux/target/jvm/constant.lux
+++ b/stdlib/source/lux/target/jvm/constant.lux
@@ -7,6 +7,7 @@
["." equivalence (#+ Equivalence)]]
[data
[number
+ ["." i32 (#+ I32)]
["." i64]
["." int]
["." frac]]
@@ -25,7 +26,7 @@
["#." descriptor (#+ Descriptor)]
["#." index (#+ Index)]
[encoding
- ["#." unsigned (#+ U4)]]]])
+ ["#." unsigned]]]])
(type: #export UTF8 Text)
@@ -53,16 +54,6 @@
(|>> :representation //index.writer))
)
-(def: sign-mask Int (|> +1 (i64.left-shift 63)))
-(def: number-mask Int (|> +1 (i64.left-shift 31) dec))
-
-(def: #export (i32 i64)
- (-> Int U4)
- (|> (i64.or (|> i64 (i64.and sign-mask) (i64.arithmetic-right-shift 32))
- (|> i64 (i64.and number-mask)))
- .nat
- //unsigned.u4))
-
(import: #long java/lang/Float
(#static floatToRawIntBits #manual [float] int))
@@ -104,7 +95,7 @@
(-> <marker> <type>)
(|>> :abstraction))]
- [integer Integer U4]
+ [integer Integer I32]
[float Float java/lang/Float]
[long Long .Int]
[double Double Frac]
@@ -118,8 +109,8 @@
(~~ (template.splice <write>))
(~~ (template.splice <writer>)))))]
- [integer-writer Integer [//unsigned.nat] [binaryF.bits/32]]
- [float-writer Float [java/lang/Float::floatToRawIntBits host.int-to-long] [..i32 //unsigned.nat binaryF.bits/32]]
+ [integer-writer Integer [] [binaryF.bits/32]]
+ [float-writer Float [java/lang/Float::floatToRawIntBits host.int-to-long] [i32.i32 binaryF.bits/32]]
[long-writer Long [] [binaryF.bits/64]]
[double-writer Double [java/lang/Double::doubleToRawLongBits] [binaryF.bits/64]]
[string-writer String [] [//index.writer]]
@@ -184,7 +175,7 @@
[(<tag> reference) (<tag> sample)]
(:: <equivalence> = reference sample))
([#UTF8 text.equivalence]
- [#Integer (..value-equivalence //unsigned.equivalence)]
+ [#Integer (..value-equivalence i32.equivalence)]
[#Long (..value-equivalence int.equivalence)]
[#Float (..value-equivalence float-equivalence)]
[#Double (..value-equivalence frac.equivalence)]
diff --git a/stdlib/source/lux/target/jvm/constant/pool.lux b/stdlib/source/lux/target/jvm/constant/pool.lux
index 590102a09..6db92879c 100644
--- a/stdlib/source/lux/target/jvm/constant/pool.lux
+++ b/stdlib/source/lux/target/jvm/constant/pool.lux
@@ -10,6 +10,7 @@
["." exception (#+ exception:)]]
[data
[number
+ ["." i32]
["." int]
["." frac]]
["." text
@@ -149,7 +150,7 @@
(Finder <type>)
(!find <tag> <equivalence> <format> reference)))]
- [integer Integer #//.Integer (//.value-equivalence //unsigned.equivalence) (|>> //.value //unsigned.nat %.nat)]
+ [integer Integer #//.Integer (//.value-equivalence i32.equivalence) (|>> //.value .nat %.nat)]
[float Float #//.Float (//.value-equivalence //.float-equivalence) (|>> //.value host.float-to-double %.frac)]
[long Long #//.Long (//.value-equivalence int.equivalence) (|>> //.value %.int)]
[double Double #//.Double (//.value-equivalence frac.equivalence) (|>> //.value %.frac)]
diff --git a/stdlib/source/lux/tool/compiler/phase/generation/jvm/structure.lux b/stdlib/source/lux/tool/compiler/phase/generation/jvm/structure.lux
index 6c2dfc277..beeeea2c7 100644
--- a/stdlib/source/lux/tool/compiler/phase/generation/jvm/structure.lux
+++ b/stdlib/source/lux/tool/compiler/phase/generation/jvm/structure.lux
@@ -3,6 +3,8 @@
[abstract
["." monad (#+ do)]]
[data
+ [number
+ ["." i32]]
[collection
["." list]]]
[target
@@ -21,7 +23,7 @@
(def: unitG (Program Any) (//primitive.text /////synthesis.unit))
(template: (!integer <value>)
- (|> <value> .int _constant.i32 _constant.integer))
+ (|> <value> .i64 i32.i32 _constant.integer))
(def: #export (tuple generate membersS)
(Generator (Tuple Synthesis))
diff --git a/stdlib/source/test/lux/data.lux b/stdlib/source/test/lux/data.lux
index 4b0f02903..116a4c890 100644
--- a/stdlib/source/test/lux/data.lux
+++ b/stdlib/source/test/lux/data.lux
@@ -12,6 +12,9 @@
["#." product]
["#." sum]
[number
+ ["#." i8]
+ ["#." i16]
+ ["#." i32]
["#." i64]
["#." nat]
["#." int]
@@ -29,6 +32,9 @@
(def: number
Test
($_ _.and
+ /i8.test
+ /i16.test
+ /i32.test
/i64.test
/nat.test
/int.test
diff --git a/stdlib/source/test/lux/data/number/i16.lux b/stdlib/source/test/lux/data/number/i16.lux
new file mode 100644
index 000000000..d44ce68f0
--- /dev/null
+++ b/stdlib/source/test/lux/data/number/i16.lux
@@ -0,0 +1,39 @@
+(.module:
+ [lux #*
+ ["_" test (#+ Test)]
+ [data
+ ["." name]
+ ["%" text/format (#+ format)]]
+ [abstract
+ [monad (#+ do)]
+ {[0 #test]
+ [/
+ ["$." equivalence]]}]
+ [math
+ ["r" random (#+ Random)]]]
+ {1
+ ["." /
+ ["/#" // #_
+ ["#." i64 (#+ Mask)]]]})
+
+(def: #export i16
+ (Random /.I16)
+ (:: r.functor map /.i16 r.i64))
+
+(def: mask
+ Mask
+ (//i64.or //i64.sign
+ (//i64.mask 15)))
+
+(def: #export test
+ Test
+ (<| (_.context (name.module (name-of /._)))
+ (do r.monad
+ [expected (:: @ map (|>> (//i64.and ..mask) (: I64)) r.i64)]
+ ($_ _.and
+ ($equivalence.spec /.equivalence ..i16)
+
+ (_.test "Can convert between I64 and I16"
+ (let [actual (|> expected /.i16 /.i64)]
+ (:: //i64.equivalence = expected actual)))
+ ))))
diff --git a/stdlib/source/test/lux/data/number/i32.lux b/stdlib/source/test/lux/data/number/i32.lux
new file mode 100644
index 000000000..ae7e0ae41
--- /dev/null
+++ b/stdlib/source/test/lux/data/number/i32.lux
@@ -0,0 +1,39 @@
+(.module:
+ [lux #*
+ ["_" test (#+ Test)]
+ [data
+ ["." name]
+ ["%" text/format (#+ format)]]
+ [abstract
+ [monad (#+ do)]
+ {[0 #test]
+ [/
+ ["$." equivalence]]}]
+ [math
+ ["r" random (#+ Random)]]]
+ {1
+ ["." /
+ ["/#" // #_
+ ["#." i64 (#+ Mask)]]]})
+
+(def: #export i32
+ (Random /.I32)
+ (:: r.functor map /.i32 r.i64))
+
+(def: mask
+ Mask
+ (//i64.or //i64.sign
+ (//i64.mask 31)))
+
+(def: #export test
+ Test
+ (<| (_.context (name.module (name-of /._)))
+ (do r.monad
+ [expected (:: @ map (|>> (//i64.and ..mask) (: I64)) r.i64)]
+ ($_ _.and
+ ($equivalence.spec /.equivalence ..i32)
+
+ (_.test "Can convert between I64 and I32"
+ (let [actual (|> expected /.i32 /.i64)]
+ (:: //i64.equivalence = expected actual)))
+ ))))
diff --git a/stdlib/source/test/lux/data/number/i64.lux b/stdlib/source/test/lux/data/number/i64.lux
index c4124669b..fd4b3adeb 100644
--- a/stdlib/source/test/lux/data/number/i64.lux
+++ b/stdlib/source/test/lux/data/number/i64.lux
@@ -1,11 +1,14 @@
(.module:
[lux #*
- ["%" data/text/format (#+ format)]
["_" test (#+ Test)]
+ [data
+ ["." name]
+ ["%" text/format (#+ format)]]
[abstract
[monad (#+ do)]
{[0 #test]
[/
+ ["$." equivalence]
["$." monoid]]}]
[math
["r" random]]]
@@ -16,11 +19,12 @@
(def: #export test
Test
- (<| (_.context (%.name (name-of /._)))
+ (<| (_.context (name.module (name-of /._)))
(do r.monad
[pattern r.nat
idx (:: @ map (n/% /.width) r.nat)]
($_ _.and
+ ($equivalence.spec /.equivalence r.i64)
($monoid.spec //nat.equivalence /.disjunction r.nat)
($monoid.spec //nat.equivalence /.conjunction r.nat)
diff --git a/stdlib/source/test/lux/data/number/i8.lux b/stdlib/source/test/lux/data/number/i8.lux
new file mode 100644
index 000000000..dc4b799fe
--- /dev/null
+++ b/stdlib/source/test/lux/data/number/i8.lux
@@ -0,0 +1,39 @@
+(.module:
+ [lux #*
+ ["_" test (#+ Test)]
+ [data
+ ["." name]
+ ["%" text/format (#+ format)]]
+ [abstract
+ [monad (#+ do)]
+ {[0 #test]
+ [/
+ ["$." equivalence]]}]
+ [math
+ ["r" random (#+ Random)]]]
+ {1
+ ["." /
+ ["/#" // #_
+ ["#." i64 (#+ Mask)]]]})
+
+(def: #export i8
+ (Random /.I8)
+ (:: r.functor map /.i8 r.i64))
+
+(def: mask
+ Mask
+ (//i64.or //i64.sign
+ (//i64.mask 7)))
+
+(def: #export test
+ Test
+ (<| (_.context (name.module (name-of /._)))
+ (do r.monad
+ [expected (:: @ map (|>> (//i64.and ..mask) (: I64)) r.i64)]
+ ($_ _.and
+ ($equivalence.spec /.equivalence ..i8)
+
+ (_.test "Can convert between I64 and I8"
+ (let [actual (|> expected /.i8 /.i64)]
+ (:: //i64.equivalence = expected actual)))
+ ))))