@effekt-lang/effekt 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -18
- package/bin/effekt +0 -0
- package/libraries/common/args.effekt +0 -27
- package/libraries/common/array.effekt +34 -63
- package/libraries/common/bench.effekt +40 -22
- package/libraries/common/buffer.effekt +8 -20
- package/libraries/common/bytes.effekt +5 -15
- package/libraries/common/dequeue.effekt +5 -5
- package/libraries/common/effekt.effekt +51 -92
- package/libraries/common/exception.effekt +0 -1
- package/libraries/common/io/console.effekt +30 -36
- package/libraries/common/io/error.effekt +131 -30
- package/libraries/common/io/filesystem.effekt +262 -0
- package/libraries/common/io/network.effekt +30 -54
- package/libraries/common/io/time.effekt +9 -12
- package/libraries/common/io.effekt +54 -124
- package/libraries/common/list.effekt +345 -327
- package/libraries/common/process.effekt +0 -1
- package/libraries/common/queue.effekt +1 -3
- package/libraries/common/ref.effekt +11 -24
- package/libraries/common/result.effekt +6 -14
- package/libraries/common/seq.effekt +28 -49
- package/libraries/common/string/tty.effekt +66 -0
- package/libraries/common/string.effekt +7 -49
- package/libraries/common/test.effekt +96 -34
- package/libraries/js/unsafe/cont.effekt +1 -1
- package/libraries/llvm/io.c +258 -378
- package/libraries/llvm/main.c +3 -0
- package/libraries/llvm/rts.ll +57 -38
- package/libraries/llvm/types.c +10 -1
- package/licenses/eclipse public license, version 2.0 - epl-2.0.html +4 -4
- package/licenses/mit license - mit-license.html +21 -20
- package/licenses/the bsd license - bsd-license.html +20 -21
- package/licenses/the mit license - mit.html +22 -21
- package/package.json +1 -1
- package/libraries/chez/lift/effekt.ss +0 -118
- package/libraries/common/io/files.effekt +0 -282
- package/libraries/js/io.js +0 -143
- package/libraries/llvm/io.ll +0 -19
- package/libraries/ml/effekt.sml +0 -65
- package/libraries/ml/internal/mllist.effekt +0 -9
- package/libraries/ml/internal/mloption.effekt +0 -18
- package/libraries/ml/random.effekt +0 -85
- package/libraries/ml/text/regex.effekt +0 -102
|
@@ -30,10 +30,6 @@ namespace chez {
|
|
|
30
30
|
extern include chezMonadic "../chez/monadic/effekt.ss"
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
namespace ml {
|
|
34
|
-
extern include ml "../ml/effekt.sml"
|
|
35
|
-
}
|
|
36
|
-
|
|
37
33
|
namespace llvm {
|
|
38
34
|
extern include llvm "../llvm/rts.ll"
|
|
39
35
|
extern include llvm "../llvm/forward-declare-c.ll"
|
|
@@ -49,10 +45,6 @@ extern def println(value: String): Unit =
|
|
|
49
45
|
call void @c_io_println_String(%Pos ${value})
|
|
50
46
|
ret %Pos zeroinitializer ; Unit
|
|
51
47
|
"""
|
|
52
|
-
ml { print(value); print("\n") }
|
|
53
|
-
|
|
54
|
-
extern io def print(value: String): Unit =
|
|
55
|
-
ml "print ${value}"
|
|
56
48
|
|
|
57
49
|
def println(value: Int): Unit = println(value.show)
|
|
58
50
|
def println(value: Unit): Unit = println(value.show)
|
|
@@ -63,7 +55,6 @@ def println(value: Byte): Unit = println(value.show)
|
|
|
63
55
|
extern pure def show(value: Int): String =
|
|
64
56
|
js "'' + ${value}"
|
|
65
57
|
chez "(show-number ${value})"
|
|
66
|
-
ml "show'int ${value}"
|
|
67
58
|
llvm """
|
|
68
59
|
%z = call %Pos @c_buffer_show_Int(%Int ${value})
|
|
69
60
|
ret %Pos %z
|
|
@@ -74,7 +65,6 @@ def show(value: Unit): String = "()"
|
|
|
74
65
|
extern pure def show(value: Double): String =
|
|
75
66
|
js "'' + ${value}"
|
|
76
67
|
chez "(show-number ${value})"
|
|
77
|
-
ml "show'real ${value}"
|
|
78
68
|
llvm """
|
|
79
69
|
%z = call %Pos @c_buffer_show_Double(%Double ${value})
|
|
80
70
|
ret %Pos %z
|
|
@@ -89,7 +79,6 @@ def show(value: Bool): String =
|
|
|
89
79
|
extern pure def show(value: Char): String =
|
|
90
80
|
js "String.fromCodePoint(${value})"
|
|
91
81
|
chez "(string (integer->char ${value}))"
|
|
92
|
-
ml "str (chr ${value})"
|
|
93
82
|
llvm """
|
|
94
83
|
%z = call %Pos @c_buffer_show_Char(%Int ${value})
|
|
95
84
|
ret %Pos %z
|
|
@@ -115,7 +104,6 @@ extern io def inspect[R](value: R): Unit =
|
|
|
115
104
|
extern pure def infixConcat(s1: String, s2: String): String =
|
|
116
105
|
js "((${s1}) + (${s2}))"
|
|
117
106
|
chez "(string-append ${s1} ${s2})"
|
|
118
|
-
ml "${s1} ^ ${s2}"
|
|
119
107
|
llvm """
|
|
120
108
|
%spz = call %Pos @c_buffer_concatenate(%Pos ${s1}, %Pos ${s2})
|
|
121
109
|
ret %Pos %spz
|
|
@@ -124,7 +112,6 @@ extern pure def infixConcat(s1: String, s2: String): String =
|
|
|
124
112
|
extern pure def length(str: String): Int =
|
|
125
113
|
js "${str}.length"
|
|
126
114
|
chez "(string-length ${str})"
|
|
127
|
-
ml "String.size ${str}"
|
|
128
115
|
llvm """
|
|
129
116
|
%x = call %Int @c_buffer_length(%Pos ${str})
|
|
130
117
|
call void @erasePositive(%Pos ${str})
|
|
@@ -134,7 +121,6 @@ extern pure def length(str: String): Int =
|
|
|
134
121
|
extern pure def unsafeSubstring(str: String, from: Int, to: Int): String =
|
|
135
122
|
js "${str}.substring(${from}, ${to})"
|
|
136
123
|
chez "(substring ${str} ${from} ${to})" // potentially raises: "Exception in substring: ..."
|
|
137
|
-
ml "String.extract (${str}, ${from}, SOME (${to} - ${from}))"
|
|
138
124
|
llvm """
|
|
139
125
|
%x = call %Pos @c_buffer_substring(%Pos ${str}, i64 ${from}, i64 ${to})
|
|
140
126
|
ret %Pos %x
|
|
@@ -147,7 +133,6 @@ extern pure def unsafeSubstring(str: String, from: Int, to: Int): String =
|
|
|
147
133
|
extern io def random(): Double =
|
|
148
134
|
js "Math.random()"
|
|
149
135
|
chez "(random 1.0)"
|
|
150
|
-
ml "mlRandomReal ()"
|
|
151
136
|
|
|
152
137
|
// References and state
|
|
153
138
|
// ====================
|
|
@@ -159,13 +144,12 @@ extern io def random(): Double =
|
|
|
159
144
|
|
|
160
145
|
// Equality
|
|
161
146
|
// ========
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
*/
|
|
147
|
+
|
|
148
|
+
/// Result of comparison between two objects according to some order:
|
|
149
|
+
///
|
|
150
|
+
/// - `Less()` means that the first object is *before* the first in the order,
|
|
151
|
+
/// - `Equal()` means that the two objects are the same in the order,
|
|
152
|
+
/// - and `Greater()` means that the second object is *before* the first in the order.
|
|
169
153
|
type Ordering {
|
|
170
154
|
Less();
|
|
171
155
|
Equal();
|
|
@@ -175,7 +159,8 @@ type Ordering {
|
|
|
175
159
|
extern pure def genericCompareImpl[R](x: R, y: R): Int =
|
|
176
160
|
js "$effekt.compare(${x}, ${y})"
|
|
177
161
|
|
|
178
|
-
|
|
162
|
+
/// Compares two values of the same type, returning an `Ordering`.
|
|
163
|
+
/// Only available on the JavaScript backend.
|
|
179
164
|
def genericCompare[R](x: R, y: R): Ordering = {
|
|
180
165
|
genericCompareImpl(x, y) match {
|
|
181
166
|
case -1 => Less()
|
|
@@ -197,13 +182,10 @@ def println(o: Ordering): Unit = println(o.show)
|
|
|
197
182
|
// Comparison ops
|
|
198
183
|
// ==============
|
|
199
184
|
|
|
200
|
-
|
|
201
|
-
* Structural equality: Not available in the LLVM backend
|
|
202
|
-
*/
|
|
185
|
+
/// Structural equality: Not available in the LLVM backend
|
|
203
186
|
extern pure def equals[R](x: R, y: R): Bool =
|
|
204
187
|
js "$effekt.equals(${x}, ${y})"
|
|
205
188
|
chez "(equal? ${x} ${y})"
|
|
206
|
-
ml "${x} = ${y}"
|
|
207
189
|
|
|
208
190
|
def differsFrom[R](x: R, y: R): Bool =
|
|
209
191
|
not(equals(x, y))
|
|
@@ -212,12 +194,10 @@ def differsFrom[R](x: R, y: R): Bool =
|
|
|
212
194
|
extern pure def infixEq(x: Unit, y: Unit): Bool =
|
|
213
195
|
js "true"
|
|
214
196
|
chez "#t"
|
|
215
|
-
ml "true"
|
|
216
197
|
|
|
217
198
|
extern pure def infixEq(x: Int, y: Int): Bool =
|
|
218
199
|
js "${x} === ${y}"
|
|
219
200
|
chez "(equal? ${x} ${y})"
|
|
220
|
-
ml "${x} = ${y}"
|
|
221
201
|
llvm """
|
|
222
202
|
%z = icmp eq %Int ${x}, ${y}
|
|
223
203
|
%fat_z = zext i1 %z to i64
|
|
@@ -228,7 +208,6 @@ extern pure def infixEq(x: Int, y: Int): Bool =
|
|
|
228
208
|
extern pure def infixNeq(x: Int, y: Int): Bool =
|
|
229
209
|
js "${x} !== ${y}"
|
|
230
210
|
chez "(not (equal? ${x} ${y}))"
|
|
231
|
-
ml "${x} <> ${y}"
|
|
232
211
|
llvm """
|
|
233
212
|
%z = icmp ne %Int ${x}, ${y}
|
|
234
213
|
%fat_z = zext i1 %z to i64
|
|
@@ -239,7 +218,6 @@ extern pure def infixNeq(x: Int, y: Int): Bool =
|
|
|
239
218
|
extern pure def infixEq(x: Char, y: Char): Bool =
|
|
240
219
|
js "${x} === ${y}"
|
|
241
220
|
chez "(equal? ${x} ${y})"
|
|
242
|
-
ml "${x} = ${y}"
|
|
243
221
|
llvm """
|
|
244
222
|
%z = icmp eq %Int ${x}, ${y}
|
|
245
223
|
%fat_z = zext i1 %z to i64
|
|
@@ -250,7 +228,6 @@ extern pure def infixEq(x: Char, y: Char): Bool =
|
|
|
250
228
|
extern pure def infixNeq(x: Char, y: Char): Bool =
|
|
251
229
|
js "${x} !== ${y}"
|
|
252
230
|
chez "(not (equal? ${x} ${y}))"
|
|
253
|
-
ml "${x} <> ${y}"
|
|
254
231
|
llvm """
|
|
255
232
|
%z = icmp ne %Int ${x}, ${y}
|
|
256
233
|
%fat_z = zext i1 %z to i64
|
|
@@ -261,7 +238,6 @@ extern pure def infixNeq(x: Char, y: Char): Bool =
|
|
|
261
238
|
extern pure def infixEq(x: String, y: String): Bool =
|
|
262
239
|
js "${x} === ${y}"
|
|
263
240
|
chez "(equal? ${x} ${y})"
|
|
264
|
-
ml "${x} = ${y}"
|
|
265
241
|
llvm """
|
|
266
242
|
%res = call %Pos @c_buffer_eq(%Pos ${x}, %Pos ${y})
|
|
267
243
|
ret %Pos %res
|
|
@@ -272,7 +248,6 @@ def infixNeq(x: String, y: String): Bool = not(x == y)
|
|
|
272
248
|
extern pure def infixEq(x: Bool, y: Bool): Bool =
|
|
273
249
|
js "${x} === ${y}"
|
|
274
250
|
chez "(equal? ${x} ${y})"
|
|
275
|
-
ml "${x} = ${y}"
|
|
276
251
|
llvm """
|
|
277
252
|
%slim_x = extractvalue %Pos ${x}, 0
|
|
278
253
|
%slim_y = extractvalue %Pos ${y}, 0
|
|
@@ -285,7 +260,6 @@ extern pure def infixEq(x: Bool, y: Bool): Bool =
|
|
|
285
260
|
extern pure def infixNeq(x: Bool, y: Bool): Bool =
|
|
286
261
|
js "${x} !== ${y}"
|
|
287
262
|
chez "(not (equal? ${x} ${y}))"
|
|
288
|
-
ml "${x} <> ${y}"
|
|
289
263
|
llvm """
|
|
290
264
|
%slim_x = extractvalue %Pos ${x}, 0
|
|
291
265
|
%slim_y = extractvalue %Pos ${y}, 0
|
|
@@ -301,87 +275,69 @@ extern pure def infixNeq(x: Bool, y: Bool): Bool =
|
|
|
301
275
|
extern pure def infixAdd(x: Int, y: Int): Int =
|
|
302
276
|
js "(${x} + ${y})"
|
|
303
277
|
chez "(+ ${x} ${y})"
|
|
304
|
-
ml "(${x}: int) + ${y}"
|
|
305
278
|
llvm "%z = add %Int ${x}, ${y} ret %Int %z"
|
|
306
279
|
|
|
307
280
|
extern pure def infixMul(x: Int, y: Int): Int =
|
|
308
281
|
js "(${x} * ${y})"
|
|
309
282
|
chez "(* ${x} ${y})"
|
|
310
|
-
ml "(${x}: int) * ${y}"
|
|
311
283
|
llvm "%z = mul %Int ${x}, ${y} ret %Int %z"
|
|
312
284
|
|
|
313
285
|
extern pure def infixDiv(x: Int, y: Int): Int =
|
|
314
286
|
js "Math.floor(${x} / ${y})"
|
|
315
287
|
chez "(floor (/ ${x} ${y}))"
|
|
316
|
-
ml "(${x}: int) div ${y}"
|
|
317
288
|
llvm "%z = sdiv %Int ${x}, ${y} ret %Int %z"
|
|
318
289
|
|
|
319
290
|
extern pure def infixSub(x: Int, y: Int): Int =
|
|
320
291
|
js "(${x} - ${y})"
|
|
321
292
|
chez "(- ${x} ${y})"
|
|
322
|
-
ml "(${x}: int) - ${y}"
|
|
323
293
|
llvm "%z = sub %Int ${x}, ${y} ret %Int %z"
|
|
324
294
|
|
|
325
295
|
extern pure def mod(x: Int, y: Int): Int =
|
|
326
296
|
js "(${x} % ${y})"
|
|
327
297
|
chez "(modulo ${x} ${y})"
|
|
328
|
-
ml "(${x}: int) mod ${y}"
|
|
329
298
|
llvm "%z = srem %Int ${x}, ${y} ret %Int %z"
|
|
330
299
|
|
|
331
300
|
extern pure def infixAdd(x: Double, y: Double): Double =
|
|
332
301
|
js "(${x} + ${y})"
|
|
333
302
|
chez "(+ ${x} ${y})"
|
|
334
|
-
ml "(${x}: real) + ${y}"
|
|
335
303
|
llvm "%z = fadd %Double ${x}, ${y} ret %Double %z"
|
|
336
304
|
|
|
337
305
|
extern pure def infixMul(x: Double, y: Double): Double =
|
|
338
306
|
js "(${x} * ${y})"
|
|
339
307
|
chez "(* ${x} ${y})"
|
|
340
|
-
ml "(${x}: real) * ${y}"
|
|
341
308
|
llvm "%z = fmul %Double ${x}, ${y} ret %Double %z"
|
|
342
309
|
|
|
343
310
|
extern pure def infixSub(x: Double, y: Double): Double =
|
|
344
311
|
js "(${x} - ${y})"
|
|
345
312
|
chez "(- ${x} ${y})"
|
|
346
|
-
ml "(${x}: real) - ${y}"
|
|
347
313
|
llvm "%z = fsub %Double ${x}, ${y} ret %Double %z"
|
|
348
314
|
|
|
349
315
|
extern pure def infixDiv(x: Double, y: Double): Double =
|
|
350
316
|
js "(${x} / ${y})"
|
|
351
317
|
chez "(/ ${x} ${y})"
|
|
352
|
-
ml "(${x}: real) / ${y}"
|
|
353
318
|
llvm "%z = fdiv %Double ${x}, ${y} ret %Double %z"
|
|
354
319
|
|
|
355
320
|
extern pure def cos(x: Double): Double =
|
|
356
321
|
js "Math.cos(${x})"
|
|
357
322
|
chez "(cos ${x})"
|
|
358
|
-
ml "Math.cos ${x}"
|
|
359
323
|
|
|
360
324
|
extern pure def sin(x: Double): Double =
|
|
361
325
|
js "Math.sin(${x})"
|
|
362
326
|
chez "(sin ${x})"
|
|
363
|
-
ml "Math.sin ${x}"
|
|
364
327
|
|
|
365
328
|
extern pure def atan(x: Double): Double =
|
|
366
329
|
js "Math.atan(${x})"
|
|
367
330
|
chez "(atan ${x})"
|
|
368
|
-
ml "Math.atan ${x}"
|
|
369
331
|
|
|
370
332
|
extern pure def tan(x: Double): Double =
|
|
371
333
|
js "Math.tan(${x})"
|
|
372
334
|
chez "(tan ${x})"
|
|
373
|
-
ml "Math.tan ${x}"
|
|
374
335
|
|
|
375
336
|
extern pure def sqrt(x: Double): Double =
|
|
376
337
|
js "Math.sqrt(${x})"
|
|
377
338
|
chez "(sqrt ${x})"
|
|
378
|
-
ml "Math.sqrt ${x}"
|
|
379
339
|
llvm "%z = call %Double @llvm.sqrt.f64(double ${x}) ret %Double %z"
|
|
380
340
|
|
|
381
|
-
extern llvm """
|
|
382
|
-
declare double @llvm.sqrt.f64(double %x)
|
|
383
|
-
"""
|
|
384
|
-
|
|
385
341
|
def square(x: Double): Double = x * x
|
|
386
342
|
|
|
387
343
|
def neg(n: Double): Double =
|
|
@@ -396,52 +352,73 @@ def abs(n: Double): Double =
|
|
|
396
352
|
extern pure def log(x: Double): Double =
|
|
397
353
|
js "Math.log(${x})"
|
|
398
354
|
chez "(log ${x})"
|
|
399
|
-
ml "Math.ln ${x}"
|
|
400
355
|
|
|
401
356
|
extern pure def log1p(x: Double): Double =
|
|
402
357
|
js "Math.log1p(${x})"
|
|
403
358
|
chez "(log (+ ${x} 1))"
|
|
404
|
-
ml "Math.ln (${x} + 1.0)"
|
|
405
359
|
|
|
406
360
|
extern pure def exp(x: Double): Double =
|
|
407
361
|
js "Math.exp(${x})"
|
|
408
362
|
chez "(exp ${x})"
|
|
409
|
-
|
|
363
|
+
|
|
364
|
+
def pow(base: Double, exponent: Int): Double = {
|
|
365
|
+
def loop(base: Double, exponent: Int, acc: Double): Double = {
|
|
366
|
+
if (exponent == 0) acc
|
|
367
|
+
else if (exponent.mod(2) == 0) loop(base * base, exponent / 2, acc) // even exponent
|
|
368
|
+
else loop(base, exponent - 1, acc * base) // odd exponent
|
|
369
|
+
}
|
|
370
|
+
loop(base, exponent, 1.0)
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
extern pure def pow(base: Double, exponent: Double): Double =
|
|
374
|
+
js "Math.pow(${base}, ${exponent})"
|
|
375
|
+
chez "(expt ${base} ${exponent})"
|
|
410
376
|
|
|
411
377
|
// since we do not have "extern val", yet
|
|
412
378
|
extern pure def _pi(): Double =
|
|
413
379
|
js "Math.PI"
|
|
414
380
|
chez "(* 4 (atan 1))"
|
|
415
|
-
ml "Math.pi"
|
|
416
381
|
|
|
417
382
|
val PI: Double = _pi()
|
|
418
383
|
|
|
419
384
|
extern pure def toInt(d: Double): Int =
|
|
420
385
|
js "Math.trunc(${d})"
|
|
421
386
|
chez "(flonum->fixnum ${d})"
|
|
422
|
-
ml "Real.trunc ${d}"
|
|
423
387
|
llvm "%z = fptosi double ${d} to %Int ret %Int %z"
|
|
424
388
|
|
|
425
389
|
extern pure def toDouble(d: Int): Double =
|
|
426
390
|
js "${d}"
|
|
427
391
|
chez "${d}"
|
|
428
|
-
ml "Real.fromInt ${d}"
|
|
429
392
|
llvm "%z = sitofp i64 ${d} to double ret double %z"
|
|
430
393
|
|
|
431
394
|
extern pure def round(d: Double): Int =
|
|
432
395
|
js "Math.round(${d})"
|
|
433
396
|
chez "(round ${d})"
|
|
434
|
-
|
|
397
|
+
llvm """
|
|
398
|
+
%i = call %Double @llvm.round.f64(double ${d})
|
|
399
|
+
%z = fptosi double %i to %Int ret %Int %z
|
|
400
|
+
"""
|
|
401
|
+
|
|
402
|
+
def round(d: Double, digits: Int): Double = {
|
|
403
|
+
val factor = pow(10.0, digits)
|
|
404
|
+
round(d * factor).toDouble / factor
|
|
405
|
+
}
|
|
435
406
|
|
|
436
407
|
extern pure def floor(d: Double): Int =
|
|
437
408
|
js "Math.floor(${d})"
|
|
438
409
|
chez "(flonum->fixnum (floor ${d}))"
|
|
439
|
-
|
|
410
|
+
llvm """
|
|
411
|
+
%i = call %Double @llvm.floor.f64(double ${d})
|
|
412
|
+
%z = fptosi double %i to %Int ret %Int %z
|
|
413
|
+
"""
|
|
440
414
|
|
|
441
415
|
extern pure def ceil(d: Double): Int =
|
|
442
416
|
js "Math.ceil(${d})"
|
|
443
417
|
chez "(flonum->fixnum (ceiling ${d}))"
|
|
444
|
-
|
|
418
|
+
llvm """
|
|
419
|
+
%i = call %Double @llvm.ceil.f64(double ${d})
|
|
420
|
+
%z = fptosi double %i to %Int ret %Int %z
|
|
421
|
+
"""
|
|
445
422
|
|
|
446
423
|
def min(n: Int, m: Int): Int =
|
|
447
424
|
if (n < m) n else m
|
|
@@ -459,7 +436,6 @@ def abs(n: Int): Int =
|
|
|
459
436
|
extern pure def infixLt(x: Int, y: Int): Bool =
|
|
460
437
|
js "(${x} < ${y})"
|
|
461
438
|
chez "(< ${x} ${y})"
|
|
462
|
-
ml "(${x}: int) < ${y}"
|
|
463
439
|
llvm """
|
|
464
440
|
%z = icmp slt %Int ${x}, ${y}
|
|
465
441
|
%fat_z = zext i1 %z to i64
|
|
@@ -470,7 +446,6 @@ extern pure def infixLt(x: Int, y: Int): Bool =
|
|
|
470
446
|
extern pure def infixLte(x: Int, y: Int): Bool =
|
|
471
447
|
js "(${x} <= ${y})"
|
|
472
448
|
chez "(<= ${x} ${y})"
|
|
473
|
-
ml "(${x}: int) <= ${y}"
|
|
474
449
|
llvm """
|
|
475
450
|
%z = icmp sle %Int ${x}, ${y}
|
|
476
451
|
%fat_z = zext i1 %z to i64
|
|
@@ -481,7 +456,6 @@ extern pure def infixLte(x: Int, y: Int): Bool =
|
|
|
481
456
|
extern pure def infixGt(x: Int, y: Int): Bool =
|
|
482
457
|
js "(${x} > ${y})"
|
|
483
458
|
chez "(> ${x} ${y})"
|
|
484
|
-
ml "(${x}: int) > ${y}"
|
|
485
459
|
llvm """
|
|
486
460
|
%z = icmp sgt %Int ${x}, ${y}
|
|
487
461
|
%fat_z = zext i1 %z to i64
|
|
@@ -492,7 +466,6 @@ extern pure def infixGt(x: Int, y: Int): Bool =
|
|
|
492
466
|
extern pure def infixGte(x: Int, y: Int): Bool =
|
|
493
467
|
js "(${x} >= ${y})"
|
|
494
468
|
chez "(>= ${x} ${y})"
|
|
495
|
-
ml "(${x}: int) >= ${y}"
|
|
496
469
|
llvm """
|
|
497
470
|
%z = icmp sge %Int ${x}, ${y}
|
|
498
471
|
%fat_z = zext i1 %z to i64
|
|
@@ -503,17 +476,14 @@ extern pure def infixGte(x: Int, y: Int): Bool =
|
|
|
503
476
|
extern pure def infixEq(x: Double, y: Double): Bool =
|
|
504
477
|
js "${x} === ${y}"
|
|
505
478
|
chez "(= ${x} ${y})"
|
|
506
|
-
ml "(${x}: real) = ${y}"
|
|
507
479
|
|
|
508
480
|
extern pure def infixNeq(x: Double, y: Double): Bool =
|
|
509
481
|
js "${x} !== ${y}"
|
|
510
482
|
chez "(not (= ${x} ${y}))"
|
|
511
|
-
ml "(${x}: real) <> ${y}"
|
|
512
483
|
|
|
513
484
|
extern pure def infixLt(x: Double, y: Double): Bool =
|
|
514
485
|
js "(${x} < ${y})"
|
|
515
486
|
chez "(< ${x} ${y})"
|
|
516
|
-
ml "(${x}: real) < ${y}"
|
|
517
487
|
llvm """
|
|
518
488
|
%z = fcmp olt %Double ${x}, ${y}
|
|
519
489
|
%fat_z = zext i1 %z to i64
|
|
@@ -524,12 +494,10 @@ extern pure def infixLt(x: Double, y: Double): Bool =
|
|
|
524
494
|
extern pure def infixLte(x: Double, y: Double): Bool =
|
|
525
495
|
js "(${x} <= ${y})"
|
|
526
496
|
chez "(<= ${x} ${y})"
|
|
527
|
-
ml "(${x}: real) <= ${y}"
|
|
528
497
|
|
|
529
498
|
extern pure def infixGt(x: Double, y: Double): Bool =
|
|
530
499
|
js "(${x} > ${y})"
|
|
531
500
|
chez "(> ${x} ${y})"
|
|
532
|
-
ml "(${x}: real) > ${y}"
|
|
533
501
|
llvm """
|
|
534
502
|
%z = fcmp ogt %Double ${x}, ${y}
|
|
535
503
|
%fat_z = zext i1 %z to i64
|
|
@@ -540,28 +508,23 @@ extern pure def infixGt(x: Double, y: Double): Bool =
|
|
|
540
508
|
extern pure def infixGte(x: Double, y: Double): Bool =
|
|
541
509
|
js "(${x} >= ${y})"
|
|
542
510
|
chez "(>= ${x} ${y})"
|
|
543
|
-
ml "(${x}: real) >= ${y}"
|
|
544
511
|
|
|
545
512
|
// TODO do we really need those? if yes, move to string.effekt
|
|
546
513
|
extern pure def infixLt(x: String, y: String): Bool =
|
|
547
514
|
js "(${x} < ${y})"
|
|
548
515
|
chez "(< ${x} ${y})"
|
|
549
|
-
ml "(${x}: string) < ${y}"
|
|
550
516
|
|
|
551
517
|
extern pure def infixLte(x: String, y: String): Bool =
|
|
552
518
|
js "(${x} <= ${y})"
|
|
553
519
|
chez "(<= ${x} ${y})"
|
|
554
|
-
ml "(${x}: string) <= ${y}"
|
|
555
520
|
|
|
556
521
|
extern pure def infixGt(x: String, y: String): Bool =
|
|
557
522
|
js "(${x} > ${y})"
|
|
558
523
|
chez "(> ${x} ${y})"
|
|
559
|
-
ml "(${x}: string) > ${y}"
|
|
560
524
|
|
|
561
525
|
extern pure def infixGte(x: String, y: String): Bool =
|
|
562
526
|
js "(${x} >= ${y})"
|
|
563
527
|
chez "(>= ${x} ${y})"
|
|
564
|
-
ml "(${x}: string) >= ${y}"
|
|
565
528
|
|
|
566
529
|
|
|
567
530
|
// Boolean operations
|
|
@@ -569,7 +532,6 @@ extern pure def infixGte(x: String, y: String): Bool =
|
|
|
569
532
|
extern pure def not(b: Bool): Bool =
|
|
570
533
|
js "!${b}"
|
|
571
534
|
chez "(not ${b})"
|
|
572
|
-
ml "not ${b}"
|
|
573
535
|
llvm """
|
|
574
536
|
%p = extractvalue %Pos ${b}, 0
|
|
575
537
|
%q = xor i64 1, %p
|
|
@@ -586,11 +548,19 @@ def infixAnd { first: => Bool } { second: => Bool }: Bool =
|
|
|
586
548
|
|
|
587
549
|
// Bitwise operations
|
|
588
550
|
// ==================
|
|
551
|
+
|
|
552
|
+
/// Arithmetic left shift
|
|
589
553
|
extern pure def bitwiseShl(x: Int, y: Int): Int =
|
|
590
554
|
js "(${x} << ${y})"
|
|
591
555
|
chez "(ash ${x} ${y})"
|
|
592
556
|
llvm "%z = shl %Int ${x}, ${y} ret %Int %z"
|
|
593
557
|
|
|
558
|
+
/// Arithmetic right shift
|
|
559
|
+
extern pure def bitwiseShr(x: Int, y: Int): Int =
|
|
560
|
+
js "(${x} >> ${y})"
|
|
561
|
+
chez "(ash ${x} (- ${y}))"
|
|
562
|
+
llvm "%z = ashr %Int ${x}, ${y} ret %Int %z"
|
|
563
|
+
|
|
594
564
|
extern pure def bitwiseAnd(x: Int, y: Int): Int =
|
|
595
565
|
js "(${x} & ${y})"
|
|
596
566
|
chez "(logand ${x} ${y})"
|
|
@@ -620,24 +590,17 @@ extern pure def toInt(n: Byte): Int =
|
|
|
620
590
|
//
|
|
621
591
|
// js: undefined || null
|
|
622
592
|
// chez: #f
|
|
623
|
-
// ml: NONE (of option 'a)
|
|
624
593
|
// llvm: null?
|
|
625
594
|
|
|
626
|
-
|
|
627
|
-
* The value used by the FFI to represent undefined values
|
|
628
|
-
*/
|
|
595
|
+
/// The value used by the FFI to represent undefined values
|
|
629
596
|
extern pure def undefined[A](): A =
|
|
630
597
|
js "undefined"
|
|
631
598
|
chez "#f"
|
|
632
|
-
ml "NONE"
|
|
633
599
|
|
|
634
|
-
|
|
635
|
-
* Is an FFI value undefined?
|
|
636
|
-
*/
|
|
600
|
+
/// Is an FFI value undefined?
|
|
637
601
|
extern pure def isUndefined[A](value: A): Bool =
|
|
638
602
|
js "(${value} === undefined || ${value} === null)"
|
|
639
603
|
chez "(eq? ${value} #f)"
|
|
640
|
-
ml "Option.isSome ${value}"
|
|
641
604
|
|
|
642
605
|
|
|
643
606
|
// Tuples
|
|
@@ -669,9 +632,7 @@ def loop { f: {Control} => Unit }: Unit = try {
|
|
|
669
632
|
def continue() = loop { f }
|
|
670
633
|
}
|
|
671
634
|
|
|
672
|
-
|
|
673
|
-
* Calls provided action repeatedly. `start` is inclusive, `end` is not.
|
|
674
|
-
*/
|
|
635
|
+
/// Calls provided action repeatedly. `start` is inclusive, `end` is not.
|
|
675
636
|
def each(start: Int, end: Int) { action: (Int) => Unit } = {
|
|
676
637
|
def loop(i: Int): Unit =
|
|
677
638
|
if (i < end) { action(i); loop(i + 1) }
|
|
@@ -679,9 +640,7 @@ def each(start: Int, end: Int) { action: (Int) => Unit } = {
|
|
|
679
640
|
loop(start)
|
|
680
641
|
}
|
|
681
642
|
|
|
682
|
-
|
|
683
|
-
* Calls provided action repeatedly with support for breaking. `start` is inclusive, `end` is not.
|
|
684
|
-
*/
|
|
643
|
+
/// Calls provided action repeatedly with support for breaking. `start` is inclusive, `end` is not.
|
|
685
644
|
def each(start: Int, end: Int) { action: (Int) {Control} => Unit } = {
|
|
686
645
|
var i = start;
|
|
687
646
|
loop { {l} =>
|
|
@@ -53,7 +53,6 @@ def wrongFormat(msg: String): Nothing / Exception[WrongFormat] =
|
|
|
53
53
|
extern io def panic[R](msg: String): R =
|
|
54
54
|
js "(function() { throw ${msg} })()"
|
|
55
55
|
chez "(raise ${msg})"
|
|
56
|
-
ml "raise Fail ${msg}"
|
|
57
56
|
llvm """
|
|
58
57
|
call void @c_io_println_String(%Pos ${msg})
|
|
59
58
|
call void @exit(i32 1)
|
|
@@ -1,53 +1,47 @@
|
|
|
1
1
|
module io/console
|
|
2
2
|
|
|
3
3
|
import io
|
|
4
|
-
import io/time // just for testing
|
|
5
|
-
|
|
6
|
-
extern js """
|
|
7
|
-
const readline = require('node:readline');
|
|
8
|
-
"""
|
|
9
4
|
|
|
10
5
|
interface Console {
|
|
11
6
|
def readLine(): String
|
|
12
7
|
def writeLine(content: String): Unit
|
|
13
8
|
}
|
|
14
9
|
|
|
10
|
+
/// Handler for the console effect, using the Console available in js
|
|
11
|
+
def console[R] { program: () => R / Console }: R = {
|
|
12
|
+
val c = js::newConsole()
|
|
13
|
+
try {
|
|
14
|
+
val r = program()
|
|
15
|
+
js::close(c)
|
|
16
|
+
return r
|
|
17
|
+
} with Console {
|
|
18
|
+
def readLine() = resume(js::readLine(c))
|
|
19
|
+
def writeLine(message) = resume(js::writeLine(c, message))
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
15
23
|
namespace js {
|
|
24
|
+
|
|
25
|
+
extern jsNode """
|
|
26
|
+
const readline = require('node:readline');
|
|
27
|
+
"""
|
|
28
|
+
|
|
16
29
|
extern type JSConsole
|
|
17
|
-
|
|
18
|
-
|
|
30
|
+
|
|
31
|
+
extern io def newConsole(): JSConsole =
|
|
32
|
+
jsNode """readline.createInterface({
|
|
19
33
|
input: process.stdin,
|
|
20
34
|
output: process.stdout,
|
|
21
35
|
})"""
|
|
22
|
-
extern {io} def close(console: JSConsole): Unit =
|
|
23
|
-
js "${console}.close()"
|
|
24
36
|
|
|
25
|
-
extern
|
|
26
|
-
|
|
27
|
-
}
|
|
37
|
+
extern io def close(console: JSConsole): Unit =
|
|
38
|
+
jsNode "${console}.close()"
|
|
28
39
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
*/
|
|
32
|
-
def console[R] { prog: => R / Console }: R / AsyncIO = {
|
|
33
|
-
val c = js::newConsole()
|
|
34
|
-
try { val res = prog(); js::close(c); res } with Console {
|
|
35
|
-
def readLine() = {
|
|
36
|
-
resume(do performIO[String](box { write =>
|
|
37
|
-
js::readline(c, write)
|
|
38
|
-
}))
|
|
39
|
-
}
|
|
40
|
-
def writeLine(content) = resume(println(content))
|
|
41
|
-
}
|
|
42
|
-
}
|
|
40
|
+
extern async def readLine(console: JSConsole): String =
|
|
41
|
+
jsNode "$effekt.callcc(callback => ${console}.once('line', callback))"
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
extern {io} def writeStdoutCallback(message: String, k: () => Unit at {io, global}): Unit =
|
|
47
|
-
js "process.stdout.write(${message}, 'utf-8', () => (${k})().run())"
|
|
48
|
-
|
|
49
|
-
def write(message: String): Unit / IO =
|
|
50
|
-
do performIO[Unit](box { write => writeStdoutCallback(message, box { write(()) })})
|
|
43
|
+
extern io def writeLine(console: JSConsole, message: String): Unit =
|
|
44
|
+
jsNode "${console}.output.write(${message} + '\\n')"
|
|
51
45
|
}
|
|
52
46
|
|
|
53
47
|
namespace examples {
|
|
@@ -58,9 +52,9 @@ namespace examples {
|
|
|
58
52
|
do writeLine("Hi " ++ name ++ ", nice to meet you!")
|
|
59
53
|
}
|
|
60
54
|
|
|
61
|
-
def main() =
|
|
55
|
+
def main() = {
|
|
62
56
|
with console;
|
|
63
57
|
greeter()
|
|
64
|
-
}
|
|
58
|
+
}
|
|
65
59
|
|
|
66
|
-
}
|
|
60
|
+
}
|