@effekt-lang/effekt 0.76.0 → 0.78.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 +4 -3
- package/libraries/common/bytearray.effekt +44 -25
- package/libraries/common/char.effekt +12 -5
- package/libraries/common/effekt.effekt +10 -13
- package/libraries/common/list.effekt +22 -0
- package/libraries/common/map.effekt +109 -83
- package/libraries/common/set.effekt +25 -14
- package/libraries/common/string.effekt +28 -0
- package/libraries/common/stringbuffer.effekt +5 -5
- package/libraries/llvm/bytearray.c +14 -5
- package/libraries/llvm/forward-declare-c.ll +1 -0
- package/licenses/eclipse public license, version 2.0 - epl-2.0.html +3 -3
- package/licenses/mit license - mit-license.html +61 -53
- package/licenses/the bsd license - bsd-license.html +60 -52
- package/licenses/the mit license - mit.html +60 -52
- package/package.json +1 -1
|
@@ -9,7 +9,7 @@ record Set[A](tree: internal::Tree[A, Unit], compare: (A, A) => Ordering at {})
|
|
|
9
9
|
/// Create a new empty set using a pure, first-class comparison function.
|
|
10
10
|
///
|
|
11
11
|
/// O(1)
|
|
12
|
-
def empty[A](compare: (A, A) => Ordering at {}): Set[A] =
|
|
12
|
+
def empty[A](?compare: (A, A) => Ordering at {}): Set[A] =
|
|
13
13
|
Set(internal::empty(), compare)
|
|
14
14
|
|
|
15
15
|
/// Create a new empty set using a generic comparison function.
|
|
@@ -36,7 +36,7 @@ def nonEmpty[A](s: Set[A]): Bool = internal::nonEmpty(s.tree)
|
|
|
36
36
|
/// Requires a pure, first-class comparison function.
|
|
37
37
|
///
|
|
38
38
|
/// O(1)
|
|
39
|
-
def singleton[A](element: A, compare: (A, A) => Ordering at {}): Set[A] =
|
|
39
|
+
def singleton[A](element: A, ?compare: (A, A) => Ordering at {}): Set[A] =
|
|
40
40
|
Set(internal::singleton(element, ()), compare)
|
|
41
41
|
|
|
42
42
|
/// Create a new set containing a single `element` and a generic comparison function.
|
|
@@ -81,7 +81,7 @@ def toMap[K, V](keys: Set[K]) { valueOf: K => V }: Map[K, V] = {
|
|
|
81
81
|
///
|
|
82
82
|
/// O(N log N)
|
|
83
83
|
/// O(N) if the list is sorted
|
|
84
|
-
def fromList[A](list: List[A], compare: (A, A) => Ordering at {}): Set[A] = {
|
|
84
|
+
def fromList[A](list: List[A], ?compare: (A, A) => Ordering at {}): Set[A] = {
|
|
85
85
|
val tree: internal::Tree[A, Unit] = internal::fromList(list.map { k => (k, ()) }, compare)
|
|
86
86
|
Set(tree, compare)
|
|
87
87
|
}
|
|
@@ -105,15 +105,23 @@ def fromListGeneric[A](list: List[A]): Set[A] = {
|
|
|
105
105
|
def foreach[A](s: Set[A]) { action: A => Unit }: Unit =
|
|
106
106
|
internal::foreach(s.tree) { (k, _v) => action(k) }
|
|
107
107
|
|
|
108
|
+
/// Traverse all elements in *reverse* order, running the function `action` on each element.
|
|
109
|
+
///
|
|
110
|
+
/// Law: `s.foreachReversed { action } === s.toList.reverse.foreach { action }`
|
|
111
|
+
///
|
|
112
|
+
/// O(N)
|
|
113
|
+
def foreachReversed[A](s: Set[A]) { action: A => Unit }: Unit =
|
|
114
|
+
internal::foreachReversed(s.tree) { (k, _v) => action(k) }
|
|
115
|
+
|
|
108
116
|
/// Create a list from a given set.
|
|
109
117
|
///
|
|
110
118
|
/// O(N)
|
|
111
119
|
def toList[A](s: Set[A]): List[A] = {
|
|
112
120
|
var acc = Nil()
|
|
113
|
-
s.
|
|
121
|
+
s.foreachReversed { a =>
|
|
114
122
|
acc = Cons(a, acc)
|
|
115
123
|
}
|
|
116
|
-
acc
|
|
124
|
+
acc
|
|
117
125
|
}
|
|
118
126
|
|
|
119
127
|
/// Check if a predicate holds for all elements in a given set.
|
|
@@ -189,7 +197,7 @@ def deleteMany[A](s: Set[A], list: List[A]): Set[A] = {
|
|
|
189
197
|
/// Uses an explicit comparison function.
|
|
190
198
|
///
|
|
191
199
|
/// O(???)
|
|
192
|
-
def difference[A](s1: Set[A], s2: Set[A], compare: (A, A) => Ordering at {}): Set[A] = {
|
|
200
|
+
def difference[A](s1: Set[A], s2: Set[A], ?compare: (A, A) => Ordering at {}): Set[A] = {
|
|
193
201
|
val newTree = internal::difference(s1.tree, s2.tree, compare)
|
|
194
202
|
Set(newTree, compare)
|
|
195
203
|
}
|
|
@@ -206,7 +214,7 @@ def difference[A](s1: Set[A], s2: Set[A]): Set[A] =
|
|
|
206
214
|
/// Uses an explicit comparison function.
|
|
207
215
|
///
|
|
208
216
|
/// O(???)
|
|
209
|
-
def union[A](s1: Set[A], s2: Set[A], compare: (A, A) => Ordering at {}): Set[A] = {
|
|
217
|
+
def union[A](s1: Set[A], s2: Set[A], ?compare: (A, A) => Ordering at {}): Set[A] = {
|
|
210
218
|
val newTree = internal::union(s1.tree, s2.tree, compare) { (_k, _v1, _v2) => () }
|
|
211
219
|
Set(newTree, compare)
|
|
212
220
|
}
|
|
@@ -222,7 +230,7 @@ def union[A](s1: Set[A], s2: Set[A]): Set[A] =
|
|
|
222
230
|
/// Uses an explicit comparison function.
|
|
223
231
|
///
|
|
224
232
|
/// O(???)
|
|
225
|
-
def intersection[A](s1: Set[A], s2: Set[A], compare: (A, A) => Ordering at {}): Set[A] = {
|
|
233
|
+
def intersection[A](s1: Set[A], s2: Set[A], ?compare: (A, A) => Ordering at {}): Set[A] = {
|
|
226
234
|
val newTree = internal::intersection(s1.tree, s2.tree, compare) { (_k, _v1, _v2) => () }
|
|
227
235
|
Set(newTree, compare)
|
|
228
236
|
}
|
|
@@ -245,17 +253,20 @@ def each[A](set: Set[A]): Unit / emit[A] =
|
|
|
245
253
|
|
|
246
254
|
/// Collects elements emitted by a push stream producer `stream` into a new set
|
|
247
255
|
/// using provided `compare` function, discarding the result of the producer.
|
|
248
|
-
def collect[A](compare: (A, A) => Ordering at {}) { stream: () => Unit / emit[A] }: Set[A] =
|
|
256
|
+
def collect[A](?compare: (A, A) => Ordering at {}) { stream: () => Unit / emit[A] }: Set[A] =
|
|
249
257
|
returning::collect[A, Unit](compare){stream}.second
|
|
250
258
|
|
|
251
259
|
namespace returning {
|
|
252
260
|
/// Collects elements emitted by a push stream producer `stream` into a new set
|
|
253
261
|
/// using provided `compare` function, returning the result of the producer as well as the collected set.
|
|
254
|
-
def collect[A, R](compare: (A, A) => Ordering at {}) { stream: () => R / emit[A] }: (R, Set[A]) =
|
|
255
|
-
|
|
256
|
-
|
|
262
|
+
def collect[A, R](?compare: (A, A) => Ordering at {}) { stream: () => R / emit[A] }: (R, Set[A]) = {
|
|
263
|
+
var set = set::empty(compare)
|
|
264
|
+
val r = try {
|
|
265
|
+
stream()
|
|
257
266
|
} with emit[A] { (v) =>
|
|
258
|
-
|
|
259
|
-
(
|
|
267
|
+
set = set.insert(v)
|
|
268
|
+
resume(())
|
|
260
269
|
}
|
|
270
|
+
(r, set)
|
|
271
|
+
}
|
|
261
272
|
}
|
|
@@ -210,6 +210,28 @@ namespace internal {
|
|
|
210
210
|
do emit(c.utf8ByteCount)
|
|
211
211
|
}
|
|
212
212
|
}
|
|
213
|
+
|
|
214
|
+
def compareCodePoints(left: String, right: String): Ordering = {
|
|
215
|
+
val ln = left.length
|
|
216
|
+
val rn = right.length
|
|
217
|
+
def go(i: Int, j: Int): Ordering =
|
|
218
|
+
if (i >= ln) { if (j >= rn) Equal() else Less() }
|
|
219
|
+
else if (j >= rn) Greater()
|
|
220
|
+
else {
|
|
221
|
+
val a = unsafeCharAt(left, i)
|
|
222
|
+
val b = unsafeCharAt(right, j)
|
|
223
|
+
compareChar(a, b) match {
|
|
224
|
+
case Equal() =>
|
|
225
|
+
// equal code points have equal widths, so take the step only once
|
|
226
|
+
val w = a.charWidth
|
|
227
|
+
go(i + w, j + w)
|
|
228
|
+
case Less() => Less()
|
|
229
|
+
case Greater() => Greater()
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
go(0, 0)
|
|
234
|
+
}
|
|
213
235
|
}
|
|
214
236
|
|
|
215
237
|
/// Returns the number of bytes that the given `str` would take up in a UTF-8 encoding.
|
|
@@ -235,6 +257,12 @@ extern def utf8ByteLength(str: String) at {io, global}: Int =
|
|
|
235
257
|
// extern def unsafeIndexOf(str: String, sub: String) at {}: Int =
|
|
236
258
|
// js "${str}.indexOf(${sub})"
|
|
237
259
|
|
|
260
|
+
/// Compares two strings lexicographically by code point.
|
|
261
|
+
/// Identical on every backend.
|
|
262
|
+
extern def compareStringBytes(left: String, right: String) at {}: Ordering =
|
|
263
|
+
llvm { compareByteArray(fromString(left), fromString(right)) }
|
|
264
|
+
default { internal::compareCodePoints(left, right) }
|
|
265
|
+
|
|
238
266
|
def charAt(str: String, index: Int): Char / Exception[OutOfBounds] =
|
|
239
267
|
if (index < 0 || index >= length(str))
|
|
240
268
|
do raise(OutOfBounds(), "Index out of bounds: " ++ show(index) ++ " in string: '" ++ str ++ "'")
|
|
@@ -28,11 +28,11 @@ def flushableStringBuffer[A] { program: () => A / { write, flush } }: A = {
|
|
|
28
28
|
program()
|
|
29
29
|
} with write { string =>
|
|
30
30
|
val bytes = fromString(string)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
val n = bytes.size
|
|
32
|
+
ensureCapacity(n)
|
|
33
|
+
// safe: `ensureCapacity` just established the target range
|
|
34
|
+
bytearray::unsafeCopy(bytes, 0, buffer, position, n)
|
|
35
|
+
position = position + n
|
|
36
36
|
resume(())
|
|
37
37
|
} with flush {
|
|
38
38
|
val string = buffer.resize(position).toString()
|
|
@@ -56,6 +56,17 @@ uint8_t* c_bytearray_data(const struct Pos arr) {
|
|
|
56
56
|
return data;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
struct Pos c_bytearray_copy(const struct Pos source, const Int sourceOffset,
|
|
60
|
+
const struct Pos target, const Int targetOffset,
|
|
61
|
+
const Int length) {
|
|
62
|
+
// memmove, not memcpy: the ranges may overlap, and may even be the same bytearray
|
|
63
|
+
memmove(c_bytearray_data(target) + targetOffset,
|
|
64
|
+
c_bytearray_data(source) + sourceOffset, length);
|
|
65
|
+
erasePositive(source);
|
|
66
|
+
erasePositive(target);
|
|
67
|
+
return Unit;
|
|
68
|
+
}
|
|
69
|
+
|
|
59
70
|
struct Pos c_bytearray_construct(const uint64_t n, const uint8_t *data) {
|
|
60
71
|
struct Pos arr = c_bytearray_new(n);
|
|
61
72
|
memcpy(c_bytearray_data(arr), data, n);
|
|
@@ -134,11 +145,9 @@ struct Pos c_bytearray_concatenate(const struct Pos left, const struct Pos right
|
|
|
134
145
|
uint64_t left_size = left.tag;
|
|
135
146
|
uint64_t right_size = right.tag;
|
|
136
147
|
const struct Pos concatenated = c_bytearray_new(left_size + right_size);
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
? c_bytearray_data(left)[j]
|
|
141
|
-
: c_bytearray_data(right)[j - left_size];
|
|
148
|
+
// two memcpys rather than a byte loop with a branch per byte
|
|
149
|
+
memcpy(c_bytearray_data(concatenated), c_bytearray_data(left), left_size);
|
|
150
|
+
memcpy(c_bytearray_data(concatenated) + left_size, c_bytearray_data(right), right_size);
|
|
142
151
|
|
|
143
152
|
erasePositive(left);
|
|
144
153
|
erasePositive(right);
|
|
@@ -25,6 +25,7 @@ declare %Int @c_bytearray_size(%Pos)
|
|
|
25
25
|
declare %Byte @c_bytearray_get(%Pos, %Int)
|
|
26
26
|
declare %Pos @c_bytearray_set(%Pos, %Int, %Byte)
|
|
27
27
|
|
|
28
|
+
declare %Pos @c_bytearray_copy(%Pos, %Int, %Pos, %Int, %Int)
|
|
28
29
|
declare ptr @c_bytearray_data(%Pos)
|
|
29
30
|
declare %Pos @c_bytearray_construct(i64, ptr)
|
|
30
31
|
|
|
@@ -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-KKbnVOd8.js"></script>
|
|
3
|
+
<link rel="modulepreload" crossorigin href="/public/assets/main-BKIcjYwC.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-BzlpBkIh.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>
|