@effekt-lang/effekt 0.2.1 → 0.3.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.
Files changed (75) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +36 -0
  3. package/bin/effekt +0 -0
  4. package/bin/effekt.sh +2 -0
  5. package/libraries/chez/THIRD-PARTY.txt +11 -0
  6. package/libraries/chez/callcc/datatype.ss +188 -0
  7. package/libraries/chez/callcc/effekt.ss +31 -0
  8. package/libraries/chez/callcc/seq.ss +44 -0
  9. package/libraries/chez/callcc/seq0.ss +69 -0
  10. package/libraries/chez/callcc/tail.ss +76 -0
  11. package/libraries/chez/callcc/tail0.ss +89 -0
  12. package/libraries/chez/common/effekt_primitives.ss +105 -0
  13. package/libraries/chez/common/immutable/cslist.effekt +37 -0
  14. package/libraries/chez/common/mutable/dict.effekt +28 -0
  15. package/libraries/chez/common/text/pregexp.scm +772 -0
  16. package/libraries/chez/common/text/regex.effekt +31 -0
  17. package/libraries/chez/lift/effekt.ss +118 -0
  18. package/libraries/chez/monadic/effekt.ss +84 -0
  19. package/libraries/chez/monadic/seq0.ss +76 -0
  20. package/libraries/common/args.effekt +95 -0
  21. package/libraries/common/array.effekt +225 -0
  22. package/libraries/common/bench.effekt +60 -0
  23. package/libraries/common/buffer.effekt +123 -0
  24. package/libraries/common/bytes.effekt +125 -0
  25. package/libraries/common/dequeue.effekt +92 -0
  26. package/libraries/common/effekt.effekt +764 -0
  27. package/libraries/common/exception.effekt +122 -0
  28. package/libraries/common/io/console.effekt +66 -0
  29. package/libraries/common/io/error.effekt +365 -0
  30. package/libraries/common/io/files.effekt +282 -0
  31. package/libraries/common/io/network.effekt +105 -0
  32. package/libraries/common/io/time.effekt +15 -0
  33. package/libraries/common/io.effekt +158 -0
  34. package/libraries/common/list.effekt +687 -0
  35. package/libraries/common/option.effekt +72 -0
  36. package/libraries/common/process.effekt +10 -0
  37. package/libraries/common/queue.effekt +140 -0
  38. package/libraries/common/ref.effekt +63 -0
  39. package/libraries/common/result.effekt +45 -0
  40. package/libraries/common/seq.effekt +914 -0
  41. package/libraries/common/string.effekt +395 -0
  42. package/libraries/common/test.effekt +98 -0
  43. package/libraries/js/effekt_builtins.js +57 -0
  44. package/libraries/js/effekt_runtime.js +385 -0
  45. package/libraries/js/io.js +143 -0
  46. package/libraries/js/mutable/map.effekt +31 -0
  47. package/libraries/js/text/regex.effekt +33 -0
  48. package/libraries/js/unsafe/cont.effekt +11 -0
  49. package/libraries/js/web/dom.effekt +45 -0
  50. package/libraries/llvm/array.c +53 -0
  51. package/libraries/llvm/buffer.c +286 -0
  52. package/libraries/llvm/forward-declare-c.ll +43 -0
  53. package/libraries/llvm/hole.c +11 -0
  54. package/libraries/llvm/io.c +566 -0
  55. package/libraries/llvm/io.ll +19 -0
  56. package/libraries/llvm/main.c +41 -0
  57. package/libraries/llvm/ref.c +45 -0
  58. package/libraries/llvm/rts.ll +761 -0
  59. package/libraries/llvm/sanity.c +16 -0
  60. package/libraries/llvm/types.c +43 -0
  61. package/libraries/ml/effekt.sml +65 -0
  62. package/libraries/ml/internal/mllist.effekt +9 -0
  63. package/libraries/ml/internal/mloption.effekt +18 -0
  64. package/libraries/ml/random.effekt +85 -0
  65. package/libraries/ml/text/regex.effekt +102 -0
  66. package/licenses/THIRD-PARTY.txt +21 -0
  67. package/licenses/apache-2.0 - license-2.0.txt +202 -0
  68. package/licenses/eclipse public license, version 2.0 - epl-2.0.html +61 -0
  69. package/licenses/kiama-license.txt +373 -0
  70. package/licenses/kiama-readme.txt +186 -0
  71. package/licenses/mit license - mit-license.html +1239 -0
  72. package/licenses/the apache software license, version 2.0 - license-2.0.txt +202 -0
  73. package/licenses/the bsd license - bsd-license.html +1237 -0
  74. package/licenses/the mit license - mit.html +1239 -0
  75. package/package.json +26 -18
