@effekt-lang/effekt 0.11.0 → 0.13.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/bin/effekt CHANGED
Binary file
@@ -11,7 +11,7 @@ import io/error
11
11
  /// Describes push streams by emitting values of type `A`.
12
12
  effect emit[A](value: A): Unit
13
13
 
14
- /// Describes pull streams by requiring values of type `A`.
14
+ /// Describes pull streams by reading values of type `A`.
15
15
  ///
16
16
  /// The producer can decide to `stop` emitting values.
17
17
  effect read[A](): A / stop
@@ -28,20 +28,14 @@ def for[A, R] { stream: () => R / emit[A] } { action: A => Unit }: R =
28
28
  resume(action(value))
29
29
  }
30
30
 
31
- /// Like `for[A, R]`, but fixes the result of producing computation to the
32
- /// common type `Unit`. This simplifies annotating the type of stream
33
- /// elements `A` without having to also annotate `R`.
31
+ /// Like `for[A, R]`, but ignores the result of the stream, and consequently
32
+ /// works for any type. Use this to annotate the type of stream elements
33
+ /// `A` without having to also annotate `R`.
34
34
  ///
35
35
  /// e.g. for[Int] { prog() } { el => println(el) }
36
- def for[A] { stream: () => Unit / emit[A] } { action: A => Unit }: Unit =
37
- for[A, Unit]{stream}{action}
38
-
39
- def continually[A] { action: () => A }: Nothing / emit[A] = {
40
- def go(): Nothing = {
41
- do emit(action())
42
- go()
43
- }
44
- go()
36
+ def for[A] { stream: () => Any / emit[A] } { action: A => Unit }: Unit = {
37
+ for[A, Any]{stream}{action}
38
+ ()
45
39
  }
46
40
 
47
41
  /// Turns a `list` into a producer of a push stream
@@ -91,23 +85,28 @@ def boundary[R] { program: () => R / stop }: Option[R] =
91
85
  try {
92
86
  Some(program())
93
87
  } with stop {
94
- def stop() = None()
88
+ None()
95
89
  }
96
90
 
97
- def exhaustively[A] { program: () => A / stop } { action: A => Unit }: Unit =
91
+ def boundary { program: () => Any / stop }: Unit = {
92
+ boundary[Any]{program}
93
+ ()
94
+ }
95
+
96
+ /// Run `program` forever until `stop` is thrown.
97
+ def exhaustively { program: () => Any / stop }: Unit =
98
98
  try {
99
99
  def go(): Unit = {
100
- action(program())
100
+ program()
101
101
  go()
102
102
  }
103
103
  go()
104
104
  } with stop {
105
- def stop() = ()
105
+ ()
106
106
  }
107
107
 
108
108
 
109
- // In Effekt lower bounds are inclusive and upper bounds are exclusive
110
-
109
+ /// In Effekt lower bounds are inclusive and upper bounds are exclusive
111
110
  record Indexed[A](index: Int, value: A)
112
111
 
113
112
  def range(lower: Int, upper: Int): Unit / emit[Int] =
@@ -137,7 +136,7 @@ def index[A, R] { stream: () => R / emit[A] }: R / emit[Indexed[A]] = {
137
136
  }
138
137
 
139
138
  /// If `number` is zero or negative it does nothing
140
- def take[A, R](number: Int) { stream: () => R / emit[A] }: R / { emit[A], stop } = {
139
+ def limit[A, R](number: Int) { stream: () => R / emit[A] }: R / { emit[A], stop } = {
141
140
  if (number <= 0) do stop();
142
141
  var i = 1;
143
142
  try {
@@ -152,6 +151,13 @@ def take[A, R](number: Int) { stream: () => R / emit[A] }: R / { emit[A], stop }
152
151
  }
153
152
  }
154
153
 
154
+ /// If `number` is zero or negative it does nothing
155
+ def limit[A](number: Int) { stream: () => Any / emit[A] }: Unit / emit[A] =
156
+ boundary {
157
+ limit[A, Any](number){stream}
158
+ }
159
+
160
+
155
161
  /// If `number` is zero or negative it does nothing
156
162
  def replicate[A](number: Int) { action: () => A }: Unit / emit[A] =
157
163
  if (number > 0) {
@@ -170,8 +176,8 @@ def sum[R] { stream : () => R / emit[Int] }: (R, Int) = {
170
176
  }
171
177
  }
172
178
 
173
- def sum { stream : () => Unit / emit[Int] }: Int =
174
- sum[Unit]{stream}.second
179
+ def sum { stream : () => Any / emit[Int] }: Int =
180
+ sum[Any]{stream}.second
175
181
 
176
182
  def collectList[A, R] { stream: () => R / emit[A] }: (R, List[A]) =
177
183
  try {
@@ -181,8 +187,8 @@ def collectList[A, R] { stream: () => R / emit[A] }: (R, List[A]) =
181
187
  (r, Cons(v, vs))
182
188
  }
183
189
 
184
- def collectList[A] { stream: () => Unit / emit[A] }: List[A] =
185
- collectList[A, Unit]{stream}.second
190
+ def collectList[A] { stream: () => Any / emit[A] }: List[A] =
191
+ collectList[A, Any]{stream}.second
186
192
 
187
193
  def collectArray[A, R] { stream: () => R / emit[A] }: (R, Array[A]) = {
188
194
  var i = 0
@@ -197,8 +203,8 @@ def collectArray[A, R] { stream: () => R / emit[A] }: (R, Array[A]) = {
197
203
  }
198
204
  }
199
205
 
200
- def collectArray[A] { stream: () => Unit / emit[A] }: Array[A] =
201
- collectArray[A, Unit]{stream}.second
206
+ def collectArray[A] { stream: () => Any / emit[A] }: Array[A] =
207
+ collectArray[A, Any]{stream}.second
202
208
 
203
209
  def collectBytes[R] { stream: () => R / emit[Byte] }: (R, ByteArray) = {
204
210
  var i = 0
@@ -213,10 +219,10 @@ def collectBytes[R] { stream: () => R / emit[Byte] }: (R, ByteArray) = {
213
219
  }
214
220
  }
215
221
 
216
- def collectBytes { stream: () => Unit / emit[Byte] }: ByteArray =
217
- collectBytes[Unit]{stream}.second
222
+ def collectBytes { stream: () => Any / emit[Byte] }: ByteArray =
223
+ collectBytes[Any]{stream}.second
218
224
 
219
- def feed[T](list: List[T]) { reader: () => Unit / read[T] } = {
225
+ def feed[T, R](list: List[T]) { reader: () => R / read[T] }: R = {
220
226
  var l = list
221
227
  try {
222
228
  reader()
@@ -232,14 +238,16 @@ def feed[T](list: List[T]) { reader: () => Unit / read[T] } = {
232
238
  }
233
239
  }
234
240
 
235
- def feed[T](array: Array[T]) { reader: () => Unit / read[T] } = {
241
+ def feed[T, R](array: Array[T]) { reader: () => R / read[T] }: R = {
236
242
  var i = 0
237
243
  try {
238
244
  reader()
239
245
  } with read[T] {
240
246
  resume {
241
247
  if (i < array.size) {
242
- array.unsafeGet(i)
248
+ val c = i
249
+ i = c + 1
250
+ array.unsafeGet(c)
243
251
  } else {
244
252
  do stop()
245
253
  }
@@ -247,14 +255,16 @@ def feed[T](array: Array[T]) { reader: () => Unit / read[T] } = {
247
255
  }
248
256
  }
249
257
 
250
- def feed(bytes: ByteArray) { reader: () => Unit / read[Byte] } = {
258
+ def feed[R](bytes: ByteArray) { reader: () => R / read[Byte] }: R = {
251
259
  var i = 0
252
260
  try {
253
261
  reader()
254
262
  } with read[Byte] {
255
263
  resume {
256
264
  if (i < bytes.size) {
257
- bytes.unsafeGet(i)
265
+ val c = i
266
+ i = c + 1
267
+ bytes.unsafeGet(c)
258
268
  } else {
259
269
  do stop()
260
270
  }
@@ -262,7 +272,7 @@ def feed(bytes: ByteArray) { reader: () => Unit / read[Byte] } = {
262
272
  }
263
273
  }
264
274
 
265
- def source[A, R] { stream: () => Unit / emit[A] } { reader: () => R / read[A] }: R = {
275
+ def source[A, R] { stream: () => Any / emit[A] } { reader: () => R / read[A] }: R = {
266
276
  var next = box { None() }
267
277
  next = box {
268
278
  try {
@@ -282,6 +292,21 @@ def source[A, R] { stream: () => Unit / emit[A] } { reader: () => R / read[A] }:
282
292
  }
283
293
  }
284
294
 
295
+ def source[A] { stream: () => Any / emit[A] } { reader: () => Any / read[A] }: Unit = {
296
+ source[A, Any]{stream}{reader}
297
+ ()
298
+ }
299
+
300
+ /// Combines two streams together producing a stream of pairs in lockstep.
301
+ /// Given two streams of length `n` and `m`, it produces a stream of length `min(n, m)`.
302
+ def zip[A, B] { stream1: () => Any / emit[A] } { stream2: () => Any / emit[B] } { action: (A, B) => Any }: Unit = {
303
+ with source[A] { stream1 }
304
+ with source[B] { stream2 }
305
+
306
+ exhaustively {
307
+ action(do read[A](), do read[B]())
308
+ }
309
+ }
285
310
 
286
311
  def writeFile[R](path: String) { stream: () => R / emit[Byte] }: R / Exception[IOError] = {
287
312
 
@@ -407,13 +432,15 @@ def feed(string: String) { reader: () => Unit / read[Char] } =
407
432
 
408
433
  def each(string: String): Unit / emit[Char] =
409
434
  feed(string) {
410
- exhaustively[Char] { do read() } { char => do emit(char) }
435
+ exhaustively {
436
+ do emit[Char](do read[Char]())
437
+ }
411
438
  }
412
439
 
413
440
  def collectString[R] { stream: () => R / emit[Char] }: (R, String) = {
414
- val (result, bytes) = collectBytes { encodeUTF8 { stream } }
441
+ val (result, bytes) = collectBytes[R] { encodeUTF8 { stream } }
415
442
  (result, bytes.toString)
416
443
  }
417
444
 
418
- def collectString { stream: () => Unit / emit[Char] }: String =
419
- collectString[Unit]{stream}.second
445
+ def collectString { stream: () => Any / emit[Char] }: String =
446
+ collectString[Any]{stream}.second
@@ -74,7 +74,7 @@
74
74
  ; This is used for two purposes:
75
75
  ; - a refied first-class list of stacks (cyclic linked-list)
76
76
  ; - as part of an intrusive linked-list of stacks (meta stack)
77
- %StackValue = type { %ReferenceCount, %Memory, %Prompt, i1, %Stack }
77
+ %StackValue = type { %ReferenceCount, %Memory, %Prompt, %Stack }
78
78
 
79
79
 
80
80
 
@@ -111,6 +111,7 @@ declare double @llvm.ceil.f64(double)
111
111
  declare double @llvm.floor.f64(double)
112
112
  declare void @print(i64)
113
113
  declare void @exit(i64)
114
+ declare void @llvm.assume(i1)
114
115
 
115
116
 
116
117
  ; Prompts
@@ -258,20 +259,19 @@ define private %StackPointer @stackAllocate(%Stack %stack, i64 %n) {
258
259
  %stackPointer_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1, i32 0
259
260
  %limit_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1, i32 2
260
261
 
261
- %currentStackPointer = load %StackPointer, ptr %stackPointer_pointer
262
- %limit = load %Limit, ptr %limit_pointer
263
-
262
+ %currentStackPointer = load %StackPointer, ptr %stackPointer_pointer, !alias.scope !2
263
+ %limit = load %Limit, ptr %limit_pointer, !alias.scope !2
264
264
  %nextStackPointer = getelementptr i8, %StackPointer %currentStackPointer, i64 %n
265
265
  %isInside = icmp ule %StackPointer %nextStackPointer, %limit
266
266
  br i1 %isInside, label %continue, label %realloc
267
267
 
268
268
  continue:
269
- store %StackPointer %nextStackPointer, ptr %stackPointer_pointer
269
+ store %StackPointer %nextStackPointer, ptr %stackPointer_pointer, !alias.scope !2
270
270
  ret %StackPointer %currentStackPointer
271
271
 
272
272
  realloc:
273
273
  %base_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1, i32 1
274
- %base = load %Base, ptr %base_pointer
274
+ %base = load %Base, ptr %base_pointer, !alias.scope !2
275
275
 
276
276
  %intStackPointer = ptrtoint %StackPointer %currentStackPointer to i64
277
277
  %intBase = ptrtoint %Base %base to i64
@@ -285,31 +285,48 @@ realloc:
285
285
  %newStackPointer = getelementptr i8, %Base %newBase, i64 %size
286
286
  %newNextStackPointer = getelementptr i8, %StackPointer %newStackPointer, i64 %n
287
287
 
288
- store %StackPointer %newNextStackPointer, ptr %stackPointer_pointer
289
- store %Base %newBase, ptr %base_pointer
290
- store %Limit %newLimit, ptr %limit_pointer
288
+ store %StackPointer %newNextStackPointer, ptr %stackPointer_pointer, !alias.scope !2
289
+ store %Base %newBase, ptr %base_pointer, !alias.scope !2
290
+ store %Limit %newLimit, ptr %limit_pointer, !alias.scope !2
291
291
 
292
292
  ret %StackPointer %newStackPointer
293
293
  }
294
294
 
295
295
  define private %StackPointer @stackDeallocate(%Stack %stack, i64 %n) {
296
296
  %stackPointer_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1, i32 0
297
- %stackPointer = load %StackPointer, ptr %stackPointer_pointer
297
+ %stackPointer = load %StackPointer, ptr %stackPointer_pointer, !alias.scope !2
298
+
299
+ %limit_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1, i32 2
300
+ %limit = load %Limit, ptr %limit_pointer, !alias.scope !2
301
+ %isInside = icmp ule %StackPointer %stackPointer, %limit
302
+ call void @llvm.assume(i1 %isInside)
298
303
 
299
304
  %o = sub i64 0, %n
300
305
  %newStackPointer = getelementptr i8, %StackPointer %stackPointer, i64 %o
301
- store %StackPointer %newStackPointer, ptr %stackPointer_pointer
306
+ store %StackPointer %newStackPointer, ptr %stackPointer_pointer, !alias.scope !2
302
307
 
303
308
  ret %StackPointer %newStackPointer
304
309
  }
305
310
 
306
- define i64 @nextPowerOfTwo(i64 %x) {
311
+ define private i64 @nextPowerOfTwo(i64 %x) {
307
312
  %leadingZeros = call i64 @llvm.ctlz.i64(i64 %x, i1 false)
308
313
  %numBits = sub i64 64, %leadingZeros
309
314
  %result = shl i64 1, %numBits
310
315
  ret i64 %result
311
316
  }
312
317
 
318
+ define private void @assumeFrameHeaderWasPopped(%Stack %stack) alwaysinline {
319
+ %stackPointer_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1, i32 0
320
+ %stackPointer = load %StackPointer, ptr %stackPointer_pointer, !alias.scope !2
321
+ %oldStackPointer = getelementptr %FrameHeader, %StackPointer %stackPointer, i64 1
322
+
323
+ %limit_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1, i32 2
324
+ %limit = load %Limit, ptr %limit_pointer, !alias.scope !2
325
+ %isInside = icmp ule %StackPointer %oldStackPointer, %limit
326
+ call void @llvm.assume(i1 %isInside)
327
+ ret void
328
+ }
329
+
313
330
  ; Meta-stack management
314
331
 
315
332
  define private %Memory @newMemory() {
@@ -336,7 +353,7 @@ define private %Stack @reset(%Stack %oldStack) {
336
353
 
337
354
  %stack.0 = insertvalue %StackValue zeroinitializer, %Memory %stackMemory, 1
338
355
  %stack.1 = insertvalue %StackValue %stack.0, %Prompt %prompt, 2
339
- %stack.2 = insertvalue %StackValue %stack.1, %Stack %oldStack, 4
356
+ %stack.2 = insertvalue %StackValue %stack.1, %Stack %oldStack, 3
340
357
 
341
358
  store %StackValue %stack.2, %Stack %stack
342
359
 
@@ -347,59 +364,55 @@ define private %Stack @reset(%Stack %oldStack) {
347
364
  }
348
365
 
349
366
  define private void @updatePrompts(%Stack %stack) {
350
- %dirtyBit_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 3
351
- %dirtyBit = load i1, ptr %dirtyBit_pointer
352
- br i1 %dirtyBit, label %continue, label %done
367
+ %prompt_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 2
368
+ %prompt = load %Prompt, ptr %prompt_pointer
369
+ %stack_pointer = getelementptr %PromptValue, %Prompt %prompt, i64 0, i32 1
370
+ %promptStack = load %Stack, ptr %stack_pointer
371
+ %isThis = icmp eq %Stack %promptStack, %stack
372
+ br i1 %isThis, label %done, label %continue
353
373
 
354
374
  done:
355
375
  ret void
356
376
 
357
377
  continue:
358
- %prompt_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 2
359
- %prompt = load %Prompt, ptr %prompt_pointer
360
- %stack_pointer = getelementptr %PromptValue, %Prompt %prompt, i64 0, i32 1
361
- %promptStack = load %Stack, ptr %stack_pointer
362
378
  %isOccupied = icmp ne %Stack %promptStack, null
363
379
  br i1 %isOccupied, label %displace, label %update
364
380
 
365
381
  displace:
366
- call void @displace(%Stack %promptStack)
382
+ call void @displace(%Stack %promptStack, %Stack %promptStack)
367
383
  br label %update
368
384
 
369
385
  update:
370
386
  store %Stack %stack, ptr %stack_pointer
371
- store i1 0, ptr %dirtyBit_pointer
372
387
 
373
- %next_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 4
388
+ %next_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 3
374
389
  %next = load %Stack, ptr %next_pointer
375
390
  tail call void @updatePrompts(%Stack %next)
376
391
  ret void
377
392
  }
378
393
 
379
- define void @displace(%Stack %stack) {
394
+ define private void @displace(%Stack %stack, %Stack %end) {
380
395
  %prompt_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 2
381
- %next_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 4
382
- %dirtyBit_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 3
383
- %dirtyBit = load i1, ptr %dirtyBit_pointer
384
- br i1 %dirtyBit, label %done, label %continue
385
-
386
- done:
387
- ret void
388
-
389
- continue:
396
+ %next_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 3
390
397
  %prompt = load %Prompt, ptr %prompt_pointer
391
398
  %stack_pointer = getelementptr %PromptValue, %Prompt %prompt, i64 0, i32 1
392
399
  store %Stack null, ptr %stack_pointer
393
- store i1 1, ptr %dirtyBit_pointer
394
400
 
395
401
  %next = load %Stack, ptr %next_pointer
396
- tail call void @displace(%Stack %next)
402
+ %isEnd = icmp eq %Stack %next, %end
403
+ br i1 %isEnd, label %done, label %continue
404
+
405
+ done:
406
+ ret void
407
+
408
+ continue:
409
+ tail call void @displace(%Stack %next, %Stack %end)
397
410
  ret void
398
411
  }
399
412
 
400
- define %Stack @resume(%Resumption %resumption, %Stack %oldStack) {
413
+ define private %Stack @resume(%Resumption %resumption, %Stack %oldStack) {
401
414
  %uniqueResumption = call %Resumption @uniqueStack(%Resumption %resumption)
402
- %rest_pointer = getelementptr %StackValue, %Resumption %uniqueResumption, i64 0, i32 4
415
+ %rest_pointer = getelementptr %StackValue, %Resumption %uniqueResumption, i64 0, i32 3
403
416
  %start = load %Stack, ptr %rest_pointer
404
417
  call void @updatePrompts(%Stack %start)
405
418
 
@@ -411,7 +424,7 @@ define %Stack @resume(%Resumption %resumption, %Stack %oldStack) {
411
424
  define private {%Resumption, %Stack} @shift(%Stack %stack, %Prompt %prompt) {
412
425
  %resumpion_pointer = getelementptr %PromptValue, %Prompt %prompt, i64 0, i32 1
413
426
  %resumption = load %Stack, ptr %resumpion_pointer
414
- %next_pointer = getelementptr %StackValue, %Stack %resumption, i64 0, i32 4
427
+ %next_pointer = getelementptr %StackValue, %Stack %resumption, i64 0, i32 3
415
428
  %next = load %Stack, ptr %next_pointer
416
429
 
417
430
  store %Stack %stack, ptr %next_pointer
@@ -427,31 +440,7 @@ define private void @eraseMemory(%Memory %memory) {
427
440
  ret void
428
441
  }
429
442
 
430
- define private void @forEachObject(ptr %elementPointer, ptr %end, ptr %f) alwaysinline {
431
- %done = icmp uge ptr %elementPointer, %end
432
- br i1 %done, label %return, label %erase
433
-
434
- erase:
435
- %element = load %Pos, ptr %elementPointer
436
- call void %f(%Pos %element)
437
-
438
- %nextElementPointer = getelementptr %Pos, ptr %elementPointer, i64 1
439
- tail call void @forEachObject(ptr %nextElementPointer, ptr %end, ptr %f)
440
- ret void
441
-
442
- return:
443
- ret void
444
- }
445
-
446
- define void @erasePrompt(%Prompt %prompt, i1 %dirtyBit) alwaysinline {
447
- br i1 %dirtyBit, label %continue, label %clearPrompt
448
-
449
- clearPrompt:
450
- %stack_pointer = getelementptr %PromptValue, %Prompt %prompt, i64 0, i32 1
451
- store %Stack null, ptr %stack_pointer
452
- br label %continue
453
-
454
- continue:
443
+ define private void @erasePrompt(%Prompt %prompt) alwaysinline {
455
444
  %referenceCount_pointer = getelementptr %PromptValue, %Prompt %prompt, i64 0, i32 0
456
445
  %referenceCount = load %ReferenceCount, ptr %referenceCount_pointer
457
446
  switch %ReferenceCount %referenceCount, label %decrement [%ReferenceCount 0, label %free]
@@ -466,7 +455,7 @@ free:
466
455
  ret void
467
456
  }
468
457
 
469
- define void @sharePrompt(%Prompt %prompt) alwaysinline {
458
+ define private void @sharePrompt(%Prompt %prompt) alwaysinline {
470
459
  %referenceCount_pointer = getelementptr %PromptValue, %Prompt %prompt, i64 0, i32 0
471
460
  %referenceCount = load %ReferenceCount, ptr %referenceCount_pointer
472
461
  %newReferenceCount = add %ReferenceCount %referenceCount, 1
@@ -477,16 +466,17 @@ define void @sharePrompt(%Prompt %prompt) alwaysinline {
477
466
  define private %Stack @underflowStack(%Stack %stack) {
478
467
  %stackMemory = getelementptr %StackValue, %Stack %stack, i64 0, i32 1
479
468
  %stackPrompt = getelementptr %StackValue, %Stack %stack, i64 0, i32 2
480
- %stackDirtyBit = getelementptr %StackValue, %Stack %stack, i64 0, i32 3
481
- %stackRest = getelementptr %StackValue, %Stack %stack, i64 0, i32 4
469
+ %stackRest = getelementptr %StackValue, %Stack %stack, i64 0, i32 3
482
470
 
483
471
  %memory = load %Memory, ptr %stackMemory
484
472
  %prompt = load %Prompt, ptr %stackPrompt
485
473
  %rest = load %Stack, ptr %stackRest
486
- %dirtyBit = load i1, ptr %stackDirtyBit
474
+
475
+ %promptStack_pointer = getelementptr %PromptValue, %Prompt %prompt, i64 0, i32 1
476
+ store %Stack null, ptr %promptStack_pointer
487
477
 
488
478
  call void @eraseMemory(%Memory %memory)
489
- call void @erasePrompt(%Prompt %prompt, i1 false)
479
+ call void @erasePrompt(%Prompt %prompt)
490
480
  call void @free(%Stack %stack)
491
481
 
492
482
  ret %Stack %rest
@@ -537,7 +527,7 @@ done:
537
527
  copy:
538
528
  %newOldReferenceCount = sub %ReferenceCount %referenceCount, 1
539
529
  store %ReferenceCount %newOldReferenceCount, ptr %referenceCount_pointer
540
- %stack_pointer = getelementptr %StackValue, %Resumption %resumption, i64 0, i32 4
530
+ %stack_pointer = getelementptr %StackValue, %Resumption %resumption, i64 0, i32 3
541
531
  %stack = load %Stack, ptr %stack_pointer
542
532
 
543
533
  %size = ptrtoint ptr getelementptr (%StackValue, ptr null, i64 1) to i64
@@ -551,7 +541,7 @@ loop:
551
541
 
552
542
  %stackMemory = getelementptr %StackValue, %Stack %old, i64 0, i32 1
553
543
  %stackPrompt = getelementptr %StackValue, %Stack %old, i64 0, i32 2
554
- %stackRest = getelementptr %StackValue, %Stack %old, i64 0, i32 4
544
+ %stackRest = getelementptr %StackValue, %Stack %old, i64 0, i32 3
555
545
 
556
546
  %memory = load %Memory, ptr %stackMemory
557
547
  %prompt = load %Prompt, ptr %stackPrompt
@@ -560,8 +550,7 @@ loop:
560
550
  %newStackReferenceCounter = getelementptr %StackValue, %Stack %newStack, i64 0, i32 0
561
551
  %newStackMemory = getelementptr %StackValue, %Stack %newStack, i64 0, i32 1
562
552
  %newStackPrompt = getelementptr %StackValue, %Stack %newStack, i64 0, i32 2
563
- %newStackDirtyBit = getelementptr %StackValue, %Stack %newStack, i64 0, i32 3
564
- %newStackRest = getelementptr %StackValue, %Stack %newStack, i64 0, i32 4
553
+ %newStackRest = getelementptr %StackValue, %Stack %newStack, i64 0, i32 3
565
554
 
566
555
  %newMemory = call %Memory @copyMemory(%Memory %memory)
567
556
 
@@ -573,7 +562,6 @@ loop:
573
562
  store %ReferenceCount 0, ptr %newStackReferenceCounter
574
563
  store %Memory %newMemory, ptr %newStackMemory
575
564
  store %Prompt %prompt, ptr %newStackPrompt
576
- store i1 1, ptr %newStackDirtyBit
577
565
 
578
566
  %isEnd = icmp eq %Stack %old, %resumption
579
567
  br i1 %isEnd, label %stop, label %next
@@ -607,7 +595,7 @@ define void @eraseResumption(%Resumption %resumption) alwaysinline {
607
595
  ret void
608
596
 
609
597
  free:
610
- %stack_pointer = getelementptr %StackValue, %Resumption %resumption, i64 0, i32 4
598
+ %stack_pointer = getelementptr %StackValue, %Resumption %resumption, i64 0, i32 3
611
599
  %stack = load %Stack, ptr %stack_pointer
612
600
  store %Stack null, ptr %stack_pointer
613
601
  call void @eraseStack(%Stack %stack)
@@ -617,17 +605,25 @@ define void @eraseResumption(%Resumption %resumption) alwaysinline {
617
605
  define void @eraseStack(%Stack %stack) alwaysinline {
618
606
  %stackPointer_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1, i32 0
619
607
  %prompt_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 2
620
- %dirtyBit_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 3
621
- %rest_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 4
608
+ %rest_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 3
622
609
 
623
610
  %stackPointer = load %StackPointer, ptr %stackPointer_pointer
624
611
  %prompt = load %Stack, ptr %prompt_pointer
625
- %dirtyBit = load i1, ptr %dirtyBit_pointer
626
612
  %rest = load %Stack, ptr %rest_pointer
627
613
 
614
+ %promptStack_pointer = getelementptr %PromptValue, %Prompt %prompt, i64 0, i32 1
615
+ %promptStack = load %Stack, ptr %promptStack_pointer
616
+ %isThisStack = icmp eq %Stack %promptStack, %stack
617
+ br i1 %isThisStack, label %clearPrompt, label %free
618
+
619
+ clearPrompt:
620
+ store %Stack null, ptr %promptStack_pointer
621
+ br label %free
622
+
623
+ free:
628
624
  call void @free(%Stack %stack)
629
625
  call void @eraseFrames(%StackPointer %stackPointer)
630
- call void @erasePrompt(%Prompt %prompt, i1 %dirtyBit)
626
+ call void @erasePrompt(%Prompt %prompt)
631
627
 
632
628
  %isNull = icmp eq %Stack %rest, null
633
629
  br i1 %isNull, label %done, label %next
@@ -776,3 +772,13 @@ define void @run_Pos(%Neg %f, %Pos %argument) {
776
772
  tail call tailcc %Pos %functionPointer(%Object %object, %Evidence 0, %Pos %argument, %Stack %stack)
777
773
  ret void
778
774
  }
775
+
776
+
777
+ ; Scope domains
778
+ !0 = !{!"types"}
779
+
780
+ ; Scopes
781
+ !1 = !{!"stackValues", !0}
782
+
783
+ ; Scope lists
784
+ !2 = !{!1}
@@ -1,4 +1,4 @@
1
- <!doctype html><html lang=en><head><meta charset=utf-8><meta http-equiv=x-ua-compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><title>Eclipse Public License 2.0 (EPL) | The Eclipse Foundation</title><meta property="og:title" content="Eclipse Public License 2.0 (EPL) | The Eclipse Foundation"><meta name=twitter:title content="Eclipse Public License 2.0 (EPL) | The Eclipse Foundation"><meta name=description content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta property="og:description" content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta name=twitter:description content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta name=author content="Wayne Beaton"><link href=/favicon.ico rel=icon type=image/x-icon><meta property="og:image" content="https://www.eclipse.org/images/logos/eclipse-foundation-400x400.png"><meta name=twitter:image content="https://www.eclipse.org/images/logos/eclipse-foundation-400x400.png"><meta name=twitter:card content="summary"><meta name=twitter:site content="@eclipsefdn"><meta name=twitter:creator content="@eclipsefdn"><meta property="og:url" content="https://www.eclipse.org/legal/epl-2.0/"><meta property="og:type" content="website"><meta property="og:site_name" content="Eclipse Foundation"><meta name=keywords content="epl,epl-2.0,legal,foundation,eclipse,eclipse public license,license,licenses"><meta name=generator content="Hugo 0.110.0"><link rel=canonical href=https://www.eclipse.org/legal/epl-2.0/><link rel=alternate href=/legal/epl-2.0/index.xml type=application/rss+xml title><link rel=stylesheet href="/public/css/styles.css?v=1732475737"><script>(function(e,t,n,s,o){e[s]=e[s]||[],e[s].push({"gtm.start":(new Date).getTime(),event:"gtm.js"});var a=t.getElementsByTagName(n)[0],i=t.createElement(n),r=s!="dataLayer"?"&l="+s:"";i.async=!0,i.src="https://www.googletagmanager.com/gtm.js?id="+o+r,a.parentNode.insertBefore(i,a)})(window,document,"script","dataLayer","GTM-5WLCZXC")</script><script>var tableClasses="table"</script><link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel=stylesheet type=text/css></head><body><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-5WLCZXC" height=0 width=0 style=display:none;visibility:hidden></iframe></noscript><a class=sr-only href=#content>Skip to main content</a><header class="header-wrapper header-wrapper" id=header><div class=header-toolbar><div class=container><div class=header-toolbar-row><div class="toolbar-btn toolbar-search-btn dropdown"><button class=dropdown-toggle id=toolbar-search type=button data-toggle=dropdown tabindex=0 aria-label=Search>
1
+ <!doctype html><html lang=en><head><meta charset=utf-8><meta http-equiv=x-ua-compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><title>Eclipse Public License 2.0 (EPL) | The Eclipse Foundation</title><meta property="og:title" content="Eclipse Public License 2.0 (EPL) | The Eclipse Foundation"><meta name=twitter:title content="Eclipse Public License 2.0 (EPL) | The Eclipse Foundation"><meta name=description content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta property="og:description" content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta name=twitter:description content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta name=author content="Wayne Beaton"><link href=/favicon.ico rel=icon type=image/x-icon><meta property="og:image" content="https://www.eclipse.org/images/logos/eclipse-foundation-400x400.png"><meta name=twitter:image content="https://www.eclipse.org/images/logos/eclipse-foundation-400x400.png"><meta name=twitter:card content="summary"><meta name=twitter:site content="@eclipsefdn"><meta name=twitter:creator content="@eclipsefdn"><meta property="og:url" content="https://www.eclipse.org/legal/epl-2.0/"><meta property="og:type" content="website"><meta property="og:site_name" content="Eclipse Foundation"><meta name=keywords content="epl,epl-2.0,legal,foundation,eclipse,eclipse public license,license,licenses"><meta name=generator content="Hugo 0.110.0"><link rel=canonical href=https://www.eclipse.org/legal/epl-2.0/><link rel=alternate href=/legal/epl-2.0/index.xml type=application/rss+xml title><link rel=stylesheet href="/public/css/styles.css?v=1733685326"><script>(function(e,t,n,s,o){e[s]=e[s]||[],e[s].push({"gtm.start":(new Date).getTime(),event:"gtm.js"});var a=t.getElementsByTagName(n)[0],i=t.createElement(n),r=s!="dataLayer"?"&l="+s:"";i.async=!0,i.src="https://www.googletagmanager.com/gtm.js?id="+o+r,a.parentNode.insertBefore(i,a)})(window,document,"script","dataLayer","GTM-5WLCZXC")</script><script>var tableClasses="table"</script><link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel=stylesheet type=text/css></head><body><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-5WLCZXC" height=0 width=0 style=display:none;visibility:hidden></iframe></noscript><a class=sr-only href=#content>Skip to main content</a><header class="header-wrapper header-wrapper" id=header><div class=header-toolbar><div class=container><div class=header-toolbar-row><div class="toolbar-btn toolbar-search-btn dropdown"><button class=dropdown-toggle id=toolbar-search type=button data-toggle=dropdown tabindex=0 aria-label=Search>
2
2
  <i class="fa fa-search fa-lg" aria-role=none></i></button><div class="toolbar-search-bar-wrapper dropdown-menu dropdown-menu-right" aria-labelledby=toolbar-search><form action=https://www.eclipse.org/home/search method=get><div class=search-bar><input class=search-bar-input name=q placeholder=Search>
3
3
  <button>
4
4
  <i class="fa fa-search" type=submit></i></button></div></form></div></div><div class="toolbar-btn toolbar-user-menu-btn dropdown"><button class=dropdown-toggle id=toolbar-user-menu type=button data-toggle=dropdown tabindex=0 aria-label="User Menu">
@@ -57,5 +57,5 @@ open source software collaboration and innovation.</p></div><div class=mega-menu
57
57
  <i class="fa fa-linkedin fa-stack-1x fa-inverse" aria-hidden=true></i>
58
58
  <span class=sr-only>Linkedin account</span></span></a></li></ul></div></div><div class="footer-sections row equal-height-md font-bold"><div class=col-md-15><div class=row><section id=footer-eclipse-foundation class="footer-section col-sm-8"><div class=menu-heading>Eclipse Foundation</div><ul class=nav><li><a href=https://www.eclipse.org/org/>About</a></li><li><a href=https://projects.eclipse.org/>Projects</a></li><li><a href=https://www.eclipse.org/collaborations/>Collaborations</a></li><li><a href=https://www.eclipse.org/membership/>Membership</a></li><li><a href=https://www.eclipse.org/sponsor/>Sponsor</a></li></ul></section><section id=footer-legal class="footer-section col-sm-8"><div class=menu-heading>Legal</div><ul class=nav><li><a href=https://www.eclipse.org/legal/privacy/>Privacy Policy</a></li><li><a href=https://www.eclipse.org/legal/terms-of-use/>Terms of Use</a></li><li><a href=https://www.eclipse.org/legal/compliance/>Compliance</a></li><li><a href=https://www.eclipse.org/org/documents/Community_Code_of_Conduct.php>Code of Conduct</a></li><li><a href=https://www.eclipse.org/legal/>Legal Resources</a></li><li><a class=toolbar-manage-cookies href=# onclick=event.preventDefault()>Manage Cookies</a></li></ul></section><section id=footer-more class="footer-section col-sm-8"><div class=menu-heading>More</div><ul class=nav><li><a href=https://www.eclipse.org/security/>Report a Vulnerability</a></li><li><a href=https://status.eclipse.org/>Service Status</a></li><li><a href=https://www.eclipse.org/org/foundation/contact.php>Contact Us</a></li><li><a href=https://www.eclipse.org/projects/support/>Support</a></li></ul></section></div></div><div id=footer-end class="footer-section col-md-8 col-md-offset-1 col-sm-24"><div class=footer-end-newsletter><form id=mc-embedded-subscribe-form action=https://eclipsecon.us6.list-manage.com/subscribe/post method=post novalidate target=_blank><label class=footer-end-newsletter-label for=email>Subscribe to our Newsletter</label><div class=footer-end-newsletter-input-wrapper><input class=footer-end-newsletter-input type=email id=email name=EMAIL autocomplete=email placeholder="Enter your email address"><div><i class="fa fa-solid fa-envelope fa-lg" aria-hidden=true></i></div></div><input type=hidden name=u value=eaf9e1f06f194eadc66788a85>
59
59
  <input type=hidden name=id value=46e57eacf1>
60
- <input id=mc-embedded-subscribe type=submit name=subscribe hidden></form></div></div></div><div class="col-sm-24 margin-top-20"><div class=row><div id=copyright class=col-md-16><p id=copyright-text>Copyright &copy; Eclipse Foundation AISBL. All Rights Reserved.</p></div></div></div><a href=# class=scrollup>Back to the top</a></div></footer><div id=footer-js><script src="/public/js/main.js?v1.0?v=1732475737"></script>
60
+ <input id=mc-embedded-subscribe type=submit name=subscribe hidden></form></div></div></div><div class="col-sm-24 margin-top-20"><div class=row><div id=copyright class=col-md-16><p id=copyright-text>Copyright &copy; Eclipse Foundation AISBL. All Rights Reserved.</p></div></div></div><a href=# class=scrollup>Back to the top</a></div></footer><div id=footer-js><script src="/public/js/main.js?v1.0?v=1733685326"></script>
61
61
  <script>(function(){})(jQuery,document)</script></div></body></html>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@effekt-lang/effekt",
3
3
  "author": "Jonathan Brachthäuser",
4
- "version": "0.11.0",
4
+ "version": "0.13.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/effekt-lang/effekt.git"