Current section

26 Versions

Jump to

Compare versions

8 files changed
+78 additions
-64 deletions
  @@ -1,7 +1,7 @@
1 1 "use strict";
2 2
3 3 import Bitstring from "../bitstring.mjs";
4 - import Erlang_UnicodeUtil from "./unicode_util.mjs";
4 + import Erlang_Unicode_Util from "./unicode_util.mjs";
5 5 import Interpreter from "../interpreter.mjs";
6 6 import Type from "../type.mjs";
7 7
  @@ -17,7 +17,7 @@ const Erlang_Elixir_Utils = {
17 17 let current = str;
18 18
19 19 while (true) {
20 - const result = Erlang_UnicodeUtil["cp/1"](current);
20 + const result = Erlang_Unicode_Util["cp/1"](current);
21 21
22 22 if (Type.isList(result) && result.data.length === 0) {
23 23 break;
  @@ -2,7 +2,7 @@
2 2
3 3 import Bitstring from "../bitstring.mjs";
4 4 import Erlang_Unicode from "./unicode.mjs";
5 - import Erlang_UnicodeUtil from "./unicode_util.mjs";
5 + import Erlang_Unicode_Util from "./unicode_util.mjs";
6 6 import ERTS from "../erts.mjs";
7 7 import Interpreter from "../interpreter.mjs";
8 8 import Type from "../type.mjs";
  @@ -216,7 +216,7 @@ const Erlang_String = {
216 216 let current = string;
217 217
218 218 while (true) {
219 - const gcResult = Erlang_UnicodeUtil["gc/1"](current);
219 + const gcResult = Erlang_Unicode_Util["gc/1"](current);
220 220
221 221 if (Type.isList(gcResult) && gcResult.data.length === 0) {
222 222 return Type.integer(count);
  @@ -473,7 +473,7 @@ const Erlang_String = {
473 473
474 474 // Helper: Extract first codepoint using unicode_util.cp/1
475 475 const extractFirstCodepoint = (subject) => {
476 - const cpResult = Erlang_UnicodeUtil["cp/1"](subject);
476 + const cpResult = Erlang_Unicode_Util["cp/1"](subject);
477 477
478 478 // Check if unicode_util.cp/1 returned an error tuple
479 479 if (Type.isTuple(cpResult)) {
  @@ -9,16 +9,16 @@ import Type from "../type.mjs";
9 9 // If the given ported Erlang function calls other Erlang functions, then list such dependencies in the "Deps" comment (see :erlang./=/2 for an example).
10 10 // Also, in such case add respective call graph edges in Hologram.CallGraph.list_runtime_mfas/1.
11 11
12 - const Erlang_UnicodeUtil = {
12 + const Erlang_Unicode_Util = {
13 13 // Start _cpl/2
14 14 "_cpl/2": (list, restList) => {
15 - const isCP = Erlang_UnicodeUtil["_is_cp/1"];
15 + const isCP = Erlang_Unicode_Util["_is_cp/1"];
16 16
17 17 // [C] when is_integer(C)
18 18 if (isCP(list)) {
19 19 return Type.improperList([
20 20 list,
21 - Erlang_UnicodeUtil["_cpl_1_cont/1"](restList),
21 + Erlang_Unicode_Util["_cpl_1_cont/1"](restList),
22 22 ]);
23 23 }
24 24
  @@ -41,7 +41,7 @@ const Erlang_UnicodeUtil = {
41 41 return restList;
42 42 }
43 43
44 - return Erlang_UnicodeUtil["cp/1"](restList);
44 + return Erlang_Unicode_Util["cp/1"](restList);
45 45 }
46 46
47 47 // Merge collected codepoints with restList
  @@ -53,7 +53,7 @@ const Erlang_UnicodeUtil = {
53 53 return Type.list([...result, ...restList.data]);
54 54 }
55 55
56 - const restListResult = Erlang_UnicodeUtil["cp/1"](restList);
56 + const restListResult = Erlang_Unicode_Util["cp/1"](restList);
57 57
58 58 if (Type.isList(restListResult) && restListResult.isProper) {
59 59 return Type.list([...result, ...restListResult.data]);
  @@ -66,7 +66,7 @@ const Erlang_UnicodeUtil = {
66 66 const firstElement = list.data[idx];
67 67
68 68 if (idx === list.data.length - 1) {
69 - const contResult = Erlang_UnicodeUtil["_cpl_cont/2"](
69 + const contResult = Erlang_Unicode_Util["_cpl_cont/2"](
70 70 firstElement,
71 71 restList,
72 72 );
  @@ -87,7 +87,7 @@ const Erlang_UnicodeUtil = {
87 87 ? Type.list([Type.list(list.data.slice(idx + 1))])
88 88 : Type.list([Type.list(list.data.slice(idx + 1)), ...restList.data]);
89 89
90 - const contResult = Erlang_UnicodeUtil["_cpl_cont/2"](
90 + const contResult = Erlang_Unicode_Util["_cpl_cont/2"](
91 91 firstElement,
92 92 newRestList,
93 93 );
  @@ -114,7 +114,7 @@ const Erlang_UnicodeUtil = {
114 114 }
115 115
116 116 // Continue processing restList for non-binary elements or nested structures
117 - return Erlang_UnicodeUtil["cp/1"](restList);
117 + return Erlang_Unicode_Util["cp/1"](restList);
118 118 }
119 119
120 120 // Binary handling: <<C/utf8, T/binary>>
  @@ -123,12 +123,15 @@ const Erlang_UnicodeUtil = {
123 123
124 124 // Invalid UTF-8
125 125 if (text === false) {
126 - const errorPayload = Erlang_UnicodeUtil["_merge_lcr/2"](list, restList);
126 + const errorPayload = Erlang_Unicode_Util["_merge_lcr/2"](
127 + list,
128 + restList,
129 + );
127 130 return Type.tuple([Type.atom("error"), errorPayload]);
128 131 }
129 132
130 133 if (text.length === 0) {
131 - return Erlang_UnicodeUtil["cp/1"](restList);
134 + return Erlang_Unicode_Util["cp/1"](restList);
132 135 }
133 136
134 137 const codepoint = text.codePointAt(0);
  @@ -171,7 +174,7 @@ const Erlang_UnicodeUtil = {
171 174
172 175 // Start _cpl_1_cont/1
173 176 "_cpl_1_cont/1": (restList) => {
174 - const isCP = Erlang_UnicodeUtil["_is_cp/1"];
177 + const isCP = Erlang_Unicode_Util["_is_cp/1"];
175 178
176 179 if (!Type.isList(restList)) {
177 180 return restList;
  @@ -188,19 +191,19 @@ const Erlang_UnicodeUtil = {
188 191 if (isCP(firstElement)) {
189 192 return Type.improperList([
190 193 firstElement,
191 - Erlang_UnicodeUtil["_cpl_1_cont2/1"](tail),
194 + Erlang_Unicode_Util["_cpl_1_cont2/1"](tail),
192 195 ]);
193 196 }
194 197
195 198 // [L|T]
196 - return Erlang_UnicodeUtil["_cpl_cont/2"](firstElement, tail);
199 + return Erlang_Unicode_Util["_cpl_cont/2"](firstElement, tail);
197 200 },
198 201 // End _cpl_1_cont/1
199 202 // Deps: [:unicode_util._cpl_1_cont2/1, :unicode_util._cpl_cont/2, :unicode_util._is_cp/1]
200 203
201 204 // Start _cpl_1_cont2/1
202 205 "_cpl_1_cont2/1": (restList) => {
203 - const isCP = Erlang_UnicodeUtil["_is_cp/1"];
206 + const isCP = Erlang_Unicode_Util["_is_cp/1"];
204 207
205 208 if (!Type.isList(restList)) {
206 209 return restList;
  @@ -217,24 +220,24 @@ const Erlang_UnicodeUtil = {
217 220 if (isCP(firstElement)) {
218 221 return Type.improperList([
219 222 firstElement,
220 - Erlang_UnicodeUtil["_cpl_1_cont3/1"](tail),
223 + Erlang_Unicode_Util["_cpl_1_cont3/1"](tail),
221 224 ]);
222 225 }
223 226
224 227 // [L]
225 228 if (restList.data.length === 1) {
226 - return Erlang_UnicodeUtil["_cpl_1_cont2/1"](firstElement);
229 + return Erlang_Unicode_Util["_cpl_1_cont2/1"](firstElement);
227 230 }
228 231
229 232 // [L|T]
230 - return Erlang_UnicodeUtil["_cpl_cont2/2"](firstElement, tail);
233 + return Erlang_Unicode_Util["_cpl_cont2/2"](firstElement, tail);
231 234 },
232 235 // End _cpl_1_cont2/1
233 236 // Deps: [:unicode_util._cpl_1_cont3/1, :unicode_util._cpl_cont2/2, :unicode_util._is_cp/1]
234 237
235 238 // Start _cpl_1_cont3/1
236 239 "_cpl_1_cont3/1": (restList) => {
237 - const isCP = Erlang_UnicodeUtil["_is_cp/1"];
240 + const isCP = Erlang_Unicode_Util["_is_cp/1"];
238 241
239 242 if (!Type.isList(restList)) {
240 243 return restList;
  @@ -253,13 +256,13 @@ const Erlang_UnicodeUtil = {
253 256
254 257 // [L]
255 258 if (restList.data.length === 1) {
256 - return Erlang_UnicodeUtil["_cpl_1_cont3/1"](firstElement);
259 + return Erlang_Unicode_Util["_cpl_1_cont3/1"](firstElement);
257 260 }
258 261
259 262 // [L|T]
260 263 const tail = Type.list(restList.data.slice(1));
261 264
262 - return Erlang_UnicodeUtil["_cpl_cont3/2"](firstElement, tail);
265 + return Erlang_Unicode_Util["_cpl_cont3/2"](firstElement, tail);
263 266 },
264 267 // End _cpl_1_cont3/1
265 268 // Deps: [:unicode_util._cpl_cont3/2, :unicode_util._is_cp/1]
  @@ -268,7 +271,7 @@ const Erlang_UnicodeUtil = {
268 271 "_cpl_cont/2": (list, restList) => {
269 272 if (Type.isList(list) && list.data.length > 0) {
270 273 // Inline optimized index-based logic to avoid O(n²) slicing behavior
271 - const isCP = Erlang_UnicodeUtil["_is_cp/1"];
274 + const isCP = Erlang_Unicode_Util["_is_cp/1"];
272 275 const result = [];
273 276 let idx = 0;
274 277
  @@ -285,7 +288,7 @@ const Erlang_UnicodeUtil = {
285 288 return restList;
286 289 }
287 290
288 - return Erlang_UnicodeUtil["cp/1"](restList);
291 + return Erlang_Unicode_Util["cp/1"](restList);
289 292 }
290 293
291 294 if (restList.data.length > 0 && Type.isBinary(restList.data[0])) {
  @@ -296,7 +299,7 @@ const Erlang_UnicodeUtil = {
296 299 return Type.list([...result, ...restList.data]);
297 300 }
298 301
299 - const restListResult = Erlang_UnicodeUtil["cp/1"](restList);
302 + const restListResult = Erlang_Unicode_Util["cp/1"](restList);
300 303
301 304 if (Type.isList(restListResult) && restListResult.isProper) {
302 305 return Type.list([...result, ...restListResult.data]);
  @@ -308,7 +311,7 @@ const Erlang_UnicodeUtil = {
308 311 const firstElement = list.data[idx];
309 312
310 313 if (idx === list.data.length - 1) {
311 - const cplResult = Erlang_UnicodeUtil["_cpl/2"](firstElement, restList);
314 + const cplResult = Erlang_Unicode_Util["_cpl/2"](firstElement, restList);
312 315
313 316 if (result.length === 0) {
314 317 return cplResult;
  @@ -326,7 +329,10 @@ const Erlang_UnicodeUtil = {
326 329 ? Type.list([Type.list(list.data.slice(idx + 1))])
327 330 : Type.list([Type.list(list.data.slice(idx + 1)), ...restList.data]);
328 331
329 - const cplResult = Erlang_UnicodeUtil["_cpl/2"](firstElement, newRestList);
332 + const cplResult = Erlang_Unicode_Util["_cpl/2"](
333 + firstElement,
334 + newRestList,
335 + );
330 336
331 337 if (result.length === 0) {
332 338 return cplResult;
  @@ -341,7 +347,7 @@ const Erlang_UnicodeUtil = {
341 347
342 348 // []
343 349 if (Type.isList(list) && list.data.length === 0) {
344 - return Erlang_UnicodeUtil["cp/1"](restList);
350 + return Erlang_Unicode_Util["cp/1"](restList);
345 351 }
346 352
347 353 // Binary handling: <<C/utf8, T/binary>>
  @@ -350,12 +356,15 @@ const Erlang_UnicodeUtil = {
350 356
351 357 // Invalid UTF-8: return error tuple
352 358 if (text === false) {
353 - const errorPayload = Erlang_UnicodeUtil["_merge_lcr/2"](list, restList);
359 + const errorPayload = Erlang_Unicode_Util["_merge_lcr/2"](
360 + list,
361 + restList,
362 + );
354 363 return Type.tuple([Type.atom("error"), errorPayload]);
355 364 }
356 365
357 366 if (text.length === 0) {
358 - return Erlang_UnicodeUtil["cp/1"](restList);
367 + return Erlang_Unicode_Util["cp/1"](restList);
359 368 }
360 369
361 370 // Calculate character length in UTF-16 code units (surrogate pairs are 2 units)
  @@ -404,7 +413,7 @@ const Erlang_UnicodeUtil = {
404 413 "_cpl_cont2/2": (list, restList) => {
405 414 if (Type.isList(list) && list.data.length > 0) {
406 415 // Inline optimized index-based logic to avoid O(n²) slicing behavior
407 - const isCP = Erlang_UnicodeUtil["_is_cp/1"];
416 + const isCP = Erlang_Unicode_Util["_is_cp/1"];
408 417 const result = [];
409 418 let idx = 0;
410 419
  @@ -431,7 +440,7 @@ const Erlang_UnicodeUtil = {
431 440 const firstElement = list.data[idx];
432 441
433 442 if (idx === list.data.length - 1) {
434 - const cont2Result = Erlang_UnicodeUtil["_cpl_1_cont2/1"](
443 + const cont2Result = Erlang_Unicode_Util["_cpl_1_cont2/1"](
435 444 Type.list([firstElement, ...restList.data]),
436 445 );
437 446
  @@ -453,7 +462,7 @@ const Erlang_UnicodeUtil = {
453 462 ? Type.list([Type.list(list.data.slice(idx + 1))])
454 463 : Type.list([Type.list(list.data.slice(idx + 1)), ...restList.data]);
455 464
456 - const cont2Result = Erlang_UnicodeUtil["_cpl_cont2/2"](
465 + const cont2Result = Erlang_Unicode_Util["_cpl_cont2/2"](
457 466 firstElement,
458 467 newRestList,
459 468 );
  @@ -480,7 +489,7 @@ const Erlang_UnicodeUtil = {
480 489 "_cpl_cont3/2": (list, restList) => {
481 490 if (Type.isList(list) && list.data.length > 0) {
482 491 // Inline optimized index-based logic to avoid O(n²) slicing behavior
483 - const isCP = Erlang_UnicodeUtil["_is_cp/1"];
492 + const isCP = Erlang_Unicode_Util["_is_cp/1"];
484 493 const result = [];
485 494 let idx = 0;
486 495
  @@ -507,7 +516,7 @@ const Erlang_UnicodeUtil = {
507 516 const firstElement = list.data[idx];
508 517
509 518 if (idx === list.data.length - 1) {
510 - const cont3Result = Erlang_UnicodeUtil["_cpl_1_cont3/1"](
519 + const cont3Result = Erlang_Unicode_Util["_cpl_1_cont3/1"](
511 520 Type.list([firstElement, ...restList.data]),
512 521 );
513 522
  @@ -529,7 +538,7 @@ const Erlang_UnicodeUtil = {
529 538 ? Type.list([Type.list(list.data.slice(idx + 1))])
530 539 : Type.list([Type.list(list.data.slice(idx + 1)), ...restList.data]);
531 540
532 - const cont3Result = Erlang_UnicodeUtil["_cpl_cont3/2"](
541 + const cont3Result = Erlang_Unicode_Util["_cpl_cont3/2"](
533 542 firstElement,
534 543 newRestList,
535 544 );
  @@ -581,7 +590,7 @@ const Erlang_UnicodeUtil = {
581 590
582 591 // Start cp/1
583 592 "cp/1": (string) => {
584 - const isCP = Erlang_UnicodeUtil["_is_cp/1"];
593 + const isCP = Erlang_Unicode_Util["_is_cp/1"];
585 594
586 595 // [C|_] when is_integer(C)
587 596 if (Type.isList(string) && string.data.length > 0 && isCP(string.data[0])) {
  @@ -590,13 +599,13 @@ const Erlang_UnicodeUtil = {
590 599
591 600 // [List]
592 601 if (Type.isList(string) && string.data.length === 1) {
593 - return Erlang_UnicodeUtil["cp/1"](string.data[0]);
602 + return Erlang_Unicode_Util["cp/1"](string.data[0]);
594 603 }
595 604
596 605 // [List|R] - proper list with multiple elements
597 606 if (Type.isList(string) && string.isProper && string.data.length > 1) {
598 607 const restList = Type.list(string.data.slice(1));
599 - return Erlang_UnicodeUtil["_cpl/2"](string.data[0], restList);
608 + return Erlang_Unicode_Util["_cpl/2"](string.data[0], restList);
600 609 }
601 610
602 611 // [List|Tail] - improper list (tail is not a list)
  @@ -606,17 +615,17 @@ const Erlang_UnicodeUtil = {
606 615
607 616 // If head is empty list, continue with tail
608 617 if (Type.isList(head) && head.data.length === 0) {
609 - return Erlang_UnicodeUtil["cp/1"](tail);
618 + return Erlang_Unicode_Util["cp/1"](tail);
610 619 }
611 620
612 621 // If head is empty binary, continue with tail
613 622 if (Type.isBinary(head) && Bitstring.isEmpty(head)) {
614 - return Erlang_UnicodeUtil["cp/1"](tail);
623 + return Erlang_Unicode_Util["cp/1"](tail);
615 624 }
616 625
617 626 // If tail is empty list, treat as proper list [head]
618 627 if (Type.isList(tail) && tail.data.length === 0) {
619 - return Erlang_UnicodeUtil["cp/1"](head);
628 + return Erlang_Unicode_Util["cp/1"](head);
620 629 }
621 630
622 631 // For other cases, process head element and combine result with tail
  @@ -629,7 +638,7 @@ const Erlang_UnicodeUtil = {
629 638 }
630 639
631 640 if (text.length === 0) {
632 - return Erlang_UnicodeUtil["cp/1"](tail);
641 + return Erlang_Unicode_Util["cp/1"](tail);
633 642 }
634 643
635 644 const codepoint = text.codePointAt(0);
  @@ -643,11 +652,11 @@ const Erlang_UnicodeUtil = {
643 652
644 653 // Case: head is a list - recursively process it, then append tail
645 654 if (Type.isList(head)) {
646 - const headResult = Erlang_UnicodeUtil["cp/1"](head);
655 + const headResult = Erlang_Unicode_Util["cp/1"](head);
647 656
648 657 // If head processing yielded empty list, continue with tail
649 658 if (Type.isList(headResult) && headResult.data.length === 0) {
650 - return Erlang_UnicodeUtil["cp/1"](tail);
659 + return Erlang_Unicode_Util["cp/1"](tail);
651 660 }
652 661
653 662 // If head processing yielded a list (proper or improper), append tail
  @@ -743,7 +752,7 @@ const Erlang_UnicodeUtil = {
743 752 };
744 753
745 754 const extractHead = (input) => {
746 - const cpResult = Erlang_UnicodeUtil["cp/1"](input);
755 + const cpResult = Erlang_Unicode_Util["cp/1"](input);
747 756
748 757 if (Type.isTuple(cpResult)) return {error: cpResult};
749 758
  @@ -922,10 +931,10 @@ const Erlang_UnicodeUtil = {
922 931 return collectCluster(arg, "", []);
923 932 }
924 933
925 - return Erlang_UnicodeUtil["cp/1"](arg);
934 + return Erlang_Unicode_Util["cp/1"](arg);
926 935 },
927 936 // End gc/1
928 937 // Deps: [:unicode_util.cp/1]
929 938 };
930 939
931 - export default Erlang_UnicodeUtil;
940 + export default Erlang_Unicode_Util;
  @@ -10,7 +10,7 @@ export default class HologramBoxedError extends Error {
10 10 this.struct = struct;
11 11
12 12 const boxedType = Interpreter.getErrorType(this);
13 - const boxedMessage = Interpreter.getErrorMessage(this);
13 + const boxedMessage = Interpreter.resolveErrorMessage(struct);
14 14
15 15 this.message = `(${boxedType}) ${boxedMessage}`;
16 16 }
  @@ -365,7 +365,7 @@ export default class Hologram {
365 365 } catch (error) {
366 366 if (error instanceof HologramBoxedError) {
367 367 error.name = Interpreter.getErrorType(error);
368 - error.message = Interpreter.getErrorMessage(error);
368 + error.message = Interpreter.resolveErrorMessage(error.struct);
369 369 }
370 370
371 371 throw error;
  @@ -652,7 +652,7 @@ export default class Hologram {
652 652 // Executed only once, on the initial page load.
653 653 // Deps: [:maps.get/2]
654 654 static async #init() {
655 - // TODO: consider when implementing boxed error handling
655 + // TODO: consider when porting Elixir error handling
656 656 // window.addEventListener("error", (event) => {
657 657 // if (event.error instanceof HologramBoxedError) {
658 658 // console.error(`${event.error.message}\n`, event.error);
  @@ -660,15 +660,14 @@ export default class Hologram {
660 660 // }
661 661 // });
662 662
663 + // TODO: consider when porting Elixir error handling
663 664 window.addEventListener("error", (event) => {
664 665 if (event.error instanceof HologramBoxedError) {
665 666 GlobalRegistry.set("lastBoxedError", {
666 667 module: Interpreter.inspect(
667 668 Erlang_Maps["get/2"](Type.atom("__struct__"), event.error.struct),
668 669 ),
669 - message: Bitstring.toText(
670 - Erlang_Maps["get/2"](Type.atom("message"), event.error.struct),
671 - ),
670 + message: Interpreter.resolveErrorMessage(event.error.struct),
672 671 });
673 672 }
674 673 });
Loading more files…