@effekt-lang/effekt 0.19.0 → 0.20.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/effekt.effekt +22 -0
- package/libraries/common/heap.effekt +103 -0
- package/libraries/common/io/filesystem.effekt +49 -66
- package/libraries/common/resizable_array.effekt +235 -0
- package/libraries/common/stream.effekt +2 -2
- package/libraries/common/stringbuffer.effekt +65 -0
- package/libraries/common/union_find.effekt +113 -0
- package/libraries/llvm/forward-declare-c.ll +1 -0
- package/libraries/llvm/io.c +17 -43
- package/libraries/llvm/main.c +1 -1
- package/libraries/llvm/panic.c +20 -0
- package/libraries/llvm/rts.ll +141 -142
- package/licenses/eclipse public license, version 2.0 - epl-2.0.html +4 -4
- package/licenses/mit license - mit-license.html +77 -17
- package/licenses/the bsd license - bsd-license.html +77 -17
- package/licenses/the mit license - mit.html +76 -16
- package/package.json +1 -1
- package/libraries/llvm/hole.c +0 -11
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
module union_find
|
|
2
|
+
import resizable_array
|
|
3
|
+
|
|
4
|
+
/// Classic mutable union-find data structure on integer indices,
|
|
5
|
+
/// with union-by-rank and path compression.
|
|
6
|
+
record UnionFind(rawElements: ResizableArray[Int])
|
|
7
|
+
|
|
8
|
+
namespace internal {
|
|
9
|
+
// -(rk + 1) for roots
|
|
10
|
+
// parent for inner nodes
|
|
11
|
+
def isRoot(u: UnionFind, s: Int): Bool / Exception[MissingValue] = {
|
|
12
|
+
with on[OutOfBounds].default { do raise(MissingValue(), "No node " ++ s.show) }
|
|
13
|
+
u.rawElements.get(s) < 0
|
|
14
|
+
}
|
|
15
|
+
def parent(u: UnionFind, s: Int): Int / Exception[MissingValue] = {
|
|
16
|
+
with on[OutOfBounds].default { do raise(MissingValue(), "No node " ++ s.show) }
|
|
17
|
+
val c = u.rawElements.get(s)
|
|
18
|
+
if (c < 0) {
|
|
19
|
+
do raise(MissingValue(), "Root node " ++ s.show ++ " has no parent.")
|
|
20
|
+
} else {
|
|
21
|
+
c
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
def rank(u: UnionFind, s: Int): Int / Exception[MissingValue] = {
|
|
25
|
+
with on[OutOfBounds].default { do raise(MissingValue(), "No node " ++ s.show) }
|
|
26
|
+
val c = u.rawElements.get(s)
|
|
27
|
+
if (c < 0) {
|
|
28
|
+
-1 * c - 1
|
|
29
|
+
} else {
|
|
30
|
+
do raise(MissingValue(), "Only root nodes have a rank.")
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
def setParent(u: UnionFind, child: Int, parent: Int) = {
|
|
34
|
+
with on[OutOfBounds].default { do raise(MissingValue(), "No node " ++ child.show) }
|
|
35
|
+
u.rawElements.set(child, parent)
|
|
36
|
+
}
|
|
37
|
+
def setRank(u: UnionFind, root: Int, rank: Int) = {
|
|
38
|
+
with on[OutOfBounds].default { do raise(MissingValue(), "No node " ++ root.show) }
|
|
39
|
+
u.rawElements.set(root, -1 * rank - 1)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
def unionFind(): UnionFind =
|
|
44
|
+
UnionFind(resizableArray())
|
|
45
|
+
|
|
46
|
+
def unionFind(capacity: Int): UnionFind =
|
|
47
|
+
UnionFind(resizableArray(capacity))
|
|
48
|
+
|
|
49
|
+
/// Make a new set in the union-find datastructure and return its index
|
|
50
|
+
///
|
|
51
|
+
/// O(1) amortized, worst-case O(n) if the capacity does not suffice
|
|
52
|
+
def makeSet(u: UnionFind): Int = {
|
|
53
|
+
u.rawElements.add(-1)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/// Find the representative of the given element.
|
|
57
|
+
///
|
|
58
|
+
/// O(inverse-ackermann(n)) amortized
|
|
59
|
+
def find(u: UnionFind, s: Int): Int / Exception[MissingValue] = {
|
|
60
|
+
def goFind(s: Int): Int = {
|
|
61
|
+
if (u.internal::isRoot(s)) {
|
|
62
|
+
s
|
|
63
|
+
} else {
|
|
64
|
+
goFind(u.internal::parent(s))
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
val root = goFind(s)
|
|
68
|
+
|
|
69
|
+
def goCompress(s: Int): Unit = {
|
|
70
|
+
if (not(u.internal::isRoot(s))) {
|
|
71
|
+
val p = u.internal::parent(s)
|
|
72
|
+
u.internal::setParent(s, root)
|
|
73
|
+
goCompress(p)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
goCompress(s)
|
|
77
|
+
|
|
78
|
+
root
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/// Make it such that the sets *represented by* x and y are merged
|
|
82
|
+
///
|
|
83
|
+
/// O(1)
|
|
84
|
+
def unionRoots(u: UnionFind, x: Int, y: Int): Int / Exception[MissingValue] = {
|
|
85
|
+
if(not(u.internal::isRoot(x) && u.internal::isRoot(y))) {
|
|
86
|
+
panic("unionRoots should only be called on representatives")
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
def addChild(root: Int, child: Int) = {
|
|
90
|
+
if (u.internal::rank(root) == u.internal::rank(child)) {
|
|
91
|
+
u.internal::setRank(root, u.internal::rank(root) + 1)
|
|
92
|
+
}
|
|
93
|
+
u.internal::setParent(child, root)
|
|
94
|
+
root
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (x == y) {
|
|
98
|
+
x
|
|
99
|
+
} else if (u.internal::rank(x) < u.internal::rank(y)) {
|
|
100
|
+
addChild(y, x)
|
|
101
|
+
} else {
|
|
102
|
+
addChild(x, y)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/// Make it so a and b are in the same set
|
|
107
|
+
///
|
|
108
|
+
/// O(inverse-ackermann(n)) amortized
|
|
109
|
+
def union(u: UnionFind, a: Int, b: Int): Int / Exception[MissingValue] = {
|
|
110
|
+
val x = u.find(a)
|
|
111
|
+
val y = u.find(b)
|
|
112
|
+
u.unionRoots(x, y)
|
|
113
|
+
}
|
package/libraries/llvm/io.c
CHANGED
|
@@ -62,50 +62,12 @@ void c_resume_int_fs(uv_fs_t* request) {
|
|
|
62
62
|
resume_Int(stack, result);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
switch (mode.tag) {
|
|
67
|
-
case 0: // ReadOnly()
|
|
68
|
-
return UV_FS_O_RDONLY;
|
|
69
|
-
case 1: // WriteOnly()
|
|
70
|
-
return UV_FS_O_WRONLY | UV_FS_O_CREAT | UV_FS_O_TRUNC;
|
|
71
|
-
case 2: // AppendOnly()
|
|
72
|
-
return UV_FS_O_WRONLY | UV_FS_O_CREAT | UV_FS_O_APPEND;
|
|
73
|
-
case 3: // ReadWrite()
|
|
74
|
-
return UV_FS_O_RDWR | UV_FS_O_CREAT | UV_FS_O_TRUNC;
|
|
75
|
-
case 4: // ReadAppend()
|
|
76
|
-
return UV_FS_O_RDWR | UV_FS_O_CREAT | UV_FS_O_APPEND;
|
|
77
|
-
case 5: // AppendExclusive()
|
|
78
|
-
return UV_FS_O_WRONLY | UV_FS_O_CREAT | UV_FS_O_APPEND | UV_FS_O_EXCL;
|
|
79
|
-
case 6: // ReadAppendExclusive()
|
|
80
|
-
return UV_FS_O_RDWR | UV_FS_O_CREAT | UV_FS_O_APPEND | UV_FS_O_EXCL;
|
|
81
|
-
case 7: // AppendSync()
|
|
82
|
-
return UV_FS_O_WRONLY | UV_FS_O_CREAT | UV_FS_O_APPEND | UV_FS_O_SYNC;
|
|
83
|
-
case 8: // ReadAppendSync()
|
|
84
|
-
return UV_FS_O_RDWR | UV_FS_O_CREAT | UV_FS_O_APPEND | UV_FS_O_SYNC;
|
|
85
|
-
case 9: // ReadSync()
|
|
86
|
-
return UV_FS_O_RDONLY | UV_FS_O_SYNC;
|
|
87
|
-
case 10: // ReadWriteSync()
|
|
88
|
-
return UV_FS_O_RDWR | UV_FS_O_SYNC;
|
|
89
|
-
case 11: // WriteExclusive()
|
|
90
|
-
return UV_FS_O_WRONLY | UV_FS_O_CREAT | UV_FS_O_TRUNC | UV_FS_O_EXCL;
|
|
91
|
-
case 12: // ReadWriteExclusive()
|
|
92
|
-
return UV_FS_O_RDWR | UV_FS_O_CREAT | UV_FS_O_TRUNC | UV_FS_O_EXCL;
|
|
93
|
-
default:
|
|
94
|
-
// Invalid tag value
|
|
95
|
-
return -1;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
void c_fs_open(String path, struct Pos mode, Stack stack) {
|
|
65
|
+
void c_fs_open(String path, int flags, Stack stack) {
|
|
100
66
|
|
|
101
67
|
// Convert the Effekt String to a 0-terminated string
|
|
102
68
|
char* path_str = c_bytearray_into_nullterminated_string(path);
|
|
103
69
|
erasePositive((struct Pos) path);
|
|
104
70
|
|
|
105
|
-
// Convert the Effekt String representing the opening mode to libuv flags
|
|
106
|
-
int flags = modeFlags(mode);
|
|
107
|
-
erasePositive((struct Pos) mode);
|
|
108
|
-
|
|
109
71
|
uv_fs_t* request = malloc(sizeof(uv_fs_t));
|
|
110
72
|
request->data = stack;
|
|
111
73
|
|
|
@@ -123,6 +85,18 @@ void c_fs_open(String path, struct Pos mode, Stack stack) {
|
|
|
123
85
|
return;
|
|
124
86
|
}
|
|
125
87
|
|
|
88
|
+
void c_fs_open_reading(String path, Stack stack) {
|
|
89
|
+
c_fs_open(path, UV_FS_O_RDONLY, stack);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
void c_fs_open_writing(String path, Stack stack) {
|
|
93
|
+
c_fs_open(path, UV_FS_O_WRONLY | UV_FS_O_CREAT | UV_FS_O_TRUNC, stack);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
void c_fs_open_appending(String path, Stack stack) {
|
|
97
|
+
c_fs_open(path, UV_FS_O_WRONLY | UV_FS_O_CREAT | UV_FS_O_APPEND, stack);
|
|
98
|
+
}
|
|
99
|
+
|
|
126
100
|
void c_fs_read(Int file, struct Pos buffer, Int offset, Int size, Int position, Stack stack) {
|
|
127
101
|
|
|
128
102
|
uv_buf_t buf = uv_buf_init((char*)(c_bytearray_data(buffer) + offset), size);
|
|
@@ -177,11 +151,11 @@ void c_fs_close(Int file, Stack stack) {
|
|
|
177
151
|
/**
|
|
178
152
|
* Maps the libuv error code to a stable (platform independent) numeric value.
|
|
179
153
|
*
|
|
180
|
-
* Tries to use most common
|
|
181
|
-
* for those without common
|
|
154
|
+
* Tries to use most common error number integer values, but introduces fresh values (> 200)
|
|
155
|
+
* for those without common error number values.
|
|
182
156
|
*/
|
|
183
|
-
Int c_error_number(Int
|
|
184
|
-
switch (
|
|
157
|
+
Int c_error_number(Int error) {
|
|
158
|
+
switch (error) {
|
|
185
159
|
case UV_EPERM: return 1; // EPERM
|
|
186
160
|
case UV_ENOENT: return 2; // ENOENT
|
|
187
161
|
case UV_ESRCH: return 3; // ESRCH
|
package/libraries/llvm/main.c
CHANGED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#ifndef EFFEKT_PANIC_C
|
|
2
|
+
#define EFFEKT_PANIC_C
|
|
3
|
+
|
|
4
|
+
#include <stdio.h>
|
|
5
|
+
|
|
6
|
+
// TODO:
|
|
7
|
+
// this should _morally_ be using `stderr`, but we don't tee it in tests
|
|
8
|
+
// see PR #823 & issue #815 for context
|
|
9
|
+
|
|
10
|
+
void hole() {
|
|
11
|
+
printf("PANIC: Reached a hole in the program\n");
|
|
12
|
+
exit(1);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
void duplicated_prompt() {
|
|
16
|
+
printf("PANIC: Continuation invoked itself\n");
|
|
17
|
+
exit(1);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
#endif
|