@effekt-lang/effekt 0.55.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/chez/common/effekt_primitives.ss +10 -4
- 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 +133 -0
- 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/json.effekt +19 -19
- package/libraries/common/list.effekt +4 -3
- package/libraries/common/option.effekt +1 -1
- package/libraries/common/queue.effekt +3 -3
- package/libraries/common/random.effekt +1 -1
- 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/common/union_find.effekt +7 -7
- package/libraries/js/effekt_builtins.js +1 -1
- package/libraries/llvm/forward-declare-c.ll +2 -2
- package/libraries/llvm/io.c +2 -2
- package/libraries/llvm/panic.c +2 -0
- package/libraries/llvm/rts.ll +17 -38
- package/licenses/eclipse public license, version 2.0 - epl-2.0.html +3 -3
- package/licenses/mit license - mit-license.html +76 -45
- package/licenses/the bsd license - bsd-license.html +75 -46
- package/licenses/the mit license - mit.html +76 -45
- package/package.json +1 -1
|
@@ -30,12 +30,12 @@ extern type Ref[T]
|
|
|
30
30
|
|
|
31
31
|
/// Allocates a new reference, keeping its value _undefined_.
|
|
32
32
|
/// Prefer using `ref` constructor instead to ensure that the value is defined.
|
|
33
|
-
extern def
|
|
33
|
+
extern def unsafeAllocate[T]() at global: Ref[T] =
|
|
34
34
|
js "{ value: undefined }"
|
|
35
35
|
chez "(box #f)"
|
|
36
36
|
llvm """
|
|
37
37
|
; sizeof Header + sizeof Pos = 32
|
|
38
|
-
%ref = tail call noalias ptr @
|
|
38
|
+
%ref = tail call noalias ptr @calloc(i64 noundef 32, i64 1)
|
|
39
39
|
%refEraser = getelementptr ptr, ptr %ref, i64 1
|
|
40
40
|
%fieldTag = getelementptr ptr, ptr %ref, i64 2
|
|
41
41
|
%fieldData_pointer = getelementptr ptr, ptr %ref, i64 3
|
|
@@ -21,42 +21,26 @@ def size[T](arr: ResizableArray[T]) = arr.rawSizePtr.get
|
|
|
21
21
|
|
|
22
22
|
/// Allocate a new, empty dynamic array with given initial capacity
|
|
23
23
|
def resizableArray[T](capacity: Int): ResizableArray[T] = {
|
|
24
|
-
ResizableArray(ref(0), ref(
|
|
24
|
+
ResizableArray(ref(0), ref(unsafeAllocate(capacity)))
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
///
|
|
27
|
+
/// Aallocate a new, empty dynamic array
|
|
28
28
|
def resizableArray[T](): ResizableArray[T] = resizableArray(8)
|
|
29
29
|
|
|
30
|
+
|
|
30
31
|
/// Throw an OutOfBounds exception if index is not a valid index into arr
|
|
31
|
-
def boundsCheck[T](arr: ResizableArray[T], index: Int): Unit / Exception[OutOfBounds] =
|
|
32
|
+
def boundsCheck[T](arr: ResizableArray[T], index: Int): Unit / Exception[OutOfBounds] =
|
|
32
33
|
if (index < 0 || index >= arr.size) {
|
|
33
34
|
do raise(OutOfBounds(), "Array index out of bounds: " ++ show(index))
|
|
34
35
|
}
|
|
35
|
-
}
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
///
|
|
39
|
-
/// precondition: index is a valid index into the array
|
|
40
|
-
///
|
|
41
|
-
/// O(1)
|
|
42
|
-
def unsafeGet[T](arr: ResizableArray[T], index: Int): T = {
|
|
43
|
-
arr.rawContentPtr.get.unsafeGet(index)
|
|
44
|
-
}
|
|
37
|
+
|
|
45
38
|
/// get the element at position index in the array
|
|
46
39
|
///
|
|
47
40
|
/// O(1)
|
|
48
41
|
def get[T](arr: ResizableArray[T], index: Int): T / Exception[OutOfBounds] = {
|
|
49
42
|
arr.boundsCheck(index);
|
|
50
|
-
arr.
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/// set the element at position index in the array
|
|
54
|
-
///
|
|
55
|
-
/// precondition: index is a valid index into the array
|
|
56
|
-
///
|
|
57
|
-
/// O(1)
|
|
58
|
-
def unsafeSet[T](arr: ResizableArray[T], index: Int, value: T): Unit = {
|
|
59
|
-
arr.rawContentPtr.get.unsafeSet(index, value)
|
|
43
|
+
arr.rawContentPtr.get.get(index)
|
|
60
44
|
}
|
|
61
45
|
|
|
62
46
|
/// set the element at position index in the array
|
|
@@ -64,19 +48,7 @@ def unsafeSet[T](arr: ResizableArray[T], index: Int, value: T): Unit = {
|
|
|
64
48
|
/// O(1)
|
|
65
49
|
def set[T](arr: ResizableArray[T], index: Int, value: T): Unit / Exception[OutOfBounds] = {
|
|
66
50
|
arr.boundsCheck(index);
|
|
67
|
-
arr.
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/// swap the elements at the given positions in the array
|
|
71
|
-
///
|
|
72
|
-
/// precondition: both are valid indices into the array
|
|
73
|
-
///
|
|
74
|
-
/// O(1)
|
|
75
|
-
def unsafeSwap[T](arr: ResizableArray[T], index1: Int, index2: Int): Unit = {
|
|
76
|
-
val raw = arr.rawContentPtr.get
|
|
77
|
-
val tmp = raw.unsafeGet(index1)
|
|
78
|
-
raw.unsafeSet(index1, raw.unsafeGet(index2))
|
|
79
|
-
raw.unsafeSet(index2, tmp)
|
|
51
|
+
arr.rawContentPtr.get.set(index, value)
|
|
80
52
|
}
|
|
81
53
|
|
|
82
54
|
/// swap the elements at the given positions in the array
|
|
@@ -84,22 +56,10 @@ def unsafeSwap[T](arr: ResizableArray[T], index1: Int, index2: Int): Unit = {
|
|
|
84
56
|
/// O(1)
|
|
85
57
|
def swap[T](arr: ResizableArray[T], index1: Int, index2: Int): Unit / Exception[OutOfBounds] = {
|
|
86
58
|
arr.boundsCheck(max(index1, index2))
|
|
87
|
-
arr.
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
///
|
|
92
|
-
/// precondition: given capacity is at least the size of the array
|
|
93
|
-
///
|
|
94
|
-
/// O(n)
|
|
95
|
-
def unsafeSetCapacity[T](arr: ResizableArray[T], capacity: Int): Unit = {
|
|
96
|
-
with on[OutOfBounds].panic
|
|
97
|
-
val oldRaw = arr.rawContentPtr.get
|
|
98
|
-
if (oldRaw.size != capacity) {
|
|
99
|
-
val newRaw = array::allocate(capacity)
|
|
100
|
-
oldRaw.copy(0, newRaw, 0, arr.size)
|
|
101
|
-
arr.rawContentPtr.set(newRaw)
|
|
102
|
-
}
|
|
59
|
+
val raw = arr.rawContentPtr.get
|
|
60
|
+
val tmp = raw.get(index1)
|
|
61
|
+
raw.set(index1, raw.get(index2))
|
|
62
|
+
raw.set(index2, tmp)
|
|
103
63
|
}
|
|
104
64
|
|
|
105
65
|
/// Change the resizable array to have exactly the given capacity.
|
|
@@ -110,16 +70,21 @@ def setCapacity[T](arr: ResizableArray[T], capacity: Int): Unit / Exception[OutO
|
|
|
110
70
|
if (arr.size > capacity) {
|
|
111
71
|
do raise(OutOfBounds(), "Cannot change capacity of ResizableArray to " ++ capacity.show ++ " below size " ++ arr.size.show)
|
|
112
72
|
}
|
|
113
|
-
arr.
|
|
73
|
+
val oldRaw = arr.rawContentPtr.get
|
|
74
|
+
if (oldRaw.size != capacity) {
|
|
75
|
+
val newRaw = array::unsafeAllocate(capacity)
|
|
76
|
+
oldRaw.copy(0, newRaw, 0, arr.size)
|
|
77
|
+
arr.rawContentPtr.set(newRaw)
|
|
78
|
+
}
|
|
114
79
|
}
|
|
115
80
|
|
|
116
81
|
/// If the shrinkThreshold is reached, shrink by growFactor, otherwise do nothing
|
|
117
82
|
///
|
|
118
83
|
/// O(n)
|
|
119
|
-
def maybeShrink[T](arr: ResizableArray[T]): Unit = {
|
|
84
|
+
def maybeShrink[T](arr: ResizableArray[T]): Unit / Exception[OutOfBounds] = {
|
|
120
85
|
if(arr.size.toDouble < arr.rawContentPtr.get.size.toDouble * shrinkThreshold) {
|
|
121
86
|
val newCap = max(arr.size, (arr.rawContentPtr.get.size.toDouble / growFactor).ceil)
|
|
122
|
-
arr.
|
|
87
|
+
arr.setCapacity(newCap)
|
|
123
88
|
}
|
|
124
89
|
}
|
|
125
90
|
|
|
@@ -144,11 +109,11 @@ def setResizing[T](arr: ResizableArray[T], index: Int, value: T): Unit / Excepti
|
|
|
144
109
|
do raise(OutOfBounds(), "Negative index " ++ index.show)
|
|
145
110
|
}
|
|
146
111
|
if (index < arr.size) {
|
|
147
|
-
arr.rawContentPtr.get.
|
|
112
|
+
arr.rawContentPtr.get.set(index, value)
|
|
148
113
|
}
|
|
149
114
|
ensureCapacity(arr, index + 1)
|
|
150
|
-
arr.rawContentPtr.get.
|
|
151
|
-
arr.rawSizePtr.set(index + 1)
|
|
115
|
+
arr.rawContentPtr.get.set(index, value)
|
|
116
|
+
if (index >= arr.size) arr.rawSizePtr.set(index + 1)
|
|
152
117
|
}
|
|
153
118
|
|
|
154
119
|
/// Add a new element at the end of the resizable array.
|
|
@@ -166,9 +131,10 @@ def add[T](arr: ResizableArray[T], value: T): Int = {
|
|
|
166
131
|
///
|
|
167
132
|
/// O(1) amortized, O(n) worst case
|
|
168
133
|
def popRight[T](arr: ResizableArray[T]): T / Exception[OutOfBounds] = {
|
|
169
|
-
arr.
|
|
170
|
-
arr.
|
|
171
|
-
val r = arr.
|
|
134
|
+
val last = arr.size - 1
|
|
135
|
+
arr.boundsCheck(last)
|
|
136
|
+
val r = arr.rawContentPtr.get.get(last)
|
|
137
|
+
arr.rawSizePtr.set(last)
|
|
172
138
|
arr.maybeShrink()
|
|
173
139
|
r
|
|
174
140
|
}
|
|
@@ -176,51 +142,51 @@ def popRight[T](arr: ResizableArray[T]): T / Exception[OutOfBounds] = {
|
|
|
176
142
|
|
|
177
143
|
def foreachIndex[T](arr: ResizableArray[T]){ body: (Int, T) => Unit }: Unit = {
|
|
178
144
|
each(0, arr.size) { i =>
|
|
179
|
-
body(i, arr.rawContentPtr.get.
|
|
145
|
+
body(i, arr.rawContentPtr.get.get(i))
|
|
180
146
|
}
|
|
181
147
|
}
|
|
182
|
-
def foreachIndex[T](arr: ResizableArray[T]){ body: (Int, T) {
|
|
148
|
+
def foreachIndex[T](arr: ResizableArray[T]){ body: (Int, T) {Label} => Unit }: Unit = {
|
|
183
149
|
each(0, arr.size) { (i){label} =>
|
|
184
|
-
body(i, arr.rawContentPtr.get.
|
|
150
|
+
body(i, arr.rawContentPtr.get.get(i)){label}
|
|
185
151
|
}
|
|
186
152
|
}
|
|
187
153
|
def foreach[T](arr: ResizableArray[T]){ body: T => Unit }: Unit = {
|
|
188
154
|
each(0, arr.size) { i =>
|
|
189
|
-
body(arr.rawContentPtr.get.
|
|
155
|
+
body(arr.rawContentPtr.get.get(i))
|
|
190
156
|
}
|
|
191
157
|
}
|
|
192
|
-
def foreach[T](arr: ResizableArray[T]){ body: (T) {
|
|
158
|
+
def foreach[T](arr: ResizableArray[T]){ body: (T) {Label} => Unit }: Unit = {
|
|
193
159
|
each(0, arr.size) { (i){label} =>
|
|
194
|
-
body(arr.rawContentPtr.get.
|
|
160
|
+
body(arr.rawContentPtr.get.get(i)){label}
|
|
195
161
|
}
|
|
196
162
|
}
|
|
197
|
-
def foreachIndexReversed[T](arr: ResizableArray[T]){ body: (Int, T){
|
|
163
|
+
def foreachIndexReversed[T](arr: ResizableArray[T]){ body: (Int, T){Label} => Unit }: Unit = {
|
|
198
164
|
var i = arr.size - 1
|
|
199
165
|
loop { {l} =>
|
|
200
166
|
if (i < 0) { l.break() }
|
|
201
|
-
body(i, arr.rawContentPtr.get.
|
|
167
|
+
body(i, arr.rawContentPtr.get.get(i)){l}
|
|
202
168
|
i = i - 1
|
|
203
169
|
}
|
|
204
170
|
}
|
|
205
171
|
def foreachIndexReversed[T](arr: ResizableArray[T]){ body: (Int, T) => Unit }: Unit = {
|
|
206
172
|
var i = arr.size - 1
|
|
207
173
|
while(i >= 0) {
|
|
208
|
-
body(i, arr.rawContentPtr.get.
|
|
174
|
+
body(i, arr.rawContentPtr.get.get(i))
|
|
209
175
|
i = i - 1
|
|
210
176
|
}
|
|
211
177
|
}
|
|
212
|
-
def foreachReversed[T](arr: ResizableArray[T]){ body: (T){
|
|
178
|
+
def foreachReversed[T](arr: ResizableArray[T]){ body: (T){Label} => Unit }: Unit = {
|
|
213
179
|
var i = arr.size - 1
|
|
214
180
|
loop { {l} =>
|
|
215
181
|
if (i < 0) { l.break() }
|
|
216
|
-
body(arr.rawContentPtr.get.
|
|
182
|
+
body(arr.rawContentPtr.get.get(i)){l}
|
|
217
183
|
i = i - 1
|
|
218
184
|
}
|
|
219
185
|
}
|
|
220
186
|
def foreachReversed[T](arr: ResizableArray[T]){ body: T => Unit }: Unit = {
|
|
221
187
|
var i = arr.size - 1
|
|
222
188
|
while (i >= 0) {
|
|
223
|
-
body(arr.rawContentPtr.get.
|
|
189
|
+
body(arr.rawContentPtr.get.get(i))
|
|
224
190
|
i = i - 1
|
|
225
191
|
}
|
|
226
192
|
}
|
|
@@ -228,7 +194,7 @@ def foreachReversed[T](arr: ResizableArray[T]){ body: T => Unit }: Unit = {
|
|
|
228
194
|
def toList[T](arr: ResizableArray[T]): List[T] = {
|
|
229
195
|
def go(i: Int, acc: List[T]): List[T] = {
|
|
230
196
|
if (i < 0) { acc } else {
|
|
231
|
-
go(i - 1, Cons(arr.
|
|
197
|
+
go(i - 1, Cons(arr.rawContentPtr.get.get(i), acc))
|
|
232
198
|
}
|
|
233
199
|
}
|
|
234
200
|
go(arr.size - 1, Nil())
|
|
@@ -579,14 +579,14 @@ def each[A](seq: Seq[A]) { consume: (A) => Unit }: Unit = {
|
|
|
579
579
|
}
|
|
580
580
|
}
|
|
581
581
|
|
|
582
|
-
def each[A](seq: Seq[A]) { f: (A) {
|
|
582
|
+
def each[A](seq: Seq[A]) { f: (A) {Label} => Unit }: Unit = try {
|
|
583
583
|
seq.each { (el) =>
|
|
584
|
-
try { f(el) {inner} } with inner:
|
|
584
|
+
try { f(el) {inner} } with inner: Label {
|
|
585
585
|
def break() = outer.break()
|
|
586
586
|
def continue() = ()
|
|
587
587
|
}
|
|
588
588
|
}
|
|
589
|
-
} with outer:
|
|
589
|
+
} with outer: Label {
|
|
590
590
|
def break() = ()
|
|
591
591
|
def continue() = ()
|
|
592
592
|
}
|
|
@@ -627,14 +627,14 @@ def eachReverse[A](seq: Seq[A]) { consume: A => Unit }: Unit = {
|
|
|
627
627
|
}
|
|
628
628
|
}
|
|
629
629
|
|
|
630
|
-
def eachReverse[A](seq: Seq[A]) { f: (A) {
|
|
630
|
+
def eachReverse[A](seq: Seq[A]) { f: (A) {Label} => Unit }: Unit = try {
|
|
631
631
|
seq.eachReverse { (el) =>
|
|
632
|
-
try { f(el) {inner} } with inner:
|
|
632
|
+
try { f(el) {inner} } with inner: Label {
|
|
633
633
|
def break() = outer.break()
|
|
634
634
|
def continue() = ()
|
|
635
635
|
}
|
|
636
636
|
}
|
|
637
|
-
} with outer:
|
|
637
|
+
} with outer: Label {
|
|
638
638
|
def break() = ()
|
|
639
639
|
def continue() = ()
|
|
640
640
|
}
|
|
@@ -854,7 +854,7 @@ def map[A, B](seq: Seq[A]) { f: A => B }: Seq[B] = {
|
|
|
854
854
|
result
|
|
855
855
|
}
|
|
856
856
|
|
|
857
|
-
def map[A, B](seq: Seq[A]) { f: (A) {
|
|
857
|
+
def map[A, B](seq: Seq[A]) { f: (A) {Label} => B }: Seq[B] = {
|
|
858
858
|
var result: Seq[B] = Empty()
|
|
859
859
|
seq.each { (a) {label} => result = result.consRight(f(a) {label}) }
|
|
860
860
|
result
|
|
@@ -15,8 +15,6 @@ effect emit[A](value: A): Unit
|
|
|
15
15
|
/// The producer can decide to `stop` emitting values.
|
|
16
16
|
effect read[A](): A / stop
|
|
17
17
|
|
|
18
|
-
/// Signal from a producer to a consumer that there are no further values.
|
|
19
|
-
effect stop(): Nothing
|
|
20
18
|
|
|
21
19
|
/// Like `for[A, R]`, but ignores the result of the stream, and consequently
|
|
22
20
|
/// works for any type. Use this to annotate the type of stream elements
|
|
@@ -50,25 +48,8 @@ def fix[T] { one: T => Unit / emit[T] } { stream: => Unit / emit[T] }: Unit =
|
|
|
50
48
|
}
|
|
51
49
|
|
|
52
50
|
|
|
53
|
-
def boundary { program: () => Unit / stop }: Unit = {
|
|
54
|
-
returning::boundary[Unit]{program}
|
|
55
|
-
()
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/// Run `program` forever until `stop` is thrown.
|
|
59
|
-
def exhaustively { program: () => Unit / stop }: Unit =
|
|
60
|
-
try {
|
|
61
|
-
def go(): Unit = {
|
|
62
|
-
program()
|
|
63
|
-
go()
|
|
64
|
-
}
|
|
65
|
-
go()
|
|
66
|
-
} with stop {
|
|
67
|
-
()
|
|
68
|
-
}
|
|
69
|
-
|
|
70
51
|
def many[A] { action: () => A / stop }: Unit / emit[A] =
|
|
71
|
-
|
|
52
|
+
loop { do emit(action()) }
|
|
72
53
|
|
|
73
54
|
def some[A] { action: () => A / stop }: Unit / { emit[A], stop } = {
|
|
74
55
|
do emit(action())
|
|
@@ -230,7 +211,7 @@ def zip[A, B] { stream1: () => Unit / emit[A] } { stream2: () => Unit / emit[B]
|
|
|
230
211
|
with source[A] { stream1 }
|
|
231
212
|
with source[B] { stream2 }
|
|
232
213
|
|
|
233
|
-
|
|
214
|
+
loop {
|
|
234
215
|
action(do read(), do read())
|
|
235
216
|
}
|
|
236
217
|
}
|
|
@@ -241,7 +222,7 @@ def zipLongest[A, B] { stream1: () => Unit / emit[A] } { stream2: () => Unit / e
|
|
|
241
222
|
with source[A] { stream1 }
|
|
242
223
|
with source[B] { stream2 }
|
|
243
224
|
|
|
244
|
-
|
|
225
|
+
loop {
|
|
245
226
|
try {
|
|
246
227
|
val a = do read[A]()
|
|
247
228
|
try {
|
|
@@ -15,9 +15,9 @@ namespace internal {
|
|
|
15
15
|
def parent(u: UnionFind, s: Int): Int / Exception[MissingValue] = {
|
|
16
16
|
with on[OutOfBounds].default { do raise(MissingValue(), "No node " ++ s.show) }
|
|
17
17
|
val c = u.rawElements.get(s)
|
|
18
|
-
if (c < 0) {
|
|
19
|
-
do raise(MissingValue(), "Root node " ++ s.show ++ " has no parent.")
|
|
20
|
-
} else {
|
|
18
|
+
if (c < 0) {
|
|
19
|
+
do raise(MissingValue(), "Root node " ++ s.show ++ " has no parent.")
|
|
20
|
+
} else {
|
|
21
21
|
c
|
|
22
22
|
}
|
|
23
23
|
}
|
|
@@ -31,11 +31,11 @@ namespace internal {
|
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
def setParent(u: UnionFind, child: Int, parent: Int) = {
|
|
34
|
-
with
|
|
34
|
+
with default[OutOfBounds, Unit] { do raise(MissingValue(), "No node " ++ child.show) }
|
|
35
35
|
u.rawElements.set(child, parent)
|
|
36
36
|
}
|
|
37
37
|
def setRank(u: UnionFind, root: Int, rank: Int) = {
|
|
38
|
-
with
|
|
38
|
+
with default[OutOfBounds, Unit] { do raise(MissingValue(), "No node " ++ root.show) }
|
|
39
39
|
u.rawElements.set(root, -1 * rank - 1)
|
|
40
40
|
}
|
|
41
41
|
}
|
|
@@ -66,7 +66,7 @@ def find(u: UnionFind, s: Int): Int / Exception[MissingValue] = {
|
|
|
66
66
|
}
|
|
67
67
|
val root = goFind(s)
|
|
68
68
|
|
|
69
|
-
def goCompress(s: Int): Unit = {
|
|
69
|
+
def goCompress(s: Int): Unit = {
|
|
70
70
|
if (not(u.internal::isRoot(s))) {
|
|
71
71
|
val p = u.internal::parent(s)
|
|
72
72
|
u.internal::setParent(s, root)
|
|
@@ -82,7 +82,7 @@ def find(u: UnionFind, s: Int): Int / Exception[MissingValue] = {
|
|
|
82
82
|
///
|
|
83
83
|
/// O(1)
|
|
84
84
|
def unionRoots(u: UnionFind, x: Int, y: Int): Int / Exception[MissingValue] = {
|
|
85
|
-
if(not(u.internal::isRoot(x) && u.internal::isRoot(y))) {
|
|
85
|
+
if(not(u.internal::isRoot(x) && u.internal::isRoot(y))) {
|
|
86
86
|
panic("unionRoots should only be called on representatives")
|
|
87
87
|
}
|
|
88
88
|
|
|
@@ -56,6 +56,6 @@ $effekt.println = function println$impl(str) {
|
|
|
56
56
|
|
|
57
57
|
$effekt.unit = { __unit: true }
|
|
58
58
|
|
|
59
|
-
$effekt.
|
|
59
|
+
$effekt.unreachable = function() { throw "should not be reachable!" }
|
|
60
60
|
|
|
61
61
|
$effekt.hole = function(pos) { throw pos + " not implemented yet" }
|
|
@@ -7,8 +7,8 @@ declare void @c_io_println(%Pos)
|
|
|
7
7
|
declare %Pos @c_io_readln()
|
|
8
8
|
declare %Double @c_io_random()
|
|
9
9
|
|
|
10
|
-
declare void @hole(i8*)
|
|
11
|
-
declare void @duplicated_prompt()
|
|
10
|
+
declare void @hole(i8*) cold
|
|
11
|
+
declare void @duplicated_prompt() cold
|
|
12
12
|
|
|
13
13
|
declare %Pos @c_ref_fresh(%Pos)
|
|
14
14
|
declare %Pos @c_ref_get(%Pos)
|
package/libraries/llvm/io.c
CHANGED
|
@@ -143,8 +143,8 @@ void c_fs_read(Int file, struct Pos buffer, Int offset, Int size, Int position,
|
|
|
143
143
|
if (result < 0) {
|
|
144
144
|
uv_fs_req_cleanup(request);
|
|
145
145
|
free(request);
|
|
146
|
+
free(read_closure);
|
|
146
147
|
resume_Int(stack, result);
|
|
147
|
-
free(read_closure);
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
150
|
|
|
@@ -166,8 +166,8 @@ void c_fs_write(Int file, struct Pos buffer, Int offset, Int size, Int position,
|
|
|
166
166
|
if (result < 0) {
|
|
167
167
|
uv_fs_req_cleanup(request);
|
|
168
168
|
free(request);
|
|
169
|
+
free(write_closure);
|
|
169
170
|
resume_Int(stack, result);
|
|
170
|
-
free(write_closure);
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
173
|
|
package/libraries/llvm/panic.c
CHANGED
|
@@ -7,11 +7,13 @@
|
|
|
7
7
|
// this should _morally_ be using `stderr`, but we don't tee it in tests
|
|
8
8
|
// see PR #823 & issue #815 for context
|
|
9
9
|
|
|
10
|
+
__attribute__((cold))
|
|
10
11
|
void hole(const char* message) {
|
|
11
12
|
printf("PANIC: %s not implemented yet\n", message);
|
|
12
13
|
exit(1);
|
|
13
14
|
}
|
|
14
15
|
|
|
16
|
+
__attribute__((cold))
|
|
15
17
|
void duplicated_prompt() {
|
|
16
18
|
printf("PANIC: Continuation invoked itself\n");
|
|
17
19
|
exit(1);
|
package/libraries/llvm/rts.ll
CHANGED
|
@@ -97,6 +97,7 @@
|
|
|
97
97
|
declare ptr @malloc(i64)
|
|
98
98
|
declare void @free(ptr)
|
|
99
99
|
declare ptr @realloc(ptr, i64)
|
|
100
|
+
declare noalias ptr @calloc(i64, i64)
|
|
100
101
|
declare void @memcpy(ptr, ptr, i64)
|
|
101
102
|
declare i64 @llvm.ctlz.i64 (i64 , i1)
|
|
102
103
|
declare i64 @llvm.fshr.i64(i64, i64, i64)
|
|
@@ -407,7 +408,7 @@ define private void @invalidate(%Stack %stack, %Stack %end) {
|
|
|
407
408
|
|
|
408
409
|
error:
|
|
409
410
|
call void @duplicated_prompt()
|
|
410
|
-
|
|
411
|
+
unreachable
|
|
411
412
|
|
|
412
413
|
check:
|
|
413
414
|
%isEnd = icmp eq %Stack %next, %end
|
|
@@ -690,15 +691,13 @@ define private %Stack @withEmptyStack() {
|
|
|
690
691
|
ret %Stack %stack
|
|
691
692
|
}
|
|
692
693
|
|
|
693
|
-
define void @resume_Int(%Stack %stack, %Int %
|
|
694
|
-
%
|
|
695
|
-
|
|
696
|
-
%returnAddress = load %ReturnAddress, ptr %returnAddressPointer, !alias.scope !12, !noalias !22
|
|
697
|
-
tail call tailcc void %returnAddress(%Int %argument, %Stack %stack)
|
|
694
|
+
define ccc void @resume_Int(%Stack %stack, %Int %integer) {
|
|
695
|
+
%argument = call ccc %Pos @coerceIntPos(%Int %integer)
|
|
696
|
+
call ccc void @resume_Pos(%Stack %stack, %Pos %argument)
|
|
698
697
|
ret void
|
|
699
698
|
}
|
|
700
699
|
|
|
701
|
-
define void @resume_Pos(%Stack %stack, %Pos %argument) {
|
|
700
|
+
define ccc void @resume_Pos(%Stack %stack, %Pos %argument) {
|
|
702
701
|
%stackPointer = call ccc %StackPointer @stackDeallocate(%Stack %stack, i64 24)
|
|
703
702
|
%returnAddressPointer = getelementptr %FrameHeader, %StackPointer %stackPointer, i64 0, i32 0
|
|
704
703
|
%returnAddress = load %ReturnAddress, ptr %returnAddressPointer, !alias.scope !12, !noalias !22
|
|
@@ -706,56 +705,36 @@ define void @resume_Pos(%Stack %stack, %Pos %argument) {
|
|
|
706
705
|
ret void
|
|
707
706
|
}
|
|
708
707
|
|
|
709
|
-
define void @run(%Pos %boxed) {
|
|
710
|
-
; unbox
|
|
711
|
-
%f = call %Neg @coercePosNeg(%Pos %boxed)
|
|
708
|
+
define ccc void @run(%Pos %boxed) {
|
|
712
709
|
|
|
713
|
-
|
|
710
|
+
%function = call %Neg @coercePosNeg(%Pos %boxed)
|
|
714
711
|
%stack = call %Stack @withEmptyStack()
|
|
715
712
|
|
|
716
|
-
|
|
717
|
-
%
|
|
718
|
-
%object = extractvalue %Neg %f, 1
|
|
713
|
+
%arrayPointer = extractvalue %Neg %function, 0
|
|
714
|
+
%object = extractvalue %Neg %function, 1
|
|
719
715
|
%functionPointerPointer = getelementptr ptr, ptr %arrayPointer, i64 0
|
|
720
716
|
%functionPointer = load ptr, ptr %functionPointerPointer, !alias.scope !15, !noalias !25
|
|
721
717
|
|
|
722
|
-
; call
|
|
723
718
|
tail call tailcc %Pos %functionPointer(%Object %object, %Stack %stack)
|
|
724
719
|
ret void
|
|
725
720
|
}
|
|
726
721
|
|
|
727
|
-
define void @run_Int(%Pos %boxed,
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
; fresh stack
|
|
732
|
-
%stack = call %Stack @withEmptyStack()
|
|
733
|
-
|
|
734
|
-
; prepare call
|
|
735
|
-
%arrayPointer = extractvalue %Neg %f, 0
|
|
736
|
-
%object = extractvalue %Neg %f, 1
|
|
737
|
-
%functionPointerPointer = getelementptr ptr, ptr %arrayPointer, i64 0
|
|
738
|
-
%functionPointer = load ptr, ptr %functionPointerPointer, !alias.scope !15, !noalias !25
|
|
739
|
-
|
|
740
|
-
; call
|
|
741
|
-
tail call tailcc %Pos %functionPointer(%Object %object, i64 %argument, %Stack %stack)
|
|
722
|
+
define ccc void @run_Int(%Pos %boxed, %Int %integer) {
|
|
723
|
+
%argument = call ccc %Pos @coerceIntPos(%Int %integer)
|
|
724
|
+
call ccc %Pos @run_Pos(%Pos %boxed, %Pos %argument)
|
|
742
725
|
ret void
|
|
743
726
|
}
|
|
744
727
|
|
|
745
|
-
define void @run_Pos(%Pos %boxed, %Pos %argument) {
|
|
746
|
-
; unbox
|
|
747
|
-
%f = call %Neg @coercePosNeg(%Pos %boxed)
|
|
728
|
+
define ccc void @run_Pos(%Pos %boxed, %Pos %argument) {
|
|
748
729
|
|
|
749
|
-
|
|
730
|
+
%function = call ccc %Neg @coercePosNeg(%Pos %boxed)
|
|
750
731
|
%stack = call %Stack @withEmptyStack()
|
|
751
732
|
|
|
752
|
-
|
|
753
|
-
%
|
|
754
|
-
%object = extractvalue %Neg %f, 1
|
|
733
|
+
%arrayPointer = extractvalue %Neg %function, 0
|
|
734
|
+
%object = extractvalue %Neg %function, 1
|
|
755
735
|
%functionPointerPointer = getelementptr ptr, ptr %arrayPointer, i64 0
|
|
756
736
|
%functionPointer = load ptr, ptr %functionPointerPointer, !alias.scope !15, !noalias !25
|
|
757
737
|
|
|
758
|
-
; call
|
|
759
738
|
tail call tailcc %Pos %functionPointer(%Object %object, %Pos %argument, %Stack %stack)
|
|
760
739
|
ret void
|
|
761
740
|
}
|