@effekt-lang/effekt 0.56.0 → 0.57.0
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/README.md +1 -1
- package/bin/effekt +0 -0
- package/libraries/common/array.effekt +107 -104
- package/libraries/common/buffer.effekt +3 -3
- package/libraries/common/bytearray.effekt +41 -18
- package/libraries/common/control.effekt +27 -0
- package/libraries/common/dictionary.effekt +13 -13
- package/libraries/common/effekt.effekt +27 -24
- package/libraries/common/heap.effekt +23 -15
- package/libraries/common/io/filesystem.effekt +2 -2
- package/libraries/common/list.effekt +4 -3
- package/libraries/common/queue.effekt +3 -3
- package/libraries/common/ref.effekt +2 -2
- package/libraries/common/resizable_array.effekt +39 -73
- package/libraries/common/seq.effekt +7 -7
- package/libraries/common/stream.effekt +3 -22
- package/libraries/common/string.effekt +1 -1
- package/libraries/common/stringbuffer.effekt +1 -1
- package/libraries/llvm/rts.ll +1 -0
- package/licenses/mit license - mit-license.html +6 -6
- package/licenses/the bsd license - bsd-license.html +4 -6
- package/licenses/the mit license - mit.html +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ play with it and give us your feedback :)
|
|
|
13
13
|
|
|
14
14
|
## Examples
|
|
15
15
|
|
|
16
|
-
If you are looking for examples of the Effekt language, we invite you to look at the [casestudies](https://github.com/effekt-lang/effekt/tree/
|
|
16
|
+
If you are looking for examples of the Effekt language, we invite you to look at the [casestudies](https://github.com/effekt-lang/effekt/tree/main/examples/casestudies) and the [language tour](https://effekt-lang.org/tour).
|
|
17
17
|
|
|
18
18
|
## Installation
|
|
19
19
|
|
package/bin/effekt
CHANGED
|
Binary file
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
module array
|
|
2
2
|
|
|
3
3
|
import effekt
|
|
4
|
-
import exception
|
|
5
|
-
import list
|
|
6
4
|
import option
|
|
7
5
|
import stream
|
|
6
|
+
import control
|
|
7
|
+
import list
|
|
8
|
+
import exception
|
|
8
9
|
|
|
9
10
|
/// A mutable 0-indexed fixed-sized array.
|
|
10
11
|
extern type Array[T]
|
|
@@ -18,8 +19,6 @@ extern type Array[T]
|
|
|
18
19
|
*/
|
|
19
20
|
|
|
20
21
|
extern llvm """
|
|
21
|
-
declare noalias ptr @calloc(i64, i64)
|
|
22
|
-
|
|
23
22
|
define void @array_erase_fields(ptr %array_pointer) {
|
|
24
23
|
entry:
|
|
25
24
|
%data_pointer = getelementptr inbounds i64, ptr %array_pointer, i64 1
|
|
@@ -43,7 +42,7 @@ exit:
|
|
|
43
42
|
|
|
44
43
|
/// Allocates a new array of size `size`, keeping its values _undefined_.
|
|
45
44
|
/// Prefer using `array` constructor instead to ensure that values are defined.
|
|
46
|
-
extern def
|
|
45
|
+
extern def unsafeAllocate[T](size: Int) at global: Array[T] =
|
|
47
46
|
js "(new Array(${size}))"
|
|
48
47
|
chez "(make-vector ${size})" // creates an array filled with 0s on CS
|
|
49
48
|
llvm """
|
|
@@ -58,18 +57,18 @@ extern def allocate[T](size: Int) at global: Array[T] =
|
|
|
58
57
|
%ret_pos = insertvalue %Pos { i64 0, ptr poison }, ptr %calloc, 1
|
|
59
58
|
ret %Pos %ret_pos
|
|
60
59
|
"""
|
|
61
|
-
vm "array::
|
|
60
|
+
vm "array::unsafeAllocate(Int)"
|
|
62
61
|
|
|
63
62
|
/// Fills a given array in-place.
|
|
64
63
|
def fill[T](arr: Array[T], filler: T): Unit = {
|
|
65
64
|
arr.foreachIndex { (idx, _) =>
|
|
66
|
-
arr.
|
|
65
|
+
arr.set(idx, filler)
|
|
67
66
|
}
|
|
68
67
|
}
|
|
69
68
|
|
|
70
69
|
/// Creates a new Array of size `size` filled with the value `init`
|
|
71
70
|
def array[T](size: Int, init: T): Array[T] = {
|
|
72
|
-
val arr =
|
|
71
|
+
val arr = unsafeAllocate[T](size);
|
|
73
72
|
arr.fill(init)
|
|
74
73
|
arr
|
|
75
74
|
}
|
|
@@ -77,10 +76,10 @@ def array[T](size: Int, init: T): Array[T] = {
|
|
|
77
76
|
/// Converts a List `list` to an Array
|
|
78
77
|
def fromList[T](list: List[T]): Array[T] = {
|
|
79
78
|
val listSize = list.size();
|
|
80
|
-
val arr =
|
|
79
|
+
val arr = unsafeAllocate(listSize);
|
|
81
80
|
|
|
82
81
|
foreachIndex(list) { (i, head) =>
|
|
83
|
-
arr.
|
|
82
|
+
arr.set(i, head)
|
|
84
83
|
}
|
|
85
84
|
return arr;
|
|
86
85
|
}
|
|
@@ -99,14 +98,36 @@ extern def size[T](arr: Array[T]) at {}: Int =
|
|
|
99
98
|
"""
|
|
100
99
|
vm "array::size[T](Array[T])"
|
|
101
100
|
|
|
101
|
+
extern llvm """
|
|
102
|
+
define void @assertInbounds(i64 %index, %Pos %arr) alwaysinline {
|
|
103
|
+
%pos_data = extractvalue %Pos %arr, 1
|
|
104
|
+
%size_pointer = getelementptr inbounds i64, ptr %pos_data, i64 2
|
|
105
|
+
%size = load i64, ptr %size_pointer
|
|
106
|
+
%in_bounds = icmp ult i64 %index, %size
|
|
107
|
+
br i1 %in_bounds, label %ok, label %out
|
|
108
|
+
out:
|
|
109
|
+
call void @exit(i64 1)
|
|
110
|
+
unreachable
|
|
111
|
+
ok:
|
|
112
|
+
ret void
|
|
113
|
+
}
|
|
114
|
+
"""
|
|
115
|
+
|
|
116
|
+
extern js """
|
|
117
|
+
function array$get(arr, index) {
|
|
118
|
+
if (index < 0 || index >= arr.length) throw 'Index out of bounds';
|
|
119
|
+
return arr[index];
|
|
120
|
+
}
|
|
121
|
+
"""
|
|
122
|
+
|
|
123
|
+
|
|
102
124
|
/// Gets the element of the `arr` at given `index` in constant time.
|
|
103
|
-
///
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
extern def unsafeGet[T](arr: Array[T], index: Int) at global: T =
|
|
107
|
-
js "${arr}[${index}]"
|
|
125
|
+
/// Aborts the program when the index is out of bounds.
|
|
126
|
+
extern def get[T](arr: Array[T], index: Int) at global: T =
|
|
127
|
+
js "array$get(${arr}, ${index})"
|
|
108
128
|
chez "(vector-ref ${arr} ${index})"
|
|
109
129
|
llvm """
|
|
130
|
+
call void @assertInbounds(i64 ${index}, %Pos ${arr})
|
|
110
131
|
%pos_data = extractvalue %Pos ${arr}, 1
|
|
111
132
|
|
|
112
133
|
%data_pointer = getelementptr inbounds ptr, ptr %pos_data, i64 3
|
|
@@ -117,23 +138,23 @@ extern def unsafeGet[T](arr: Array[T], index: Int) at global: T =
|
|
|
117
138
|
tail call void @erasePositive(%Pos ${arr})
|
|
118
139
|
ret %Pos %element
|
|
119
140
|
"""
|
|
120
|
-
vm "array::
|
|
141
|
+
vm "array::get[T](Array[T], Int)"
|
|
121
142
|
|
|
122
143
|
extern js """
|
|
123
144
|
function array$set(arr, index, value) {
|
|
145
|
+
if (index < 0 || index >= arr.length) throw 'Index out of bounds';
|
|
124
146
|
arr[index] = value;
|
|
125
147
|
return $effekt.unit
|
|
126
148
|
}
|
|
127
149
|
"""
|
|
128
150
|
|
|
129
151
|
/// Sets the element of the `arr` at given `index` to `value` in constant time.
|
|
130
|
-
///
|
|
131
|
-
|
|
132
|
-
/// Prefer using `set` instead.
|
|
133
|
-
extern def unsafeSet[T](arr: Array[T], index: Int, value: T) at global: Unit =
|
|
152
|
+
/// Aborts the program when the index is out of bounds.
|
|
153
|
+
extern def set[T](arr: Array[T], index: Int, value: T) at global: Unit =
|
|
134
154
|
js "array$set(${arr}, ${index}, ${value})"
|
|
135
155
|
chez "(begin (vector-set! ${arr} ${index} ${value}) #f)"
|
|
136
156
|
llvm """
|
|
157
|
+
call void @assertInbounds(i64 ${index}, %Pos ${arr})
|
|
137
158
|
%array_data = extractvalue %Pos ${arr}, 1
|
|
138
159
|
|
|
139
160
|
%data_pointer = getelementptr inbounds i64, ptr %array_data, i64 3
|
|
@@ -144,28 +165,22 @@ extern def unsafeSet[T](arr: Array[T], index: Int, value: T) at global: Unit =
|
|
|
144
165
|
tail call void @erasePositive(%Pos ${arr})
|
|
145
166
|
ret %Pos zeroinitializer
|
|
146
167
|
"""
|
|
147
|
-
vm "array::
|
|
168
|
+
vm "array::set[T](Array[T], Int, T)"
|
|
148
169
|
|
|
149
170
|
// Derived operations:
|
|
150
171
|
|
|
151
|
-
///
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
/// Sets the element of the `arr` at given `index` to `value` in constant time,
|
|
158
|
-
/// throwing an `Exception[OutOfBounds]` unless `0 ≤ index < arr.size`.
|
|
159
|
-
def set[T](arr: Array[T], index: Int, value: T): Unit / Exception[OutOfBounds] =
|
|
160
|
-
if (index >= 0 && index < arr.size) unsafeSet(arr, index, value)
|
|
161
|
-
else do raise(OutOfBounds(), "Array index out of bounds: " ++ show(index))
|
|
172
|
+
/// Allocates a new array initialized with zero integer values.
|
|
173
|
+
extern def allocateZeros(size: Int) at global: Array[Int] =
|
|
174
|
+
llvm { unsafeAllocate(size) }
|
|
175
|
+
vm { unsafeAllocate(size) }
|
|
176
|
+
default { array(size, 0) }
|
|
162
177
|
|
|
163
178
|
/// Builds a new Array of size `size` from a computation `index` which gets an index
|
|
164
179
|
/// and returns a value that will be on that position in the resulting array
|
|
165
180
|
def build[T](size: Int) { index: Int => T }: Array[T] = {
|
|
166
|
-
val arr =
|
|
181
|
+
val arr = unsafeAllocate[T](size);
|
|
167
182
|
each(0, size) { i =>
|
|
168
|
-
|
|
183
|
+
set(arr, i, index(i))
|
|
169
184
|
};
|
|
170
185
|
arr
|
|
171
186
|
}
|
|
@@ -174,11 +189,11 @@ def build[T](size: Int) { index: Int => T }: Array[T] = {
|
|
|
174
189
|
///
|
|
175
190
|
/// O(N + M)
|
|
176
191
|
def resize[T](source: Array[T], size: Int): Array[T] = {
|
|
177
|
-
val target =
|
|
192
|
+
val target = unsafeAllocate(size)
|
|
178
193
|
val n = min(source.size, target.size)
|
|
179
194
|
def go(i: Int): Array[T] =
|
|
180
195
|
if (i < n) {
|
|
181
|
-
target.
|
|
196
|
+
target.set(i, source.get(i))
|
|
182
197
|
go(i + 1)
|
|
183
198
|
} else {
|
|
184
199
|
target
|
|
@@ -195,40 +210,28 @@ def copy[T](array: Array[T]): Array[T] =
|
|
|
195
210
|
/**
|
|
196
211
|
* Copies `length`-many elements from `from` to `to`
|
|
197
212
|
* starting at `start` (in `from`) and `offset` (in `to`)
|
|
213
|
+
* Panics if any of those are out of bounds.
|
|
198
214
|
*/
|
|
199
|
-
def copy[T](from: Array[T], start: Int, to: Array[T], offset: Int, length: Int): Unit
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
if (length > 0) {
|
|
205
|
-
to.unsafeSet(j, from.unsafeGet(i))
|
|
206
|
-
go(i + 1, j + 1, length - 1)
|
|
215
|
+
def copy[T](from: Array[T], start: Int, to: Array[T], offset: Int, length: Int): Unit = {
|
|
216
|
+
def go(i: Int, j: Int, n: Int): Unit =
|
|
217
|
+
if (n > 0) {
|
|
218
|
+
to.set(j, from.get(i))
|
|
219
|
+
go(i + 1, j + 1, n - 1)
|
|
207
220
|
}
|
|
208
|
-
|
|
209
|
-
if (startValid && offsetValid) go(start, offset, length)
|
|
210
|
-
else do raise(OutOfBounds(), "Array index out of bounds, when copying")
|
|
221
|
+
go(start, offset, length)
|
|
211
222
|
}
|
|
212
223
|
|
|
213
224
|
|
|
214
225
|
// Utility functions:
|
|
215
226
|
|
|
216
227
|
/// Swap the value at index i with that at index j.
|
|
217
|
-
///
|
|
218
|
-
///
|
|
219
|
-
/// O(1)
|
|
220
|
-
def unsafeSwap[A](arr: Array[A], i: Int, j: Int): Unit = {
|
|
221
|
-
val tmp = arr.unsafeGet(i)
|
|
222
|
-
arr.unsafeSet(i, arr.unsafeGet(j))
|
|
223
|
-
arr.unsafeSet(j, tmp)
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/// Swap the value at index i with that at index j.
|
|
228
|
+
/// Panics if the indices are out bounds.
|
|
227
229
|
///
|
|
228
230
|
/// O(1)
|
|
229
|
-
def swap[A](arr: Array[A], i: Int, j: Int): Unit
|
|
230
|
-
|
|
231
|
-
arr.
|
|
231
|
+
def swap[A](arr: Array[A], i: Int, j: Int): Unit = {
|
|
232
|
+
val tmp = arr.get(i)
|
|
233
|
+
arr.set(i, arr.get(j))
|
|
234
|
+
arr.set(j, tmp)
|
|
232
235
|
}
|
|
233
236
|
|
|
234
237
|
/// Converts the given array into a list.
|
|
@@ -238,7 +241,7 @@ def toList[T](arr: Array[T]): List[T] = {
|
|
|
238
241
|
var i = arr.size - 1;
|
|
239
242
|
var l = Nil[T]()
|
|
240
243
|
while (i >= 0) {
|
|
241
|
-
l = Cons(arr.
|
|
244
|
+
l = Cons(arr.get(i), l)
|
|
242
245
|
i = i - 1
|
|
243
246
|
}
|
|
244
247
|
l
|
|
@@ -249,15 +252,15 @@ def toList[T](arr: Array[T]): List[T] = {
|
|
|
249
252
|
/// O(N)
|
|
250
253
|
def foreach[T](arr: Array[T]){ action: T => Unit }: Unit =
|
|
251
254
|
each(0, arr.size) { i =>
|
|
252
|
-
action(arr.
|
|
255
|
+
action(arr.get(i))
|
|
253
256
|
}
|
|
254
257
|
|
|
255
258
|
/// Traverse an array, applying the given action on every element.
|
|
256
259
|
///
|
|
257
260
|
/// O(N)
|
|
258
|
-
def foreach[T](arr: Array[T]){ action: (T) {
|
|
261
|
+
def foreach[T](arr: Array[T]){ action: (T) {Label} => Unit }: Unit =
|
|
259
262
|
each(0, arr.size) { (i) {label} =>
|
|
260
|
-
action(arr.
|
|
263
|
+
action(arr.get(i)) {label}
|
|
261
264
|
}
|
|
262
265
|
|
|
263
266
|
/// Traverse an array, applying the given action on every element and its (zero-based) index.
|
|
@@ -265,15 +268,15 @@ def foreach[T](arr: Array[T]){ action: (T) {Control} => Unit }: Unit =
|
|
|
265
268
|
/// O(N)
|
|
266
269
|
def foreachIndex[T](arr: Array[T]){ action: (Int, T) => Unit }: Unit =
|
|
267
270
|
each(0, arr.size) { i =>
|
|
268
|
-
action(i, arr.
|
|
271
|
+
action(i, arr.get(i))
|
|
269
272
|
}
|
|
270
273
|
|
|
271
274
|
/// Traverse an array, applying the given action on every element and its (zero-based) index.
|
|
272
275
|
///
|
|
273
276
|
/// O(N)
|
|
274
|
-
def foreachIndex[T](arr: Array[T]){ action: (Int, T) {
|
|
277
|
+
def foreachIndex[T](arr: Array[T]){ action: (Int, T) {Label} => Unit }: Unit =
|
|
275
278
|
each(0, arr.size) { (i) {label} =>
|
|
276
|
-
action(i, arr.
|
|
279
|
+
action(i, arr.get(i)) {label}
|
|
277
280
|
}
|
|
278
281
|
|
|
279
282
|
/// Sum the elements of the array.
|
|
@@ -295,7 +298,7 @@ def equals[A](this: Array[A], other: Array[A]) { eq: (A, A) => Bool }: Bool = {
|
|
|
295
298
|
else {
|
|
296
299
|
var res = true
|
|
297
300
|
this.foreachIndex { (idx, elem) {label} =>
|
|
298
|
-
if (not(eq(elem, other.
|
|
301
|
+
if (not(eq(elem, other.get(idx)))) {
|
|
299
302
|
res = false
|
|
300
303
|
label.break()
|
|
301
304
|
}
|
|
@@ -310,7 +313,7 @@ def equals[A](this: Array[A], other: Array[A]) { eq: (A, A) => Bool }: Bool = {
|
|
|
310
313
|
/// O(N)
|
|
311
314
|
def map[A](arr: Array[A]) { f: A => A }: Unit = {
|
|
312
315
|
arr.foreachIndex { (idx, elem) =>
|
|
313
|
-
arr.
|
|
316
|
+
arr.set(idx, f(arr.get(idx)))
|
|
314
317
|
}
|
|
315
318
|
}
|
|
316
319
|
|
|
@@ -319,9 +322,9 @@ def map[A](arr: Array[A]) { f: A => A }: Unit = {
|
|
|
319
322
|
///
|
|
320
323
|
/// O(N)
|
|
321
324
|
def mapped[A, B](arr: Array[A]) { f: A => B }: Array[B] = {
|
|
322
|
-
val res =
|
|
325
|
+
val res = unsafeAllocate(arr.size)
|
|
323
326
|
arr.foreachIndex { (idx, elem) =>
|
|
324
|
-
res.
|
|
327
|
+
res.set(idx, f(arr.get(idx)))
|
|
325
328
|
}
|
|
326
329
|
res
|
|
327
330
|
}
|
|
@@ -335,11 +338,11 @@ def reverse[A](arr: Array[A]): Unit = {
|
|
|
335
338
|
|
|
336
339
|
// Swap elements from start and end, moving towards the middle
|
|
337
340
|
each(0, mid) { i =>
|
|
338
|
-
val temp = arr.
|
|
341
|
+
val temp = arr.get(i)
|
|
339
342
|
val j = size - 1 - i
|
|
340
|
-
val other = arr.
|
|
341
|
-
arr.
|
|
342
|
-
arr.
|
|
343
|
+
val other = arr.get(j)
|
|
344
|
+
arr.set(i, other)
|
|
345
|
+
arr.set(j, temp)
|
|
343
346
|
}
|
|
344
347
|
}
|
|
345
348
|
/// Creates a new array with elements in reverse order.
|
|
@@ -347,12 +350,12 @@ def reverse[A](arr: Array[A]): Unit = {
|
|
|
347
350
|
/// O(N)
|
|
348
351
|
def reversed[A](arr: Array[A]): Array[A] = {
|
|
349
352
|
val size = arr.size()
|
|
350
|
-
val result =
|
|
353
|
+
val result = unsafeAllocate[A](size)
|
|
351
354
|
|
|
352
355
|
// Copy elements in reverse order to new array
|
|
353
356
|
each(0, size) { i =>
|
|
354
|
-
val value = arr.
|
|
355
|
-
result.
|
|
357
|
+
val value = arr.get(i)
|
|
358
|
+
result.set(size - 1 - i, value)
|
|
356
359
|
}
|
|
357
360
|
result
|
|
358
361
|
}
|
|
@@ -385,7 +388,7 @@ def filtered[A](arr: Array[A]) { shouldKeep: A => Bool }: Array[A] = {
|
|
|
385
388
|
var idx = 0
|
|
386
389
|
arr.foreach { x =>
|
|
387
390
|
if (shouldKeep(x)) {
|
|
388
|
-
res.
|
|
391
|
+
res.set(idx, x)
|
|
389
392
|
idx = idx + 1
|
|
390
393
|
}
|
|
391
394
|
}
|
|
@@ -430,9 +433,9 @@ def count[A](arr: Array[A]) { predicate: A => Bool }: Int = {
|
|
|
430
433
|
/// O(N)
|
|
431
434
|
def take[A](arr: Array[A], n: Int): Array[A] = {
|
|
432
435
|
val len = min(max(0, n), arr.size)
|
|
433
|
-
val result =
|
|
436
|
+
val result = unsafeAllocate[A](len)
|
|
434
437
|
each(0, len) { i =>
|
|
435
|
-
result.
|
|
438
|
+
result.set(i, arr.get(i))
|
|
436
439
|
}
|
|
437
440
|
result
|
|
438
441
|
}
|
|
@@ -444,9 +447,9 @@ def take[A](arr: Array[A], n: Int): Array[A] = {
|
|
|
444
447
|
def drop[A](arr: Array[A], n: Int): Array[A] = {
|
|
445
448
|
val start = min(max(0, n), arr.size)
|
|
446
449
|
val len = arr.size - start
|
|
447
|
-
val result =
|
|
450
|
+
val result = unsafeAllocate[A](len)
|
|
448
451
|
each(0, len) { i =>
|
|
449
|
-
result.
|
|
452
|
+
result.set(i, arr.get(i + start))
|
|
450
453
|
}
|
|
451
454
|
result
|
|
452
455
|
}
|
|
@@ -459,9 +462,9 @@ def sliced[A](arr: Array[A], start: Int, end: Int): Array[A] = {
|
|
|
459
462
|
val validStart = min(max(0, start), arr.size)
|
|
460
463
|
val validEnd = min(max(validStart, end), arr.size)
|
|
461
464
|
val len = validEnd - validStart
|
|
462
|
-
val result =
|
|
465
|
+
val result = unsafeAllocate[A](len)
|
|
463
466
|
each(0, len) { i =>
|
|
464
|
-
result.
|
|
467
|
+
result.set(i, arr.get(i + validStart))
|
|
465
468
|
}
|
|
466
469
|
result
|
|
467
470
|
}
|
|
@@ -472,9 +475,9 @@ def sliced[A](arr: Array[A], start: Int, end: Int): Array[A] = {
|
|
|
472
475
|
/// O(min(N, M))
|
|
473
476
|
def zipped[A, B](this: Array[A], other: Array[B]): Array[(A, B)] = {
|
|
474
477
|
val len = min(this.size, other.size)
|
|
475
|
-
val result =
|
|
478
|
+
val result = unsafeAllocate[(A, B)](len)
|
|
476
479
|
each(0, len) { i =>
|
|
477
|
-
result.
|
|
480
|
+
result.set(i, (this.get(i), other.get(i)))
|
|
478
481
|
}
|
|
479
482
|
result
|
|
480
483
|
}
|
|
@@ -485,9 +488,9 @@ def zipped[A, B](this: Array[A], other: Array[B]): Array[(A, B)] = {
|
|
|
485
488
|
/// O(min(N, M))
|
|
486
489
|
def zippedWith[A, B, C](this: Array[A], other: Array[B]) { f: (A, B) => C }: Array[C] = {
|
|
487
490
|
val len = min(this.size, other.size)
|
|
488
|
-
val result =
|
|
491
|
+
val result = unsafeAllocate[C](len)
|
|
489
492
|
each(0, len) { i =>
|
|
490
|
-
result.
|
|
493
|
+
result.set(i, f(this.get(i), other.get(i)))
|
|
491
494
|
}
|
|
492
495
|
result
|
|
493
496
|
}
|
|
@@ -497,12 +500,12 @@ def zippedWith[A, B, C](this: Array[A], other: Array[B]) { f: (A, B) => C }: Arr
|
|
|
497
500
|
///
|
|
498
501
|
/// O(N)
|
|
499
502
|
def unzipped[A, B](arr: Array[(A, B)]): (Array[A], Array[B]) = {
|
|
500
|
-
val arr1 =
|
|
501
|
-
val arr2 =
|
|
503
|
+
val arr1 = unsafeAllocate(arr.size)
|
|
504
|
+
val arr2 = unsafeAllocate(arr.size)
|
|
502
505
|
arr.foreachIndex { (idx, tpl) =>
|
|
503
506
|
val (x, y) = tpl
|
|
504
|
-
arr1.
|
|
505
|
-
arr2.
|
|
507
|
+
arr1.set(idx, x)
|
|
508
|
+
arr2.set(idx, y)
|
|
506
509
|
}
|
|
507
510
|
(arr1, arr2)
|
|
508
511
|
}
|
|
@@ -519,10 +522,10 @@ def partioned[A](arr: Array[A]) { pred: A => Bool }: (Array[A], Array[A]) = {
|
|
|
519
522
|
var fidx = 0
|
|
520
523
|
arr.foreach { x =>
|
|
521
524
|
if (pred(x)) {
|
|
522
|
-
tcases.
|
|
525
|
+
tcases.set(tidx, x)
|
|
523
526
|
tidx = tidx + 1
|
|
524
527
|
} else {
|
|
525
|
-
fcases.
|
|
528
|
+
fcases.set(fidx, x)
|
|
526
529
|
fidx = fidx + 1
|
|
527
530
|
}
|
|
528
531
|
}
|
|
@@ -564,7 +567,7 @@ def binarySearch[A](arr: Array[A], toFind: A) { ord: (A, A) => Ordering }: Optio
|
|
|
564
567
|
if (lowerIdx > upperIdx) None()
|
|
565
568
|
else {
|
|
566
569
|
val mid = lowerIdx + (upperIdx - lowerIdx) / 2
|
|
567
|
-
val current = arr.
|
|
570
|
+
val current = arr.get(mid)
|
|
568
571
|
ord(current, toFind) match {
|
|
569
572
|
case Less() => binarySearch(mid + 1, upperIdx)
|
|
570
573
|
case Greater() => binarySearch(lowerIdx, mid - 1)
|
|
@@ -581,18 +584,18 @@ def binarySearch[A](arr: Array[A], toFind: A) { ord: (A, A) => Ordering }: Optio
|
|
|
581
584
|
/// O(N log N) average case
|
|
582
585
|
def sort[A](arr: Array[A]) { ord: (A, A) => Ordering }: Unit = {
|
|
583
586
|
def partition(low: Int, high: Int): Int = {
|
|
584
|
-
val pivot = arr.
|
|
587
|
+
val pivot = arr.get(high)
|
|
585
588
|
var i = low - 1
|
|
586
589
|
|
|
587
590
|
each(low, high) { j =>
|
|
588
|
-
ord(arr.
|
|
591
|
+
ord(arr.get(j), pivot) match {
|
|
589
592
|
case Less() =>
|
|
590
593
|
i = i + 1
|
|
591
|
-
|
|
594
|
+
swap(arr, i, j)
|
|
592
595
|
case _ => ()
|
|
593
596
|
}
|
|
594
597
|
}
|
|
595
|
-
|
|
598
|
+
swap(arr, i + 1, high)
|
|
596
599
|
i + 1
|
|
597
600
|
}
|
|
598
601
|
|
|
@@ -653,7 +656,7 @@ def each[T](array: Array[T]): Unit / emit[T] = {
|
|
|
653
656
|
val n = array.size
|
|
654
657
|
def go(i: Int): Unit = {
|
|
655
658
|
if (i < n) {
|
|
656
|
-
do emit(array.
|
|
659
|
+
do emit(array.get(i))
|
|
657
660
|
go(i + 1)
|
|
658
661
|
}
|
|
659
662
|
}
|
|
@@ -669,7 +672,7 @@ def feed[T, R](array: Array[T]) { reader: () => R / read[T] }: R = {
|
|
|
669
672
|
if (i < array.size) {
|
|
670
673
|
val c = i
|
|
671
674
|
i = c + 1
|
|
672
|
-
array.
|
|
675
|
+
array.get(c)
|
|
673
676
|
} else {
|
|
674
677
|
do stop()
|
|
675
678
|
}
|
|
@@ -683,12 +686,12 @@ def collect[A] { stream: () => Unit / emit[A] }: Array[A] =
|
|
|
683
686
|
namespace returning {
|
|
684
687
|
def collect[A, R] { stream: () => R / emit[A] }: (R, Array[A]) = {
|
|
685
688
|
var i = 0
|
|
686
|
-
var a =
|
|
689
|
+
var a = unsafeAllocate(1)
|
|
687
690
|
try {
|
|
688
691
|
(stream(), a.resize(i))
|
|
689
692
|
} with emit[A] { (v) =>
|
|
690
693
|
if (i >= a.size) { a = a.resize(2 * a.size) }
|
|
691
|
-
a.
|
|
694
|
+
a.set(i, v)
|
|
692
695
|
i = i + 1
|
|
693
696
|
resume(())
|
|
694
697
|
}
|
|
@@ -33,7 +33,7 @@ def emptyBuffer[T](capacity: Int): Buffer[T] at global = {
|
|
|
33
33
|
}
|
|
34
34
|
def arrayBuffer[T](initialCapacity: Int): Buffer[T] at global = {
|
|
35
35
|
// TODO allocate buffer (and array) into a region r.
|
|
36
|
-
val contents = array::
|
|
36
|
+
val contents = array::unsafeAllocate[T](initialCapacity)
|
|
37
37
|
val head = ref(0)
|
|
38
38
|
val tail = ref(0)
|
|
39
39
|
|
|
@@ -50,7 +50,7 @@ def arrayBuffer[T](initialCapacity: Int): Buffer[T] at global = {
|
|
|
50
50
|
def read() = {
|
|
51
51
|
if (size() <= 0) None()
|
|
52
52
|
else {
|
|
53
|
-
val result: T = contents.
|
|
53
|
+
val result: T = contents.get(head.get)
|
|
54
54
|
head.set(mod(head.get + 1, initialCapacity))
|
|
55
55
|
Some(result)
|
|
56
56
|
}
|
|
@@ -58,7 +58,7 @@ def arrayBuffer[T](initialCapacity: Int): Buffer[T] at global = {
|
|
|
58
58
|
def write(el: T) = {
|
|
59
59
|
if (capacity() <= 0) <> // raise(BufferOverflow())
|
|
60
60
|
|
|
61
|
-
contents.
|
|
61
|
+
contents.set(tail.get, el)
|
|
62
62
|
tail.set(mod(tail.get + 1, initialCapacity))
|
|
63
63
|
}
|
|
64
64
|
}
|