@effekt-lang/effekt 0.50.0 → 0.52.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 CHANGED
Binary file
@@ -199,7 +199,7 @@ namespace returning {
199
199
  if(stopped){
200
200
  resume { do stop() }
201
201
  } else {
202
- do read[Char] match {
202
+ do read() match {
203
203
  case '\n' => stopped = true; resume { do stop() }
204
204
  case char => resume { return char }
205
205
  }
@@ -164,6 +164,10 @@ extern def unsafeSubstring(str: String, from: Int, to: Int) at {}: String =
164
164
  extern def random() at io: Double =
165
165
  js "Math.random()"
166
166
  chez "(random 1.0)"
167
+ llvm """
168
+ %r = call double @c_io_random()
169
+ ret double %r
170
+ """
167
171
  vm "effekt::random()"
168
172
 
169
173
  // References and state
@@ -362,97 +362,110 @@ namespace internal {
362
362
  declare %Int @c_error_number(%Int)
363
363
  """
364
364
 
365
- extern jsNode """
366
- const os = require('node:os');
365
+ extern jsNode """
366
+ const { getSystemErrorName } = require('node:util');
367
367
 
368
368
  /**
369
369
  * Maps the error code to a Effekt-stable (platform independent) numeric value.
370
370
  *
371
371
  * Tries to use most common errno integer values, but introduces fresh values (> 200)
372
372
  * for those without common errno values.
373
+ *
374
+ * The mapping from platfrom-specific error codes to Effekt error codes is handled by
375
+ * getSystemErrorName from 'node:util', which in turn uses the error code conventions from libuv.
376
+ * For reference, see the following Deno code which is more readable than the NodeJS implementation:
377
+ * https://github.com/denoland/deno/blob/8fb073d7b4ea83b57fd1bf9875681347b414bbe6/ext/node/polyfills/internal_binding/uv.ts
373
378
  */
374
379
  function errorNumber(errno) {
375
- const errnoMap = {
376
- [os.constants.errno.EPERM]: 1,
377
- [os.constants.errno.ENOENT]: 2,
378
- [os.constants.errno.ESRCH]: 3,
379
- [os.constants.errno.EINTR]: 4,
380
- [os.constants.errno.EIO]: 5,
381
- [os.constants.errno.ENXIO]: 6,
382
- [os.constants.errno.E2BIG]: 7,
383
- [os.constants.errno.EBADF]: 9,
384
- [os.constants.errno.EAGAIN]: 11,
385
- [os.constants.errno.ENOMEM]: 12,
386
- [os.constants.errno.EACCES]: 13,
387
- [os.constants.errno.EFAULT]: 14,
388
- [os.constants.errno.EBUSY]: 16,
389
- [os.constants.errno.EEXIST]: 17,
390
- [os.constants.errno.EXDEV]: 18,
391
- [os.constants.errno.ENODEV]: 19,
392
- [os.constants.errno.ENOTDIR]: 20,
393
- [os.constants.errno.EISDIR]: 21,
394
- [os.constants.errno.EINVAL]: 22,
395
- [os.constants.errno.ENFILE]: 23,
396
- [os.constants.errno.EMFILE]: 24,
397
- [os.constants.errno.ENOTTY]: 25,
398
- [os.constants.errno.ETXTBSY]: 26,
399
- [os.constants.errno.EFBIG]: 27,
400
- [os.constants.errno.ENOSPC]: 28,
401
- [os.constants.errno.ESPIPE]: 29,
402
- [os.constants.errno.EROFS]: 30,
403
- [os.constants.errno.EMLINK]: 31,
404
- [os.constants.errno.EPIPE]: 32,
405
- [os.constants.errno.ERANGE]: 34,
406
- [os.constants.errno.ENAMETOOLONG]: 36,
407
- [os.constants.errno.ELOOP]: 40,
408
- [os.constants.errno.EOVERFLOW]: 75,
409
- [os.constants.errno.EFTYPE]: 79,
410
- [os.constants.errno.EILSEQ]: 84,
411
- [os.constants.errno.ENOTSOCK]: 88,
412
- [os.constants.errno.EDESTADDRREQ]: 89,
413
- [os.constants.errno.EMSGSIZE]: 90,
414
- [os.constants.errno.EPROTOTYPE]: 91,
415
- [os.constants.errno.ENOPROTOOPT]: 92,
416
- [os.constants.errno.EPROTONOSUPPORT]: 93,
417
- [os.constants.errno.ESOCKTNOSUPPORT]: 94,
418
- [os.constants.errno.ENOTSUP]: 95,
419
- [os.constants.errno.EAFNOSUPPORT]: 97,
420
- [os.constants.errno.EADDRINUSE]: 98,
421
- [os.constants.errno.EADDRNOTAVAIL]: 99,
422
- [os.constants.errno.ENETDOWN]: 100,
423
- [os.constants.errno.ENETUNREACH]: 101,
424
- [os.constants.errno.ECONNABORTED]: 103,
425
- [os.constants.errno.ECONNRESET]: 104,
426
- [os.constants.errno.ENOBUFS]: 105,
427
- [os.constants.errno.EISCONN]: 106,
428
- [os.constants.errno.ENOTCONN]: 107,
429
- [os.constants.errno.ETIMEDOUT]: 110,
430
- [os.constants.errno.ECONNREFUSED]: 111,
431
- [os.constants.errno.EHOSTUNREACH]: 113,
432
- [os.constants.errno.EALREADY]: 114,
433
- [os.constants.errno.ECANCELED]: 125,
434
- [os.constants.errno.EAI_ADDRFAMILY]: 200,
435
- [os.constants.errno.EAI_AGAIN]: 201,
436
- [os.constants.errno.EAI_BADFLAGS]: 202,
437
- [os.constants.errno.EAI_BADHINTS]: 203,
438
- [os.constants.errno.EAI_CANCELED]: 204,
439
- [os.constants.errno.EAI_FAIL]: 205,
440
- [os.constants.errno.EAI_FAMILY]: 206,
441
- [os.constants.errno.EAI_MEMORY]: 207,
442
- [os.constants.errno.EAI_NODATA]: 208,
443
- [os.constants.errno.EAI_NONAME]: 209,
444
- [os.constants.errno.EAI_OVERFLOW]: 210,
445
- [os.constants.errno.EAI_PROTOCOL]: 211,
446
- [os.constants.errno.EAI_SERVICE]: 212,
447
- [os.constants.errno.EAI_SOCKTYPE]: 213,
448
- [os.constants.errno.ECHARSET]: 215,
449
- [os.constants.errno.ENONET]: 216,
450
- [os.constants.errno.UNKNOWN]: 217,
451
- [os.constants.errno.EOF]: 218,
452
- [os.constants.errno.EUNATCH]: 219,
453
- [os.constants.errno.ESHUTDOWN]: 220
380
+ const mapByName = {
381
+ EPERM: 1,
382
+ ENOENT: 2,
383
+ ESRCH: 3,
384
+ EINTR: 4,
385
+ EIO: 5,
386
+ ENXIO: 6,
387
+ E2BIG: 7,
388
+ EBADF: 9,
389
+ EAGAIN: 11,
390
+ ENOMEM: 12,
391
+ EACCES: 13,
392
+ EFAULT: 14,
393
+ EBUSY: 16,
394
+ EEXIST: 17,
395
+ EXDEV: 18,
396
+ ENODEV: 19,
397
+ ENOTDIR: 20,
398
+ EISDIR: 21,
399
+ EINVAL: 22,
400
+ ENFILE: 23,
401
+ EMFILE: 24,
402
+ ENOTTY: 25,
403
+ ETXTBSY: 26,
404
+ EFBIG: 27,
405
+ ENOSPC: 28,
406
+ ESPIPE: 29,
407
+ EROFS: 30,
408
+ EMLINK: 31,
409
+ EPIPE: 32,
410
+ ERANGE: 34,
411
+ ENAMETOOLONG: 36,
412
+ ELOOP: 40,
413
+ EOVERFLOW: 75,
414
+ EFTYPE: 79,
415
+ EILSEQ: 84,
416
+ ENOTSOCK: 88,
417
+ EDESTADDRREQ: 89,
418
+ EMSGSIZE: 90,
419
+ EPROTOTYPE: 91,
420
+ ENOPROTOOPT: 92,
421
+ EPROTONOSUPPORT: 93,
422
+ ESOCKTNOSUPPORT: 94,
423
+ ENOTSUP: 95,
424
+ EAFNOSUPPORT: 97,
425
+ EADDRINUSE: 98,
426
+ EADDRNOTAVAIL: 99,
427
+ ENETDOWN: 100,
428
+ ENETUNREACH: 101,
429
+ ECONNABORTED: 103,
430
+ ECONNRESET: 104,
431
+ ENOBUFS: 105,
432
+ EISCONN: 106,
433
+ ENOTCONN: 107,
434
+ ETIMEDOUT: 110,
435
+ ECONNREFUSED: 111,
436
+ EHOSTUNREACH: 113,
437
+ EALREADY: 114,
438
+ ECANCELED: 125,
439
+
440
+ EAI_ADDRFAMILY: 200,
441
+ EAI_AGAIN: 201,
442
+ EAI_BADFLAGS: 202,
443
+ EAI_BADHINTS: 203,
444
+ EAI_CANCELED: 204,
445
+ EAI_FAIL: 205,
446
+ EAI_FAMILY: 206,
447
+ EAI_MEMORY: 207,
448
+ EAI_NODATA: 208,
449
+ EAI_NONAME: 209,
450
+ EAI_OVERFLOW: 210,
451
+ EAI_PROTOCOL: 211,
452
+ EAI_SERVICE: 212,
453
+ EAI_SOCKTYPE: 213,
454
+ ECHARSET: 215,
455
+ ENONET: 216,
456
+ UNKNOWN: 217,
457
+ EOF: 218,
458
+ EUNATCH: 219,
459
+ ESHUTDOWN: 220
454
460
  };
455
- return errnoMap[-errno] || -1; // Default to -1 for unknown error names
461
+
462
+ // When the error code is not known, we return 217 (UNKNOWN).
463
+ try {
464
+ const name = getSystemErrorName(errno);
465
+ return mapByName[name] ?? 217;
466
+ } catch {
467
+ return 217;
468
+ }
456
469
  }
457
470
  """
458
471
 
@@ -469,7 +482,7 @@ namespace internal {
469
482
  def checkResult(result: Int): Int / Exception[IOError] =
470
483
  if (result < 0) {
471
484
  val ioError = fromNumber(internal::errorNumber(result));
472
- do raise[IOError](ioError, message(ioError))
485
+ do raise(ioError, message(ioError))
473
486
  } else {
474
487
  result
475
488
  }
@@ -158,7 +158,7 @@ def readQuotedString(): Unit / { Scan[Char], emit[Char], Exception[WrongFormat]
158
158
  def decodeJson(): Unit / {Scan[Char], JsonBuilder, Exception[WrongFormat]} = {
159
159
  with boundary
160
160
  skipWhitespace()
161
- if(do peek[Char]() is c) {
161
+ if(do peek() is c) {
162
162
  c match {
163
163
  case 'n' => expectString("null"); do null()
164
164
  case 't' => expectString("true"); do bool(true)
@@ -177,7 +177,7 @@ def decodeJsonObject(): Unit / {Scan[Char], JsonObjectBuilder, Exception[WrongFo
177
177
  expectString("{")
178
178
  with boundary
179
179
  skipWhitespace()
180
- while(do peek[Char]() is c and (c != '}')) {
180
+ while(do peek() is c and (c != '}')) {
181
181
  if (not(first)) { expectString(",") }
182
182
  val k = string::collect { readQuotedString() }
183
183
  skipWhitespace()
@@ -188,20 +188,20 @@ def decodeJsonObject(): Unit / {Scan[Char], JsonObjectBuilder, Exception[WrongFo
188
188
  skipWhitespace()
189
189
  first = false
190
190
  }
191
- do skip[Char]()
191
+ do skip()
192
192
  }
193
193
  def decodeJsonList(): Unit / {Scan[Char], JsonBuilder, Exception[WrongFormat]} = {
194
194
  var first = true
195
195
  expectString("[")
196
196
  with boundary
197
197
  skipWhitespace()
198
- while(do peek[Char]() is c and (c != ']')) {
198
+ while(do peek() is c and (c != ']')) {
199
199
  if (not(first)) { expectString(",") }
200
200
  decodeJson()
201
201
  skipWhitespace()
202
202
  first = false
203
203
  }
204
- do skip[Char]()
204
+ do skip()
205
205
  }
206
206
 
207
207
  // --------------------------------------------------------------------------------
@@ -73,7 +73,7 @@ def devurandom { randomnessReader: () => Unit / random }: Unit / Exception[IOErr
73
73
  try {
74
74
  with readFile("/dev/urandom")
75
75
  try randomnessReader() with random {
76
- resume(do read[Byte]())
76
+ resume(do read())
77
77
  }
78
78
  } with stop {
79
79
  do raise(io::error::EOF(), "Unexpected EOF when reading /dev/urandom!")
@@ -12,8 +12,8 @@ interface Scan[A] {
12
12
 
13
13
  /// Advance the Scanner to the next character, returning it.
14
14
  def read[A](): A / { Scan[A], stop } = {
15
- val t = do peek[A]()
16
- do skip[A]()
15
+ val t = do peek()
16
+ do skip()
17
17
  return t
18
18
  }
19
19
 
@@ -26,9 +26,9 @@ def expect(message: String) { scanner: () => Unit / stop }: Unit / Exception[Wro
26
26
 
27
27
  /// Check that the next token satisfies the predicate and skip and return it when it does.
28
28
  def readIf[A] { predicate: A => Bool }: A / { Scan[A], stop } = {
29
- val t = do peek[A]()
29
+ val t = do peek()
30
30
  if (predicate(t)) {
31
- do skip[A]()
31
+ do skip()
32
32
  return t
33
33
  } else {
34
34
  do stop()
@@ -42,7 +42,7 @@ def skipIf[A] { predicate: A => Bool }: Unit / { Scan[A], stop } = {
42
42
 
43
43
  def readSome[A, B] { convert: A => Option[B] }: B / { Scan[A], stop } =
44
44
  if (convert(do peek()) is Some(t)) {
45
- do skip[A]()
45
+ do skip()
46
46
  return t
47
47
  } else {
48
48
  do stop()
@@ -53,7 +53,7 @@ def tryRead[A, B] { convert: A => B / Exception[WrongFormat] }: B / { Scan[A], s
53
53
  with on[WrongFormat].default { do stop() }
54
54
 
55
55
  val t = convert(do peek())
56
- do skip[A]()
56
+ do skip()
57
57
  return t
58
58
  }
59
59
 
@@ -130,7 +130,7 @@ def scanner[A, R] { scanner: () => R / Scan[A] }: R / read[A] = {
130
130
  def peek() = resume {
131
131
  last match {
132
132
  case None() =>
133
- val t = do read[A]()
133
+ val t = do read()
134
134
  last = Some(t)
135
135
  return t
136
136
  case Some(t) =>
@@ -140,7 +140,7 @@ def scanner[A, R] { scanner: () => R / Scan[A] }: R / read[A] = {
140
140
  def skip() = resume {
141
141
  last match {
142
142
  case None() =>
143
- val _ = do read[A]()
143
+ val _ = do read()
144
144
  return ()
145
145
  case Some(t) =>
146
146
  last = None()
@@ -145,7 +145,7 @@ def zip[A, B] { stream1: () => Unit / emit[A] } { stream2: () => Unit / emit[B]
145
145
  with source[B] { stream2 }
146
146
 
147
147
  exhaustively {
148
- action(do read[A](), do read[B]())
148
+ action(do read(), do read())
149
149
  }
150
150
  }
151
151
 
@@ -246,7 +246,7 @@ def feed[R](string: String) { reader: () => R / read[Char] } =
246
246
  def each(string: String): Unit / emit[Char] =
247
247
  feed(string) {
248
248
  exhaustively {
249
- do emit[Char](do read[Char]())
249
+ do emit(do read())
250
250
  }
251
251
  }
252
252
 
@@ -5,6 +5,7 @@ declare %Pos @c_get_arg(i64)
5
5
 
6
6
  declare void @c_io_println(%Pos)
7
7
  declare %Pos @c_io_readln()
8
+ declare %Double @c_io_random()
8
9
 
9
10
  declare void @hole(i8*)
10
11
  declare void @duplicated_prompt()
@@ -4,8 +4,8 @@
4
4
  #include <uv.h>
5
5
  #include <string.h> // to compare flag names
6
6
 
7
- // Println and Readln
8
- // ------------------
7
+ // Println and Readln and Random
8
+ // -----------------------------
9
9
 
10
10
  void c_io_println(String text) {
11
11
  for (uint64_t j = 0; j < text.tag; ++j) {
@@ -34,6 +34,10 @@ String c_io_readln() {
34
34
  return result;
35
35
  }
36
36
 
37
+ double c_io_random(void) {
38
+ return (double)rand() / (double)RAND_MAX;
39
+ }
40
+
37
41
  // Lib UV Bindings
38
42
  // ---------------
39
43
  // Ideas behind the LLVM / libuv implementation.
@@ -34,6 +34,7 @@ uint64_t c_get_argc() {
34
34
  int main(int argc, char *argv[]) {
35
35
  program_argc = argc;
36
36
  program_argv = argv;
37
+ setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
37
38
  effektMain();
38
39
  uv_loop_t *loop = uv_default_loop();
39
40
  uv_run(loop, UV_RUN_DEFAULT);
@@ -1,5 +1,5 @@
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.jpg"><meta name=twitter:image content="https://www.eclipse.org/images/og-image.jpg"><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=/legal/epl-2.0/index.xml type=application/rss+xml title><link rel=stylesheet href="/public/css/styles.css?v=1762110989"><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
+ <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.jpg"><meta name=twitter:image content="https://www.eclipse.org/images/og-image.jpg"><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=/legal/epl-2.0/index.xml type=application/rss+xml title><link rel=stylesheet href="/public/css/styles.css?v=1763320624"><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>
3
3
  <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>
4
4
  <button>
5
5
  <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">
@@ -64,4 +64,4 @@ open source software collaboration and innovation.</p></div><div class=mega-menu
64
64
  <i class="fa-brands fa-linkedin-in fa-stack-1x fa-inverse" aria-hidden=true></i>
65
65
  <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://eclipse.us6.list-manage.com/subscribe/post?u=eaf9e1f06f194eadc66788a85&amp;id=e7538485cd&amp;f_id=00f9c2e1f0" 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">
66
66
  <button class="footer-end-newsletter-submit btn btn-link" id=mc-embedded-subscribe type=submit name=subscribe>
67
- <i class="fa fa-solid fa-envelope fa-lg" aria-hidden=true></i></button></div></form></div></div></div><div class="col-sm-24 margin-top-20"><div class=row><div id=copyright class=col-sm-16><p id=copyright-text>Copyright &copy; 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=1762110989"></script><script>(function(){})(jQuery,document)</script></div></body></html>
67
+ <i class="fa fa-solid fa-envelope fa-lg" aria-hidden=true></i></button></div></form></div></div></div><div class="col-sm-24 margin-top-20"><div class=row><div id=copyright class=col-sm-16><p id=copyright-text>Copyright &copy; 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=1763320624"></script><script>(function(){})(jQuery,document)</script></div></body></html>