@effekt-lang/effekt 0.79.0 → 0.81.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/io/network.effekt +1 -1
- package/libraries/common/io.effekt +1 -1
- package/libraries/common/process.effekt +3 -3
- package/libraries/common/sourcepos.effekt +75 -0
- package/libraries/common/test.effekt +57 -56
- package/libraries/js/effekt_runtime.js +19 -3
- package/libraries/llvm/io.c +17 -17
- package/libraries/llvm/rts.ll +16 -15
- package/libraries/llvm/types.c +3 -3
- package/licenses/eclipse public license, version 2.0 - epl-2.0.html +3 -3
- package/licenses/mit license - mit-license.html +155 -199
- package/licenses/the bsd license - bsd-license.html +155 -199
- package/licenses/the mit license - mit.html +156 -200
- package/package.json +1 -1
package/bin/effekt
CHANGED
|
Binary file
|
|
@@ -182,7 +182,7 @@ namespace internal {
|
|
|
182
182
|
extern def listen(listener: Int, handler: Connection => Unit at {io, async, global}) at async: Int =
|
|
183
183
|
jsNode "$effekt.capture(k => tcp$listen(${listener}, ${handler}, k))"
|
|
184
184
|
llvm """
|
|
185
|
-
notail call void @c_tcp_listen(%Int ${listener}, %
|
|
185
|
+
notail call void @c_tcp_listen(%Int ${listener}, %Neg ${handler}, %Stack %stack)
|
|
186
186
|
ret void
|
|
187
187
|
"""
|
|
188
188
|
|
|
@@ -12,7 +12,7 @@ extern def spawn[T](task: () => T at {io, async, global}) at async: Unit =
|
|
|
12
12
|
js "$effekt.capture(k => { setTimeout(() => k($effekt.unit), 0); return $effekt.run(${task}) })"
|
|
13
13
|
llvm """
|
|
14
14
|
notail call void @c_yield(%Stack %stack)
|
|
15
|
-
notail call void @run(%
|
|
15
|
+
notail call void @run(%Neg ${task})
|
|
16
16
|
ret void
|
|
17
17
|
"""
|
|
18
18
|
|
|
@@ -48,7 +48,7 @@ extern def onStdout(opts: SpawnOptions, callback: String => Unit at {io, global}
|
|
|
48
48
|
};
|
|
49
49
|
return old; })()"""
|
|
50
50
|
llvm """
|
|
51
|
-
%opts = call %Pos @c_spawn_options_on_stdout(%Pos ${opts}, %
|
|
51
|
+
%opts = call %Pos @c_spawn_options_on_stdout(%Pos ${opts}, %Neg ${callback})
|
|
52
52
|
ret %Pos %opts
|
|
53
53
|
"""
|
|
54
54
|
extern def onStderr(opts: SpawnOptions, callback: String => Unit at {io, global}) at {}: SpawnOptions =
|
|
@@ -64,7 +64,7 @@ extern def onStderr(opts: SpawnOptions, callback: String => Unit at {io, global}
|
|
|
64
64
|
};
|
|
65
65
|
return old; })()"""
|
|
66
66
|
llvm """
|
|
67
|
-
%opts = call %Pos @c_spawn_options_on_stderr(%Pos ${opts}, %
|
|
67
|
+
%opts = call %Pos @c_spawn_options_on_stderr(%Pos ${opts}, %Neg ${callback})
|
|
68
68
|
ret %Pos %opts
|
|
69
69
|
"""
|
|
70
70
|
extern type WritableStream =
|
|
@@ -84,7 +84,7 @@ extern def withStdin(opts: SpawnOptions, callback: WritableStream => Unit at {io
|
|
|
84
84
|
return old;
|
|
85
85
|
})()"""
|
|
86
86
|
llvm """
|
|
87
|
-
%opts = call %Pos @c_spawn_options_pipe_stdin(%Pos ${opts}, %
|
|
87
|
+
%opts = call %Pos @c_spawn_options_pipe_stdin(%Pos ${opts}, %Neg ${callback})
|
|
88
88
|
ret %Pos %opts
|
|
89
89
|
"""
|
|
90
90
|
extern def write(to: WritableStream, s: String) at io: Unit =
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
module sourcepos
|
|
2
|
+
import io/error
|
|
3
|
+
import io/filesystem
|
|
4
|
+
import stringbuffer
|
|
5
|
+
import tty
|
|
6
|
+
|
|
7
|
+
def toGccStyleString(sp: SourcePosition): String = {
|
|
8
|
+
s"${sp.file}:${sp.startLine.show()}:${sp.startColumn.show()}"
|
|
9
|
+
}
|
|
10
|
+
def toClangStyleString = toGccStyleString
|
|
11
|
+
def toMsvcStyleString(sp: SourcePosition): String = {
|
|
12
|
+
s"${sp.file}(${sp.startLine.show()},${sp.startColumn.show()})"
|
|
13
|
+
}
|
|
14
|
+
def toPythonStyleString(sp: SourcePosition): String = {
|
|
15
|
+
s"File \"${sp.file}\", line ${sp.startLine.show()}"
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
def getSourceLine(file: String, line: Int): String / {Exception[IOError], stop} = {
|
|
19
|
+
with stringBuffer
|
|
20
|
+
with readFileUTF8(file)
|
|
21
|
+
var currentLine = 1
|
|
22
|
+
while (currentLine < line) {
|
|
23
|
+
val c = do next()
|
|
24
|
+
if (c == '\n' || c == '\r') {
|
|
25
|
+
currentLine += 1
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
var c = do next()
|
|
29
|
+
while (c != '\n' && c != '\r') {
|
|
30
|
+
do write(c.toString)
|
|
31
|
+
c = do next()
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
def getSourceText(sp: SourcePosition): String / {Exception[IOError], stop} = {
|
|
35
|
+
with stringBuffer
|
|
36
|
+
with readFileUTF8(sp.file)
|
|
37
|
+
var currentLine = 1
|
|
38
|
+
var currentColumn = 1
|
|
39
|
+
while (currentLine < sp.startLine || currentColumn < sp.startColumn) {
|
|
40
|
+
val c = do next()
|
|
41
|
+
if (c == '\n' || c == '\r') {
|
|
42
|
+
currentLine += 1
|
|
43
|
+
currentColumn = 0
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
var c = do next()
|
|
47
|
+
while (currentLine <= sp.endLine && currentColumn <= sp.endColumn) {
|
|
48
|
+
do write(c.toString)
|
|
49
|
+
if (c == '\n' || c == '\r') {
|
|
50
|
+
currentLine += 1
|
|
51
|
+
currentColumn = 0
|
|
52
|
+
}
|
|
53
|
+
c = do next()
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
def getMarkedSource(sp: SourcePosition): String / Formatted = {
|
|
58
|
+
try {
|
|
59
|
+
if (sp.startLine == sp.endLine) {
|
|
60
|
+
val line = getSourceLine(sp.file, sp.startLine)
|
|
61
|
+
val mline = line.substring(0, sp.startColumn) ++ line.substring(sp.startColumn, sp.endColumn + 1).red ++ line.substring(sp.endColumn + 1)
|
|
62
|
+
return mline ++ "\n" ++ " ".repeat(sp.startColumn - 1) ++ "^".repeat(sp.endColumn - sp.startColumn)
|
|
63
|
+
} else {
|
|
64
|
+
val prefix = getSourceLine(sp.file, sp.startLine).substring(0, sp.startColumn)
|
|
65
|
+
val suffix = getSourceLine(sp.file, sp.endLine).substring(sp.endColumn + 1)
|
|
66
|
+
val text = getSourceText(sp)
|
|
67
|
+
return prefix ++ text.red ++ suffix
|
|
68
|
+
}
|
|
69
|
+
} with stop {
|
|
70
|
+
"(invalid source position)"
|
|
71
|
+
} with Exception[IOError] {
|
|
72
|
+
def raise(e, m) =
|
|
73
|
+
"(can't open source file: " ++ m ++ ")"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -1,102 +1,103 @@
|
|
|
1
1
|
import tty
|
|
2
2
|
import process
|
|
3
3
|
import bench
|
|
4
|
+
import sourcepos
|
|
4
5
|
|
|
5
6
|
interface Assertion {
|
|
6
|
-
def assert(condition: Bool, msg: String): Unit
|
|
7
|
+
def assert(condition: Bool, msg: String, ?sourcePosition: SourcePosition): Unit
|
|
7
8
|
}
|
|
8
9
|
|
|
9
|
-
def assertTrue(condition: Bool, msg: String) =
|
|
10
|
-
do assert(condition, msg)
|
|
10
|
+
def assertTrue(condition: Bool, msg: String, ?sourcePosition: SourcePosition) =
|
|
11
|
+
do assert(condition, msg, sourcePosition)
|
|
11
12
|
|
|
12
|
-
def assertTrue(condition: Bool) =
|
|
13
|
-
do assert(condition, "Assertion failed")
|
|
13
|
+
def assertTrue(condition: Bool, ?sourcePosition: SourcePosition) =
|
|
14
|
+
do assert(condition, "Assertion failed", sourcePosition)
|
|
14
15
|
|
|
15
|
-
def assertFalse(condition: Bool, msg: String) =
|
|
16
|
-
do assert(not(condition), msg)
|
|
16
|
+
def assertFalse(condition: Bool, msg: String, ?sourcePosition: SourcePosition) =
|
|
17
|
+
do assert(not(condition), msg, sourcePosition)
|
|
17
18
|
|
|
18
|
-
def assertFalse(condition: Bool) =
|
|
19
|
-
do assert(not(condition), "Assertion failed")
|
|
19
|
+
def assertFalse(condition: Bool, ?sourcePosition: SourcePosition) =
|
|
20
|
+
do assert(not(condition), "Assertion failed", sourcePosition)
|
|
20
21
|
|
|
21
|
-
def assert(obtained: Int, expected: Int, msg: String): Unit / Assertion =
|
|
22
|
-
assertEqual(obtained, expected, msg) { (x, y) => x == y }
|
|
22
|
+
def assert(obtained: Int, expected: Int, msg: String, ?sourcePosition: SourcePosition): Unit / Assertion =
|
|
23
|
+
assertEqual(obtained, expected, msg, sourcePosition) { (x, y) => x == y }
|
|
23
24
|
|
|
24
|
-
def assert(obtained: Bool, expected: Bool, msg: String): Unit / Assertion =
|
|
25
|
-
assertEqual(obtained, expected, msg) { (x, y) => x == y }
|
|
25
|
+
def assert(obtained: Bool, expected: Bool, msg: String, ?sourcePosition: SourcePosition): Unit / Assertion =
|
|
26
|
+
assertEqual(obtained, expected, msg, sourcePosition) { (x, y) => x == y }
|
|
26
27
|
|
|
27
|
-
def assert(obtained: Char, expected: Char, msg: String): Unit / Assertion =
|
|
28
|
-
assertEqual(obtained, expected, msg) { (x, y) => x == y }
|
|
28
|
+
def assert(obtained: Char, expected: Char, msg: String, ?sourcePosition: SourcePosition): Unit / Assertion =
|
|
29
|
+
assertEqual(obtained, expected, msg, sourcePosition) { (x, y) => x == y }
|
|
29
30
|
|
|
30
|
-
def assert(obtained: String, expected: String, msg: String): Unit / Assertion =
|
|
31
|
-
assertEqual(obtained, expected, msg) { (x, y) => x == y }
|
|
31
|
+
def assert(obtained: String, expected: String, msg: String, ?sourcePosition: SourcePosition): Unit / Assertion =
|
|
32
|
+
assertEqual(obtained, expected, msg, sourcePosition) { (x, y) => x == y }
|
|
32
33
|
|
|
33
|
-
def assert(obtained: Int, expected: Int): Unit / { Assertion, Formatted } =
|
|
34
|
-
assertEqual(obtained, expected) { (x, y) => x == y } { x => show(x) }
|
|
34
|
+
def assert(obtained: Int, expected: Int, ?sourcePosition: SourcePosition): Unit / { Assertion, Formatted } =
|
|
35
|
+
assertEqual(obtained, expected, sourcePosition) { (x, y) => x == y } { x => show(x) }
|
|
35
36
|
|
|
36
|
-
def assert(obtained: Byte, expected: Byte): Unit / { Assertion, Formatted } =
|
|
37
|
-
assertEqual(obtained, expected) { (x, y) => x == y } { x => show(x) }
|
|
37
|
+
def assert(obtained: Byte, expected: Byte, ?sourcePosition: SourcePosition): Unit / { Assertion, Formatted } =
|
|
38
|
+
assertEqual(obtained, expected, sourcePosition) { (x, y) => x == y } { x => show(x) }
|
|
38
39
|
|
|
39
|
-
def assert(obtained: Bool, expected: Bool): Unit / { Assertion, Formatted } =
|
|
40
|
-
assertEqual(obtained, expected) { (x, y) => x == y } { x => show(x) }
|
|
40
|
+
def assert(obtained: Bool, expected: Bool, ?sourcePosition: SourcePosition): Unit / { Assertion, Formatted } =
|
|
41
|
+
assertEqual(obtained, expected, sourcePosition) { (x, y) => x == y } { x => show(x) }
|
|
41
42
|
|
|
42
|
-
def assert(obtained: Char, expected: Char): Unit / { Assertion, Formatted } =
|
|
43
|
-
assertEqual(obtained, expected) { (x, y) => x == y } { x => show(x) }
|
|
43
|
+
def assert(obtained: Char, expected: Char, ?sourcePosition: SourcePosition): Unit / { Assertion, Formatted } =
|
|
44
|
+
assertEqual(obtained, expected, sourcePosition) { (x, y) => x == y } { x => show(x) }
|
|
44
45
|
|
|
45
|
-
def assert(obtained: String, expected: String): Unit / { Assertion, Formatted } =
|
|
46
|
-
assertEqual(obtained, expected) { (x, y) => x == y } { x => show(x) }
|
|
46
|
+
def assert(obtained: String, expected: String, ?sourcePosition: SourcePosition): Unit / { Assertion, Formatted } =
|
|
47
|
+
assertEqual(obtained, expected, sourcePosition) { (x, y) => x == y } { x => show(x) }
|
|
47
48
|
|
|
48
|
-
def assertEqual[A](obtained: A, expected: A, msg: String): Unit / Assertion =
|
|
49
|
-
assertEqual(obtained, expected, msg) { (x, y) => x.genericEquals(y) }
|
|
49
|
+
def assertEqual[A](obtained: A, expected: A, msg: String, ?sourcePosition: SourcePosition): Unit / Assertion =
|
|
50
|
+
assertEqual(obtained, expected, msg, sourcePosition) { (x, y) => x.genericEquals(y) }
|
|
50
51
|
|
|
51
|
-
def assertEqual[A](obtained: A, expected: A): Unit / { Assertion, Formatted } =
|
|
52
|
-
assertEqual(obtained, expected) { (x, y) => x.genericEquals(y) } { x => x.genericShow }
|
|
52
|
+
def assertEqual[A](obtained: A, expected: A, ?sourcePosition: SourcePosition): Unit / { Assertion, Formatted } =
|
|
53
|
+
assertEqual(obtained, expected, sourcePosition) { (x, y) => x.genericEquals(y) } { x => x.genericShow }
|
|
53
54
|
|
|
54
|
-
def assertEqual[A](obtained: A, expected: A, msg: String) { equals: (A, A) => Bool }: Unit / Assertion =
|
|
55
|
-
do assert(equals(obtained, expected), msg)
|
|
55
|
+
def assertEqual[A](obtained: A, expected: A, msg: String, ?sourcePosition: SourcePosition) { equals: (A, A) => Bool }: Unit / Assertion =
|
|
56
|
+
do assert(equals(obtained, expected), msg, sourcePosition)
|
|
56
57
|
|
|
57
|
-
def assertEqual[A](obtained: A, expected: A) { equals: (A, A) => Bool } { show: A => String }: Unit / { Assertion, Formatted } =
|
|
58
|
-
do assert(equals(obtained, expected), Formatted::tryEmit(Escape::RESET) ++ "Expected: ".dim ++ show(expected).green ++ "\n Obtained: ".dim ++ show(obtained).red)
|
|
58
|
+
def assertEqual[A](obtained: A, expected: A, ?sourcePosition: SourcePosition) { equals: (A, A) => Bool } { show: A => String }: Unit / { Assertion, Formatted } =
|
|
59
|
+
do assert(equals(obtained, expected), Formatted::tryEmit(Escape::RESET) ++ "Expected: ".dim ++ show(expected).green ++ "\n Obtained: ".dim ++ show(obtained).red, sourcePosition)
|
|
59
60
|
// NOTE: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
60
61
|
// Here's an accidental capture! Can we prevent this somehow nicely?
|
|
61
62
|
|
|
62
|
-
def assertNotThrown[E](ex: on[E]) { body: => Unit / Exception[E] }: Unit / Assertion =
|
|
63
|
-
ex.default { do assert(false, "Unexpected Exception") } {body}
|
|
63
|
+
def assertNotThrown[E](ex: on[E], ?sourcePosition: SourcePosition) { body: => Unit / Exception[E] }: Unit / Assertion =
|
|
64
|
+
ex.default { do assert(false, "Unexpected Exception", sourcePosition) } {body}
|
|
64
65
|
|
|
65
|
-
def assertNoThrow[E] { body: => Unit / Exception[E] }: Unit / Assertion =
|
|
66
|
-
on[E].default{ do assert(false, "Unexpected Exception") } {body}
|
|
66
|
+
def assertNoThrow[E](?sourcePosition: SourcePosition) { body: => Unit / Exception[E] }: Unit / Assertion =
|
|
67
|
+
on[E].default{ do assert(false, "Unexpected Exception", sourcePosition) } {body}
|
|
67
68
|
|
|
68
|
-
def assertThrown[E](ex: on[E]) { body: => Unit / Exception[E] }: Unit / Assertion =
|
|
69
|
-
do assert(ex.default { true } { body(); false }, "Expected Exception, but exited normally")
|
|
69
|
+
def assertThrown[E](ex: on[E], ?sourcePosition: SourcePosition) { body: => Unit / Exception[E] }: Unit / Assertion =
|
|
70
|
+
do assert(ex.default { true } { body(); false }, "Expected Exception, but exited normally", sourcePosition)
|
|
70
71
|
|
|
71
|
-
def assertThrows[E] { body: => Unit / Exception[E] }: Unit / Assertion =
|
|
72
|
-
do assert(on[E].default { true } { body(); false }, "Expected Exception, but exited normally")
|
|
72
|
+
def assertThrows[E](?sourcePosition: SourcePosition) { body: => Unit / Exception[E] }: Unit / Assertion =
|
|
73
|
+
do assert(on[E].default { true } { body(); false }, "Expected Exception, but exited normally", sourcePosition)
|
|
73
74
|
|
|
74
|
-
def assertFail { body: => Unit / fail }: Unit / Assertion =
|
|
75
|
-
do assert(succeeds {body}, "Expected 'fail', but exited normally")
|
|
75
|
+
def assertFail(?sourcePosition: SourcePosition) { body: => Unit / fail }: Unit / Assertion =
|
|
76
|
+
do assert(succeeds {body}, "Expected 'fail', but exited normally", sourcePosition)
|
|
76
77
|
|
|
77
|
-
def assertNoFail { body: => Unit / fail }: Unit / Assertion =
|
|
78
|
-
onFail { do assert(false, "Unexpected 'fail'") } {body}
|
|
78
|
+
def assertNoFail(?sourcePosition: SourcePosition) { body: => Unit / fail }: Unit / Assertion =
|
|
79
|
+
onFail { do assert(false, "Unexpected 'fail'", sourcePosition) } {body}
|
|
79
80
|
|
|
80
81
|
|
|
81
82
|
interface Test {
|
|
82
|
-
def success(name: String, duration: Int): Unit
|
|
83
|
-
def failure(name: String, msg: String, duration: Int): Unit
|
|
83
|
+
def success(name: String, duration: Int, ?sourcePosition: SourcePosition): Unit
|
|
84
|
+
def failure(name: String, msg: String, duration: Int, ?sourcePosition: SourcePosition): Unit
|
|
84
85
|
}
|
|
85
86
|
|
|
86
87
|
/// Runs the `body` as a test under the given `name`
|
|
87
88
|
/// See `suite` for examples.
|
|
88
|
-
def test(name: String) { body: => Unit / Assertion } = {
|
|
89
|
+
def test(name: String, ?sourcePosition: SourcePosition) { body: => Unit / Assertion } = {
|
|
89
90
|
val startTime = bench::relativeTimestamp()
|
|
90
91
|
try {
|
|
91
92
|
body()
|
|
92
93
|
val duration = Duration::diff(startTime, bench::relativeTimestamp())
|
|
93
|
-
do success(name, duration)
|
|
94
|
+
do success(name, duration, sourcePosition)
|
|
94
95
|
} with Assertion {
|
|
95
|
-
def assert(condition, msg) =
|
|
96
|
+
def assert(condition, msg, assertSourcePosition) =
|
|
96
97
|
if (condition) resume(())
|
|
97
98
|
else {
|
|
98
99
|
val duration = Duration::diff(startTime, bench::relativeTimestamp())
|
|
99
|
-
do failure(name, msg, duration)
|
|
100
|
+
do failure(name, msg, duration, assertSourcePosition)
|
|
100
101
|
}
|
|
101
102
|
}
|
|
102
103
|
}
|
|
@@ -138,17 +139,17 @@ def suite(name: String, printTimes: Bool) { body: => Unit / { Test, Formatted }
|
|
|
138
139
|
val totalDuration = timed {
|
|
139
140
|
try { body() } with Test {
|
|
140
141
|
// 2a) Handle a passing test on success
|
|
141
|
-
def success(name, duration) = {
|
|
142
|
+
def success(name, duration, sourcePosition) = {
|
|
142
143
|
passed = passed + 1
|
|
143
144
|
println("✓".green ++ " " ++ name ++ duration.ms)
|
|
144
145
|
resume(())
|
|
145
146
|
}
|
|
146
147
|
|
|
147
148
|
// 2b) Handle a failing test on failure, additionally printing its message
|
|
148
|
-
def failure(name, msg, duration) = {
|
|
149
|
+
def failure(name, msg, duration, sourcePosition) = {
|
|
149
150
|
failed = failed + 1
|
|
150
151
|
println("✕".red ++ " " ++ name ++ duration.ms)
|
|
151
|
-
println(" " ++ msg.red)
|
|
152
|
+
println(" " ++ msg.red ++ " at " ++ sourcePosition.toGccStyleString())
|
|
152
153
|
resume(())
|
|
153
154
|
}
|
|
154
155
|
}
|
|
@@ -58,6 +58,7 @@ class Arena {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
function snapshot(s) {
|
|
61
|
+
if (s === null) return null
|
|
61
62
|
const snap = { store: s, root: s.root, generation: s.generation }
|
|
62
63
|
s.generation = s.generation + 1
|
|
63
64
|
return snap
|
|
@@ -85,9 +86,13 @@ function reroot(target) {
|
|
|
85
86
|
node.value = Mem
|
|
86
87
|
cur = node
|
|
87
88
|
}
|
|
89
|
+
|
|
90
|
+
// 3. Reclaim the path to reuse the buffer eagerly
|
|
91
|
+
_rerootPath.length = 0
|
|
88
92
|
}
|
|
89
93
|
|
|
90
94
|
function restore(store, snap) {
|
|
95
|
+
if (snap === null) return // nothing saved ~> nothing to restore
|
|
91
96
|
if (snap.root.value !== Mem) {
|
|
92
97
|
// fast path: continuation is resumed immediately with no writes in between
|
|
93
98
|
reroot(snap.root)
|
|
@@ -99,7 +104,18 @@ function restore(store, snap) {
|
|
|
99
104
|
// Common Runtime
|
|
100
105
|
// --------------
|
|
101
106
|
const TOPLEVEL_K = (x, ks) => { throw { computationIsDone: true, result: x } }
|
|
102
|
-
const TOPLEVEL_KS = { stack: null, prompt: Symbol("toplevel"), arena:
|
|
107
|
+
const TOPLEVEL_KS = { stack: null, prompt: Symbol("toplevel"), arena: null, rest: null }
|
|
108
|
+
|
|
109
|
+
// The first variable in a scope creates its arena; until then `ks.arena` is null.
|
|
110
|
+
function VAR(init, ks) {
|
|
111
|
+
const arena = ks.arena !== null ? ks.arena : (ks.arena = new Arena())
|
|
112
|
+
return arena.fresh(init)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function REGION(ks) {
|
|
116
|
+
const arena = ks.arena !== null ? ks.arena : (ks.arena = new Arena())
|
|
117
|
+
return arena.newRegion()
|
|
118
|
+
}
|
|
103
119
|
|
|
104
120
|
function THUNK(f) {
|
|
105
121
|
f.thunk = true
|
|
@@ -109,7 +125,7 @@ function THUNK(f) {
|
|
|
109
125
|
function CAPTURE(body) {
|
|
110
126
|
return (ks, k) => {
|
|
111
127
|
const res = body(x => TRAMPOLINE(() => k(x, ks)))
|
|
112
|
-
if (res
|
|
128
|
+
if (typeof res === "function") return res
|
|
113
129
|
else throw { computationIsDone: true, result: $effekt.unit }
|
|
114
130
|
}
|
|
115
131
|
}
|
|
@@ -120,7 +136,7 @@ const RETURN = (x, ks) => ks.rest.stack(x, ks.rest)
|
|
|
120
136
|
function RESET(prog, ks, k) {
|
|
121
137
|
const prompt = Symbol(); // gensym
|
|
122
138
|
const rest = { stack: k, prompt: ks.prompt, arena: ks.arena, rest: ks.rest }
|
|
123
|
-
return prog(prompt, { stack: null, prompt, arena:
|
|
139
|
+
return prog(prompt, { stack: null, prompt, arena: null, rest }, RETURN)
|
|
124
140
|
}
|
|
125
141
|
|
|
126
142
|
function SHIFT(p, body, ks, k) {
|
package/libraries/llvm/io.c
CHANGED
|
@@ -383,18 +383,18 @@ Int c_tcp_bind(String host, Int port) {
|
|
|
383
383
|
|
|
384
384
|
typedef struct {
|
|
385
385
|
Stack stack;
|
|
386
|
-
struct
|
|
386
|
+
struct Neg handler;
|
|
387
387
|
} tcp_listen_closure_t;
|
|
388
388
|
|
|
389
389
|
void c_tcp_listen_cb(uv_stream_t* server, int status) {
|
|
390
390
|
tcp_listen_closure_t* listen_closure = (tcp_listen_closure_t*)server->data;
|
|
391
391
|
Stack closure_stack = listen_closure->stack;
|
|
392
|
-
struct
|
|
392
|
+
struct Neg closure_handler = listen_closure->handler;
|
|
393
393
|
|
|
394
394
|
if (status < 0) {
|
|
395
395
|
server->data = NULL;
|
|
396
396
|
free(listen_closure);
|
|
397
|
-
|
|
397
|
+
eraseNegative(closure_handler);
|
|
398
398
|
resume_Int(closure_stack, status);
|
|
399
399
|
return;
|
|
400
400
|
}
|
|
@@ -406,7 +406,7 @@ void c_tcp_listen_cb(uv_stream_t* server, int status) {
|
|
|
406
406
|
free(client);
|
|
407
407
|
server->data = NULL;
|
|
408
408
|
free(listen_closure);
|
|
409
|
-
|
|
409
|
+
eraseNegative(closure_handler);
|
|
410
410
|
resume_Int(closure_stack, result);
|
|
411
411
|
return;
|
|
412
412
|
}
|
|
@@ -416,16 +416,16 @@ void c_tcp_listen_cb(uv_stream_t* server, int status) {
|
|
|
416
416
|
uv_close((uv_handle_t*)client, (uv_close_cb)free);
|
|
417
417
|
server->data = NULL;
|
|
418
418
|
free(listen_closure);
|
|
419
|
-
|
|
419
|
+
eraseNegative(closure_handler);
|
|
420
420
|
resume_Int(closure_stack, result);
|
|
421
421
|
return;
|
|
422
422
|
}
|
|
423
423
|
|
|
424
|
-
|
|
424
|
+
shareNegative(closure_handler);
|
|
425
425
|
run_Int(closure_handler, (int64_t)client);
|
|
426
426
|
}
|
|
427
427
|
|
|
428
|
-
void c_tcp_listen(Int listener, struct
|
|
428
|
+
void c_tcp_listen(Int listener, struct Neg handler, Stack stack) {
|
|
429
429
|
uv_stream_t* server = (uv_stream_t*)listener;
|
|
430
430
|
|
|
431
431
|
tcp_listen_closure_t* listen_closure = malloc(sizeof(tcp_listen_closure_t));
|
|
@@ -436,7 +436,7 @@ void c_tcp_listen(Int listener, struct Pos handler, Stack stack) {
|
|
|
436
436
|
int result = uv_listen(server, SOMAXCONN, c_tcp_listen_cb);
|
|
437
437
|
if (result < 0) {
|
|
438
438
|
free(listen_closure);
|
|
439
|
-
|
|
439
|
+
eraseNegative(handler);
|
|
440
440
|
resume_Int(stack, result);
|
|
441
441
|
return;
|
|
442
442
|
}
|
|
@@ -451,9 +451,9 @@ void c_tcp_shutdown(Int handle, Stack stack) {
|
|
|
451
451
|
|
|
452
452
|
if (listen_closure) {
|
|
453
453
|
Stack closure_stack = listen_closure->stack;
|
|
454
|
-
struct
|
|
454
|
+
struct Neg closure_handler = listen_closure->handler;
|
|
455
455
|
free(listen_closure);
|
|
456
|
-
|
|
456
|
+
eraseNegative(closure_handler);
|
|
457
457
|
resume_Int(closure_stack, 0);
|
|
458
458
|
}
|
|
459
459
|
}
|
|
@@ -601,7 +601,7 @@ static void subproc_alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_
|
|
|
601
601
|
}
|
|
602
602
|
|
|
603
603
|
typedef struct {
|
|
604
|
-
struct
|
|
604
|
+
struct Neg handler;
|
|
605
605
|
} subproc_stream_cb_closure_t;
|
|
606
606
|
void subproc_stream_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) {
|
|
607
607
|
subproc_stream_cb_closure_t* clos = (subproc_stream_cb_closure_t*)(stream->data);
|
|
@@ -611,12 +611,12 @@ void subproc_stream_cb(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf)
|
|
|
611
611
|
run_Pos(clos->handler, chunk);
|
|
612
612
|
} else {
|
|
613
613
|
uv_read_stop(stream);
|
|
614
|
-
|
|
614
|
+
eraseNegative(clos->handler);
|
|
615
615
|
free(clos);
|
|
616
616
|
if (buf->base) free(buf->base);
|
|
617
617
|
}
|
|
618
618
|
}
|
|
619
|
-
struct Pos subproc_options_on_stream(struct Pos opts, size_t id, uv_stdio_flags flags, struct
|
|
619
|
+
struct Pos subproc_options_on_stream(struct Pos opts, size_t id, uv_stdio_flags flags, struct Neg callback) {
|
|
620
620
|
uv_process_options_t* options = (uv_process_options_t*)opts.obj;
|
|
621
621
|
|
|
622
622
|
options->stdio[id].flags = UV_CREATE_PIPE | flags;
|
|
@@ -631,13 +631,13 @@ struct Pos subproc_options_on_stream(struct Pos opts, size_t id, uv_stdio_flags
|
|
|
631
631
|
|
|
632
632
|
return opts;
|
|
633
633
|
}
|
|
634
|
-
struct Pos c_spawn_options_on_stdout(struct Pos opts, struct
|
|
634
|
+
struct Pos c_spawn_options_on_stdout(struct Pos opts, struct Neg callback) {
|
|
635
635
|
return subproc_options_on_stream(opts, 1, UV_WRITABLE_PIPE, callback);
|
|
636
636
|
}
|
|
637
|
-
struct Pos c_spawn_options_on_stderr(struct Pos opts, struct
|
|
637
|
+
struct Pos c_spawn_options_on_stderr(struct Pos opts, struct Neg callback) {
|
|
638
638
|
return subproc_options_on_stream(opts, 2, UV_WRITABLE_PIPE, callback);
|
|
639
639
|
}
|
|
640
|
-
struct Pos c_spawn_options_pipe_stdin(struct Pos opts, struct
|
|
640
|
+
struct Pos c_spawn_options_pipe_stdin(struct Pos opts, struct Neg callback) {
|
|
641
641
|
return subproc_options_on_stream(opts, 0, UV_READABLE_PIPE, callback);
|
|
642
642
|
}
|
|
643
643
|
|
|
@@ -754,7 +754,7 @@ void c_spawn(struct Pos cmd, struct Pos args, struct Pos options, Stack stack) {
|
|
|
754
754
|
subproc_stream_cb_closure_t* clos = (subproc_stream_cb_closure_t*)(stream->data);
|
|
755
755
|
struct Pos str = (struct Pos) { .tag = 0, .obj = stream, };
|
|
756
756
|
run_Pos(clos->handler, str);
|
|
757
|
-
|
|
757
|
+
eraseNegative(clos->handler);
|
|
758
758
|
free(clos);
|
|
759
759
|
}
|
|
760
760
|
if(opts->stdio[1].flags & UV_CREATE_PIPE)
|
package/libraries/llvm/rts.ll
CHANGED
|
@@ -91,9 +91,6 @@
|
|
|
91
91
|
%Double = type double
|
|
92
92
|
%Byte = type i8
|
|
93
93
|
%Char = type i64
|
|
94
|
-
%Bool = type %Pos
|
|
95
|
-
%Unit = type %Pos
|
|
96
|
-
%String = type %Pos
|
|
97
94
|
|
|
98
95
|
; Foreign imports
|
|
99
96
|
|
|
@@ -726,9 +723,11 @@ define private %Stack @withEmptyStack() {
|
|
|
726
723
|
ret %Stack %stack
|
|
727
724
|
}
|
|
728
725
|
|
|
729
|
-
define ccc void @resume_Int(%Stack %stack, %Int %
|
|
730
|
-
%
|
|
731
|
-
|
|
726
|
+
define ccc void @resume_Int(%Stack %stack, %Int %argument) {
|
|
727
|
+
%stackPointer = call ccc %StackPointer @stackDeallocate(%Stack %stack, i64 24)
|
|
728
|
+
%returnAddressPointer = getelementptr %FrameHeader, %StackPointer %stackPointer, i64 0, i32 0
|
|
729
|
+
%returnAddress = load %ReturnAddress, ptr %returnAddressPointer, !alias.scope !12, !noalias !22
|
|
730
|
+
tail call tailcc void %returnAddress(%Int %argument, %Stack %stack)
|
|
732
731
|
ret void
|
|
733
732
|
}
|
|
734
733
|
|
|
@@ -740,9 +739,7 @@ define ccc void @resume_Pos(%Stack %stack, %Pos %argument) {
|
|
|
740
739
|
ret void
|
|
741
740
|
}
|
|
742
741
|
|
|
743
|
-
define ccc void @run(%
|
|
744
|
-
|
|
745
|
-
%function = call %Neg @coercePosNeg(%Pos %boxed)
|
|
742
|
+
define ccc void @run(%Neg %function) {
|
|
746
743
|
%stack = call %Stack @withEmptyStack()
|
|
747
744
|
|
|
748
745
|
%arrayPointer = extractvalue %Neg %function, 0
|
|
@@ -754,15 +751,19 @@ define ccc void @run(%Pos %boxed) {
|
|
|
754
751
|
ret void
|
|
755
752
|
}
|
|
756
753
|
|
|
757
|
-
define ccc void @run_Int(%
|
|
758
|
-
%
|
|
759
|
-
|
|
754
|
+
define ccc void @run_Int(%Neg %function, %Int %argument) {
|
|
755
|
+
%stack = call %Stack @withEmptyStack()
|
|
756
|
+
|
|
757
|
+
%arrayPointer = extractvalue %Neg %function, 0
|
|
758
|
+
%object = extractvalue %Neg %function, 1
|
|
759
|
+
%functionPointerPointer = getelementptr ptr, ptr %arrayPointer, i64 0
|
|
760
|
+
%functionPointer = load ptr, ptr %functionPointerPointer, !alias.scope !15, !noalias !25
|
|
761
|
+
|
|
762
|
+
tail call tailcc %Pos %functionPointer(%Object %object, %Int %argument, %Stack %stack)
|
|
760
763
|
ret void
|
|
761
764
|
}
|
|
762
765
|
|
|
763
|
-
define ccc void @run_Pos(%
|
|
764
|
-
|
|
765
|
-
%function = call ccc %Neg @coercePosNeg(%Pos %boxed)
|
|
766
|
+
define ccc void @run_Pos(%Neg %function, %Pos %argument) {
|
|
766
767
|
%stack = call %Stack @withEmptyStack()
|
|
767
768
|
|
|
768
769
|
%arrayPointer = extractvalue %Neg %function, 0
|
package/libraries/llvm/types.c
CHANGED
|
@@ -38,9 +38,9 @@ typedef struct StackValue* Stack;
|
|
|
38
38
|
extern void resume_Int(Stack, Int);
|
|
39
39
|
extern void resume_Pos(Stack, struct Pos);
|
|
40
40
|
|
|
41
|
-
extern void run(struct
|
|
42
|
-
extern void run_Int(struct
|
|
43
|
-
extern void run_Pos(struct
|
|
41
|
+
extern void run(struct Neg);
|
|
42
|
+
extern void run_Int(struct Neg, Int);
|
|
43
|
+
extern void run_Pos(struct Neg, struct Pos);
|
|
44
44
|
|
|
45
45
|
// Reference counting primitives defined in LLVM
|
|
46
46
|
extern void eraseNegative(struct Neg);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
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>
|
|
2
|
-
<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/og-image-template_hu_cdf3b1afdf89db6f.png"><meta name=twitter:image content="https://www.eclipse.org/images/og-image-template_hu_cdf3b1afdf89db6f.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.144.2"><link rel=canonical href=https://www.eclipse.org/legal/epl-2.0/><link rel=alternate href=https://www.eclipse.org//legal/epl-2.0/index.xml type=application/rss+xml title><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> <script type="module" crossorigin src="/public/assets/legal/epl-2.0/index-
|
|
3
|
-
<link rel="modulepreload" crossorigin href="/public/assets/main-
|
|
2
|
+
<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/og-image-template_hu_cdf3b1afdf89db6f.png"><meta name=twitter:image content="https://www.eclipse.org/images/og-image-template_hu_cdf3b1afdf89db6f.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.144.2"><link rel=canonical href=https://www.eclipse.org/legal/epl-2.0/><link rel=alternate href=https://www.eclipse.org//legal/epl-2.0/index.xml type=application/rss+xml title><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> <script type="module" crossorigin src="/public/assets/legal/epl-2.0/index-D8ggeb7P.js"></script>
|
|
3
|
+
<link rel="modulepreload" crossorigin href="/public/assets/main-mybPeJDO.js">
|
|
4
4
|
<link rel="modulepreload" crossorigin href="/public/assets/get-body-content-D33PtpOf.js">
|
|
5
5
|
<link rel="modulepreload" crossorigin href="/public/assets/generate-body-content-BZFBJ1cI.js">
|
|
6
|
-
<link rel="stylesheet" crossorigin href="/public/assets/main-
|
|
6
|
+
<link rel="stylesheet" crossorigin href="/public/assets/main-ZVxMvmhT.css">
|
|
7
7
|
</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 href=#main class=skip-link>Skip to content</a><div class=eclipsefdn-featured-story-banner data-publish-target=eclipse_org></div><header class="header-wrapper header-wrapper" id=header><div class="navigation-bar dark"><div class=container><div class=navigation-bar-inner><div class=navigation-bar-left><a class="focus-highlight focus-inverse" href=/><img class=navigation-bar-brand src=https://www.eclipse.org/eclipse.org-common/themes/solstice/public/images/logo/eclipse-foundation-white-orange.svg alt="Eclipse Foundation"></a></div><nav class="navigation-bar-nav hidden-xs hidden-sm"><ul><li><button type=button class="btn btn-link" data-target=join-us-menu>Join us</button></li><li><button type=button class="btn btn-link" data-target=what-we-do-menu>What we do</button></li><li><button type=button class="btn btn-link" data-target=resources-menu>Resources</button></li><li><button type=button class="btn btn-link" data-target=about-us-menu>About us</button></li></ul></nav><div class=navigation-bar-right><div class="navigation-bar-controls hidden-xs hidden-sm"><ul><li class=dropdown><a class="dropdown-toggle link-unstyled focus-highlight" tabindex=0 id=search-dropdown-toggle data-toggle=dropdown href=# aria-label=Search><i class="fa-solid fa-magnifying-glass" aria-hidden=true></i></a><form class="search-bar dropdown-menu dropdown-menu-right" aria-labelledby=search-dropdown-toggle action=https://www.eclipse.org/home/search/ method=get><input class=search-bar-input name=q placeholder=Search>
|
|
8
8
|
<button class="btn btn-link" type=submit>
|
|
9
9
|
<i class="fa-solid fa-arrow-right"></i></button></form></li><li class=dropdown><a class="dropdown-toggle focus-highlight" id=user-menu href=# data-toggle=dropdown aria-haspopup=true aria-expanded=false tabindex=0><i class="fa-regular fa-user" aria-hidden=true></i></a><ul class="dropdown-menu dropdown-menu-right" aria-labelledby=user-menu><li><a href=https://accounts.eclipse.org/user><i class="fa-solid fa-user margin-right-10" aria-hidden=true></i>
|