@effekt-lang/effekt 0.5.0 → 0.7.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/bytearray.effekt +71 -0
- package/libraries/common/effekt.effekt +8 -8
- package/libraries/common/io/console.effekt +1 -2
- package/libraries/common/io/filesystem.effekt +46 -62
- package/libraries/common/io/network.effekt +9 -9
- package/libraries/common/io/time.effekt +1 -1
- package/libraries/common/io.effekt +5 -5
- package/libraries/common/ref.effekt +1 -1
- package/libraries/common/string.effekt +3 -14
- package/libraries/js/effekt_builtins.js +5 -1
- package/libraries/js/effekt_runtime.js +185 -352
- package/libraries/llvm/bytearray.c +209 -0
- package/libraries/llvm/forward-declare-c.ll +23 -23
- package/libraries/llvm/io.c +13 -15
- package/libraries/llvm/main.c +3 -3
- package/libraries/llvm/rts.ll +267 -159
- package/libraries/llvm/types.c +3 -2
- package/licenses/eclipse public license, version 2.0 - epl-2.0.html +2 -2
- package/package.json +1 -1
- package/libraries/common/bytes.effekt +0 -115
- package/libraries/js/unsafe/cont.effekt +0 -11
- package/libraries/llvm/buffer.c +0 -286
- package/licenses/mit license - mit-license.html +0 -1240
- package/licenses/the bsd license - bsd-license.html +0 -1236
- package/licenses/the mit license - mit.html +0 -1240
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
#ifndef EFFEKT_BYTEARRAY_C
|
|
2
|
+
#define EFFEKT_BYTEARRAY_C
|
|
3
|
+
|
|
4
|
+
#include <string.h> // For memcopy
|
|
5
|
+
|
|
6
|
+
/** We represent bytearrays like positive types.
|
|
7
|
+
*
|
|
8
|
+
* - The field `tag` contains the size
|
|
9
|
+
* - The field `obj` points to memory with the following layout:
|
|
10
|
+
*
|
|
11
|
+
* +--[ Header ]--+--------------+
|
|
12
|
+
* | Rc | Eraser | Contents ... |
|
|
13
|
+
* +--------------+--------------+
|
|
14
|
+
*
|
|
15
|
+
* The eraser does nothing.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
void c_bytearray_erase_noop(void *envPtr) { (void)envPtr; }
|
|
20
|
+
|
|
21
|
+
struct Pos c_bytearray_new(const Int size) {
|
|
22
|
+
void *objPtr = malloc(sizeof(struct Header) + size);
|
|
23
|
+
struct Header *headerPtr = objPtr;
|
|
24
|
+
*headerPtr = (struct Header) { .rc = 0, .eraser = c_bytearray_erase_noop, };
|
|
25
|
+
return (struct Pos) {
|
|
26
|
+
.tag = size,
|
|
27
|
+
.obj = objPtr,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
Int c_bytearray_size(const struct Pos arr) {
|
|
32
|
+
return arr.tag;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
uint8_t* c_bytearray_data(const struct Pos arr) {
|
|
36
|
+
return arr.obj + sizeof(struct Header);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
Byte c_bytearray_get(const struct Pos arr, const Int index) {
|
|
40
|
+
Byte *dataPtr = arr.obj + sizeof(struct Header);
|
|
41
|
+
Byte element = dataPtr[index];
|
|
42
|
+
return element;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
struct Pos c_bytearray_set(const struct Pos arr, const Int index, const Byte value) {
|
|
46
|
+
Byte *dataPtr = arr.obj + sizeof(struct Header);
|
|
47
|
+
dataPtr[index] = value;
|
|
48
|
+
return Unit;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
struct Pos c_bytearray_construct(const uint64_t n, const uint8_t *data) {
|
|
52
|
+
struct Pos arr = c_bytearray_new(n);
|
|
53
|
+
|
|
54
|
+
memcpy(c_bytearray_data(arr), data, n);
|
|
55
|
+
|
|
56
|
+
return arr;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Complex Operations
|
|
60
|
+
|
|
61
|
+
struct Pos c_bytearray_from_nullterminated_string(const char *data) {
|
|
62
|
+
uint64_t n = 0;
|
|
63
|
+
while (data[++n]);
|
|
64
|
+
|
|
65
|
+
return c_bytearray_construct(n, (uint8_t*)data);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
char* c_bytearray_into_nullterminated_string(const struct Pos arr) {
|
|
69
|
+
uint64_t size = c_bytearray_size(arr);
|
|
70
|
+
|
|
71
|
+
char* result = (char*)malloc(size + 1);
|
|
72
|
+
|
|
73
|
+
memcpy(result, c_bytearray_data(arr), size);
|
|
74
|
+
|
|
75
|
+
result[size] = '\0';
|
|
76
|
+
|
|
77
|
+
// TODO we should erase the input
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// TODO do this in Effekt
|
|
82
|
+
struct Pos c_bytearray_show_Int(const Int n) {
|
|
83
|
+
char str[24];
|
|
84
|
+
sprintf(str, "%" PRId64, n);
|
|
85
|
+
return c_bytearray_from_nullterminated_string(str);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// TODO do this in Effekt
|
|
89
|
+
struct Pos c_bytearray_show_Char(const uint64_t n) {
|
|
90
|
+
char str[5] = {0}; // Max 4 bytes for UTF-8 + 1 for null terminator
|
|
91
|
+
unsigned char *buf = (unsigned char *)str;
|
|
92
|
+
|
|
93
|
+
if (n < 0x80) { // 1-byte sequence
|
|
94
|
+
buf[0] = (unsigned char)n;
|
|
95
|
+
} else if (n < 0x800) { // 2-byte sequence
|
|
96
|
+
buf[0] = (unsigned char)(0xC0 | (n >> 6));
|
|
97
|
+
buf[1] = (unsigned char)(0x80 | (n & 0x3F));
|
|
98
|
+
} else if (n < 0x10000) { // 3-byte sequence
|
|
99
|
+
buf[0] = (unsigned char)(0xE0 | (n >> 12));
|
|
100
|
+
buf[1] = (unsigned char)(0x80 | ((n >> 6) & 0x3F));
|
|
101
|
+
buf[2] = (unsigned char)(0x80 | (n & 0x3F));
|
|
102
|
+
} else if (n < 0x110000) { // 4-byte sequence
|
|
103
|
+
buf[0] = (unsigned char)(0xF0 | (n >> 18));
|
|
104
|
+
buf[1] = (unsigned char)(0x80 | ((n >> 12) & 0x3F));
|
|
105
|
+
buf[2] = (unsigned char)(0x80 | ((n >> 6) & 0x3F));
|
|
106
|
+
buf[3] = (unsigned char)(0x80 | (n & 0x3F));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return c_bytearray_from_nullterminated_string(str);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// TODO do this in Effekt
|
|
113
|
+
struct Pos c_bytearray_show_Byte(const Byte n) {
|
|
114
|
+
char str[4]; // Byte values range from 0 to 255, 3 characters + null terminator
|
|
115
|
+
sprintf(str, "%" PRIu8, n);
|
|
116
|
+
return c_bytearray_from_nullterminated_string(str);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// TODO do this in Effekt
|
|
120
|
+
struct Pos c_bytearray_show_Double(const Double x) {
|
|
121
|
+
char str[64]; // TODO is this large enough? Possibly use snprintf first
|
|
122
|
+
sprintf(str, "%g", x);
|
|
123
|
+
return c_bytearray_from_nullterminated_string(str);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// TODO do this in Effekt
|
|
127
|
+
struct Pos c_bytearray_concatenate(const struct Pos left, const struct Pos right) {
|
|
128
|
+
const struct Pos concatenated = c_bytearray_new(c_bytearray_size(left) + c_bytearray_size(right));
|
|
129
|
+
for (int64_t j = 0; j < c_bytearray_size(concatenated); ++j)
|
|
130
|
+
c_bytearray_data(concatenated)[j]
|
|
131
|
+
= j < c_bytearray_size(left)
|
|
132
|
+
? c_bytearray_data(left)[j]
|
|
133
|
+
: c_bytearray_data(right)[j - c_bytearray_size(left)];
|
|
134
|
+
|
|
135
|
+
erasePositive(left);
|
|
136
|
+
erasePositive(right);
|
|
137
|
+
return concatenated;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// TODO do this in Effekt
|
|
141
|
+
struct Pos c_bytearray_equal(const struct Pos left, const struct Pos right) {
|
|
142
|
+
uint64_t left_size = c_bytearray_size(left);
|
|
143
|
+
uint64_t right_size = c_bytearray_size(right);
|
|
144
|
+
if (left_size != right_size) {
|
|
145
|
+
erasePositive(left);
|
|
146
|
+
erasePositive(right);
|
|
147
|
+
return BooleanFalse;
|
|
148
|
+
}
|
|
149
|
+
for (uint64_t j = 0; j < left_size; ++j) {
|
|
150
|
+
if (c_bytearray_data(left)[j] != c_bytearray_data(right)[j]) {
|
|
151
|
+
erasePositive(left);
|
|
152
|
+
erasePositive(right);
|
|
153
|
+
return BooleanFalse;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
erasePositive(left);
|
|
157
|
+
erasePositive(right);
|
|
158
|
+
return BooleanTrue;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// TODO deprecate
|
|
162
|
+
struct Pos c_bytearray_substring(const struct Pos str, uint64_t start, uint64_t end) {
|
|
163
|
+
const struct Pos substr = c_bytearray_new(end - start);
|
|
164
|
+
for (int64_t j = 0; j < c_bytearray_size(substr); ++j) {
|
|
165
|
+
c_bytearray_data(substr)[j] = c_bytearray_data(str)[start+j];
|
|
166
|
+
}
|
|
167
|
+
erasePositive(str);
|
|
168
|
+
return substr;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// TODO deprecate
|
|
172
|
+
uint32_t c_bytearray_character_at(const struct Pos str, const uint64_t index) {
|
|
173
|
+
const uint8_t *bytes = c_bytearray_data(str);
|
|
174
|
+
uint8_t first_byte = bytes[index];
|
|
175
|
+
uint32_t character = 0;
|
|
176
|
+
|
|
177
|
+
uint32_t length = c_bytearray_size(str);
|
|
178
|
+
|
|
179
|
+
if (first_byte < 0x80) {
|
|
180
|
+
// Single-byte character (0xxxxxxx)
|
|
181
|
+
character = first_byte;
|
|
182
|
+
} else if ((first_byte & 0xE0) == 0xC0) {
|
|
183
|
+
// Two-byte character (110xxxxx 10xxxxxx)
|
|
184
|
+
if (index + 1 < length) {
|
|
185
|
+
character = ((first_byte & 0x1F) << 6) |
|
|
186
|
+
(bytes[index + 1] & 0x3F);
|
|
187
|
+
}
|
|
188
|
+
} else if ((first_byte & 0xF0) == 0xE0) {
|
|
189
|
+
// Three-byte character (1110xxxx 10xxxxxx 10xxxxxx)
|
|
190
|
+
if (index + 2 < length) {
|
|
191
|
+
character = ((first_byte & 0x0F) << 12) |
|
|
192
|
+
((bytes[index + 1] & 0x3F) << 6) |
|
|
193
|
+
(bytes[index + 2] & 0x3F);
|
|
194
|
+
}
|
|
195
|
+
} else if ((first_byte & 0xF8) == 0xF0) {
|
|
196
|
+
// Four-byte character (11110xxx 10xxxxxx 10xxxxxx 10xxxxxx)
|
|
197
|
+
if (index + 3 < length) {
|
|
198
|
+
character = ((first_byte & 0x07) << 18) |
|
|
199
|
+
((bytes[index + 1] & 0x3F) << 12) |
|
|
200
|
+
((bytes[index + 2] & 0x3F) << 6) |
|
|
201
|
+
(bytes[index + 3] & 0x3F);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
erasePositive(str);
|
|
206
|
+
return character;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
#endif
|
|
@@ -8,29 +8,6 @@ declare void @c_io_println_Int(%Int)
|
|
|
8
8
|
declare void @c_io_println_Double(%Double)
|
|
9
9
|
declare void @c_io_println_String(%Pos)
|
|
10
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
11
|
declare void @hole()
|
|
35
12
|
|
|
36
13
|
declare %Pos @c_ref_fresh(%Pos)
|
|
@@ -41,3 +18,26 @@ declare %Pos @c_array_new(%Int)
|
|
|
41
18
|
declare %Int @c_array_size(%Pos)
|
|
42
19
|
declare %Pos @c_array_get(%Pos, %Int)
|
|
43
20
|
declare %Pos @c_array_set(%Pos, %Int, %Pos)
|
|
21
|
+
|
|
22
|
+
declare %Pos @c_bytearray_new(%Int)
|
|
23
|
+
declare %Int @c_bytearray_size(%Pos)
|
|
24
|
+
declare %Byte @c_bytearray_get(%Pos, %Int)
|
|
25
|
+
declare %Pos @c_bytearray_set(%Pos, %Int, %Byte)
|
|
26
|
+
|
|
27
|
+
declare ptr @c_bytearray_data(%Pos)
|
|
28
|
+
declare %Pos @c_bytearray_construct(i64, ptr)
|
|
29
|
+
|
|
30
|
+
declare %Pos @c_bytearray_from_nullterminated_string(ptr)
|
|
31
|
+
declare ptr @c_bytearray_into_nullterminated_string(%Pos)
|
|
32
|
+
|
|
33
|
+
declare %Pos @c_bytearray_show_Int(i64)
|
|
34
|
+
declare %Pos @c_bytearray_show_Char(i32)
|
|
35
|
+
declare %Pos @c_bytearray_show_Byte(i8)
|
|
36
|
+
declare %Pos @c_bytearray_show_Double(double)
|
|
37
|
+
|
|
38
|
+
declare %Pos @c_bytearray_concatenate(%Pos, %Pos)
|
|
39
|
+
declare %Pos @c_bytearray_equal(%Pos, %Pos)
|
|
40
|
+
|
|
41
|
+
declare %Pos @c_bytearray_substring(%Pos, i64, i64)
|
|
42
|
+
declare %Int @c_bytearray_character_at(%Pos, i64)
|
|
43
|
+
|
package/libraries/llvm/io.c
CHANGED
|
@@ -20,8 +20,8 @@ void c_io_println_Double(const Double x) {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
void c_io_println_String(String text) {
|
|
23
|
-
for (
|
|
24
|
-
putchar(
|
|
23
|
+
for (int64_t j = 0; j < c_bytearray_size(text); ++j)
|
|
24
|
+
putchar(c_bytearray_data(text)[j]);
|
|
25
25
|
erasePositive(text);
|
|
26
26
|
putchar('\n');
|
|
27
27
|
}
|
|
@@ -34,7 +34,7 @@ void c_io_println_String(String text) {
|
|
|
34
34
|
// Share memory between Effekt-buffers and libuv buffers
|
|
35
35
|
// -----------------------------------------------------
|
|
36
36
|
// A libuv buffer is a {ptr, i64} where i64 is the capacity
|
|
37
|
-
// while our buffer (from
|
|
37
|
+
// while our buffer (from bytearray.c, which is ref-counted) is a %Pos with a
|
|
38
38
|
// pointer and a length. The data ptr is shared between the two such that
|
|
39
39
|
// libuv (and underlying mechanisms) can directly write into our buffer without
|
|
40
40
|
// copying. Since our buffer is ref-counted, this has the advantage that we
|
|
@@ -96,10 +96,10 @@ int modeFlags(struct Pos mode) {
|
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
void c_fs_open(
|
|
99
|
+
void c_fs_open(String path, struct Pos mode, Stack stack) {
|
|
100
100
|
|
|
101
101
|
// Convert the Effekt String to a 0-terminated string
|
|
102
|
-
char* path_str =
|
|
102
|
+
char* path_str = c_bytearray_into_nullterminated_string(path);
|
|
103
103
|
erasePositive((struct Pos) path);
|
|
104
104
|
|
|
105
105
|
// Convert the Effekt String representing the opening mode to libuv flags
|
|
@@ -123,17 +123,16 @@ void c_fs_open(struct Pos path, struct Pos mode, Stack stack) {
|
|
|
123
123
|
return;
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
void c_fs_read(Int
|
|
126
|
+
void c_fs_read(Int file, struct Pos buffer, Int offset, Int size, Int position, Stack stack) {
|
|
127
127
|
|
|
128
|
-
|
|
129
|
-
uv_buf_t buf = uv_buf_init(bytes, c_buffer_length(buffer));
|
|
128
|
+
uv_buf_t buf = uv_buf_init((char*)(c_bytearray_data(buffer) + offset), size);
|
|
130
129
|
// erasePositive(buffer);
|
|
131
130
|
// TODO we should erase the buffer but abort if this was the last reference
|
|
132
131
|
|
|
133
132
|
uv_fs_t* request = malloc(sizeof(uv_fs_t));
|
|
134
133
|
request->data = stack;
|
|
135
134
|
|
|
136
|
-
int result = uv_fs_read(uv_default_loop(), request,
|
|
135
|
+
int result = uv_fs_read(uv_default_loop(), request, file, &buf, 1, position, c_resume_int_fs);
|
|
137
136
|
|
|
138
137
|
if (result < 0) {
|
|
139
138
|
uv_fs_req_cleanup(request);
|
|
@@ -142,17 +141,16 @@ void c_fs_read(Int fd, struct Pos buffer, Int offset, Stack stack) {
|
|
|
142
141
|
}
|
|
143
142
|
}
|
|
144
143
|
|
|
145
|
-
void c_fs_write(Int
|
|
144
|
+
void c_fs_write(Int file, struct Pos buffer, Int offset, Int size, Int position, Stack stack) {
|
|
146
145
|
|
|
147
|
-
|
|
148
|
-
uv_buf_t buf = uv_buf_init(bytes, c_buffer_length(buffer));
|
|
146
|
+
uv_buf_t buf = uv_buf_init((char*)(c_bytearray_data(buffer) + offset), size);
|
|
149
147
|
// erasePositive(buffer);
|
|
150
148
|
// TODO we should erase the buffer but abort if this was the last reference
|
|
151
149
|
|
|
152
150
|
uv_fs_t* request = malloc(sizeof(uv_fs_t));
|
|
153
151
|
request->data = stack;
|
|
154
152
|
|
|
155
|
-
int result = uv_fs_write(uv_default_loop(), request,
|
|
153
|
+
int result = uv_fs_write(uv_default_loop(), request, file, &buf, 1, position, c_resume_int_fs);
|
|
156
154
|
|
|
157
155
|
if (result < 0) {
|
|
158
156
|
uv_fs_req_cleanup(request);
|
|
@@ -161,12 +159,12 @@ void c_fs_write(Int fd, struct Pos buffer, Int offset, Stack stack) {
|
|
|
161
159
|
}
|
|
162
160
|
}
|
|
163
161
|
|
|
164
|
-
void c_fs_close(Int
|
|
162
|
+
void c_fs_close(Int file, Stack stack) {
|
|
165
163
|
|
|
166
164
|
uv_fs_t* request = malloc(sizeof(uv_fs_t));
|
|
167
165
|
request->data = stack;
|
|
168
166
|
|
|
169
|
-
int result = uv_fs_close(uv_default_loop(), request,
|
|
167
|
+
int result = uv_fs_close(uv_default_loop(), request, file, c_resume_int_fs);
|
|
170
168
|
|
|
171
169
|
if (result < 0) {
|
|
172
170
|
uv_fs_req_cleanup(request);
|
package/libraries/llvm/main.c
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
#include "sanity.c"
|
|
13
13
|
#include "types.c"
|
|
14
|
-
#include "
|
|
14
|
+
#include "bytearray.c"
|
|
15
15
|
#include "io.c"
|
|
16
16
|
#include "hole.c"
|
|
17
17
|
#include "ref.c"
|
|
@@ -25,9 +25,9 @@ char** program_argv;
|
|
|
25
25
|
|
|
26
26
|
struct Pos c_get_arg(uint64_t idx) {
|
|
27
27
|
if(idx < (uint64_t)program_argc) {
|
|
28
|
-
return
|
|
28
|
+
return c_bytearray_from_nullterminated_string(program_argv[idx]);
|
|
29
29
|
} else {
|
|
30
|
-
return
|
|
30
|
+
return c_bytearray_new(0);
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
uint64_t c_get_argc() {
|