@@ -0,0 +1,286 @@
1
+ #ifndef EFFEKT_BUFFER_C
2
+ #define EFFEKT_BUFFER_C
3
+
4
+ #include "stdlib.h"
5
+ #include <stdint.h>
6
+ #include <string.h> // For memcopy
7
+
8
+ /** We represent buffers like positive types.
9
+ *
10
+ * - The field `tag` contains offset (32bit) and length (32bit), which is equal to
11
+ * the tag (64bit) in Pos;
12
+ * - The field `obj` points to memory with the following layout:
13
+ *
14
+ * +--[ Header ]--+--------------+
15
+ * | Rc | Eraser | Contents ... |
16
+ * +--------------+--------------+
17
+ *
18
+ * The eraser is always a null pointer since it does not need to do anything.
19
+ */
20
+
21
+ // TODO It may be performance-advantageous to implement this C file's semantics
22
+ // in LLVM, since the linker cannot realistically be asked to satisfactorily
23
+ // inline.
24
+ // Alternatively, one could drop gcc and combine Effekt-compiler-generated LLVM
25
+ // with clang-generated LLVM from this file's entire translation unit.
26
+
27
+
28
+ struct Pos c_buffer(const uint32_t offset, const uint32_t length, void* obj) {
29
+ return (struct Pos) {
30
+ .tag = ((uint64_t)offset << 32) | (uint32_t)length,
31
+ .obj = obj,
32
+ };
33
+ }
34
+
35
+ void c_buffer_erase_noop(void *envPtr) { (void)envPtr; }
36
+
37
+ uint64_t c_buffer_offset(const struct Pos buffer) {
38
+ return (uint32_t)(buffer.tag >> 32); // Extract offset from the upper 32 bits
39
+ }
40
+
41
+ // Function to get the length from Pos
42
+ // WARNING: This does not erase the Pos argument!
43
+ uint64_t c_buffer_length(const struct Pos buffer) {
44
+ return (uint32_t)(buffer.tag & 0xFFFFFFFF); // Extract length from the lower 32 bits
45
+ }
46
+
47
+ uint8_t *c_buffer_bytes(const struct Pos buffer) {
48
+ return (uint8_t *) (buffer.obj + sizeof(struct Header) + c_buffer_offset(buffer));
49
+ }
50
+
51
+ struct Pos c_buffer_construct(const uint64_t n, const uint8_t *data) {
52
+ uint8_t *obj = (uint8_t *)malloc(sizeof(struct Header) + n * sizeof *obj);
53
+ ASSERT_NON_NULL(obj);
54
+
55
+ struct Header *header = (void*) obj;
56
+ *header = (struct Header) { .rc = 0, .eraser = c_buffer_erase_noop, };
57
+
58
+ // Copy data
59
+ memcpy(obj + sizeof(struct Header), data, n);
60
+
61
+ return c_buffer(0, n, obj);
62
+ }
63
+
64
+ struct Pos c_buffer_construct_zeroed(const uint64_t n) {
65
+ uint8_t *zeroes = calloc(sizeof(struct Header) + n, sizeof *zeroes);
66
+ ASSERT_NON_NULL(zeroes)
67
+
68
+ struct Header *header = (void*) zeroes;
69
+ *header = (struct Header) { .rc = 0, .eraser = c_buffer_erase_noop, };
70
+
71
+ return c_buffer(0, n, zeroes);
72
+ }
73
+
74
+ struct Pos c_buffer_construct_uninitialized(const uint64_t n) {
75
+ uint8_t *data = malloc(sizeof(struct Header) + n * sizeof *data);
76
+ ASSERT_NON_NULL(data)
77
+
78
+ struct Header *header = (void*) data;
79
+ *header = (struct Header) { .rc = 0, .eraser = c_buffer_erase_noop, };
80
+
81
+ return c_buffer(0, n, data);
82
+ }
83
+
84
+ struct Pos c_buffer_slice(struct Pos buffer, const uint64_t offset, const uint64_t length) {
85
+
86
+ if ((c_buffer_offset(buffer) + offset + length) > c_buffer_length(buffer))
87
+ return buffer;
88
+
89
+ return c_buffer(c_buffer_offset(buffer) + offset, length, buffer.obj);
90
+ }
91
+
92
+ struct Pos c_buffer_clone(const struct Pos buffer) {
93
+ return c_buffer_construct(c_buffer_length(buffer), c_buffer_bytes(buffer));
94
+ }
95
+
96
+ void c_buffer_copy(const struct Pos from, struct Pos to, uint64_t startFrom, uint64_t startTo, uint64_t length) {
97
+ // Check bounds
98
+ if ((startFrom + length > c_buffer_length(from)) || (startTo + length > c_buffer_length(to))) {
99
+ return;
100
+ }
101
+
102
+ // Get pointers to the source and destination slices
103
+ uint8_t *from_bytes = c_buffer_bytes(from) + startFrom;
104
+ uint8_t *to_bytes = c_buffer_bytes(to) + startTo;
105
+
106
+ // Copy bytes from `from` to `to`
107
+ memcpy(to_bytes, from_bytes, length);
108
+ }
109
+
110
+
111
+ /**
112
+ * Converts a buffer to a null-terminated string, handling zero bytes by encoding them as non-minimal UTF-8 sequences.
113
+ *
114
+ * Note: the returned pointer needs to be managed manually!
115
+ *
116
+ * @param buffer The buffer to convert.
117
+ * @return A null-terminated string representing the contents of the buffer.
118
+ */
119
+ char* c_buffer_as_null_terminated_string(const struct Pos buffer) {
120
+ uint64_t length = c_buffer_length(buffer);
121
+ uint64_t zero_runes = 0;
122
+ uint8_t* bytes = c_buffer_bytes(buffer);
123
+
124
+ // Count zero runes
125
+ for (uint64_t j = 0; j < length; ++j) {
126
+ zero_runes += !bytes[j];
127
+ }
128
+
129
+ // Allocate buffer for the null-terminated string
130
+ uint64_t n = length + zero_runes;
131
+ char *buf = (char *) malloc((n + 1) * sizeof(*buf));
132
+ ASSERT_NON_NULL(buf)
133
+
134
+ uint64_t i = 0;
135
+ for (uint64_t j = 0; j < length; ++j) {
136
+ buf[i++] = bytes[j];
137
+ if (buf[i-1] == 0) {
138
+ buf[i-1] = 0xc0; // 0b11000000
139
+ buf[i++] = 0x80; // 0b10000000
140
+ }
141
+ }
142
+
143
+ // Null-terminate the string
144
+ buf[n] = '\0';
145
+
146
+ return buf;
147
+ }
148
+
149
+ struct Pos c_buffer_construct_from_null_terminated_string(const char *data_nt) {
150
+ uint64_t n = 0;
151
+ while (data_nt[++n]);
152
+
153
+ return c_buffer_construct(n, (uint8_t *) data_nt);
154
+ }
155
+
156
+
157
+ struct Pos c_buffer_concatenate(const struct Pos left, const struct Pos right) {
158
+ const struct Pos concatenated = c_buffer_construct_zeroed(
159
+ c_buffer_length(left) + c_buffer_length(right));
160
+ for (uint64_t j = 0; j < c_buffer_length(concatenated); ++j)
161
+ c_buffer_bytes(concatenated)[j]
162
+ = j < c_buffer_length(left)
163
+ ? c_buffer_bytes(left)[j]
164
+ : c_buffer_bytes(right)[j - c_buffer_length(left)];
165
+
166
+ erasePositive(left);
167
+ erasePositive(right);
168
+ return concatenated;
169
+ }
170
+
171
+ struct Pos c_buffer_eq(const struct Pos left, const struct Pos right) {
172
+ uint64_t left_len = c_buffer_length(left);
173
+ uint64_t right_len = c_buffer_length(right);
174
+ if (left_len != right_len) {
175
+ erasePositive(left);
176
+ erasePositive(right);
177
+ return BooleanFalse;
178
+ }
179
+ for (uint64_t j = 0; j < left_len; ++j) {
180
+ if (c_buffer_bytes(left)[j] != c_buffer_bytes(right)[j]) {
181
+ erasePositive(left);
182
+ erasePositive(right);
183
+ return BooleanFalse;
184
+ }
185
+ }
186
+ erasePositive(left);
187
+ erasePositive(right);
188
+ return BooleanTrue;
189
+ }
190
+
191
+ struct Pos c_buffer_substring(const struct Pos str, uint64_t start, uint64_t end) {
192
+ const struct Pos substr = c_buffer_construct_zeroed(end - start);
193
+ for (uint64_t j = 0; j < c_buffer_length(substr); ++j) {
194
+ c_buffer_bytes(substr)[j] = c_buffer_bytes(str)[start+j];
195
+ }
196
+ erasePositive(str);
197
+ return substr;
198
+ }
199
+
200
+ struct Pos c_buffer_show_Int(const Int n) {
201
+ char str[24];
202
+ sprintf(str, "%" PRId64, n);
203
+ return c_buffer_construct_from_null_terminated_string(str);
204
+ }
205
+
206
+ struct Pos c_buffer_show_Byte(const uint8_t n) {
207
+ char str[4]; // Byte values range from 0 to 255, 3 characters + null terminator
208
+ sprintf(str, "%" PRIu8, n);
209
+ return c_buffer_construct_from_null_terminated_string(str);
210
+ }
211
+
212
+ struct Pos c_buffer_show_Char(const uint64_t n) {
213
+ char str[5] = {0}; // Max 4 bytes for UTF-8 + 1 for null terminator
214
+ unsigned char *buf = (unsigned char *)str;
215
+
216
+ if (n < 0x80) { // 1-byte sequence
217
+ buf[0] = (unsigned char)n;
218
+ } else if (n < 0x800) { // 2-byte sequence
219
+ buf[0] = (unsigned char)(0xC0 | (n >> 6));
220
+ buf[1] = (unsigned char)(0x80 | (n & 0x3F));
221
+ } else if (n < 0x10000) { // 3-byte sequence
222
+ buf[0] = (unsigned char)(0xE0 | (n >> 12));
223
+ buf[1] = (unsigned char)(0x80 | ((n >> 6) & 0x3F));
224
+ buf[2] = (unsigned char)(0x80 | (n & 0x3F));
225
+ } else if (n < 0x110000) { // 4-byte sequence
226
+ buf[0] = (unsigned char)(0xF0 | (n >> 18));
227
+ buf[1] = (unsigned char)(0x80 | ((n >> 12) & 0x3F));
228
+ buf[2] = (unsigned char)(0x80 | ((n >> 6) & 0x3F));
229
+ buf[3] = (unsigned char)(0x80 | (n & 0x3F));
230
+ }
231
+
232
+ return c_buffer_construct_from_null_terminated_string(str);
233
+ }
234
+
235
+ struct Pos c_buffer_show_Double(const Double x) {
236
+ char str[64]; // TODO is this large enough? Possibly use snprintf first
237
+ sprintf(str, "%g", x);
238
+ return c_buffer_construct_from_null_terminated_string(str);
239
+ }
240
+
241
+ uint64_t c_buffer_index(const struct Pos buffer, const uint64_t index) {
242
+ return c_buffer_bytes(buffer)[index];
243
+ }
244
+
245
+ void c_buffer_set(struct Pos buffer, const uint64_t index, uint8_t value) {
246
+ c_buffer_bytes(buffer)[index] = value;
247
+ }
248
+
249
+ uint32_t c_buffer_character_at(const struct Pos buffer, const uint64_t index) {
250
+ const uint8_t *bytes = c_buffer_bytes(buffer);
251
+ uint8_t first_byte = bytes[index];
252
+ uint32_t character = 0;
253
+
254
+ uint32_t length = c_buffer_length(buffer);
255
+
256
+ if (first_byte < 0x80) {
257
+ // Single-byte character (0xxxxxxx)
258
+ character = first_byte;
259
+ } else if ((first_byte & 0xE0) == 0xC0) {
260
+ // Two-byte character (110xxxxx 10xxxxxx)
261
+ if (index + 1 < length) {
262
+ character = ((first_byte & 0x1F) << 6) |
263
+ (bytes[index + 1] & 0x3F);
264
+ }
265
+ } else if ((first_byte & 0xF0) == 0xE0) {
266
+ // Three-byte character (1110xxxx 10xxxxxx 10xxxxxx)
267
+ if (index + 2 < length) {
268
+ character = ((first_byte & 0x0F) << 12) |
269
+ ((bytes[index + 1] & 0x3F) << 6) |
270
+ (bytes[index + 2] & 0x3F);
271
+ }
272
+ } else if ((first_byte & 0xF8) == 0xF0) {
273
+ // Four-byte character (11110xxx 10xxxxxx 10xxxxxx 10xxxxxx)
274
+ if (index + 3 < length) {
275
+ character = ((first_byte & 0x07) << 18) |
276
+ ((bytes[index + 1] & 0x3F) << 12) |
277
+ ((bytes[index + 2] & 0x3F) << 6) |
278
+ (bytes[index + 3] & 0x3F);
279
+ }
280
+ }
281
+
282
+ erasePositive(buffer);
283
+ return character;
284
+ }
285
+
286
+ #endif
@@ -0,0 +1,43 @@
1
+ ; forward-declared from primitives.c
2
+
3
+ declare i64 @c_get_argc()
4
+ declare %Pos @c_get_arg(i64)
5
+
6
+ declare void @c_io_println_Boolean(%Pos)
7
+ declare void @c_io_println_Int(%Int)
8
+ declare void @c_io_println_Double(%Double)
9
+ declare void @c_io_println_String(%Pos)
10
+
11
+ declare %Pos @c_buffer_construct(i64, ptr)
12
+ declare %Pos @c_buffer_concatenate(%Pos, %Pos)
13
+ declare ptr @c_buffer_as_null_terminated_string(%Pos)
14
+ declare %Pos @c_buffer_construct_from_null_terminated_string(ptr)
15
+ declare ptr @c_buffer_construct_uninitialized(i64)
16
+ declare ptr @c_buffer_bytes(ptr)
17
+ declare void @c_buffer_copy(%Pos, %Pos, i64, i64, i64)
18
+ declare %Pos @c_buffer_clone(%Pos)
19
+
20
+ declare %Pos @c_buffer_eq(%Pos, %Pos)
21
+ declare %Pos @c_buffer_substring(%Pos, i64, i64)
22
+ declare i64 @c_buffer_length(%Pos)
23
+ declare i64 @c_buffer_toInt(%Pos)
24
+ declare %Pos @c_buffer_show_Int(i64)
25
+ declare %Pos @c_buffer_show_Char(i32)
26
+ declare %Pos @c_buffer_show_Byte(i8)
27
+ declare %Pos @c_buffer_show_Double(double)
28
+ declare %Int @c_buffer_index(%Pos, i64)
29
+ declare void @c_buffer_set(%Pos, i64, i8)
30
+ declare %Int @c_buffer_character_at(%Pos, i64)
31
+
32
+ declare %Pos @c_buffer_slice(%Pos, i64, i64)
33
+
34
+ declare void @hole()
35
+
36
+ declare %Pos @c_ref_fresh(%Pos)
37
+ declare %Pos @c_ref_get(%Pos)
38
+ declare %Pos @c_ref_set(%Pos, %Pos)
39
+
40
+ declare %Pos @c_array_new(%Int)
41
+ declare %Int @c_array_size(%Pos)
42
+ declare %Pos @c_array_get(%Pos, %Int)
43
+ declare %Pos @c_array_set(%Pos, %Int, %Pos)
@@ -0,0 +1,11 @@
1
+ #ifndef EFFEKT_HOLE_C
2
+ #define EFFEKT_HOLE_C
3
+
4
+ #include <stdio.h>
5
+
6
+ void hole() {
7
+ fprintf(stderr, "PANIC: Reached a hole in the program\n");
8
+ exit(1);
9
+ }
10
+
11
+ #endif