@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.
- package/CHANGELOG.md +41 -0
- package/array.gr +56 -1
- package/array.md +83 -0
- package/bigint.md +61 -61
- package/buffer.gr +33 -31
- package/buffer.md +1 -1
- package/bytes.md +1 -1
- package/exception.gr +28 -2
- package/exception.md +37 -0
- package/float32.gr +50 -30
- package/float32.md +69 -30
- package/float64.gr +55 -34
- package/float64.md +69 -30
- package/immutablepriorityqueue.gr +332 -0
- package/immutablepriorityqueue.md +248 -0
- package/int32.md +4 -4
- package/int64.md +4 -4
- package/list.gr +73 -0
- package/list.md +110 -0
- package/map.gr +1 -2
- package/map.md +1 -1
- package/marshal.gr +1058 -0
- package/marshal.md +76 -0
- package/number.gr +122 -0
- package/number.md +172 -0
- package/package.json +1 -1
- package/pervasives.gr +16 -5
- package/pervasives.md +28 -0
- package/priorityqueue.gr +241 -0
- package/priorityqueue.md +279 -0
- package/random.md +7 -7
- package/regex.gr +5 -5
- package/runtime/compare.gr +178 -0
- package/runtime/compare.md +6 -0
- package/runtime/equal.gr +1 -2
- package/runtime/numbers.gr +331 -86
- package/runtime/numbers.md +24 -0
- package/set.gr +1 -2
- package/set.md +1 -1
- package/string.gr +97 -15
- package/string.md +65 -1
- package/sys/file.gr +3 -3
- package/sys/file.md +3 -3
- package/sys/process.gr +3 -3
- package/sys/process.md +3 -3
- package/sys/random.gr +2 -2
- package/sys/random.md +4 -4
- package/sys/time.gr +2 -2
- package/sys/time.md +2 -2
|
@@ -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
|
+
}
|
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
|
|