@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
|
@@ -1,385 +1,218 @@
|
|
|
1
|
-
const $runtime = (function() {
|
|
2
1
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
var _backup = _value
|
|
13
|
-
var cell = this;
|
|
14
|
-
return () => { _value = _backup; return cell }
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
|
-
// $getOp and $putOp are auto generated from the compiler
|
|
18
|
-
cell[$getOp] = function() {
|
|
19
|
-
return _value
|
|
20
|
-
};
|
|
21
|
-
cell[$putOp] = function(v) {
|
|
22
|
-
_value = v;
|
|
23
|
-
return $effekt.unit;
|
|
24
|
-
};
|
|
25
|
-
return cell
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function Arena() {
|
|
29
|
-
return {
|
|
30
|
-
fields: [], // Array[Cell],
|
|
31
|
-
fresh: function(init) {
|
|
32
|
-
const cell = Cell(init)
|
|
33
|
-
this.fields.push(cell)
|
|
34
|
-
return cell;
|
|
35
|
-
},
|
|
36
|
-
backup: function() {
|
|
37
|
-
return this.fields.map(c => c.backup())
|
|
38
|
-
},
|
|
39
|
-
restore: function(backup) {
|
|
40
|
-
this.fields = backup.map(c => c());
|
|
41
|
-
return this
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const global = {
|
|
47
|
-
fresh: function(init) { return Cell(init) },
|
|
48
|
-
backup: function() {},
|
|
49
|
-
restore: function(_) {}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Lists / Pairs
|
|
53
|
-
function Cons(head, tail) {
|
|
54
|
-
return { head: head, tail: tail }
|
|
55
|
-
}
|
|
56
|
-
const Nil = null
|
|
57
|
-
|
|
58
|
-
// reverseOnto[A, B, C](init: Frames[A, B], tail: Stack[B, C]): Stack[A, C]
|
|
59
|
-
function reverseOnto(init, tail) {
|
|
60
|
-
let rest = init;
|
|
61
|
-
let result = tail;
|
|
62
|
-
while (rest !== Nil) {
|
|
63
|
-
result = Cons(rest.head, result)
|
|
64
|
-
rest = rest.tail
|
|
65
|
-
}
|
|
66
|
-
return result
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
let _prompt = 2;
|
|
70
|
-
|
|
71
|
-
// Monadic Style Runtime
|
|
72
|
-
// ---------------------
|
|
73
|
-
|
|
74
|
-
const toplevel = 1;
|
|
75
|
-
|
|
76
|
-
// Result -- Trampoline
|
|
77
|
-
function Step(c, k) {
|
|
78
|
-
return { isStep: true, c: c, k: k }
|
|
79
|
-
}
|
|
80
|
-
function trampoline(r) {
|
|
81
|
-
var res = r
|
|
82
|
-
while (res !== null && res !== undefined && res.isStep) {
|
|
83
|
-
res = res.c.apply(res.k)
|
|
84
|
-
}
|
|
85
|
-
return res
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Frame = A => Control[B]
|
|
89
|
-
|
|
90
|
-
// Metacontinuations / Stacks
|
|
91
|
-
// (frames: List<Frame>, fields: [Cell], prompt: Int, tail: Stack) -> Stack
|
|
92
|
-
function Stack(frames, arena, prompt, tail) {
|
|
93
|
-
return { frames: frames, arena: arena, prompt: prompt, tail: tail }
|
|
94
|
-
}
|
|
95
|
-
function SubStack(frames, arena, backup, prompt, tail) {
|
|
96
|
-
return { frames: frames, arena: arena, backup: backup, prompt: prompt, tail: tail }
|
|
97
|
-
}
|
|
98
|
-
const EmptyStack = null;
|
|
99
|
-
|
|
100
|
-
// (stack: Stack<A, B>, a: A) -> Step<B>
|
|
101
|
-
function apply(stack, a) {
|
|
102
|
-
var s = stack;
|
|
103
|
-
while (true) {
|
|
104
|
-
if (s === EmptyStack) return a;
|
|
105
|
-
const fs = s.frames;
|
|
106
|
-
if (fs === Nil) { s = s.tail; continue }
|
|
107
|
-
const result = fs.head(a);
|
|
108
|
-
s.frames = fs.tail;
|
|
109
|
-
return Step(result, s)
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// (subcont: Stack, stack: Stack) -> Stack
|
|
114
|
-
function pushSubcont(subcont, stack) {
|
|
115
|
-
var sub = subcont;
|
|
116
|
-
var s = stack;
|
|
117
|
-
|
|
118
|
-
while (sub !== EmptyStack) {
|
|
119
|
-
s = Stack(sub.frames, sub.arena.restore(sub.backup), sub.prompt, s)
|
|
120
|
-
sub = sub.tail
|
|
2
|
+
// Common Runtime
|
|
3
|
+
// --------------
|
|
4
|
+
function Cell(init, region) {
|
|
5
|
+
const cell = {
|
|
6
|
+
value: init,
|
|
7
|
+
backup: function() {
|
|
8
|
+
const _backup = cell.value;
|
|
9
|
+
// restore function (has a STRONG reference to `this`)
|
|
10
|
+
return () => { cell.value = _backup; return cell }
|
|
121
11
|
}
|
|
122
|
-
return s;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function flatMap(stack, f) {
|
|
126
|
-
if (stack === EmptyStack) { return Stack(Cons(f, Nil), Arena(), null, stack) }
|
|
127
|
-
var fs = stack.frames
|
|
128
|
-
// it should be safe to mutate the frames field, since they are copied in the subcont
|
|
129
|
-
stack.frames = Cons(f, fs)
|
|
130
|
-
return stack
|
|
131
12
|
}
|
|
13
|
+
return cell;
|
|
14
|
+
}
|
|
132
15
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
16
|
+
const global = {
|
|
17
|
+
fresh: Cell
|
|
18
|
+
}
|
|
136
19
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
20
|
+
function Arena(_region) {
|
|
21
|
+
const region = _region;
|
|
22
|
+
return {
|
|
23
|
+
fresh: function(init) {
|
|
24
|
+
const cell = Cell(init);
|
|
25
|
+
// region keeps track what to backup, but we do not need to backup unreachable cells
|
|
26
|
+
region.push(new WeakRef(cell))
|
|
27
|
+
return cell;
|
|
28
|
+
},
|
|
29
|
+
region: _region,
|
|
30
|
+
newRegion: function() {
|
|
31
|
+
// a region aggregates weak references
|
|
32
|
+
const nested = Arena([])
|
|
33
|
+
// this doesn't work yet, since Arena.backup doesn't return a thunk
|
|
34
|
+
region.push(new WeakRef(nested))
|
|
35
|
+
return nested;
|
|
36
|
+
},
|
|
37
|
+
backup: function() {
|
|
38
|
+
const _backup = []
|
|
39
|
+
let nextIndex = 0;
|
|
40
|
+
for (const ref of region) {
|
|
41
|
+
// console.log(ref)
|
|
42
|
+
const cell = ref.deref()
|
|
43
|
+
// only backup live cells
|
|
44
|
+
if (cell) {
|
|
45
|
+
_backup[nextIndex] = cell.backup()
|
|
46
|
+
nextIndex++
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function restore() {
|
|
50
|
+
const region = []
|
|
51
|
+
let nextIndex = 0;
|
|
52
|
+
for (const restoreCell of _backup) {
|
|
53
|
+
region[nextIndex] = new WeakRef(restoreCell())
|
|
54
|
+
nextIndex++
|
|
55
|
+
}
|
|
56
|
+
return Arena(region)
|
|
155
57
|
}
|
|
58
|
+
return restore;
|
|
156
59
|
}
|
|
157
|
-
throw ("Prompt " + p + " not found")
|
|
158
60
|
}
|
|
61
|
+
}
|
|
159
62
|
|
|
160
|
-
function withState(init, f) {
|
|
161
|
-
return Control(k => {
|
|
162
|
-
const cell = k.arena.fresh(init)
|
|
163
|
-
return Step(f(cell), k)
|
|
164
|
-
})
|
|
165
|
-
}
|
|
166
63
|
|
|
167
|
-
|
|
168
|
-
return Control(k => {
|
|
169
|
-
return Step(prog(k.arena), k)
|
|
170
|
-
})
|
|
171
|
-
}
|
|
64
|
+
let _prompt = 1;
|
|
172
65
|
|
|
173
|
-
|
|
174
|
-
|
|
66
|
+
const TOPLEVEL_K = (x, ks) => { throw { computationIsDone: true, result: x } }
|
|
67
|
+
const TOPLEVEL_KS = { prompt: 0, arena: Arena([]), rest: null }
|
|
175
68
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
allocateInto(k, prompt, cell);
|
|
181
|
-
return Step(f(cell), k)
|
|
182
|
-
})
|
|
183
|
-
}
|
|
184
|
-
}
|
|
69
|
+
function THUNK(f) {
|
|
70
|
+
f.thunk = true
|
|
71
|
+
return f
|
|
72
|
+
}
|
|
185
73
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
then: f => Control(k => Step(self, flatMap(k, f))),
|
|
192
|
-
state: f => self.then(init => withState(init, f))
|
|
193
|
-
}
|
|
194
|
-
return self
|
|
74
|
+
function CAPTURE(body) {
|
|
75
|
+
return (ks, k) => {
|
|
76
|
+
const res = body(x => TRAMPOLINE(() => k(x, ks)))
|
|
77
|
+
if (res instanceof Function) return res
|
|
78
|
+
else throw { computationIsDone: true, result: $effekt.unit }
|
|
195
79
|
}
|
|
80
|
+
}
|
|
196
81
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
const delayed = a => Control(k => apply(k, a()))
|
|
200
|
-
|
|
201
|
-
const shift = (p, f) => Control(k => {
|
|
202
|
-
const split = splitAt(k, p)
|
|
203
|
-
const localCont = a => Control(k =>
|
|
204
|
-
Step(pure(a), pushSubcont(split.head, k)))
|
|
205
|
-
return Step(f(localCont), split.tail)
|
|
206
|
-
})
|
|
207
|
-
|
|
208
|
-
const callcc = f => Control(k => {
|
|
209
|
-
return f(a => trampoline(apply(k, a)))
|
|
210
|
-
})
|
|
82
|
+
const RETURN = (x, ks) => ks.rest.stack(x, ks.rest)
|
|
211
83
|
|
|
212
|
-
|
|
84
|
+
// const r = ks.arena.newRegion(); body
|
|
85
|
+
// const x = r.alloc(init); body
|
|
213
86
|
|
|
87
|
+
// HANDLE(ks, ks, (p, ks, k) => { STMT })
|
|
88
|
+
function RESET(prog, ks, k) {
|
|
89
|
+
const prompt = _prompt++;
|
|
90
|
+
const rest = { stack: k, prompt: ks.prompt, arena: ks.arena, rest: ks.rest }
|
|
91
|
+
return prog(prompt, { prompt, arena: Arena([]), rest }, RETURN)
|
|
92
|
+
}
|
|
214
93
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
k({
|
|
220
|
-
shouldRun: false,
|
|
221
|
-
cont : () => k({ shouldRun: true, cont: action })
|
|
222
|
-
})).then(a => a.shouldRun ? a.cont() : $effekt.pure(a.cont))
|
|
94
|
+
function DEALLOC(ks) {
|
|
95
|
+
const arena = ks.arena
|
|
96
|
+
if (!!arena) {
|
|
97
|
+
arena.length = arena.length - 1
|
|
223
98
|
}
|
|
99
|
+
}
|
|
224
100
|
|
|
225
|
-
|
|
101
|
+
function SHIFT(p, body, ks, k) {
|
|
226
102
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
// Direct Style Runtime
|
|
233
|
-
// --------------------
|
|
103
|
+
// TODO avoid constructing this object
|
|
104
|
+
let meta = { stack: k, prompt: ks.prompt, arena: ks.arena, rest: ks.rest }
|
|
105
|
+
let cont = null
|
|
234
106
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
class Segment {
|
|
239
|
-
constructor(frames, prompt, region, backup, tail) {
|
|
240
|
-
this.frames = frames;
|
|
241
|
-
this.prompt = prompt;
|
|
242
|
-
this.region = region;
|
|
243
|
-
this.backup = backup;
|
|
244
|
-
this.tail = tail;
|
|
245
|
-
}
|
|
107
|
+
while (!!meta && meta.prompt !== p) {
|
|
108
|
+
cont = { stack: meta.stack, prompt: meta.prompt, backup: meta.arena.backup(), rest: cont }
|
|
109
|
+
meta = meta.rest
|
|
246
110
|
}
|
|
247
|
-
|
|
111
|
+
if (!meta) { throw `Prompt not found ${p}` }
|
|
248
112
|
|
|
249
|
-
//
|
|
250
|
-
|
|
251
|
-
|
|
113
|
+
// package the prompt itself
|
|
114
|
+
cont = { stack: meta.stack, prompt: meta.prompt, backup: meta.arena.backup(), rest: cont }
|
|
115
|
+
meta = meta.rest
|
|
252
116
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
if (s.prompt === prompt) {
|
|
256
|
-
return s.body((value) => rewind(k, () => value))
|
|
257
|
-
} else {
|
|
258
|
-
throw new Suspension(s.prompt, s.body, Nil, k)
|
|
259
|
-
}
|
|
117
|
+
function resumeValue(a, ks, k) {
|
|
118
|
+
return resumeComp((ks, k) => k(a, ks), ks, k)
|
|
260
119
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
let rest = k.frames // the pure frames
|
|
269
|
-
|
|
270
|
-
// The trampoline
|
|
271
|
-
try {
|
|
272
|
-
enterRegion(region);
|
|
273
|
-
region.restore(k.backup);
|
|
274
|
-
|
|
275
|
-
let curr = rewind(k.tail, thunk)
|
|
276
|
-
while (rest !== Nil) {
|
|
277
|
-
const f = rest.head
|
|
278
|
-
rest = rest.tail
|
|
279
|
-
curr = f(curr)
|
|
280
|
-
}
|
|
281
|
-
return curr
|
|
282
|
-
} catch (s) {
|
|
283
|
-
return handleOrRethrow(prompt, s, rest)
|
|
284
|
-
} finally {
|
|
285
|
-
leaveRegion()
|
|
286
|
-
}
|
|
120
|
+
function resumeComp(c, ks, k) {
|
|
121
|
+
//console.log("Resuming", ks.arena)
|
|
122
|
+
let meta = { stack: k, prompt: ks.prompt, arena: ks.arena, rest: ks.rest }
|
|
123
|
+
let toRewind = cont
|
|
124
|
+
while (!!toRewind) {
|
|
125
|
+
meta = { stack: toRewind.stack, prompt: toRewind.prompt, arena: toRewind.backup(), rest: meta }
|
|
126
|
+
toRewind = toRewind.rest
|
|
287
127
|
}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
128
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
// pure: Frames[X, Y],
|
|
295
|
-
// cont: Resumption[A, X]
|
|
296
|
-
// )
|
|
297
|
-
class Suspension {
|
|
298
|
-
constructor(p, body, frames, cont) {
|
|
299
|
-
this.prompt = p;
|
|
300
|
-
this.body = body;
|
|
301
|
-
this.frames = frames;
|
|
302
|
-
this.cont = cont;
|
|
303
|
-
}
|
|
129
|
+
const k2 = meta.stack // TODO instead copy meta here, like elsewhere?
|
|
130
|
+
meta.stack = null
|
|
131
|
+
return () => c(meta, k2)
|
|
304
132
|
}
|
|
305
133
|
|
|
306
|
-
|
|
307
|
-
|
|
134
|
+
let k1 = meta.stack
|
|
135
|
+
meta.stack = null
|
|
136
|
+
return body(resumeValue, resumeComp, meta, k1)
|
|
137
|
+
}
|
|
308
138
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
function leaveRegion() {
|
|
319
|
-
const leftRegion = currentRegion
|
|
320
|
-
currentRegion = regions.pop()
|
|
321
|
-
return leftRegion
|
|
139
|
+
function RUN_TOPLEVEL(comp) {
|
|
140
|
+
try {
|
|
141
|
+
let a = comp(TOPLEVEL_KS, TOPLEVEL_K)
|
|
142
|
+
while (true) { a = a() }
|
|
143
|
+
} catch (e) {
|
|
144
|
+
if (e.computationIsDone) return e.result
|
|
145
|
+
else throw e
|
|
322
146
|
}
|
|
147
|
+
}
|
|
323
148
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
149
|
+
// trampolines the given computation (like RUN_TOPLEVEL, but doesn't provide continuations)
|
|
150
|
+
function TRAMPOLINE(comp) {
|
|
151
|
+
let a = comp;
|
|
152
|
+
try {
|
|
153
|
+
while (true) {
|
|
154
|
+
a = a()
|
|
155
|
+
}
|
|
156
|
+
} catch (e) {
|
|
157
|
+
if (e.computationIsDone) return e.result
|
|
158
|
+
else throw e
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// keeps the current trampoline going and dispatches the given task
|
|
163
|
+
function RUN(task) {
|
|
164
|
+
return () => task(TOPLEVEL_KS, TOPLEVEL_K)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// aborts the current continuation
|
|
168
|
+
function ABORT(value) {
|
|
169
|
+
throw { computationIsDone: true, result: value }
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
// "Public API" used in FFI
|
|
174
|
+
// ------------------------
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Captures the current continuation as a WHOLE and makes it available
|
|
178
|
+
* as argument to the passed body. For example:
|
|
179
|
+
*
|
|
180
|
+
* $effekt.capture(k => ... k(42) ...)
|
|
181
|
+
*
|
|
182
|
+
* The body
|
|
183
|
+
*
|
|
184
|
+
* $effekt.capture(k => >>> ... <<<)
|
|
185
|
+
*
|
|
186
|
+
* conceptually runs on the _native_ JS call stack. You can call JS functions,
|
|
187
|
+
* like `setTimeout` etc., but you are not expected or required to return an
|
|
188
|
+
* Effekt value like `$effekt.unit`. If you want to run an Effekt computation
|
|
189
|
+
* like in `io::spawn`, you can use `$effekt.run`.
|
|
190
|
+
*
|
|
191
|
+
* Advanced usage details:
|
|
192
|
+
*
|
|
193
|
+
* The value returned by the function passed to `capture` returns
|
|
194
|
+
* - a function: the returned function will be passed to the
|
|
195
|
+
* Effekt runtime, which performs trampolining.
|
|
196
|
+
* In this case, the Effekt runtime will keep running, though the
|
|
197
|
+
* continuation has been removed.
|
|
198
|
+
*
|
|
199
|
+
* - another value (like `undefined`): the Effekt runtime will terminate.
|
|
200
|
+
*/
|
|
201
|
+
$effekt.capture = CAPTURE
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Used to call Effekt function arguments in the JS FFI, like in `io::spawn`.
|
|
205
|
+
*
|
|
206
|
+
* Requires an active Effekt runtime (trampoline).
|
|
207
|
+
*/
|
|
208
|
+
$effekt.run = RUN
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Used to call Effekt function arguments in the JS FFI, like in `network::listen`.
|
|
212
|
+
*
|
|
213
|
+
* This function should be used when _no_ Effekt runtime is available. For instance,
|
|
214
|
+
* in callbacks passed to the NodeJS eventloop.
|
|
215
|
+
*
|
|
216
|
+
* If a runtime is available, use `$effekt.run`, instead.
|
|
217
|
+
*/
|
|
218
|
+
$effekt.runToplevel = RUN_TOPLEVEL
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!doctype html><html lang=en><head><meta charset=utf-8><meta http-equiv=x-ua-compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><title>Eclipse Public License 2.0 (EPL) | The Eclipse Foundation</title><meta property="og:title" content="Eclipse Public License 2.0 (EPL) | The Eclipse Foundation"><meta name=twitter:title content="Eclipse Public License 2.0 (EPL) | The Eclipse Foundation"><meta name=description content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta property="og:description" content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta name=twitter:description content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta name=author content="Wayne Beaton"><link href=/favicon.ico rel=icon type=image/x-icon><meta property="og:image" content="https://www.eclipse.org/images/logos/eclipse-foundation-400x400.png"><meta name=twitter:image content="https://www.eclipse.org/images/logos/eclipse-foundation-400x400.png"><meta name=twitter:card content="summary"><meta name=twitter:site content="@eclipsefdn"><meta name=twitter:creator content="@eclipsefdn"><meta property="og:url" content="https://www.eclipse.org/legal/epl-2.0/"><meta property="og:type" content="website"><meta property="og:site_name" content="Eclipse Foundation"><meta name=keywords content="epl,epl-2.0,legal,foundation,eclipse,eclipse public license,license,licenses"><meta name=generator content="Hugo 0.110.0"><link rel=canonical href=https://www.eclipse.org/legal/epl-2.0/><link rel=alternate href=/legal/epl-2.0/index.xml type=application/rss+xml title><link rel=stylesheet href="/public/css/styles.css?v=
|
|
1
|
+
<!doctype html><html lang=en><head><meta charset=utf-8><meta http-equiv=x-ua-compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><title>Eclipse Public License 2.0 (EPL) | The Eclipse Foundation</title><meta property="og:title" content="Eclipse Public License 2.0 (EPL) | The Eclipse Foundation"><meta name=twitter:title content="Eclipse Public License 2.0 (EPL) | The Eclipse Foundation"><meta name=description content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta property="og:description" content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta name=twitter:description content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta name=author content="Wayne Beaton"><link href=/favicon.ico rel=icon type=image/x-icon><meta property="og:image" content="https://www.eclipse.org/images/logos/eclipse-foundation-400x400.png"><meta name=twitter:image content="https://www.eclipse.org/images/logos/eclipse-foundation-400x400.png"><meta name=twitter:card content="summary"><meta name=twitter:site content="@eclipsefdn"><meta name=twitter:creator content="@eclipsefdn"><meta property="og:url" content="https://www.eclipse.org/legal/epl-2.0/"><meta property="og:type" content="website"><meta property="og:site_name" content="Eclipse Foundation"><meta name=keywords content="epl,epl-2.0,legal,foundation,eclipse,eclipse public license,license,licenses"><meta name=generator content="Hugo 0.110.0"><link rel=canonical href=https://www.eclipse.org/legal/epl-2.0/><link rel=alternate href=/legal/epl-2.0/index.xml type=application/rss+xml title><link rel=stylesheet href="/public/css/styles.css?v=1729448099"><script>(function(e,t,n,s,o){e[s]=e[s]||[],e[s].push({"gtm.start":(new Date).getTime(),event:"gtm.js"});var a=t.getElementsByTagName(n)[0],i=t.createElement(n),r=s!="dataLayer"?"&l="+s:"";i.async=!0,i.src="https://www.googletagmanager.com/gtm.js?id="+o+r,a.parentNode.insertBefore(i,a)})(window,document,"script","dataLayer","GTM-5WLCZXC")</script><script>var tableClasses="table"</script><link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel=stylesheet type=text/css></head><body><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-5WLCZXC" height=0 width=0 style=display:none;visibility:hidden></iframe></noscript><a class=sr-only href=#content>Skip to main content</a><header class="header-wrapper header-wrapper" id=header><div class=header-toolbar><div class=container><div class=header-toolbar-row><div class="toolbar-btn toolbar-search-btn dropdown"><button class=dropdown-toggle id=toolbar-search type=button data-toggle=dropdown tabindex=0 aria-label=Search>
|
|
2
2
|
<i class="fa fa-search fa-lg" aria-role=none></i></button><div class="toolbar-search-bar-wrapper dropdown-menu dropdown-menu-right" aria-labelledby=toolbar-search><form action=https://www.eclipse.org/home/search method=get><div class=search-bar><input class=search-bar-input name=q placeholder=Search>
|
|
3
3
|
<button>
|
|
4
4
|
<i class="fa fa-search" type=submit></i></button></div></form></div></div><div class="toolbar-btn toolbar-user-menu-btn dropdown"><button class=dropdown-toggle id=toolbar-user-menu type=button data-toggle=dropdown tabindex=0 aria-label="User Menu">
|
|
@@ -57,5 +57,5 @@ open source software collaboration and innovation.</p></div><div class=mega-menu
|
|
|
57
57
|
<i class="fa fa-linkedin fa-stack-1x fa-inverse" aria-hidden=true></i>
|
|
58
58
|
<span class=sr-only>Linkedin account</span></span></a></li></ul></div></div><div class="footer-sections row equal-height-md font-bold"><div class=col-md-15><div class=row><section id=footer-eclipse-foundation class="footer-section col-sm-8"><div class=menu-heading>Eclipse Foundation</div><ul class=nav><li><a href=https://www.eclipse.org/org/>About</a></li><li><a href=https://projects.eclipse.org/>Projects</a></li><li><a href=https://www.eclipse.org/collaborations/>Collaborations</a></li><li><a href=https://www.eclipse.org/membership/>Membership</a></li><li><a href=https://www.eclipse.org/sponsor/>Sponsor</a></li></ul></section><section id=footer-legal class="footer-section col-sm-8"><div class=menu-heading>Legal</div><ul class=nav><li><a href=https://www.eclipse.org/legal/privacy/>Privacy Policy</a></li><li><a href=https://www.eclipse.org/legal/terms-of-use/>Terms of Use</a></li><li><a href=https://www.eclipse.org/legal/compliance/>Compliance</a></li><li><a href=https://www.eclipse.org/org/documents/Community_Code_of_Conduct.php>Code of Conduct</a></li><li><a href=https://www.eclipse.org/legal/>Legal Resources</a></li><li><a class=toolbar-manage-cookies href=# onclick=event.preventDefault()>Manage Cookies</a></li></ul></section><section id=footer-more class="footer-section col-sm-8"><div class=menu-heading>More</div><ul class=nav><li><a href=https://www.eclipse.org/security/>Report a Vulnerability</a></li><li><a href=https://status.eclipse.org/>Service Status</a></li><li><a href=https://www.eclipse.org/org/foundation/contact.php>Contact Us</a></li><li><a href=https://www.eclipse.org/projects/support/>Support</a></li></ul></section></div></div><div id=footer-end class="footer-section col-md-8 col-md-offset-1 col-sm-24"><div class=footer-end-newsletter><form id=mc-embedded-subscribe-form action=https://eclipsecon.us6.list-manage.com/subscribe/post method=post novalidate target=_blank><label class=footer-end-newsletter-label for=email>Subscribe to our Newsletter</label><div class=footer-end-newsletter-input-wrapper><input class=footer-end-newsletter-input type=email id=email name=EMAIL autocomplete=email placeholder="Enter your email address"><div><i class="fa fa-solid fa-envelope fa-lg" aria-hidden=true></i></div></div><input type=hidden name=u value=eaf9e1f06f194eadc66788a85>
|
|
59
59
|
<input type=hidden name=id value=46e57eacf1>
|
|
60
|
-
<input id=mc-embedded-subscribe type=submit name=subscribe hidden></form></div></div></div><div class="col-sm-24 margin-top-20"><div class=row><div id=copyright class=col-md-16><p id=copyright-text>Copyright © Eclipse Foundation AISBL. All Rights Reserved.</p></div></div></div><a href=# class=scrollup>Back to the top</a></div></footer><div id=footer-js><script src="/public/js/main.js?v1.0?v=
|
|
60
|
+
<input id=mc-embedded-subscribe type=submit name=subscribe hidden></form></div></div></div><div class="col-sm-24 margin-top-20"><div class=row><div id=copyright class=col-md-16><p id=copyright-text>Copyright © Eclipse Foundation AISBL. All Rights Reserved.</p></div></div></div><a href=# class=scrollup>Back to the top</a></div></footer><div id=footer-js><script src="/public/js/main.js?v1.0?v=1729448099"></script>
|
|
61
61
|
<script>(function(){})(jQuery,document)</script></div></body></html>
|
package/package.json
CHANGED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
module unsafe/cont
|
|
2
|
-
|
|
3
|
-
// The type of a captured continuation
|
|
4
|
-
extern type Cont[A, B]
|
|
5
|
-
|
|
6
|
-
// we mark this as {io} since pure functions should not take block parameters.
|
|
7
|
-
extern io def cont[A, B] { r: A => B / {} }: Cont[A, B] = js "${box r}"
|
|
8
|
-
|
|
9
|
-
// This is unsafe if the continuation left the scope of the
|
|
10
|
-
// capabilities it closed over
|
|
11
|
-
extern async def apply[A, B](k: Cont[A, B], a: A): B / {} = js "${k}(${a})"
|