@grain/stdlib 0.5.0 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,178 @@
1
+ /* grainc-flags --no-pervasives */
2
+
3
+ import WasmI32, {
4
+ eq as (==),
5
+ ne as (!=),
6
+ and as (&),
7
+ xor as (^),
8
+ or as (|),
9
+ add as (+),
10
+ sub as (-),
11
+ mul as (*),
12
+ ltS as (<),
13
+ gtS as (>),
14
+ remS as (%),
15
+ shl as (<<),
16
+ shrU as (>>>),
17
+ } from "runtime/unsafe/wasmi32"
18
+ import WasmI64 from "runtime/unsafe/wasmi64"
19
+ import Memory from "runtime/unsafe/memory"
20
+ import Tags from "runtime/unsafe/tags"
21
+ import { tagSimpleNumber } from "runtime/dataStructures"
22
+ import { isNumber, cmp as numberCompare } from "runtime/numbers"
23
+
24
+ primitive (!): Bool -> Bool = "@not"
25
+ primitive (||): (Bool, Bool) -> Bool = "@or"
26
+ primitive (&&): (Bool, Bool) -> Bool = "@and"
27
+
28
+ @unsafe
29
+ let zero = WasmI32.fromGrain(0)
30
+
31
+ @unsafe
32
+ let rec heapCompareHelp = (heapTag, xptr, yptr) => {
33
+ match (heapTag) {
34
+ t when t == Tags._GRAIN_ADT_HEAP_TAG => {
35
+ // Check if the same constructor variant
36
+ let xvariant = WasmI32.load(xptr, 12n)
37
+ let yvariant = WasmI32.load(yptr, 12n)
38
+ if (xvariant != yvariant) {
39
+ tagSimpleNumber(xvariant - yvariant)
40
+ } else {
41
+ let xarity = WasmI32.load(xptr, 16n)
42
+ let yarity = WasmI32.load(yptr, 16n)
43
+
44
+ let mut result = 0
45
+
46
+ let bytes = xarity * 4n
47
+ for (let mut i = 0n; i < bytes; i += 4n) {
48
+ let sub = compareHelp(
49
+ WasmI32.load(xptr + i, 20n),
50
+ WasmI32.load(yptr + i, 20n)
51
+ )
52
+ if (WasmI32.fromGrain(sub) != zero) {
53
+ result = sub
54
+ break
55
+ }
56
+ }
57
+
58
+ result
59
+ }
60
+ },
61
+ t when t == Tags._GRAIN_RECORD_HEAP_TAG => {
62
+ let xlength = WasmI32.load(xptr, 12n)
63
+ let ylength = WasmI32.load(yptr, 12n)
64
+
65
+ let mut result = 0
66
+
67
+ let bytes = xlength * 4n
68
+ for (let mut i = 0n; i < bytes; i += 4n) {
69
+ let sub = compareHelp(
70
+ WasmI32.load(xptr + i, 16n),
71
+ WasmI32.load(yptr + i, 16n)
72
+ )
73
+ if (WasmI32.fromGrain(sub) != zero) {
74
+ result = sub
75
+ break
76
+ }
77
+ }
78
+
79
+ result
80
+ },
81
+ t when t == Tags._GRAIN_ARRAY_HEAP_TAG => {
82
+ let xlength = WasmI32.load(xptr, 4n)
83
+ let ylength = WasmI32.load(yptr, 4n)
84
+
85
+ // Check if the same length
86
+ if (xlength != ylength) {
87
+ tagSimpleNumber(xlength - ylength)
88
+ } else {
89
+ let mut result = 0
90
+ let bytes = xlength * 4n
91
+ for (let mut i = 0n; i < bytes; i += 4n) {
92
+ let sub = compareHelp(
93
+ WasmI32.load(xptr + i, 8n),
94
+ WasmI32.load(yptr + i, 8n)
95
+ )
96
+ if (WasmI32.fromGrain(sub) != zero) {
97
+ result = sub
98
+ break
99
+ }
100
+ }
101
+
102
+ result
103
+ }
104
+ },
105
+ t when (
106
+ t == Tags._GRAIN_STRING_HEAP_TAG || t == Tags._GRAIN_BYTES_HEAP_TAG
107
+ ) => {
108
+ let xlength = WasmI32.load(xptr, 4n)
109
+ let ylength = WasmI32.load(yptr, 4n)
110
+
111
+ if (xlength == ylength) {
112
+ tagSimpleNumber(Memory.compare(xptr + 8n, yptr + 8n, xlength))
113
+ } else {
114
+ if (xlength < ylength) {
115
+ let sub = Memory.compare(xptr + 8n, yptr + 8n, xlength)
116
+ // The shorter one comes first
117
+ if (sub == 0n) -1 else tagSimpleNumber(sub)
118
+ } else {
119
+ let sub = Memory.compare(xptr + 8n, yptr + 8n, ylength)
120
+ // The shorter one comes first
121
+ if (sub == 0n) 1 else tagSimpleNumber(sub)
122
+ }
123
+ }
124
+ },
125
+ t when t == Tags._GRAIN_TUPLE_HEAP_TAG => {
126
+ let xsize = WasmI32.load(xptr, 4n)
127
+ let ysize = WasmI32.load(yptr, 4n)
128
+
129
+ let mut result = 0
130
+ let bytes = xsize * 4n
131
+ for (let mut i = 0n; i < bytes; i += 4n) {
132
+ let sub = compareHelp(
133
+ WasmI32.load(xptr + i, 8n),
134
+ WasmI32.load(yptr + i, 8n)
135
+ )
136
+ if (WasmI32.fromGrain(sub) != zero) {
137
+ result = sub
138
+ break
139
+ }
140
+ }
141
+
142
+ result
143
+ },
144
+ _ => {
145
+ // No other implementation
146
+ tagSimpleNumber(xptr - yptr)
147
+ },
148
+ }
149
+ }, compareHelp = (x, y) => {
150
+ let xtag = x & Tags._GRAIN_GENERIC_TAG_MASK
151
+ let ytag = y & Tags._GRAIN_GENERIC_TAG_MASK
152
+ if ((xtag & ytag) != Tags._GRAIN_GENERIC_HEAP_TAG_TYPE) {
153
+ // Short circuit for non-pointer values
154
+ if ((xtag & Tags._GRAIN_NUMBER_TAG_MASK) == Tags._GRAIN_NUMBER_TAG_TYPE) {
155
+ // Signed comparisons are necessary for numbers
156
+ if (x < y) -1 else if (x > y) 1 else 0
157
+ } else {
158
+ // Unsigned comparisons are necessary for other stack-allocated values
159
+ if (WasmI32.ltU(x, y)) -1 else if (WasmI32.gtU(x, y)) 1 else 0
160
+ }
161
+ } else if (isNumber(x)) {
162
+ // Numbers have special comparison rules, e.g. NaN == NaN
163
+ tagSimpleNumber(numberCompare(x, y, true))
164
+ } else {
165
+ // Handle all other heap allocated things
166
+ // Can short circuit if pointers are the same
167
+ if (x == y) {
168
+ 0
169
+ } else {
170
+ heapCompareHelp(WasmI32.load(x, 0n), x, y)
171
+ }
172
+ }
173
+ }
174
+
175
+ @unsafe
176
+ export let compare = (x: a, y: a) => {
177
+ compareHelp(WasmI32.fromGrain(x), WasmI32.fromGrain(y))
178
+ }
@@ -0,0 +1,6 @@
1
+ ### Compare.**compare**
2
+
3
+ ```grain
4
+ compare : (a, a) -> Number
5
+ ```
6
+
package/runtime/equal.gr CHANGED
@@ -14,13 +14,12 @@ import WasmI32, {
14
14
  } from "runtime/unsafe/wasmi32"
15
15
  import WasmI64 from "runtime/unsafe/wasmi64"
16
16
  import Tags from "runtime/unsafe/tags"
17
+ import { isNumber, numberEqual } from "runtime/numbers"
17
18
 
18
19
  primitive (!): Bool -> Bool = "@not"
19
20
  primitive (||): (Bool, Bool) -> Bool = "@or"
20
21
  primitive (&&): (Bool, Bool) -> Bool = "@and"
21
22
 
22
- import { isNumber, numberEqual } from "runtime/numbers"
23
-
24
23
  @unsafe
25
24
  let cycleMarker = 0x80000000n
26
25