@effekt-lang/effekt 0.14.0 → 0.16.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 +0 -0
- package/libraries/common/char.effekt +47 -23
- package/libraries/common/effekt.effekt +6 -2
- package/libraries/common/io/filesystem.effekt +2 -0
- package/libraries/common/io.effekt +2 -1
- package/libraries/common/json.effekt +385 -0
- package/libraries/common/scanner.effekt +171 -0
- package/libraries/common/stream.effekt +161 -134
- package/libraries/llvm/array.c +5 -1
- package/libraries/llvm/bytearray.c +24 -18
- package/libraries/llvm/io.c +5 -5
- package/libraries/llvm/main.c +0 -1
- package/libraries/llvm/ref.c +2 -0
- package/libraries/llvm/rts.ll +20 -0
- package/licenses/eclipse public license, version 2.0 - epl-2.0.html +2 -2
- package/licenses/mit license - mit-license.html +1263 -0
- package/licenses/the bsd license - bsd-license.html +1261 -0
- package/licenses/the mit license - mit.html +1263 -0
- package/package.json +1 -1
- package/libraries/llvm/sanity.c +0 -16
|
@@ -19,24 +19,13 @@ effect read[A](): A / stop
|
|
|
19
19
|
/// Signal from a producer to a consumer that there are no further values.
|
|
20
20
|
effect stop(): Nothing
|
|
21
21
|
|
|
22
|
-
/// Canonical handler of push streams that performs `action` for every
|
|
23
|
-
/// value emitted by `stream`.
|
|
24
|
-
def for[A, R] { stream: () => R / emit[A] } { action: A => Unit }: R =
|
|
25
|
-
try {
|
|
26
|
-
stream()
|
|
27
|
-
} with emit[A] { value =>
|
|
28
|
-
resume(action(value))
|
|
29
|
-
}
|
|
30
|
-
|
|
31
22
|
/// Like `for[A, R]`, but ignores the result of the stream, and consequently
|
|
32
23
|
/// works for any type. Use this to annotate the type of stream elements
|
|
33
24
|
/// `A` without having to also annotate `R`.
|
|
34
25
|
///
|
|
35
26
|
/// e.g. for[Int] { prog() } { el => println(el) }
|
|
36
|
-
def for[A] { stream: () =>
|
|
37
|
-
for[A,
|
|
38
|
-
()
|
|
39
|
-
}
|
|
27
|
+
def for[A] { stream: () => Unit / emit[A] } { action: A => Unit }: Unit =
|
|
28
|
+
returning::for[A, Unit]{stream}{action}
|
|
40
29
|
|
|
41
30
|
/// Turns a `list` into a producer of a push stream
|
|
42
31
|
/// by emitting each contained value left-to-right.
|
|
@@ -81,20 +70,13 @@ def each(bytes: ByteArray): Unit / emit[Byte] = {
|
|
|
81
70
|
// not seq
|
|
82
71
|
|
|
83
72
|
|
|
84
|
-
def boundary
|
|
85
|
-
|
|
86
|
-
Some(program())
|
|
87
|
-
} with stop {
|
|
88
|
-
None()
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
def boundary { program: () => Any / stop }: Unit = {
|
|
92
|
-
boundary[Any]{program}
|
|
73
|
+
def boundary { program: () => Unit / stop }: Unit = {
|
|
74
|
+
returning::boundary[Unit]{program}
|
|
93
75
|
()
|
|
94
76
|
}
|
|
95
77
|
|
|
96
78
|
/// Run `program` forever until `stop` is thrown.
|
|
97
|
-
def exhaustively { program: () =>
|
|
79
|
+
def exhaustively { program: () => Unit / stop }: Unit =
|
|
98
80
|
try {
|
|
99
81
|
def go(): Unit = {
|
|
100
82
|
program()
|
|
@@ -105,6 +87,24 @@ def exhaustively { program: () => Any / stop }: Unit =
|
|
|
105
87
|
()
|
|
106
88
|
}
|
|
107
89
|
|
|
90
|
+
def many[A] { action: () => A / stop }: Unit / emit[A] =
|
|
91
|
+
exhaustively { do emit(action()) }
|
|
92
|
+
|
|
93
|
+
def some[A] { action: () => A / stop }: Unit / { emit[A], stop } = {
|
|
94
|
+
do emit(action())
|
|
95
|
+
many { action() }
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
def optionally { program: () => Unit / stop }: Bool =
|
|
99
|
+
returning::optionally[Unit]{program}.isDefined
|
|
100
|
+
|
|
101
|
+
def attempt[R] { program: () => R / stop } { fallback: () => R }: R =
|
|
102
|
+
try {
|
|
103
|
+
program()
|
|
104
|
+
} with stop {
|
|
105
|
+
fallback()
|
|
106
|
+
}
|
|
107
|
+
|
|
108
108
|
|
|
109
109
|
/// In Effekt lower bounds are inclusive and upper bounds are exclusive
|
|
110
110
|
record Indexed[A](index: Int, value: A)
|
|
@@ -123,39 +123,13 @@ def rangeFrom(lower: Int): Unit / emit[Int] = {
|
|
|
123
123
|
rangeFrom(lower + 1)
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
+
def index[A] { stream: () => Unit / emit[A] }: Unit / emit[Indexed[A]] =
|
|
127
|
+
returning::index[A, Unit]{stream}
|
|
126
128
|
|
|
127
|
-
def index[A, R] { stream: () => R / emit[A] }: R / emit[Indexed[A]] = {
|
|
128
|
-
var i = 0;
|
|
129
|
-
try {
|
|
130
|
-
stream()
|
|
131
|
-
} with emit[A] { v =>
|
|
132
|
-
val c = i;
|
|
133
|
-
i = c + 1;
|
|
134
|
-
resume(do emit(Indexed(c, v)))
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
129
|
|
|
138
130
|
/// If `number` is zero or negative it does nothing
|
|
139
|
-
def limit[A
|
|
140
|
-
|
|
141
|
-
var i = 1;
|
|
142
|
-
try {
|
|
143
|
-
stream()
|
|
144
|
-
} with emit[A] { v =>
|
|
145
|
-
if (i < number) {
|
|
146
|
-
i = i + 1;
|
|
147
|
-
resume(do emit(v))
|
|
148
|
-
} else {
|
|
149
|
-
do stop()
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
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
|
-
}
|
|
131
|
+
def limit[A](number: Int) { stream: () => Unit / emit[A] }: Unit / {emit[A], stop} =
|
|
132
|
+
returning::limit[A, Unit](number){stream}
|
|
159
133
|
|
|
160
134
|
|
|
161
135
|
/// If `number` is zero or negative it does nothing
|
|
@@ -166,61 +140,17 @@ def replicate[A](number: Int) { action: () => A }: Unit / emit[A] =
|
|
|
166
140
|
}
|
|
167
141
|
|
|
168
142
|
|
|
169
|
-
def sum
|
|
170
|
-
|
|
171
|
-
try {
|
|
172
|
-
(stream(), s)
|
|
173
|
-
} with emit[Int] { v =>
|
|
174
|
-
s = s + v;
|
|
175
|
-
resume(())
|
|
176
|
-
}
|
|
177
|
-
}
|
|
143
|
+
def sum { stream : () => Unit / emit[Int] }: Int =
|
|
144
|
+
returning::sum[Unit]{stream}.second
|
|
178
145
|
|
|
179
|
-
def
|
|
180
|
-
|
|
146
|
+
def collectList[A] { stream: () => Unit / emit[A] }: List[A] =
|
|
147
|
+
returning::collectList[A, Unit]{stream}.second
|
|
181
148
|
|
|
182
|
-
def
|
|
183
|
-
|
|
184
|
-
(stream(), Nil())
|
|
185
|
-
} with emit[A] { (v) =>
|
|
186
|
-
val (r, vs) = resume(());
|
|
187
|
-
(r, Cons(v, vs))
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
def collectList[A] { stream: () => Any / emit[A] }: List[A] =
|
|
191
|
-
collectList[A, Any]{stream}.second
|
|
192
|
-
|
|
193
|
-
def collectArray[A, R] { stream: () => R / emit[A] }: (R, Array[A]) = {
|
|
194
|
-
var i = 0
|
|
195
|
-
var a = array::allocate(1)
|
|
196
|
-
try {
|
|
197
|
-
(stream(), a.resize(i))
|
|
198
|
-
} with emit[A] { (v) =>
|
|
199
|
-
if (i >= a.size) { a = a.resize(2 * a.size) }
|
|
200
|
-
a.unsafeSet(i, v)
|
|
201
|
-
i = i + 1
|
|
202
|
-
resume(())
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
def collectArray[A] { stream: () => Any / emit[A] }: Array[A] =
|
|
207
|
-
collectArray[A, Any]{stream}.second
|
|
208
|
-
|
|
209
|
-
def collectBytes[R] { stream: () => R / emit[Byte] }: (R, ByteArray) = {
|
|
210
|
-
var i = 0
|
|
211
|
-
var a = bytearray::allocate(1)
|
|
212
|
-
try {
|
|
213
|
-
(stream(), a.resize(i))
|
|
214
|
-
} with emit[Byte] { (v) =>
|
|
215
|
-
if (i >= a.size) { a = a.resize(2 * a.size) }
|
|
216
|
-
a.unsafeSet(i, v)
|
|
217
|
-
i = i + 1
|
|
218
|
-
resume(())
|
|
219
|
-
}
|
|
220
|
-
}
|
|
149
|
+
def collectArray[A] { stream: () => Unit / emit[A] }: Array[A] =
|
|
150
|
+
returning::collectArray[A, Unit]{stream}.second
|
|
221
151
|
|
|
222
|
-
def collectBytes { stream: () =>
|
|
223
|
-
collectBytes[
|
|
152
|
+
def collectBytes { stream: () => Unit / emit[Byte] }: ByteArray =
|
|
153
|
+
returning::collectBytes[Unit]{stream}.second
|
|
224
154
|
|
|
225
155
|
def feed[T, R](list: List[T]) { reader: () => R / read[T] }: R = {
|
|
226
156
|
var l = list
|
|
@@ -272,34 +202,12 @@ def feed[R](bytes: ByteArray) { reader: () => R / read[Byte] }: R = {
|
|
|
272
202
|
}
|
|
273
203
|
}
|
|
274
204
|
|
|
275
|
-
def source[A
|
|
276
|
-
|
|
277
|
-
next = box {
|
|
278
|
-
try {
|
|
279
|
-
stream()
|
|
280
|
-
None()
|
|
281
|
-
} with emit[A] { (v) =>
|
|
282
|
-
next = box { resume(()) }
|
|
283
|
-
Some(v)
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
try {
|
|
287
|
-
reader()
|
|
288
|
-
} with read[A] {
|
|
289
|
-
resume {
|
|
290
|
-
next().getOrElse { do stop() }
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
def source[A] { stream: () => Any / emit[A] } { reader: () => Any / read[A] }: Unit = {
|
|
296
|
-
source[A, Any]{stream}{reader}
|
|
297
|
-
()
|
|
298
|
-
}
|
|
205
|
+
def source[A] { stream: () => Unit / emit[A] } { reader: () => Unit / read[A] }: Unit =
|
|
206
|
+
returning::source[A, Unit]{stream}{reader}
|
|
299
207
|
|
|
300
208
|
/// Combines two streams together producing a stream of pairs in lockstep.
|
|
301
|
-
///
|
|
302
|
-
def zip[A, B] { stream1: () =>
|
|
209
|
+
/// Terminates when either of them terminates.
|
|
210
|
+
def zip[A, B] { stream1: () => Unit / emit[A] } { stream2: () => Unit / emit[B] } { action: (A, B) => Unit }: Unit = {
|
|
303
211
|
with source[A] { stream1 }
|
|
304
212
|
with source[B] { stream2 }
|
|
305
213
|
|
|
@@ -423,7 +331,7 @@ def encodeUTF8[R] { stream: () => R / emit[Char] }: R / emit[Byte] =
|
|
|
423
331
|
resume(encodeChar(char))
|
|
424
332
|
}
|
|
425
333
|
|
|
426
|
-
def feed(string: String) { reader: () =>
|
|
334
|
+
def feed[R](string: String) { reader: () => R / read[Char] } =
|
|
427
335
|
feed(string.fromString) {
|
|
428
336
|
decodeUTF8 {
|
|
429
337
|
reader()
|
|
@@ -437,10 +345,129 @@ def each(string: String): Unit / emit[Char] =
|
|
|
437
345
|
}
|
|
438
346
|
}
|
|
439
347
|
|
|
348
|
+
def collectString { stream: () => Unit / emit[Char] }: String =
|
|
349
|
+
returning::collectString[Unit]{stream}.second
|
|
350
|
+
|
|
351
|
+
namespace returning {
|
|
352
|
+
|
|
353
|
+
/// Canonical handler of push streams that performs `action` for every
|
|
354
|
+
/// value emitted by `stream`.
|
|
355
|
+
def for[A, R] { stream: () => R / emit[A] } { action: A => Unit }: R =
|
|
356
|
+
try {
|
|
357
|
+
stream()
|
|
358
|
+
} with emit[A] { value =>
|
|
359
|
+
resume(action(value))
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
def boundary[R] { program: () => R / stop }: Option[R] =
|
|
363
|
+
try {
|
|
364
|
+
Some(program())
|
|
365
|
+
} with stop {
|
|
366
|
+
None()
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
def optionally[R] { program: () => R / stop }: Option[R] =
|
|
370
|
+
try {
|
|
371
|
+
Some(program())
|
|
372
|
+
} with stop {
|
|
373
|
+
None()
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
def index[A, R] { stream: () => R / emit[A] }: R / emit[Indexed[A]] = {
|
|
377
|
+
var i = 0;
|
|
378
|
+
try {
|
|
379
|
+
stream()
|
|
380
|
+
} with emit[A] { v =>
|
|
381
|
+
val c = i;
|
|
382
|
+
i = c + 1;
|
|
383
|
+
resume(do emit(Indexed(c, v)))
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/// If `number` is zero or negative it does nothing
|
|
388
|
+
def limit[A, R](number: Int) { stream: () => R / emit[A] }: R / { emit[A], stop } = {
|
|
389
|
+
if (number <= 0) do stop();
|
|
390
|
+
var i = 1;
|
|
391
|
+
try {
|
|
392
|
+
stream()
|
|
393
|
+
} with emit[A] { v =>
|
|
394
|
+
if (i < number) {
|
|
395
|
+
i = i + 1;
|
|
396
|
+
resume(do emit(v))
|
|
397
|
+
} else {
|
|
398
|
+
do stop()
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
def sum[R] { stream : () => R / emit[Int] }: (R, Int) = {
|
|
404
|
+
var s = 0;
|
|
405
|
+
try {
|
|
406
|
+
(stream(), s)
|
|
407
|
+
} with emit[Int] { v =>
|
|
408
|
+
s = s + v;
|
|
409
|
+
resume(())
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
def collectList[A, R] { stream: () => R / emit[A] }: (R, List[A]) =
|
|
414
|
+
try {
|
|
415
|
+
(stream(), Nil())
|
|
416
|
+
} with emit[A] { (v) =>
|
|
417
|
+
val (r, vs) = resume(());
|
|
418
|
+
(r, Cons(v, vs))
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
def collectArray[A, R] { stream: () => R / emit[A] }: (R, Array[A]) = {
|
|
422
|
+
var i = 0
|
|
423
|
+
var a = array::allocate(1)
|
|
424
|
+
try {
|
|
425
|
+
(stream(), a.resize(i))
|
|
426
|
+
} with emit[A] { (v) =>
|
|
427
|
+
if (i >= a.size) { a = a.resize(2 * a.size) }
|
|
428
|
+
a.unsafeSet(i, v)
|
|
429
|
+
i = i + 1
|
|
430
|
+
resume(())
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
def collectBytes[R] { stream: () => R / emit[Byte] }: (R, ByteArray) = {
|
|
435
|
+
var i = 0
|
|
436
|
+
var a = bytearray::allocate(1)
|
|
437
|
+
try {
|
|
438
|
+
(stream(), a.resize(i))
|
|
439
|
+
} with emit[Byte] { (v) =>
|
|
440
|
+
if (i >= a.size) { a = a.resize(2 * a.size) }
|
|
441
|
+
a.unsafeSet(i, v)
|
|
442
|
+
i = i + 1
|
|
443
|
+
resume(())
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
440
447
|
def collectString[R] { stream: () => R / emit[Char] }: (R, String) = {
|
|
441
448
|
val (result, bytes) = collectBytes[R] { encodeUTF8 { stream } }
|
|
442
449
|
(result, bytes.toString)
|
|
443
450
|
}
|
|
444
451
|
|
|
445
|
-
def
|
|
446
|
-
|
|
452
|
+
def source[A, R] { stream: () => Unit / emit[A] } { reader: () => R / read[A] }: R = {
|
|
453
|
+
var next = box { None() }
|
|
454
|
+
next = box {
|
|
455
|
+
try {
|
|
456
|
+
stream()
|
|
457
|
+
next = box { None() }
|
|
458
|
+
None()
|
|
459
|
+
} with emit[A] { (v) =>
|
|
460
|
+
next = box { resume(()) }
|
|
461
|
+
Some(v)
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
try {
|
|
465
|
+
reader()
|
|
466
|
+
} with read[A] {
|
|
467
|
+
resume {
|
|
468
|
+
next().getOrElse { do stop() }
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
}
|
package/libraries/llvm/array.c
CHANGED
|
@@ -32,13 +32,16 @@ struct Pos c_array_new(const Int size) {
|
|
|
32
32
|
|
|
33
33
|
Int c_array_size(const struct Pos arr) {
|
|
34
34
|
uint64_t *sizePtr = arr.obj + sizeof(struct Header);
|
|
35
|
-
|
|
35
|
+
uint64_t size = *sizePtr;
|
|
36
|
+
erasePositive(arr);
|
|
37
|
+
return size;
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
struct Pos c_array_get(const struct Pos arr, const Int index) {
|
|
39
41
|
struct Pos *dataPtr = arr.obj + sizeof(struct Header) + sizeof(uint64_t);
|
|
40
42
|
struct Pos element = dataPtr[index];
|
|
41
43
|
sharePositive(element);
|
|
44
|
+
erasePositive(arr);
|
|
42
45
|
return element;
|
|
43
46
|
}
|
|
44
47
|
|
|
@@ -47,6 +50,7 @@ struct Pos c_array_set(const struct Pos arr, const Int index, const struct Pos v
|
|
|
47
50
|
struct Pos element = dataPtr[index];
|
|
48
51
|
erasePositive(element);
|
|
49
52
|
dataPtr[index] = value;
|
|
53
|
+
erasePositive(arr);
|
|
50
54
|
return Unit;
|
|
51
55
|
}
|
|
52
56
|
|
|
@@ -29,30 +29,34 @@ struct Pos c_bytearray_new(const Int size) {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
Int c_bytearray_size(const struct Pos arr) {
|
|
32
|
+
erasePositive(arr);
|
|
32
33
|
return arr.tag;
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
uint8_t* c_bytearray_data(const struct Pos arr) {
|
|
36
|
-
return arr.obj + sizeof(struct Header);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
36
|
Byte c_bytearray_get(const struct Pos arr, const Int index) {
|
|
40
37
|
Byte *dataPtr = arr.obj + sizeof(struct Header);
|
|
41
38
|
Byte element = dataPtr[index];
|
|
39
|
+
erasePositive(arr);
|
|
42
40
|
return element;
|
|
43
41
|
}
|
|
44
42
|
|
|
45
43
|
struct Pos c_bytearray_set(const struct Pos arr, const Int index, const Byte value) {
|
|
46
44
|
Byte *dataPtr = arr.obj + sizeof(struct Header);
|
|
47
45
|
dataPtr[index] = value;
|
|
46
|
+
erasePositive(arr);
|
|
48
47
|
return Unit;
|
|
49
48
|
}
|
|
50
49
|
|
|
50
|
+
// Internal Operations
|
|
51
|
+
|
|
52
|
+
uint8_t* c_bytearray_data(const struct Pos arr) {
|
|
53
|
+
uint8_t *data = arr.obj + sizeof(struct Header);
|
|
54
|
+
return data;
|
|
55
|
+
}
|
|
56
|
+
|
|
51
57
|
struct Pos c_bytearray_construct(const uint64_t n, const uint8_t *data) {
|
|
52
58
|
struct Pos arr = c_bytearray_new(n);
|
|
53
|
-
|
|
54
59
|
memcpy(c_bytearray_data(arr), data, n);
|
|
55
|
-
|
|
56
60
|
return arr;
|
|
57
61
|
}
|
|
58
62
|
|
|
@@ -66,7 +70,7 @@ struct Pos c_bytearray_from_nullterminated_string(const char *data) {
|
|
|
66
70
|
}
|
|
67
71
|
|
|
68
72
|
char* c_bytearray_into_nullterminated_string(const struct Pos arr) {
|
|
69
|
-
uint64_t size =
|
|
73
|
+
uint64_t size = arr.tag;
|
|
70
74
|
|
|
71
75
|
char* result = (char*)malloc(size + 1);
|
|
72
76
|
|
|
@@ -125,12 +129,14 @@ struct Pos c_bytearray_show_Double(const Double x) {
|
|
|
125
129
|
|
|
126
130
|
// TODO do this in Effekt
|
|
127
131
|
struct Pos c_bytearray_concatenate(const struct Pos left, const struct Pos right) {
|
|
128
|
-
|
|
129
|
-
|
|
132
|
+
uint64_t left_size = left.tag;
|
|
133
|
+
uint64_t right_size = right.tag;
|
|
134
|
+
const struct Pos concatenated = c_bytearray_new(left_size + right_size);
|
|
135
|
+
for (uint64_t j = 0; j < concatenated.tag; ++j)
|
|
130
136
|
c_bytearray_data(concatenated)[j]
|
|
131
|
-
= j <
|
|
137
|
+
= j < left_size
|
|
132
138
|
? c_bytearray_data(left)[j]
|
|
133
|
-
: c_bytearray_data(right)[j -
|
|
139
|
+
: c_bytearray_data(right)[j - left_size];
|
|
134
140
|
|
|
135
141
|
erasePositive(left);
|
|
136
142
|
erasePositive(right);
|
|
@@ -139,8 +145,8 @@ struct Pos c_bytearray_concatenate(const struct Pos left, const struct Pos right
|
|
|
139
145
|
|
|
140
146
|
// TODO do this in Effekt
|
|
141
147
|
struct Pos c_bytearray_equal(const struct Pos left, const struct Pos right) {
|
|
142
|
-
uint64_t left_size =
|
|
143
|
-
uint64_t right_size =
|
|
148
|
+
uint64_t left_size = left.tag;
|
|
149
|
+
uint64_t right_size = right.tag;
|
|
144
150
|
if (left_size != right_size) {
|
|
145
151
|
erasePositive(left);
|
|
146
152
|
erasePositive(right);
|
|
@@ -161,7 +167,7 @@ struct Pos c_bytearray_equal(const struct Pos left, const struct Pos right) {
|
|
|
161
167
|
// TODO deprecate
|
|
162
168
|
struct Pos c_bytearray_substring(const struct Pos str, uint64_t start, uint64_t end) {
|
|
163
169
|
const struct Pos substr = c_bytearray_new(end - start);
|
|
164
|
-
for (
|
|
170
|
+
for (uint64_t j = 0; j < substr.tag; ++j) {
|
|
165
171
|
c_bytearray_data(substr)[j] = c_bytearray_data(str)[start+j];
|
|
166
172
|
}
|
|
167
173
|
erasePositive(str);
|
|
@@ -174,27 +180,27 @@ uint32_t c_bytearray_character_at(const struct Pos str, const uint64_t index) {
|
|
|
174
180
|
uint8_t first_byte = bytes[index];
|
|
175
181
|
uint32_t character = 0;
|
|
176
182
|
|
|
177
|
-
uint32_t
|
|
183
|
+
uint32_t size = str.tag;
|
|
178
184
|
|
|
179
185
|
if (first_byte < 0x80) {
|
|
180
186
|
// Single-byte character (0xxxxxxx)
|
|
181
187
|
character = first_byte;
|
|
182
188
|
} else if ((first_byte & 0xE0) == 0xC0) {
|
|
183
189
|
// Two-byte character (110xxxxx 10xxxxxx)
|
|
184
|
-
if (index + 1 <
|
|
190
|
+
if (index + 1 < size) {
|
|
185
191
|
character = ((first_byte & 0x1F) << 6) |
|
|
186
192
|
(bytes[index + 1] & 0x3F);
|
|
187
193
|
}
|
|
188
194
|
} else if ((first_byte & 0xF0) == 0xE0) {
|
|
189
195
|
// Three-byte character (1110xxxx 10xxxxxx 10xxxxxx)
|
|
190
|
-
if (index + 2 <
|
|
196
|
+
if (index + 2 < size) {
|
|
191
197
|
character = ((first_byte & 0x0F) << 12) |
|
|
192
198
|
((bytes[index + 1] & 0x3F) << 6) |
|
|
193
199
|
(bytes[index + 2] & 0x3F);
|
|
194
200
|
}
|
|
195
201
|
} else if ((first_byte & 0xF8) == 0xF0) {
|
|
196
202
|
// Four-byte character (11110xxx 10xxxxxx 10xxxxxx 10xxxxxx)
|
|
197
|
-
if (index + 3 <
|
|
203
|
+
if (index + 3 < size) {
|
|
198
204
|
character = ((first_byte & 0x07) << 18) |
|
|
199
205
|
((bytes[index + 1] & 0x3F) << 12) |
|
|
200
206
|
((bytes[index + 2] & 0x3F) << 6) |
|
package/libraries/llvm/io.c
CHANGED
|
@@ -20,7 +20,7 @@ void c_io_println_Double(const Double x) {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
void c_io_println_String(String text) {
|
|
23
|
-
for (
|
|
23
|
+
for (uint64_t j = 0; j < text.tag; ++j)
|
|
24
24
|
putchar(c_bytearray_data(text)[j]);
|
|
25
25
|
erasePositive(text);
|
|
26
26
|
putchar('\n');
|
|
@@ -126,8 +126,8 @@ void c_fs_open(String path, struct Pos mode, Stack stack) {
|
|
|
126
126
|
void c_fs_read(Int file, struct Pos buffer, Int offset, Int size, Int position, Stack stack) {
|
|
127
127
|
|
|
128
128
|
uv_buf_t buf = uv_buf_init((char*)(c_bytearray_data(buffer) + offset), size);
|
|
129
|
-
|
|
130
|
-
// TODO
|
|
129
|
+
erasePositive(buffer);
|
|
130
|
+
// TODO panic if this was the last reference
|
|
131
131
|
|
|
132
132
|
uv_fs_t* request = malloc(sizeof(uv_fs_t));
|
|
133
133
|
request->data = stack;
|
|
@@ -144,8 +144,8 @@ void c_fs_read(Int file, struct Pos buffer, Int offset, Int size, Int position,
|
|
|
144
144
|
void c_fs_write(Int file, struct Pos buffer, Int offset, Int size, Int position, Stack stack) {
|
|
145
145
|
|
|
146
146
|
uv_buf_t buf = uv_buf_init((char*)(c_bytearray_data(buffer) + offset), size);
|
|
147
|
-
|
|
148
|
-
// TODO
|
|
147
|
+
erasePositive(buffer);
|
|
148
|
+
// TODO panic if this was the last reference
|
|
149
149
|
|
|
150
150
|
uv_fs_t* request = malloc(sizeof(uv_fs_t));
|
|
151
151
|
request->data = stack;
|
package/libraries/llvm/main.c
CHANGED
package/libraries/llvm/ref.c
CHANGED
|
@@ -31,6 +31,7 @@ struct Pos c_ref_get(const struct Pos ref) {
|
|
|
31
31
|
struct Pos *fieldPtr = ref.obj + sizeof(struct Header);
|
|
32
32
|
struct Pos element = *fieldPtr;
|
|
33
33
|
sharePositive(element);
|
|
34
|
+
erasePositive(ref);
|
|
34
35
|
return element;
|
|
35
36
|
}
|
|
36
37
|
|
|
@@ -39,6 +40,7 @@ struct Pos c_ref_set(const struct Pos ref, const struct Pos value) {
|
|
|
39
40
|
struct Pos element = *fieldPtr;
|
|
40
41
|
erasePositive(element);
|
|
41
42
|
*fieldPtr = value;
|
|
43
|
+
erasePositive(ref);
|
|
42
44
|
return Unit;
|
|
43
45
|
}
|
|
44
46
|
|
package/libraries/llvm/rts.ll
CHANGED
|
@@ -114,6 +114,26 @@ declare void @exit(i64)
|
|
|
114
114
|
declare void @llvm.assume(i1)
|
|
115
115
|
|
|
116
116
|
|
|
117
|
+
; Boxing (externs functions, hence ccc)
|
|
118
|
+
define ccc %Pos @box(%Neg %input) {
|
|
119
|
+
%vtable = extractvalue %Neg %input, 0
|
|
120
|
+
%heap_obj = extractvalue %Neg %input, 1
|
|
121
|
+
%vtable_as_int = ptrtoint ptr %vtable to i64
|
|
122
|
+
%pos_result = insertvalue %Pos undef, i64 %vtable_as_int, 0
|
|
123
|
+
%pos_result_with_heap = insertvalue %Pos %pos_result, ptr %heap_obj, 1
|
|
124
|
+
ret %Pos %pos_result_with_heap
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
define ccc %Neg @unbox(%Pos %input) {
|
|
128
|
+
%tag = extractvalue %Pos %input, 0
|
|
129
|
+
%heap_obj = extractvalue %Pos %input, 1
|
|
130
|
+
%vtable = inttoptr i64 %tag to ptr
|
|
131
|
+
%neg_result = insertvalue %Neg undef, ptr %vtable, 0
|
|
132
|
+
%neg_result_with_heap = insertvalue %Neg %neg_result, ptr %heap_obj, 1
|
|
133
|
+
ret %Neg %neg_result_with_heap
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
|
|
117
137
|
; Prompts
|
|
118
138
|
|
|
119
139
|
define private %Prompt @currentPrompt(%Stack %stack) {
|
|
@@ -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=
|
|
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=1736104525"><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-brands fa-linkedin-in 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 © 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=
|
|
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 © 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=1736104525"></script>
|
|
61
61
|
<script>(function(){})(jQuery,document)</script></div></body></html>
|