@effekt-lang/effekt 0.4.0 → 0.6.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/array.effekt +23 -47
- package/libraries/common/bench.effekt +11 -19
- 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 +21 -23
- package/libraries/common/io/console.effekt +2 -5
- package/libraries/common/io/error.effekt +20 -28
- package/libraries/common/io/filesystem.effekt +15 -27
- package/libraries/common/io/network.effekt +4 -4
- package/libraries/common/io/time.effekt +1 -1
- package/libraries/common/io.effekt +5 -5
- package/libraries/common/list.effekt +333 -333
- package/libraries/common/queue.effekt +1 -3
- package/libraries/common/ref.effekt +7 -17
- package/libraries/common/result.effekt +6 -14
- package/libraries/common/seq.effekt +28 -49
- package/libraries/common/string.effekt +7 -15
- package/libraries/js/effekt_builtins.js +5 -1
- package/libraries/js/effekt_runtime.js +185 -352
- package/licenses/eclipse public license, version 2.0 - epl-2.0.html +2 -2
- package/package.json +1 -1
- package/libraries/js/unsafe/cont.effekt +0 -11
- package/licenses/mit license - mit-license.html +0 -1239
- package/licenses/the bsd license - bsd-license.html +0 -1237
- package/licenses/the mit license - mit.html +0 -1239
|
@@ -9,15 +9,11 @@ extern js """
|
|
|
9
9
|
}
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
* Global, mutable references
|
|
14
|
-
*/
|
|
12
|
+
/// Global, mutable references
|
|
15
13
|
extern type Ref[T]
|
|
16
14
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
* Prefer using `ref` constructor instead to ensure that the value is defined.
|
|
20
|
-
*/
|
|
15
|
+
/// Allocates a new reference of size `size`, keeping its value _undefined_.
|
|
16
|
+
/// Prefer using `ref` constructor instead to ensure that the value is defined.
|
|
21
17
|
extern global def allocate[T](): Ref[T] =
|
|
22
18
|
js "{ value: undefined }"
|
|
23
19
|
chez "(box #f)"
|
|
@@ -26,9 +22,7 @@ extern global def allocate[T](): Ref[T] =
|
|
|
26
22
|
ret %Pos %z
|
|
27
23
|
"""
|
|
28
24
|
|
|
29
|
-
|
|
30
|
-
* Creates a new reference with the initial value `init`.
|
|
31
|
-
*/
|
|
25
|
+
/// Creates a new reference with the initial value `init`.
|
|
32
26
|
extern global def ref[T](init: T): Ref[T] =
|
|
33
27
|
js "{ value: ${init} }"
|
|
34
28
|
chez "(box ${init})"
|
|
@@ -37,9 +31,7 @@ extern global def ref[T](init: T): Ref[T] =
|
|
|
37
31
|
ret %Pos %z
|
|
38
32
|
"""
|
|
39
33
|
|
|
40
|
-
|
|
41
|
-
* Gets the referenced element of the `ref` in constant time.
|
|
42
|
-
*/
|
|
34
|
+
/// Gets the referenced element of the `ref` in constant time.
|
|
43
35
|
extern global def get[T](ref: Ref[T]): T =
|
|
44
36
|
js "${ref}.value"
|
|
45
37
|
chez "(unbox ${ref})"
|
|
@@ -48,13 +40,11 @@ extern global def get[T](ref: Ref[T]): T =
|
|
|
48
40
|
ret %Pos %z
|
|
49
41
|
"""
|
|
50
42
|
|
|
51
|
-
|
|
52
|
-
* Sets the referenced element of the `ref` to `value` in constant time.
|
|
53
|
-
*/
|
|
43
|
+
/// Sets the referenced element of the `ref` to `value` in constant time.
|
|
54
44
|
extern global def set[T](ref: Ref[T], value: T): Unit =
|
|
55
45
|
js "set$impl(${ref}, ${value})"
|
|
56
46
|
chez "(set-box! ${ref} ${value})"
|
|
57
47
|
llvm """
|
|
58
48
|
%z = call %Pos @c_ref_set(%Pos ${ref}, %Pos ${value})
|
|
59
49
|
ret %Pos %z
|
|
60
|
-
"""
|
|
50
|
+
"""
|
|
@@ -4,18 +4,14 @@ import effekt
|
|
|
4
4
|
import option
|
|
5
5
|
import exception
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
* It is the "reification" of the Exception[E] effect.
|
|
10
|
-
*/
|
|
7
|
+
/// Represents the result of a potentially failing computation.
|
|
8
|
+
/// It is the "reification" of the Exception[E] effect.
|
|
11
9
|
type Result[A, E] {
|
|
12
10
|
Error(exception: E, msg: String);
|
|
13
11
|
Success(a: A)
|
|
14
12
|
}
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
* Represent ("reify") the result of a potentially failing computation.
|
|
18
|
-
*/
|
|
14
|
+
/// Represent ("reify") the result of a potentially failing computation.
|
|
19
15
|
def result[A, E] { f: => A / Exception[E] }: Result[A, E] = try {
|
|
20
16
|
Success(f())
|
|
21
17
|
} with Exception[E] {
|
|
@@ -27,18 +23,14 @@ def result[A, E](proxy: on[E]) { f: => A / Exception[E] }: Result[A, E] = try {
|
|
|
27
23
|
def raise(exc, msg) = Error(exc, msg)
|
|
28
24
|
}
|
|
29
25
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
* Monadic "reflection"
|
|
33
|
-
*/
|
|
26
|
+
/// Extracts the value of a result, if available
|
|
27
|
+
/// Monadic "reflection"
|
|
34
28
|
def value[A, E](r: Result[A, E]): A / Exception[E] = r match {
|
|
35
29
|
case Success(a) => a
|
|
36
30
|
case Error(exc, msg) => do raise(exc, msg)
|
|
37
31
|
}
|
|
38
32
|
|
|
39
|
-
|
|
40
|
-
* Converts a result to an option forgetting the error details
|
|
41
|
-
*/
|
|
33
|
+
/// Converts a result to an option forgetting the error details
|
|
42
34
|
def toOption[A, E](r: Result[A, E]): Option[A] = r match {
|
|
43
35
|
case Success(a) => Some(a)
|
|
44
36
|
case Error(exc, msg) => None()
|
|
@@ -1,41 +1,32 @@
|
|
|
1
|
+
/// This file implements the [[Seq]] type as a general purpose functional sequence.
|
|
2
|
+
///
|
|
3
|
+
/// Implemented as a 2-3 finger tree, it supports
|
|
4
|
+
/// - prepend and append in amortized O(1),
|
|
5
|
+
/// - concat(m, n) in O(log(min(m, n)))
|
|
6
|
+
/// - first and last in amortized O(1)
|
|
7
|
+
/// - size in amortized O(1)
|
|
8
|
+
///
|
|
9
|
+
/// More information on finger trees:
|
|
10
|
+
/// https://www.staff.city.ac.uk/~ross/papers/FingerTree.pdf
|
|
1
11
|
module seq
|
|
2
12
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* Implemented as a 2-3 finger tree, it supports
|
|
7
|
-
* - prepend and append in amortized O(1),
|
|
8
|
-
* - concat(m, n) in O(log(min(m, n)))
|
|
9
|
-
* - first and last in amortized O(1)
|
|
10
|
-
* - size in amortized O(1)
|
|
11
|
-
*
|
|
12
|
-
* More information on finger trees:
|
|
13
|
-
* https://www.staff.city.ac.uk/~ross/papers/FingerTree.pdf
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Sequences of elements
|
|
18
|
-
*
|
|
19
|
-
* They are represented as 2-3 finger trees.
|
|
20
|
-
*/
|
|
13
|
+
/// Sequences of elements
|
|
14
|
+
///
|
|
15
|
+
/// They are represented as 2-3 finger trees.
|
|
21
16
|
type Seq[A] {
|
|
22
17
|
Empty()
|
|
23
18
|
Single(value: A)
|
|
24
19
|
Deep(size: Int, prefix: Digit[A], middle: Tree[A], suffix: Digit[A])
|
|
25
20
|
}
|
|
26
21
|
|
|
27
|
-
|
|
28
|
-
* Result of splitting a sequence at the front or back.
|
|
29
|
-
*/
|
|
22
|
+
/// Result of splitting a sequence at the front or back.
|
|
30
23
|
type View[A] {
|
|
31
24
|
IsEmpty()
|
|
32
25
|
View(element: A, remainder: Seq[A])
|
|
33
26
|
}
|
|
34
27
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
* or splitting empty collections.
|
|
38
|
-
*/
|
|
28
|
+
/// Exception[NoSuchElement] is raised when accessing non-existing elements
|
|
29
|
+
/// or splitting empty collections.
|
|
39
30
|
record NoSuchElement()
|
|
40
31
|
|
|
41
32
|
|
|
@@ -61,11 +52,9 @@ record IndexOutOfBounds()
|
|
|
61
52
|
// Internal Types
|
|
62
53
|
// --------------
|
|
63
54
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
* It is called digit since Okasaki (1998) calls finger trees "numerical operations".
|
|
68
|
-
*/
|
|
55
|
+
/// Internal grouping of 1-4 elements
|
|
56
|
+
///
|
|
57
|
+
/// It is called digit since Okasaki (1998) calls finger trees "numerical operations".
|
|
69
58
|
type Digit[A] {
|
|
70
59
|
One(value: A)
|
|
71
60
|
Two(first: A, second: A)
|
|
@@ -73,9 +62,7 @@ type Digit[A] {
|
|
|
73
62
|
Four(first: A, second: A, third: A, fourth: A)
|
|
74
63
|
}
|
|
75
64
|
|
|
76
|
-
|
|
77
|
-
* Internal representation of a 2-3 tree
|
|
78
|
-
*/
|
|
65
|
+
/// Internal representation of a 2-3 tree
|
|
79
66
|
type Node[A] {
|
|
80
67
|
// These are necessary to avoid polymorphic recursion
|
|
81
68
|
Leaf2(first: A, second: A)
|
|
@@ -84,12 +71,10 @@ type Node[A] {
|
|
|
84
71
|
Node3(size: Int, first: Node[A], second: Node[A], third: Node[A])
|
|
85
72
|
}
|
|
86
73
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
* not support mutually recursive data type declarations.
|
|
92
|
-
*/
|
|
74
|
+
/// Internal duplicate of Seq
|
|
75
|
+
///
|
|
76
|
+
/// splitting into two type parameters is necessary since our MLton backend does
|
|
77
|
+
/// not support mutually recursive data type declarations.
|
|
93
78
|
type Finger[A, N] {
|
|
94
79
|
NoFinger()
|
|
95
80
|
SingleFinger(value: Node[A])
|
|
@@ -141,9 +126,7 @@ def size[A](tree: Tree[A]): Int = tree match {
|
|
|
141
126
|
case DeepFinger(size, _, _, _) => size
|
|
142
127
|
}
|
|
143
128
|
|
|
144
|
-
|
|
145
|
-
* The size of the given sequence
|
|
146
|
-
*/
|
|
129
|
+
/// The size of the given sequence
|
|
147
130
|
def size[A](seq: Seq[A]): Int = seq match {
|
|
148
131
|
case Empty() => 0
|
|
149
132
|
case Single(value) => 1
|
|
@@ -408,9 +391,7 @@ def reverse[A](seq: Seq[A]): Seq[A] = {
|
|
|
408
391
|
}
|
|
409
392
|
|
|
410
393
|
|
|
411
|
-
|
|
412
|
-
* Random access
|
|
413
|
-
*/
|
|
394
|
+
/// Random access
|
|
414
395
|
def index[A](seq: Seq[A], index: Int): A / Exception[NoSuchElement] = {
|
|
415
396
|
|
|
416
397
|
// invariant for all internal functions: element is in the sequence
|
|
@@ -485,9 +466,7 @@ def index[A](seq: Seq[A], index: Int): A / Exception[NoSuchElement] = {
|
|
|
485
466
|
}
|
|
486
467
|
}
|
|
487
468
|
|
|
488
|
-
|
|
489
|
-
* Random access
|
|
490
|
-
*/
|
|
469
|
+
/// Random access
|
|
491
470
|
def update[A](seq: Seq[A], index: Int, value: A): Seq[A] / Exception[NoSuchElement] = {
|
|
492
471
|
|
|
493
472
|
// invariant for all internal functions: element is in the sequence
|
|
@@ -911,4 +890,4 @@ def map[A, B](seq: Seq[A]) { f: (A) {Control} => B }: Seq[B] = {
|
|
|
911
890
|
|
|
912
891
|
|
|
913
892
|
// TODO equality comparison
|
|
914
|
-
//
|
|
893
|
+
//
|
|
@@ -34,9 +34,7 @@ def substring(str: String, from: Int): String =
|
|
|
34
34
|
str.substring(from, str.length)
|
|
35
35
|
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
* Checks whether str starts with the given prefix at `from`
|
|
39
|
-
*/
|
|
37
|
+
/// Checks whether str starts with the given prefix at `from`
|
|
40
38
|
def isSubstringAt(str: String, prefix: String, from: Int): Bool = {
|
|
41
39
|
with default[OutOfBounds, Bool] { false };
|
|
42
40
|
|
|
@@ -59,11 +57,9 @@ def startsWith(str: String, prefix: String): Bool =
|
|
|
59
57
|
def endsWith(str: String, suffix: String): Bool =
|
|
60
58
|
isSubstringAt(str, suffix, str.length - suffix.length)
|
|
61
59
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
* TODO use a more efficient way of appending strings like a buffer
|
|
66
|
-
*/
|
|
60
|
+
/// Repeats the given string n-times.
|
|
61
|
+
///
|
|
62
|
+
/// TODO use a more efficient way of appending strings like a buffer
|
|
67
63
|
def repeat(str: String, n: Int): String = {
|
|
68
64
|
def go(n: Int, result: String): String = {
|
|
69
65
|
if (n == 0) result
|
|
@@ -180,15 +176,13 @@ def toInt(str: String, base: Int): Int / Exception[WrongFormat] = {
|
|
|
180
176
|
}
|
|
181
177
|
}
|
|
182
178
|
|
|
183
|
-
|
|
179
|
+
/// Native versions of toInt (unused right now)
|
|
184
180
|
extern pure def unsafeToInt(str: String): Int =
|
|
185
181
|
js "(Number.isNaN(parseInt(${str})) ? undefined : parseInt(${str}))"
|
|
186
182
|
chez "(string->number ${str})"
|
|
187
183
|
|
|
188
184
|
|
|
189
|
-
|
|
190
|
-
* Returns the index of the first occurrence of `sub` in `str`
|
|
191
|
-
*/
|
|
185
|
+
/// Returns the index of the first occurrence of `sub` in `str`
|
|
192
186
|
def indexOf(str: String, sub: String): Option[Int] =
|
|
193
187
|
indexOf(str, sub, 0)
|
|
194
188
|
|
|
@@ -202,9 +196,7 @@ def indexOf(str: String, sub: String, from: Int): Option[Int] = {
|
|
|
202
196
|
go(from)
|
|
203
197
|
}
|
|
204
198
|
|
|
205
|
-
|
|
206
|
-
* Returns the index of the last occurence of `sub` in `str`
|
|
207
|
-
*/
|
|
199
|
+
/// Returns the index of the last occurence of `sub` in `str`
|
|
208
200
|
def lastIndexOf(str: String, sub: String): Option[Int] =
|
|
209
201
|
lastIndexOf(str, sub, str.length)
|
|
210
202
|
|
|
@@ -54,4 +54,8 @@ $effekt.println = function println$impl(str) {
|
|
|
54
54
|
console.log(str); return $effekt.unit;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
$effekt.unit = { __unit: true }
|
|
57
|
+
$effekt.unit = { __unit: true }
|
|
58
|
+
|
|
59
|
+
$effekt.emptyMatch = function() { throw "empty match" }
|
|
60
|
+
|
|
61
|
+
$effekt.hole = function() { throw "not implemented, yet" }
|