@effekt-lang/effekt 0.66.0 → 0.68.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/args.effekt +2 -2
- package/libraries/common/array.effekt +8 -9
- package/libraries/common/bytearray.effekt +7 -14
- package/libraries/common/bytestream.effekt +4 -4
- package/libraries/common/char.effekt +10 -16
- package/libraries/common/dictionary.effekt +44 -43
- package/libraries/common/effekt.effekt +18 -61
- package/libraries/common/io/channel.effekt +2 -2
- package/libraries/common/io/console.effekt +2 -1
- package/libraries/common/io/filesystem.effekt +5 -5
- package/libraries/common/io/network.effekt +2 -2
- package/libraries/common/io/promise.effekt +2 -2
- package/libraries/common/io/signal.effekt +86 -22
- package/libraries/common/json.effekt +16 -42
- package/libraries/common/list.effekt +4 -4
- package/libraries/common/process.effekt +6 -2
- package/libraries/common/random.effekt +29 -7
- package/libraries/common/ref.effekt +4 -4
- package/libraries/common/regex.effekt +6 -8
- package/libraries/common/resizable_array.effekt +4 -4
- package/libraries/common/scanner.effekt +36 -41
- package/libraries/common/stream.effekt +76 -36
- package/libraries/common/string.effekt +3 -8
- package/libraries/llvm/io.c +0 -55
- package/licenses/eclipse public license, version 2.0 - epl-2.0.html +2 -2
- package/licenses/mit license - mit-license.html +34 -32
- package/licenses/the bsd license - bsd-license.html +33 -31
- package/licenses/the mit license - mit.html +34 -32
- package/package.json +1 -1
|
@@ -46,7 +46,6 @@ extern def print(value: String): Unit =
|
|
|
46
46
|
call void @c_io_print(%Pos ${value})
|
|
47
47
|
ret %Pos zeroinitializer ; Unit
|
|
48
48
|
"""
|
|
49
|
-
vm "effekt::print(String)"
|
|
50
49
|
|
|
51
50
|
extern def println(value: String): Unit =
|
|
52
51
|
js "$effekt.println(${value})"
|
|
@@ -55,7 +54,6 @@ extern def println(value: String): Unit =
|
|
|
55
54
|
call void @c_io_println(%Pos ${value})
|
|
56
55
|
ret %Pos zeroinitializer ; Unit
|
|
57
56
|
"""
|
|
58
|
-
vm "effekt::println(String)"
|
|
59
57
|
|
|
60
58
|
extern jsNode """
|
|
61
59
|
$effekt.readln = function readln$impl(callback) {
|
|
@@ -83,6 +81,7 @@ def println(value: Unit): Unit = println(value.show)
|
|
|
83
81
|
def println(value: Double): Unit = println(value.show)
|
|
84
82
|
def println(value: Bool): Unit = println(value.show)
|
|
85
83
|
def println(value: Byte): Unit = println(value.show)
|
|
84
|
+
def println(value: Char): Unit = println(value.show)
|
|
86
85
|
|
|
87
86
|
extern def showBuiltin(value: Int) at {}: String =
|
|
88
87
|
js "'' + ${value}"
|
|
@@ -91,7 +90,6 @@ extern def showBuiltin(value: Int) at {}: String =
|
|
|
91
90
|
%z = call %Pos @c_bytearray_show_Int(%Int ${value})
|
|
92
91
|
ret %Pos %z
|
|
93
92
|
"""
|
|
94
|
-
vm "effekt::show(Int)"
|
|
95
93
|
|
|
96
94
|
extern def showBuiltin(value: Double) at {}: String =
|
|
97
95
|
js "'' + ${value}"
|
|
@@ -100,7 +98,6 @@ extern def showBuiltin(value: Double) at {}: String =
|
|
|
100
98
|
%z = call %Pos @c_bytearray_show_Double(%Double ${value})
|
|
101
99
|
ret %Pos %z
|
|
102
100
|
"""
|
|
103
|
-
vm "effekt::show(Double)"
|
|
104
101
|
|
|
105
102
|
extern def showBuiltin(value: Char) at {}: String =
|
|
106
103
|
js "String.fromCodePoint(${value})"
|
|
@@ -109,7 +106,6 @@ extern def showBuiltin(value: Char) at {}: String =
|
|
|
109
106
|
%z = call %Pos @c_bytearray_show_Char(%Int ${value})
|
|
110
107
|
ret %Pos %z
|
|
111
108
|
"""
|
|
112
|
-
vm "effekt::show(Char)"
|
|
113
109
|
|
|
114
110
|
extern def showBuiltin(value: Byte) at {}: String =
|
|
115
111
|
js "'0x' + ${value}.toString(16).toUpperCase().padStart(2, '0')"
|
|
@@ -118,11 +114,9 @@ extern def showBuiltin(value: Byte) at {}: String =
|
|
|
118
114
|
%z = call %Pos @c_bytearray_show_Byte(%Byte ${value})
|
|
119
115
|
ret %Pos %z
|
|
120
116
|
"""
|
|
121
|
-
vm "effekt::show(Byte)"
|
|
122
117
|
|
|
123
118
|
extern def inspect[R](value: R) at io: Unit =
|
|
124
119
|
default { println(show(value)) }
|
|
125
|
-
vm "effekt::inspect(Any)"
|
|
126
120
|
|
|
127
121
|
/// A fatal runtime error that cannot be caught
|
|
128
122
|
extern def panic(msg: String) at io: Nothing =
|
|
@@ -135,8 +129,8 @@ extern def panic(msg: String) at io: Nothing =
|
|
|
135
129
|
"""
|
|
136
130
|
|
|
137
131
|
extern def show[R](value: R) at {}: String =
|
|
138
|
-
js "
|
|
139
|
-
chez "(
|
|
132
|
+
js "undefined"
|
|
133
|
+
chez "(void)"
|
|
140
134
|
llvm "ret %Pos poison"
|
|
141
135
|
|
|
142
136
|
extern def genericShow[R](value: R) at {}: String =
|
|
@@ -152,7 +146,6 @@ extern def infixPlusPlus(s1: String, s2: String) at {}: String =
|
|
|
152
146
|
%spz = call %Pos @c_bytearray_concatenate(%Pos ${s1}, %Pos ${s2})
|
|
153
147
|
ret %Pos %spz
|
|
154
148
|
"""
|
|
155
|
-
vm "effekt::infixPlusPlus(String, String)"
|
|
156
149
|
|
|
157
150
|
extern def length(str: String) at {}: Int =
|
|
158
151
|
js "${str}.length"
|
|
@@ -161,7 +154,6 @@ extern def length(str: String) at {}: Int =
|
|
|
161
154
|
%x = call %Int @c_bytearray_size(%Pos ${str})
|
|
162
155
|
ret %Int %x
|
|
163
156
|
"""
|
|
164
|
-
vm "effekt::length(String)"
|
|
165
157
|
|
|
166
158
|
extern def unsafeSubstring(str: String, from: Int, to: Int) at {}: String =
|
|
167
159
|
js "${str}.substring(${from}, ${to})"
|
|
@@ -170,7 +162,6 @@ extern def unsafeSubstring(str: String, from: Int, to: Int) at {}: String =
|
|
|
170
162
|
%x = call %Pos @c_bytearray_substring(%Pos ${str}, i64 ${from}, i64 ${to})
|
|
171
163
|
ret %Pos %x
|
|
172
164
|
"""
|
|
173
|
-
vm "effekt::substring(String, Int, Int)"
|
|
174
165
|
|
|
175
166
|
|
|
176
167
|
// Side effecting ops
|
|
@@ -183,7 +174,6 @@ extern def random() at io: Double =
|
|
|
183
174
|
%r = call double @c_io_random()
|
|
184
175
|
ret double %r
|
|
185
176
|
"""
|
|
186
|
-
vm "effekt::random()"
|
|
187
177
|
|
|
188
178
|
// References and state
|
|
189
179
|
// ====================
|
|
@@ -252,7 +242,6 @@ extern def infixEq(x: Int, y: Int) at {}: Bool =
|
|
|
252
242
|
%adt_boolean = insertvalue %Pos zeroinitializer, i64 %fat_z, 0
|
|
253
243
|
ret %Pos %adt_boolean
|
|
254
244
|
"""
|
|
255
|
-
vm "effekt::infixEq(Int, Int)"
|
|
256
245
|
|
|
257
246
|
extern def infixNeq(x: Int, y: Int) at {}: Bool =
|
|
258
247
|
js "${x} !== ${y}"
|
|
@@ -263,7 +252,6 @@ extern def infixNeq(x: Int, y: Int) at {}: Bool =
|
|
|
263
252
|
%adt_boolean = insertvalue %Pos zeroinitializer, i64 %fat_z, 0
|
|
264
253
|
ret %Pos %adt_boolean
|
|
265
254
|
"""
|
|
266
|
-
vm "effekt::infixNeq(Int, Int)"
|
|
267
255
|
|
|
268
256
|
extern def infixEq(x: Char, y: Char) at {}: Bool =
|
|
269
257
|
js "${x} === ${y}"
|
|
@@ -274,7 +262,6 @@ extern def infixEq(x: Char, y: Char) at {}: Bool =
|
|
|
274
262
|
%adt_boolean = insertvalue %Pos zeroinitializer, i64 %fat_z, 0
|
|
275
263
|
ret %Pos %adt_boolean
|
|
276
264
|
"""
|
|
277
|
-
vm "effekt::infixEq(Char, Char)"
|
|
278
265
|
|
|
279
266
|
extern def infixNeq(x: Char, y: Char) at {}: Bool =
|
|
280
267
|
js "${x} !== ${y}"
|
|
@@ -293,7 +280,6 @@ extern def infixEq(x: String, y: String) at {}: Bool =
|
|
|
293
280
|
%res = call %Pos @c_bytearray_equal(%Pos ${x}, %Pos ${y})
|
|
294
281
|
ret %Pos %res
|
|
295
282
|
"""
|
|
296
|
-
vm "effekt::infixEq(String, String)"
|
|
297
283
|
|
|
298
284
|
def infixNeq(x: String, y: String): Bool = not(x == y)
|
|
299
285
|
|
|
@@ -308,7 +294,6 @@ extern def infixEq(x: Bool, y: Bool) at {}: Bool =
|
|
|
308
294
|
%adt_boolean = insertvalue %Pos zeroinitializer, i64 %fat_z, 0
|
|
309
295
|
ret %Pos %adt_boolean
|
|
310
296
|
"""
|
|
311
|
-
vm "effekt::infixEq(Bool, Bool)"
|
|
312
297
|
|
|
313
298
|
extern def infixNeq(x: Bool, y: Bool) at {}: Bool =
|
|
314
299
|
js "${x} !== ${y}"
|
|
@@ -331,7 +316,6 @@ extern def infixEq(x: Byte, y: Byte) at {}: Bool =
|
|
|
331
316
|
%adt_boolean = insertvalue %Pos zeroinitializer, i64 %fat_z, 0
|
|
332
317
|
ret %Pos %adt_boolean
|
|
333
318
|
"""
|
|
334
|
-
vm "effekt::infixEq(Byte, Byte)"
|
|
335
319
|
|
|
336
320
|
extern def infixNeq(x: Byte, y: Byte) at {}: Bool =
|
|
337
321
|
js "${x} !== ${y}"
|
|
@@ -342,7 +326,6 @@ extern def infixNeq(x: Byte, y: Byte) at {}: Bool =
|
|
|
342
326
|
%adt_boolean = insertvalue %Pos zeroinitializer, i64 %fat_z, 0
|
|
343
327
|
ret %Pos %adt_boolean
|
|
344
328
|
"""
|
|
345
|
-
vm "effekt::infixNeq(Byte, Byte)"
|
|
346
329
|
|
|
347
330
|
// Math ops
|
|
348
331
|
// ========
|
|
@@ -350,85 +333,71 @@ extern def infixPlus(x: Int, y: Int) at {}: Int =
|
|
|
350
333
|
js "(${x} + ${y})"
|
|
351
334
|
chez "(+ ${x} ${y})"
|
|
352
335
|
llvm "%z = add %Int ${x}, ${y} ret %Int %z"
|
|
353
|
-
vm "effekt::infixPlus(Int, Int)"
|
|
354
336
|
|
|
355
337
|
extern def infixStar(x: Int, y: Int) at {}: Int =
|
|
356
338
|
js "(${x} * ${y})"
|
|
357
339
|
chez "(* ${x} ${y})"
|
|
358
340
|
llvm "%z = mul %Int ${x}, ${y} ret %Int %z"
|
|
359
|
-
vm "effekt::infixStar(Int, Int)"
|
|
360
341
|
|
|
361
342
|
extern def infixSlash(x: Int, y: Int) at {}: Int =
|
|
362
343
|
js "Math.floor(${x} / ${y})"
|
|
363
344
|
chez "(floor (/ ${x} ${y}))"
|
|
364
345
|
llvm "%z = sdiv %Int ${x}, ${y} ret %Int %z"
|
|
365
|
-
vm "effekt::infixSlash(Int, Int)"
|
|
366
346
|
|
|
367
347
|
extern def infixMinus(x: Int, y: Int) at {}: Int =
|
|
368
348
|
js "(${x} - ${y})"
|
|
369
349
|
chez "(- ${x} ${y})"
|
|
370
350
|
llvm "%z = sub %Int ${x}, ${y} ret %Int %z"
|
|
371
|
-
vm "effekt::infixMinus(Int, Int)"
|
|
372
351
|
|
|
373
352
|
extern def mod(x: Int, y: Int) at {}: Int =
|
|
374
353
|
js "(${x} % ${y})"
|
|
375
354
|
chez "(modulo ${x} ${y})"
|
|
376
355
|
llvm "%z = srem %Int ${x}, ${y} ret %Int %z"
|
|
377
|
-
vm "effekt::mod(Int, Int)"
|
|
378
356
|
|
|
379
357
|
extern def infixPlus(x: Double, y: Double) at {}: Double =
|
|
380
358
|
js "(${x} + ${y})"
|
|
381
359
|
chez "(+ ${x} ${y})"
|
|
382
360
|
llvm "%z = fadd %Double ${x}, ${y} ret %Double %z"
|
|
383
|
-
vm "effekt::infixPlus(Double, Double)"
|
|
384
361
|
|
|
385
362
|
extern def infixStar(x: Double, y: Double) at {}: Double =
|
|
386
363
|
js "(${x} * ${y})"
|
|
387
364
|
chez "(* ${x} ${y})"
|
|
388
365
|
llvm "%z = fmul %Double ${x}, ${y} ret %Double %z"
|
|
389
|
-
vm "effekt::infixStar(Double, Double)"
|
|
390
366
|
|
|
391
367
|
extern def infixMinus(x: Double, y: Double) at {}: Double =
|
|
392
368
|
js "(${x} - ${y})"
|
|
393
369
|
chez "(- ${x} ${y})"
|
|
394
370
|
llvm "%z = fsub %Double ${x}, ${y} ret %Double %z"
|
|
395
|
-
vm "effekt::infixMinus(Double, Double)"
|
|
396
371
|
|
|
397
372
|
extern def infixSlash(x: Double, y: Double) at {}: Double =
|
|
398
373
|
js "(${x} / ${y})"
|
|
399
374
|
chez "(fl/ ${x} ${y})"
|
|
400
375
|
llvm "%z = fdiv %Double ${x}, ${y} ret %Double %z"
|
|
401
|
-
vm "effekt::infixSlash(Double, Double)"
|
|
402
376
|
|
|
403
377
|
extern def cos(x: Double) at {}: Double =
|
|
404
378
|
js "Math.cos(${x})"
|
|
405
379
|
chez "(cos ${x})"
|
|
406
|
-
vm "effekt::cos(Double)"
|
|
407
380
|
llvm "%z = call %Double @llvm.cos.f64(double ${x}) ret %Double %z"
|
|
408
381
|
|
|
409
382
|
extern def sin(x: Double) at {}: Double =
|
|
410
383
|
js "Math.sin(${x})"
|
|
411
384
|
chez "(sin ${x})"
|
|
412
|
-
vm "effekt::sin(Double)"
|
|
413
385
|
llvm "%z = call %Double @llvm.sin.f64(double ${x}) ret %Double %z"
|
|
414
386
|
|
|
415
387
|
extern def atan(x: Double) at {}: Double =
|
|
416
388
|
js "Math.atan(${x})"
|
|
417
389
|
chez "(atan ${x})"
|
|
418
|
-
vm "effekt::atan(Double)"
|
|
419
390
|
llvm "%z = call %Double @atan(double ${x}) ret %Double %z"
|
|
420
391
|
|
|
421
392
|
extern def tan(x: Double) at {}: Double =
|
|
422
393
|
js "Math.tan(${x})"
|
|
423
394
|
chez "(tan ${x})"
|
|
424
|
-
vm "effekt::tan(Double)"
|
|
425
395
|
llvm "%z = call %Double @tan(double ${x}) ret %Double %z"
|
|
426
396
|
|
|
427
397
|
extern def sqrt(x: Double) at {}: Double =
|
|
428
398
|
js "Math.sqrt(${x})"
|
|
429
399
|
chez "(sqrt ${x})"
|
|
430
400
|
llvm "%z = call %Double @llvm.sqrt.f64(double ${x}) ret %Double %z"
|
|
431
|
-
vm "effekt::sqrt(Double)"
|
|
432
401
|
|
|
433
402
|
def square(x: Double): Double = x * x
|
|
434
403
|
|
|
@@ -447,7 +416,6 @@ def abs(n: Double): Double =
|
|
|
447
416
|
extern def log(x: Double) at {}: Double =
|
|
448
417
|
js "Math.log(${x})"
|
|
449
418
|
chez "(log ${x})"
|
|
450
|
-
vm "effekt::log(Double)"
|
|
451
419
|
llvm "%z = call %Double @llvm.log.f64(double ${x}) ret %Double %z"
|
|
452
420
|
|
|
453
421
|
extern def log1p(x: Double) at {}: Double =
|
|
@@ -458,7 +426,6 @@ extern def log1p(x: Double) at {}: Double =
|
|
|
458
426
|
extern def exp(x: Double) at {}: Double =
|
|
459
427
|
js "Math.exp(${x})"
|
|
460
428
|
chez "(exp ${x})"
|
|
461
|
-
vm "effekt::exp(Double)"
|
|
462
429
|
llvm "%z = call %Double @llvm.exp.f64(double ${x}) ret %Double %z"
|
|
463
430
|
|
|
464
431
|
def pow(base: Double, exponent: Int): Double = {
|
|
@@ -477,14 +444,12 @@ def pow(base: Double, exponent: Int): Double = {
|
|
|
477
444
|
extern def pow(base: Double, exponent: Double) at {}: Double =
|
|
478
445
|
js "Math.pow(${base}, ${exponent})"
|
|
479
446
|
chez "(expt ${base} ${exponent})"
|
|
480
|
-
vm "effekt::pow(Double, Double)"
|
|
481
447
|
llvm "%z = call %Double @llvm.pow.f64(double ${base}, double ${exponent}) ret %Double %z"
|
|
482
448
|
|
|
483
449
|
// since we do not have "extern val", yet
|
|
484
450
|
extern def _pi() at {}: Double =
|
|
485
451
|
js "Math.PI"
|
|
486
452
|
chez "(* 4 (atan 1))"
|
|
487
|
-
vm "effekt::pi()"
|
|
488
453
|
llvm "ret double 3.14159265358979323846264338327950288419716939937510582097494459"
|
|
489
454
|
|
|
490
455
|
val PI: Double = _pi()
|
|
@@ -493,13 +458,11 @@ extern def toInt(d: Double) at {}: Int =
|
|
|
493
458
|
js "Math.trunc(${d})"
|
|
494
459
|
chez "(flonum->fixnum ${d})"
|
|
495
460
|
llvm "%z = fptosi double ${d} to %Int ret %Int %z"
|
|
496
|
-
vm "effekt::toInt(Double)"
|
|
497
461
|
|
|
498
462
|
extern def toDouble(d: Int) at {}: Double =
|
|
499
463
|
js "${d}"
|
|
500
464
|
chez "(fixnum->flonum ${d})"
|
|
501
465
|
llvm "%z = sitofp i64 ${d} to double ret double %z"
|
|
502
|
-
vm "effekt::toDouble(Int)"
|
|
503
466
|
|
|
504
467
|
|
|
505
468
|
extern def round(d: Double) at {}: Int =
|
|
@@ -509,7 +472,6 @@ extern def round(d: Double) at {}: Int =
|
|
|
509
472
|
%i = call %Double @llvm.round.f64(double ${d})
|
|
510
473
|
%z = fptosi double %i to %Int ret %Int %z
|
|
511
474
|
"""
|
|
512
|
-
vm "effekt::round(Double)"
|
|
513
475
|
|
|
514
476
|
def round(d: Double, digits: Int): Double = {
|
|
515
477
|
val factor = pow(10.0, digits)
|
|
@@ -554,7 +516,6 @@ extern def infixLt(x: Int, y: Int) at {}: Bool =
|
|
|
554
516
|
%adt_boolean = insertvalue %Pos zeroinitializer, i64 %fat_z, 0
|
|
555
517
|
ret %Pos %adt_boolean
|
|
556
518
|
"""
|
|
557
|
-
vm "effekt::infixLt(Int, Int)"
|
|
558
519
|
|
|
559
520
|
extern def infixLte(x: Int, y: Int) at {}: Bool =
|
|
560
521
|
js "(${x} <= ${y})"
|
|
@@ -565,7 +526,6 @@ extern def infixLte(x: Int, y: Int) at {}: Bool =
|
|
|
565
526
|
%adt_boolean = insertvalue %Pos zeroinitializer, i64 %fat_z, 0
|
|
566
527
|
ret %Pos %adt_boolean
|
|
567
528
|
"""
|
|
568
|
-
vm "effekt::infixLte(Int, Int)"
|
|
569
529
|
|
|
570
530
|
extern def infixGt(x: Int, y: Int) at {}: Bool =
|
|
571
531
|
js "(${x} > ${y})"
|
|
@@ -576,7 +536,6 @@ extern def infixGt(x: Int, y: Int) at {}: Bool =
|
|
|
576
536
|
%adt_boolean = insertvalue %Pos zeroinitializer, i64 %fat_z, 0
|
|
577
537
|
ret %Pos %adt_boolean
|
|
578
538
|
"""
|
|
579
|
-
vm "effekt::infixGt(Int, Int)"
|
|
580
539
|
|
|
581
540
|
extern def infixGte(x: Int, y: Int) at {}: Bool =
|
|
582
541
|
js "(${x} >= ${y})"
|
|
@@ -587,17 +546,14 @@ extern def infixGte(x: Int, y: Int) at {}: Bool =
|
|
|
587
546
|
%adt_boolean = insertvalue %Pos zeroinitializer, i64 %fat_z, 0
|
|
588
547
|
ret %Pos %adt_boolean
|
|
589
548
|
"""
|
|
590
|
-
vm "effekt::infixGte(Int, Int)"
|
|
591
549
|
|
|
592
550
|
extern def infixEq(x: Double, y: Double) at {}: Bool =
|
|
593
551
|
js "${x} === ${y}"
|
|
594
552
|
chez "(= ${x} ${y})"
|
|
595
|
-
vm "effekt::infixEq(Double, Double)"
|
|
596
553
|
|
|
597
554
|
extern def infixNeq(x: Double, y: Double) at {}: Bool =
|
|
598
555
|
js "${x} !== ${y}"
|
|
599
556
|
chez "(not (= ${x} ${y}))"
|
|
600
|
-
vm "effekt::infixNeq(Double, Double)"
|
|
601
557
|
|
|
602
558
|
extern def infixLt(x: Double, y: Double) at {}: Bool =
|
|
603
559
|
js "(${x} < ${y})"
|
|
@@ -608,12 +564,10 @@ extern def infixLt(x: Double, y: Double) at {}: Bool =
|
|
|
608
564
|
%adt_boolean = insertvalue %Pos zeroinitializer, i64 %fat_z, 0
|
|
609
565
|
ret %Pos %adt_boolean
|
|
610
566
|
"""
|
|
611
|
-
vm "effekt::infixLt(Double, Double)"
|
|
612
567
|
|
|
613
568
|
extern def infixLte(x: Double, y: Double) at {}: Bool =
|
|
614
569
|
js "(${x} <= ${y})"
|
|
615
570
|
chez "(<= ${x} ${y})"
|
|
616
|
-
vm "effekt::infixLte(Double, Double)"
|
|
617
571
|
|
|
618
572
|
extern def infixGt(x: Double, y: Double) at {}: Bool =
|
|
619
573
|
js "(${x} > ${y})"
|
|
@@ -624,12 +578,10 @@ extern def infixGt(x: Double, y: Double) at {}: Bool =
|
|
|
624
578
|
%adt_boolean = insertvalue %Pos zeroinitializer, i64 %fat_z, 0
|
|
625
579
|
ret %Pos %adt_boolean
|
|
626
580
|
"""
|
|
627
|
-
vm "effekt::infixGt(Double, Double)"
|
|
628
581
|
|
|
629
582
|
extern def infixGte(x: Double, y: Double) at {}: Bool =
|
|
630
583
|
js "(${x} >= ${y})"
|
|
631
584
|
chez "(>= ${x} ${y})"
|
|
632
|
-
vm "effekt::infixGte(Double, Double)"
|
|
633
585
|
|
|
634
586
|
// TODO do we really need those? if yes, move to string.effekt
|
|
635
587
|
extern def infixLt(x: String, y: String) at {}: Bool =
|
|
@@ -660,7 +612,6 @@ extern def not(b: Bool) at {}: Bool =
|
|
|
660
612
|
%adt_q = insertvalue %Pos zeroinitializer, i64 %q, 0
|
|
661
613
|
ret %Pos %adt_q
|
|
662
614
|
"""
|
|
663
|
-
vm "effekt::not(Bool)"
|
|
664
615
|
|
|
665
616
|
def infixBarBar { first: => Bool } { second: => Bool }: Bool =
|
|
666
617
|
if (first()) true else second()
|
|
@@ -677,38 +628,32 @@ extern def bitwiseShl(x: Int, y: Int) at {}: Int =
|
|
|
677
628
|
js "(${x} << ${y})"
|
|
678
629
|
chez "(ash ${x} ${y})"
|
|
679
630
|
llvm "%z = shl %Int ${x}, ${y} ret %Int %z"
|
|
680
|
-
vm "effekt::bitwiseShl(Int, Int)"
|
|
681
631
|
|
|
682
632
|
/// Arithmetic right shift
|
|
683
633
|
extern def bitwiseShr(x: Int, y: Int) at {}: Int =
|
|
684
634
|
js "(${x} >> ${y})"
|
|
685
635
|
chez "(ash ${x} (- ${y}))"
|
|
686
636
|
llvm "%z = ashr %Int ${x}, ${y} ret %Int %z"
|
|
687
|
-
vm "effekt::bitwiseShr(Int, Int)"
|
|
688
637
|
|
|
689
638
|
extern def bitwiseAnd(x: Int, y: Int) at {}: Int =
|
|
690
639
|
js "(${x} & ${y})"
|
|
691
640
|
chez "(logand ${x} ${y})"
|
|
692
641
|
llvm "%z = and %Int ${x}, ${y} ret %Int %z"
|
|
693
|
-
vm "effekt::bitwiseAnd(Int, Int)"
|
|
694
642
|
|
|
695
643
|
extern def bitwiseOr(x: Int, y: Int) at {}: Int =
|
|
696
644
|
js "(${x} | ${y})"
|
|
697
645
|
chez "(logior ${x} ${y})"
|
|
698
646
|
llvm "%z = or %Int ${x}, ${y} ret %Int %z"
|
|
699
|
-
vm "effekt::bitwiseOr(Int, Int)"
|
|
700
647
|
|
|
701
648
|
extern def bitwiseXor(x: Int, y: Int) at {}: Int =
|
|
702
649
|
js "(${x} ^ ${y})"
|
|
703
650
|
chez "(logxor ${x} ${y})"
|
|
704
651
|
llvm "%z = xor %Int ${x}, ${y} ret %Int %z"
|
|
705
|
-
vm "effekt::bitwiseXor(Int, Int)"
|
|
706
652
|
|
|
707
653
|
extern def bitwiseNot(x: Int) at {}: Int =
|
|
708
654
|
js "(~${x})"
|
|
709
655
|
chez "(lognot ${x})"
|
|
710
656
|
llvm "%z = xor %Int ${x}, -1 ret %Int %z"
|
|
711
|
-
vm "effekt::bitwiseNot(Int)"
|
|
712
657
|
|
|
713
658
|
|
|
714
659
|
// Byte operations
|
|
@@ -721,7 +666,6 @@ extern def toByte(n: Int) at {}: Byte =
|
|
|
721
666
|
extern def toInt(n: Byte) at {}: Int =
|
|
722
667
|
js "${n}"
|
|
723
668
|
llvm "%z = zext %Byte ${n} to %Int ret %Int %z"
|
|
724
|
-
vm "effekt::toInt(Byte)"
|
|
725
669
|
chez "${n}"
|
|
726
670
|
|
|
727
671
|
|
|
@@ -738,14 +682,21 @@ extern def toInt(n: Byte) at {}: Int =
|
|
|
738
682
|
extern def undefined[A]() at {}: A =
|
|
739
683
|
js "undefined"
|
|
740
684
|
chez "#f"
|
|
741
|
-
vm "effekt::undefined()"
|
|
742
685
|
|
|
743
686
|
/// Is an FFI value undefined?
|
|
744
687
|
extern def isUndefined[A](value: A) at {}: Bool =
|
|
745
688
|
js "(${value} === undefined || ${value} === null)"
|
|
746
689
|
chez "(eq? ${value} #f)"
|
|
747
|
-
vm "effekt::isUndefined[A](A)"
|
|
748
690
|
|
|
691
|
+
// Ascription
|
|
692
|
+
// ==========
|
|
693
|
+
|
|
694
|
+
/// Ascribe a type, for example `f().as[Int]`.
|
|
695
|
+
def as[A](x: A): A = x
|
|
696
|
+
|
|
697
|
+
/// Witness absurdity, for example `f().absurd`.
|
|
698
|
+
/// Very often the type argument is inferred.
|
|
699
|
+
def absurd[A](x: Nothing): A = x match {}
|
|
749
700
|
|
|
750
701
|
// Tuples
|
|
751
702
|
// ======
|
|
@@ -832,4 +783,10 @@ effect write(s: String): Unit
|
|
|
832
783
|
|
|
833
784
|
effect splice[A](x: A): Unit
|
|
834
785
|
|
|
786
|
+
// Source positions
|
|
787
|
+
// ================
|
|
788
|
+
//
|
|
789
|
+
// When adding an implicit value argument ?sourcePosition of this type, will have the information
|
|
790
|
+
// of the call site unless passed explicitly.
|
|
835
791
|
|
|
792
|
+
record SourcePosition(file: String, startLine: Int, startColumn: Int, endLine: Int, endColumn: Int)
|
|
@@ -33,7 +33,7 @@ def send[A, B](sender: Sender[A, B], value: A): B = {
|
|
|
33
33
|
sender.set(rest)
|
|
34
34
|
// TODO avoid yield
|
|
35
35
|
yield()
|
|
36
|
-
this.
|
|
36
|
+
this.fire(value)
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
/// Receives a value from a channel and blocks until a sender arrives.
|
|
@@ -51,7 +51,7 @@ def receive[A, B](receiver: Receiver[A, B], value: B): A = {
|
|
|
51
51
|
receiver.set(rest)
|
|
52
52
|
// TODO avoid yield
|
|
53
53
|
yield()
|
|
54
|
-
this.
|
|
54
|
+
this.wait(value)
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
// TODO streaming
|
|
@@ -74,8 +74,8 @@ def appendFile(path: String, contents: String): Unit / Exception[IOError] = {
|
|
|
74
74
|
def writeFileUTF8[R](path: String) { stream: () => R / emit[Char] }: R / Exception[IOError] =
|
|
75
75
|
writeFile(path) { encodeUTF8 { stream() } }
|
|
76
76
|
|
|
77
|
-
def readFileUTF8[R](path: String) {
|
|
78
|
-
readFile(path) { decodeUTF8 {
|
|
77
|
+
def readFileUTF8[R](path: String) { driver: () => R / next[Char] }: R / Exception[IOError] =
|
|
78
|
+
readFile(path) { decodeUTF8 { driver() } }
|
|
79
79
|
|
|
80
80
|
def writeFile[R](path: String) { stream: () => R / emit[Byte] }: R / Exception[IOError] = {
|
|
81
81
|
|
|
@@ -108,7 +108,7 @@ def writeFile[R](path: String) { stream: () => R / emit[Byte] }: R / Exception[I
|
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
def readFile[R](path: String) {
|
|
111
|
+
def readFile[R](path: String) { driver: () => R / next[Byte] }: R / Exception[IOError] = {
|
|
112
112
|
|
|
113
113
|
val file = openForReading(path);
|
|
114
114
|
with on[IOError].finalize { close(file) }
|
|
@@ -128,8 +128,8 @@ def readFile[R](path: String) { reader: () => R / read[Byte] }: R / Exception[IO
|
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
try {
|
|
131
|
-
|
|
132
|
-
} with
|
|
131
|
+
driver()
|
|
132
|
+
} with next[Byte] {
|
|
133
133
|
resume {
|
|
134
134
|
if (offset >= length) {
|
|
135
135
|
pull()
|
|
@@ -42,13 +42,13 @@ def listen(listener: Listener, handler: Connection => Unit at {io, async, global
|
|
|
42
42
|
def shutdown(listener: Listener): Unit =
|
|
43
43
|
internal::shutdown(listener)
|
|
44
44
|
|
|
45
|
-
def streaming[R](connection: Connection) { program: () => R / {
|
|
45
|
+
def streaming[R](connection: Connection) { program: () => R / {next[ByteArray], emit[ByteArray]} }: R / Exception[IOError] =
|
|
46
46
|
try {
|
|
47
47
|
program()
|
|
48
48
|
} with emit[ByteArray] { bytes =>
|
|
49
49
|
write(connection, bytes, 0, bytes.size)
|
|
50
50
|
resume(())
|
|
51
|
-
} with
|
|
51
|
+
} with next[ByteArray] { () =>
|
|
52
52
|
val bytes = bytearray::allocate(4096)
|
|
53
53
|
read(connection, bytes, 0, bytes.size) match {
|
|
54
54
|
case r and r == bytes.size => resume { return bytes }
|
|
@@ -37,7 +37,7 @@ def await[T](promise: Promise[T]): T =
|
|
|
37
37
|
val signal = signal()
|
|
38
38
|
promise.set(Pending(Cons(signal, signals)))
|
|
39
39
|
// TODO perhaps yield to avoid stack overflow
|
|
40
|
-
signal.
|
|
40
|
+
signal.wait(())
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
/// Resolves the given promise, unblocking all awaiting tasks.
|
|
@@ -48,6 +48,6 @@ def resolve[T](promise: Promise[T], value: T): Unit =
|
|
|
48
48
|
case Pending(signals) =>
|
|
49
49
|
promise.set(Resolved(value))
|
|
50
50
|
// TODO perhaps yield to avoid stack overflow
|
|
51
|
-
signals.reverse.foreach { signal =>
|
|
51
|
+
signals.reverse.foreach { signal => fire(signal, value) }
|
|
52
52
|
}
|
|
53
53
|
|
|
@@ -5,32 +5,29 @@ module io/signal
|
|
|
5
5
|
|
|
6
6
|
/// Must be fired exactly once with an A receiving a B,
|
|
7
7
|
/// and must be waited for exactly once with a B receiving an A.
|
|
8
|
-
extern type Signal[A, B]
|
|
8
|
+
extern type Signal[A, B] =
|
|
9
|
+
js "{ state: int, value, stack }"
|
|
10
|
+
llvm "%Pos"
|
|
9
11
|
|
|
10
|
-
extern
|
|
11
|
-
|
|
12
|
-
llvm """
|
|
13
|
-
%signal = call %Pos @c_signal_make()
|
|
14
|
-
ret %Pos %signal
|
|
15
|
-
"""
|
|
12
|
+
extern llvm """
|
|
13
|
+
%Signal = type { %Header, i64, ptr, %Pos }
|
|
16
14
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
define void @signal_erase(ptr %envPtr) {
|
|
16
|
+
%base = getelementptr %Header, ptr %envPtr, i64 -1
|
|
17
|
+
%statePtr = getelementptr %Signal, ptr %base, i64 0, i32 1
|
|
18
|
+
%stackPtr = getelementptr %Signal, ptr %base, i64 0, i32 2
|
|
19
|
+
%valuePtr = getelementptr %Signal, ptr %base, i64 0, i32 3
|
|
20
|
+
%state = load i64, ptr %statePtr
|
|
21
|
+
switch i64 %state, label %none [i64 0, label %free i64 1, label %free i64 2, label %free]
|
|
22
|
+
free:
|
|
23
|
+
%stack = load %Stack, ptr %stackPtr
|
|
24
|
+
%value = load %Pos, ptr %valuePtr
|
|
25
|
+
call void @erasePositive(%Pos %value)
|
|
26
|
+
call void @eraseStack(%Stack %stack)
|
|
21
27
|
ret void
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
extern def unsafeWait[A, B](signal: Signal[A, B], value: B) at async: A =
|
|
25
|
-
js "$effekt.capture(callback => signal$notify(${signal}, ${value}, callback))"
|
|
26
|
-
llvm """
|
|
27
|
-
call void @c_signal_notify(%Pos ${signal}, %Pos ${value}, %Stack %stack)
|
|
28
|
+
none:
|
|
28
29
|
ret void
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
extern llvm """
|
|
32
|
-
declare %Pos @c_signal_make()
|
|
33
|
-
declare void @c_signal_notify(%Pos, %Pos, %Stack)
|
|
30
|
+
}
|
|
34
31
|
"""
|
|
35
32
|
|
|
36
33
|
extern js """
|
|
@@ -53,3 +50,70 @@ extern js """
|
|
|
53
50
|
}
|
|
54
51
|
}
|
|
55
52
|
"""
|
|
53
|
+
|
|
54
|
+
extern def signal[A, B]() at global: Signal[A, B] =
|
|
55
|
+
js "signal$make()"
|
|
56
|
+
llvm """
|
|
57
|
+
%base = call ptr @calloc(i64 1, i64 48)
|
|
58
|
+
%eraserPtr = getelementptr %Signal, ptr %base, i64 0, i32 0, i32 1
|
|
59
|
+
store ptr @signal_erase, ptr %eraserPtr
|
|
60
|
+
%result = insertvalue %Pos { i64 0, ptr poison }, ptr %base, 1
|
|
61
|
+
ret %Pos %result
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
extern def fire[A, B](signal: Signal[A, B], value: A) at async: B =
|
|
65
|
+
js "$effekt.capture(callback => signal$notify(${signal}, ${value}, callback))"
|
|
66
|
+
llvm """
|
|
67
|
+
%base = extractvalue %Pos ${signal}, 1
|
|
68
|
+
%statePtr = getelementptr %Signal, ptr %base, i64 0, i32 1
|
|
69
|
+
%stackPtr = getelementptr %Signal, ptr %base, i64 0, i32 2
|
|
70
|
+
%valuePtr = getelementptr %Signal, ptr %base, i64 0, i32 3
|
|
71
|
+
%state = load i64, ptr %statePtr
|
|
72
|
+
switch i64 %state, label %panic [i64 0, label %init i64 1, label %fire]
|
|
73
|
+
init:
|
|
74
|
+
store i64 2, ptr %statePtr
|
|
75
|
+
store %Stack %stack, ptr %stackPtr
|
|
76
|
+
store %Pos ${value}, ptr %valuePtr
|
|
77
|
+
call void @erasePositive(%Pos ${signal})
|
|
78
|
+
ret void
|
|
79
|
+
fire:
|
|
80
|
+
%otherStack = load %Stack, ptr %stackPtr
|
|
81
|
+
%otherValue = load %Pos, ptr %valuePtr
|
|
82
|
+
store i64 3, ptr %statePtr
|
|
83
|
+
call void @erasePositive(%Pos ${signal})
|
|
84
|
+
call void @resume_Pos(%Stack %otherStack, %Pos ${value})
|
|
85
|
+
call void @resume_Pos(%Stack %stack, %Pos %otherValue)
|
|
86
|
+
ret void
|
|
87
|
+
panic:
|
|
88
|
+
call void @exit(i64 1)
|
|
89
|
+
ret void
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
extern def wait[A, B](signal: Signal[A, B], value: B) at async: A =
|
|
93
|
+
js "$effekt.capture(callback => signal$notify(${signal}, ${value}, callback))"
|
|
94
|
+
llvm """
|
|
95
|
+
%base = extractvalue %Pos ${signal}, 1
|
|
96
|
+
%statePtr = getelementptr %Signal, ptr %base, i64 0, i32 1
|
|
97
|
+
%stackPtr = getelementptr %Signal, ptr %base, i64 0, i32 2
|
|
98
|
+
%valuePtr = getelementptr %Signal, ptr %base, i64 0, i32 3
|
|
99
|
+
%state = load i64, ptr %statePtr
|
|
100
|
+
switch i64 %state, label %panic [i64 0, label %init i64 2, label %wait]
|
|
101
|
+
init:
|
|
102
|
+
store i64 1, ptr %statePtr
|
|
103
|
+
store %Stack %stack, ptr %stackPtr
|
|
104
|
+
store %Pos ${value}, ptr %valuePtr
|
|
105
|
+
call void @erasePositive(%Pos ${signal})
|
|
106
|
+
ret void
|
|
107
|
+
wait:
|
|
108
|
+
%otherStack = load %Stack, ptr %stackPtr
|
|
109
|
+
%otherValue = load %Pos, ptr %valuePtr
|
|
110
|
+
store i64 3, ptr %statePtr
|
|
111
|
+
call void @erasePositive(%Pos ${signal})
|
|
112
|
+
call void @resume_Pos(%Stack %otherStack, %Pos ${value})
|
|
113
|
+
call void @resume_Pos(%Stack %stack, %Pos %otherValue)
|
|
114
|
+
ret void
|
|
115
|
+
panic:
|
|
116
|
+
call void @exit(i64 1)
|
|
117
|
+
ret void
|
|
118
|
+
"""
|
|
119
|
+
|