@effekt-lang/effekt 0.19.0 → 0.21.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.
@@ -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
+ }
@@ -9,6 +9,7 @@ declare void @c_io_println_Double(%Double)
9
9
  declare void @c_io_println_String(%Pos)
10
10
 
11
11
  declare void @hole()
12
+ declare void @duplicated_prompt()
12
13
 
13
14
  declare %Pos @c_ref_fresh(%Pos)
14
15
  declare %Pos @c_ref_get(%Pos)
@@ -62,50 +62,12 @@ void c_resume_int_fs(uv_fs_t* request) {
62
62
  resume_Int(stack, result);
63
63
  }
64
64
 
65
- int modeFlags(struct Pos mode) {
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 errno integer values, but introduces fresh values (> 200)
181
- * for those without common errno values.
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 errno) {
184
- switch (errno) {
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
@@ -12,7 +12,7 @@
12
12
  #include "types.c"
13
13
  #include "bytearray.c"
14
14
  #include "io.c"
15
- #include "hole.c"
15
+ #include "panic.c"
16
16
  #include "ref.c"
17
17
  #include "array.c"
18
18
 
@@ -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