porffor 0.1.1 → 0.2.0-c6c8c81

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/index.html DELETED
@@ -1,1264 +0,0 @@
1
- <head>
2
- <title>porffor</title>
3
-
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width,initial-scale=1">
6
-
7
- <meta itemprop="name" content="porffor">
8
- <meta property="og:title" content="porffor">
9
- <meta itemprop="description" content="a basic experimental wip AOT optimizing JS -> Wasm compiler in JS">
10
- <meta property="og:description" content="a basic experimental wip AOT optimizing JS -> Wasm compiler in JS">
11
- <meta property="og:type" content="website">
12
-
13
- <style>
14
- @font-face {
15
- font-family: Whitney;
16
- font-style: normal;
17
- font-weight: 400;
18
- src: url(https://capybara.openasar.dev/whitney.woff2) format("woff2")
19
- }
20
-
21
- @font-face {
22
- font-family: Ginto;
23
- font-style: normal;
24
- font-weight: 500;
25
- src: url(https://capybara.openasar.dev/ginto.woff2) format("woff2")
26
- }
27
-
28
- :root {
29
- --font-normal: Whitney, "Helvetica Neue", Helvetica, Arial, sans-serif;
30
- --font-header: Ginto, "Helvetica Neue", Helvetica, Arial, sans-serif;
31
- --font-mono: Consolas, "Andale Mono WT", "Andale Mono", "Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Liberation Mono", "Nimbus Mono L", Monaco, "Courier New", Courier, monospace;
32
-
33
- --header-primary: #ffffff;
34
- --header-secondary: #b9bbbe;
35
-
36
- /* --text-normal: #dcddde;
37
- --text-muted: #a3a6aa; */
38
-
39
- --text-normal: #ffffff;
40
- --text-muted: #c1c1c2;
41
-
42
- --accent: #8545cf;
43
- --accent-light: #9c60e0;
44
- --accent-dark: #6b2faf;
45
-
46
- --background-primary: #101418;
47
- --background-secondary: #202428;
48
- --background-header: 0, 4, 8;
49
- }
50
-
51
- html, body {
52
- margin: 0;
53
- padding: 0;
54
- }
55
-
56
- body {
57
- background: var(--background-primary);
58
- }
59
-
60
- * {
61
- box-sizing: border-box;
62
- }
63
-
64
- h1 {
65
- font-weight: 500;
66
- font-family: var(--font-header);
67
- font-size: 32px;
68
-
69
- color: var(--header-primary);
70
-
71
- margin: 0;
72
- }
73
-
74
- h2 {
75
- font-weight: 500;
76
- font-family: var(--font-header);
77
- font-size: 28px;
78
-
79
- color: var(--header-primary);
80
-
81
- margin-top: 60px;
82
- margin-bottom: 8px;
83
- }
84
-
85
- header {
86
- width: 100%;
87
- height: fit-content;
88
-
89
- padding: 4px 24px;
90
-
91
- background: rgba(var(--background-header), 0.6);
92
- box-shadow: 0 8px 16px rgb(0 0 0 / 24%);
93
- backdrop-filter: blur(2px) saturate(0.5);
94
-
95
- display: flex;
96
- align-items: baseline;
97
-
98
- position: sticky;
99
- top: 0;
100
- z-index: 10;
101
- }
102
-
103
- header > h1 {
104
- color: var(--accent-light);
105
- }
106
-
107
- header code {
108
- font-family: var(--font-mono);
109
- font-size: 20px;
110
- color: var(--text-muted);
111
- }
112
-
113
- header > div {
114
- flex-grow: 1;
115
- margin-left: 4vw;
116
-
117
- display: flex;
118
- gap: 50px;
119
-
120
- /* justify-content: flex-end; */
121
- }
122
-
123
- header a {
124
- color: var(--text-normal);
125
- text-decoration: none;
126
-
127
- font-weight: 500;
128
- font-family: var(--font-header);
129
- font-size: 24px;
130
-
131
- transition: .5s color;
132
- }
133
-
134
- a:after {
135
- content: '';
136
- display: block;
137
- margin: auto;
138
- margin-top: 2px;
139
- height: 2px;
140
- width: 0px;
141
- background: transparent;
142
- transition: width .5s ease, background-color .5s ease;
143
- }
144
-
145
- header a:hover {
146
- color: var(--header-primary);
147
- }
148
-
149
- a:hover:after {
150
- width: 100%;
151
- background: var(--accent-light);
152
- }
153
-
154
- a:active:after {
155
- width: 100%;
156
- background: var(--accent);
157
- }
158
-
159
- article {
160
- padding: 6px 50px;
161
- width: 100%;
162
- max-width: 2000px;
163
- margin: auto;
164
- }
165
-
166
- .tagline {
167
- }
168
-
169
- p {
170
- font-size: 18px;
171
- font-family: var(--font-normal);
172
- color: var(--text-muted);
173
-
174
- margin-bottom: 20px;
175
- margin-top: 0px;
176
- }
177
-
178
- .cards {
179
- display: grid;
180
- grid-template-columns: repeat(3, 1fr);
181
- gap: 80px;
182
-
183
- margin-top: 12px;
184
- margin-bottom: 60px;
185
- }
186
-
187
- .columns {
188
- grid-template-columns: repeat(2, 1fr);
189
- }
190
-
191
- .cards > div {
192
- background: var(--background-secondary);
193
- box-shadow: 0 8px 16px rgb(0 0 0 / 24%);
194
- padding: 16px;
195
-
196
- display: flex;
197
-
198
- border-radius: 8px;
199
-
200
- flex-direction: column;
201
- }
202
-
203
- .cards > div svg {
204
- width: 32px;
205
- height: 32px;
206
- }
207
-
208
- .cards > div svg.stroke path {
209
- stroke: currentColor;
210
- fill: none;
211
- stroke-width: 6px;
212
- }
213
-
214
- .cards > div > h1 {
215
- font-family: var(--font-header);
216
- color: var(--header-primary);
217
-
218
- display: flex;
219
- gap: 10px;
220
-
221
- align-items: center;
222
- }
223
-
224
- .cards > div > p {
225
- font-family: var(--font-normal);
226
- color: var(--text-normal);
227
- font-size: 22px;
228
-
229
- margin-top: 12px;
230
- margin-bottom: 10px;
231
- }
232
-
233
- .cards > span {
234
- color: var(--text-muted);
235
- font-family: var(--font-header);
236
- font-size: 28px;
237
-
238
- display: flex;
239
- align-items: center;
240
- justify-content: center;
241
- }
242
-
243
- .stats {
244
- display: flex;
245
- flex-direction: column;
246
- align-self: center;
247
- }
248
-
249
- .stats > h2 {
250
- margin: 0;
251
- color: var(--text-normal);
252
- font-weight: 400;
253
-
254
- display: flex;
255
- align-items: center;
256
- }
257
-
258
- .stats > h2:not(:last-child) {
259
- margin-bottom: 40px;
260
- }
261
-
262
- .stats span {
263
- font-weight: 600;
264
- color: var(--accent-light);
265
- }
266
-
267
- .stats svg {
268
- width: 32px;
269
- height: 32px;
270
- margin-right: 12px;
271
- }
272
-
273
- header .stats svg {
274
- width: 24px;
275
- height: 24px;
276
- margin-right: 8px;
277
- }
278
-
279
- .stats [id^="stat_"] {
280
- margin: 0 8px;
281
- }
282
-
283
- /* .stats::before {
284
- content: '';
285
- width: 80%;
286
- height: 2px;
287
- background: var(--background-secondary);
288
- margin: auto;
289
-
290
- position: relative;
291
- top: -4vw;
292
- }
293
-
294
- article > :nth-last-child(2) {
295
- margin-bottom: 4vw;
296
- } */
297
-
298
- a {
299
- color: var(--accent-light);
300
- text-decoration: none;
301
- font-weight: 600;
302
-
303
- display: inline-block;
304
- }
305
-
306
- ::-webkit-scrollbar {
307
- width: 12px;
308
- }
309
-
310
- ::-webkit-scrollbar-corner {
311
- background-color: transparent;
312
- }
313
-
314
- ::-webkit-scrollbar-thumb {
315
- background-color: #303438;
316
- }
317
-
318
- ::-webkit-scrollbar-track {
319
- background-color: #000408;
320
- }
321
-
322
- ::-webkit-scrollbar-thumb, ::-webkit-scrollbar-track {
323
- border: 4px solid transparent;
324
- background-clip: padding-box;
325
- border-radius: 12px;
326
- }
327
-
328
- table {
329
- background: #202428;
330
- color: var(--header-primary);
331
- font-family: var(--font-header);
332
-
333
- border-collapse: collapse;
334
- table-layout: fixed;
335
- }
336
-
337
- .compat tr:first-child {
338
- background: #101418;
339
- font-size: 20px;
340
- }
341
-
342
- .compat tr:first-child > td:nth-child(2), .compat tr:first-child > td:nth-child(3) {
343
- width: 160px;
344
- }
345
-
346
- .compat tr {
347
- border: 2px solid var(--header-secondary);
348
- font-size: 18px;
349
- }
350
-
351
- .compat td {
352
- padding: 4px;
353
- border: 2px solid black;
354
- }
355
-
356
- .compat td:not(:first-child) {
357
- text-align: center;
358
- }
359
-
360
- td.most {
361
- background: #97ca00;
362
- }
363
-
364
- td.some {
365
- background: #dfb317;
366
- }
367
-
368
- td.initial {
369
- background: #fe7d37;
370
- }
371
-
372
- td.unsupported {
373
- background: #e05d44;
374
- }
375
-
376
- .index {
377
- margin-bottom: 20px;
378
- }
379
-
380
- .index td {
381
- padding: 4px;
382
- }
383
-
384
- .index td:first-child {
385
- border-left: 3px solid transparent;
386
- padding-left: 10px;
387
- }
388
-
389
- .index td:nth-child(2) {
390
- width: 70%;
391
- color: var(--text-normal);
392
- }
393
-
394
- .sandbox-table {
395
- margin-top: 12px;
396
- margin-bottom: 12px;
397
- }
398
-
399
- .sandbox-table td {
400
- padding: 6px;
401
- }
402
-
403
- .sandbox-table td:last-child {
404
- text-align: center;
405
- }
406
-
407
- .detailed.cards {
408
- gap: 60px;
409
- }
410
-
411
- .detailed.cards p {
412
- font-size: 20px;
413
- margin-bottom: 20px;
414
- }
415
-
416
- .detailed.cards h2 {
417
- font-size: 24px;
418
- color: var(--text-normal);
419
- margin-top: 10px;
420
- margin-bottom: -4px;
421
- }
422
-
423
- .detailed.cards p + p {
424
- margin-top: 0;
425
- }
426
-
427
- ul, ol {
428
- margin-top: 0px;
429
- margin-bottom: 16px;
430
-
431
- color: var(--text-muted);
432
- font-family: var(--font-normal);
433
- font-size: 20px;
434
- }
435
-
436
- code {
437
- font-family: var(--font-mono);
438
- font-size: 80%;
439
- color: var(--text-muted);
440
- }
441
-
442
- .usage-header {
443
- display: flex;
444
- align-items: center;
445
- justify-content: space-between;
446
- }
447
-
448
- .usage-header code {
449
- font-size: 16px;
450
- }
451
-
452
- .check {
453
- border-radius: 50%;
454
- background: var(--accent);
455
- width: 20px;
456
- height: 20px;
457
- }
458
-
459
- .check.no {
460
- background: none;
461
- }
462
-
463
- .tagline {
464
- font-size: 32px;
465
- }
466
-
467
- .subtag {
468
- color: #dcddde;
469
- font-size: 18px;
470
- margin: 0;
471
- margin-top: 4px;
472
- margin-bottom: 26px;
473
- }
474
-
475
- #split {
476
- border-top: 1px solid #606468;
477
- display: grid;
478
- grid-template-columns: 60% 1fr;
479
-
480
- width: 100%;
481
- height: 70vh;
482
- }
483
-
484
- #split > :last-child {
485
- background: #0c0c0c;
486
- color: #d0d0d0;
487
-
488
- padding: 6px;
489
-
490
- font-family: var(--font-mono);
491
- font-size: 14px;
492
- border-left: 1px solid #606468;
493
-
494
- white-space: pre;
495
-
496
- height: 100%;
497
- overflow-x: hidden;
498
- overflow-y: auto;
499
- }
500
-
501
- #output, #status {
502
- border-top: 1px solid #606468;
503
- color: var(--text-muted);
504
- background: var(--background-secondary);
505
- font-family: var(--font-mono);
506
-
507
- width: 100%;
508
- height: 8vh;
509
- font-size: 14px;
510
- padding: 6px;
511
-
512
- white-space: pre;
513
-
514
- overflow-x: hidden;
515
- overflow-y: auto;
516
- }
517
-
518
- #status {
519
- padding: 4px;
520
- font-size: 14px;
521
- height: 26px;
522
- }
523
-
524
- .ansi-31 {
525
- color: rgb(197, 15, 31);
526
- }
527
- .ansi-34 {
528
- color: rgb(0, 55, 218);
529
- }
530
- .ansi-36 {
531
- color: rgb(58, 150, 221);
532
- }
533
- .ansi-35 {
534
- color: rgb(136, 23, 152);
535
- }
536
- .ansi-95 {
537
- color: rgb(180, 0, 158);
538
- }
539
- .ansi-33 {
540
- color: rgb(193, 156, 0);
541
- }
542
- .ansi-90 {
543
- color: rgb(118, 118, 118);
544
- }
545
-
546
- #wasm-size {
547
- position: absolute;
548
- right: 6px;
549
- top: 6px;
550
- pointer-events: none;
551
- }
552
-
553
- #split > * {
554
- position: relative;
555
- }
556
-
557
- #js-size {
558
- position: absolute;
559
- right: 24px;
560
- top: 6px;
561
- pointer-events: none;
562
-
563
- z-index: 9;
564
-
565
- font-family: var(--font-mono);
566
- font-size: 14px;
567
- color: #d0d0d0;
568
-
569
- display: none;
570
- }
571
-
572
- #args {
573
- background: var(--background-secondary);
574
- font-family: var(--font-mono);
575
-
576
- width: calc(100% - 180px - 240px);
577
- margin: 0;
578
-
579
- color: var(--text-normal);
580
- border: 0;
581
- padding: 6px;
582
- float: right;
583
- font-size: 14px;
584
- }
585
-
586
- #examples_dropdown {
587
- width: 180px;
588
- padding: 4px;
589
- height: 29px;
590
- display: inline-block;
591
-
592
- color: var(--text-normal);
593
- font-family: var(--font-normal);
594
- font-size: 16px;
595
- background: var(--background-secondary);
596
- border: none;
597
-
598
- margin-right: 20px;
599
- }
600
-
601
- article {
602
- color: var(--text-muted);
603
- font-family: var(--font-normal);
604
- }
605
-
606
- #valtype_dropdown, #opt_dropdown {
607
- width: fit-content;
608
- padding: 4px;
609
- height: 29px;
610
- display: inline-block;
611
-
612
- color: var(--text-normal);
613
- font-family: var(--font-normal);
614
- font-size: 14px;
615
- background: var(--background-secondary);
616
- border: none;
617
-
618
- margin-left: 4px;
619
- margin-right: 12px;
620
- }
621
-
622
- #test262 {
623
- display: grid;
624
- grid-template-columns: 400px 1fr;
625
- gap: 24px;
626
- margin: 48px 0;
627
-
628
- width: 100%;
629
- /* height: 80vh; */
630
- height: 600px;
631
- }
632
-
633
- #commit_log {
634
- display: grid;
635
- grid-template-columns: 1fr;
636
- gap: 24px;
637
-
638
- overflow-x: auto;
639
- }
640
-
641
- #commit_log > div {
642
- display: flex;
643
- flex-direction: column;
644
-
645
- background: var(--background-secondary);
646
- padding: 8px;
647
- border-radius: 8px;
648
- }
649
-
650
- #commit_log > div > :first-child {
651
- font-size: 18px;
652
- font-weight: 500;
653
- color: var(--text-normal);
654
- }
655
-
656
- #commit_log > div > :last-child {
657
- font-size: 18px;
658
- font-weight: 500;
659
-
660
- color: #57F287;
661
-
662
- margin-top: 6px;
663
- }
664
-
665
- #commit_log > div > :last-child > span {
666
- color: var(--text-muted);
667
- font-size: 16px;
668
- margin-left: 6px;
669
- }
670
-
671
- #commit_log > div > :last-child > div {
672
- font-size: 16px;
673
- font-weight: 400;
674
- color: var(--text-muted);
675
-
676
- display: inline;
677
- float: right;
678
- }
679
-
680
- header img {
681
- vertical-align: middle;
682
- border-radius: 4px;
683
- margin-right: 8px;
684
- }
685
-
686
- #graph {
687
- /* background: var(--background-secondary);
688
-
689
- border-radius: 8px;
690
- padding: 8px; */
691
- }
692
-
693
- #graph > div {
694
- display: inline-flex;
695
- flex-direction: column;
696
- height: 100%;
697
- vertical-align: top;
698
- }
699
-
700
- #graph > div > :first-child {
701
- height: calc(100% - 20px);
702
-
703
- display: flex;
704
- flex-direction: column;
705
- }
706
-
707
- #graph > div > :last-child {
708
- height: 20px;
709
- font-size: 12px;
710
- font-family: var(--font-header);
711
- padding: 2px;
712
-
713
- border-top: 1px solid #606468;
714
- background: #000408;
715
- }
716
-
717
- .graph-0 {
718
- background: #13a10e;
719
- }
720
- .graph-1 {
721
- background: #c19c00;
722
- }
723
- .graph-2 {
724
- background: #e74856;
725
- }
726
- .graph-3 {
727
- background: #792027;
728
- }
729
- .graph-4 {
730
- background: #c50f1f;
731
- }
732
- .graph-5 {
733
- background: #cccccc;
734
- }
735
- .graph-6 {
736
- background: #dd5719;
737
- }
738
-
739
- #benches {
740
- width: 100%;
741
-
742
- display: grid;
743
- grid-template-columns: 1fr 1fr;
744
- gap: 24px 64px;
745
-
746
- margin-bottom: 64px;
747
- }
748
-
749
- #benches h2 {
750
- font-size: 22px;
751
- margin-top: 0;
752
- margin-bottom: 12px;
753
- }
754
-
755
- #benches code {
756
- font-size: 1em;
757
- }
758
-
759
- #benches > div > div {
760
- display: flex;
761
- margin-bottom: 6px;
762
- }
763
-
764
- #benches > div > div > :first-child {
765
- font-size: 18px;
766
- color: var(--text-normal);
767
- flex-basis: 140px;
768
- flex-shrink: 0;
769
- }
770
-
771
- #benches > div > div > :last-child {
772
- padding: 0 4px;
773
- background: var(--background-secondary);
774
-
775
- color: var(--text-muted);
776
- font-size: 16px;
777
-
778
- height: 22px;
779
- line-height: 22px;
780
-
781
- border-radius: 6px;
782
- }
783
-
784
- #benches .porffor {
785
- background: var(--accent-light) !important;
786
- color: var(--text-normal) !important;
787
- }
788
- </style>
789
- </head>
790
-
791
- <body>
792
- <header>
793
- <h1><img width="32" src="logo.png">porffor</h1>
794
-
795
- <div>
796
- <a href="https://github.com/CanadaHonk/porffor">GitHub</a>
797
- </div>
798
- </header>
799
-
800
- <article>
801
- <h1 class="tagline">a basic experimental wip AOT optimizing JS -> Wasm compiler in JS</h1>
802
- <!-- <h2 class="subtag">about as insane as it sounds</h2> -->
803
-
804
- <p>porffor is a very unique js engine, due a very different approach. it is seriously limited, but what it can do, it does pretty well. made from scratch except parser. began ~3 weeks ago.</p>
805
- <!-- <ul>
806
- <li>100% aot compiled</li>
807
- <li>everything is a number</li>
808
- <li>no constant runtime/preluded code</li>
809
- </ul> -->
810
-
811
- <select id="examples_dropdown"></select>
812
- valtype <select id="valtype_dropdown"></select>
813
- opt <select id="opt_dropdown"></select>
814
- <input type="text" placeholder="extra compiler args" id="args">
815
- <div id="split"></div>
816
- <div id="output"></div>
817
- <div id="status"></div>
818
-
819
- <div id="test262">
820
- <div id="commit_log"></div>
821
- <div id="graph"></div>
822
- </div>
823
-
824
- <div id="benches">
825
- <div id="bench_0">
826
- <h2>sum 1 million random numbers</h2>
827
- </div>
828
-
829
- <div id="bench_1">
830
- <h2>count prime numbers 1-10000</h2>
831
- </div>
832
-
833
- <div id="bench_2">
834
- <h2>factorial of 100</h2>
835
- </div>
836
- </div>
837
- </article>
838
-
839
- <script> (async () => {
840
- if (window.crossOriginIsolated === false) {
841
- console.log('not cross-origin isolated, registering service worker for later');
842
- const worker = await navigator.serviceWorker.register('./sw.js');
843
- }
844
-
845
- const loadScript = async x => {
846
- const el = document.createElement('script');
847
- el.src = x;
848
- document.head.append(el);
849
-
850
- await new Promise(res => el.onload = res);
851
- };
852
-
853
- if (!window.monaco) {
854
- await loadScript('https://cdn.openasar.dev/monaco-editor/min/vs/loader.js');
855
- // await new Promise(res => setTimeout(res, 500));
856
-
857
- require.config({ paths: { vs: 'https://cdn.openasar.dev/monaco-editor/min/vs' } });
858
- await new Promise(res => require(['vs/editor/editor.main'], res));
859
- }
860
-
861
- const monacoContainer = document.createElement('div');
862
- // monacoContainer.style.width = '100%';
863
- // monacoContainer.style.height = '75vh';
864
- split.appendChild(monacoContainer);
865
-
866
- const jsSize = document.createElement('div');
867
- jsSize.id = 'js-size';
868
- monacoContainer.append(jsSize);
869
-
870
- const wasmView = document.createElement('div');
871
- split.appendChild(wasmView);
872
-
873
- const status = document.getElementById('status');
874
-
875
- const examples = {
876
- 'Prime Numbers': `function isPrime(number) {
877
- if (number < 2) return false;
878
-
879
- for (let i = 2; i < number; i++) {
880
- if (number % i == 0) return false;
881
- }
882
-
883
- return true;
884
- }
885
-
886
- let counter = 0;
887
- while (counter <= 10000) {
888
- if (isPrime(counter)) console.log(counter);
889
- counter++;
890
- }`,
891
- 'Fibonacci': `let a = 0, b = 1;
892
- console.log(a); console.log(b);
893
-
894
- for (let i = 2; i <= 45; i++) {
895
- let t = b + a;
896
- a = b;
897
- b = t;
898
-
899
- console.log(t);
900
- }`,
901
- 'Factorial': `const factorial = n => n === 0 ? 1 : (n * factorial(n - 1));
902
- console.log(factorial(10));`,
903
- 'Sum of Digits': `let n = 654, sum = 0;
904
- while (n > 0) {
905
- sum += n % 10;
906
- n /= 10;
907
- }
908
-
909
- console.log(sum);`,
910
- 'Exception': `throw new Error('Hello, world!')`,
911
- 'Array Reading': `let arr = [ 2, 4, 8, 16 ];
912
- for (let i = 0; i < arr.length; i++) console.log(arr[i]);`,
913
- 'Array Prototype': `let arr = [ 1, 2, 3 ];
914
- arr.push(4); // 4
915
- arr.shift(); // 1
916
- arr.pop(); // 4
917
-
918
- arr.at(0); // 2
919
- arr.at(-1); // 3`,
920
- 'Math Proposals': `console.log(Math.signbit(1)) // false
921
- console.log(Math.signbit(-1)) // true
922
- console.log(Math.radians(180)) // 3.141592...
923
- console.log(Math.RAD_PER_DEG) // 0.017453...
924
- console.log(Math.clamp(12, 0, 10)) // 10
925
- console.log(Math.scale(4, 0, 10, 0, 1)) // 0.4`,
926
- };
927
- const defaultExample = 'Prime Numbers';
928
- let code = examples[defaultExample];
929
-
930
- const addOptions = (container, options, def) => {
931
- for (const x of options) {
932
- const el = document.createElement('option');
933
- el.textContent = x;
934
- el.selected = x === def;
935
-
936
- container.appendChild(el);
937
- }
938
- };
939
-
940
- addOptions(examples_dropdown, Object.keys(examples), defaultExample);
941
-
942
- addOptions(valtype_dropdown, [ 'i32', 'i64', 'f64' ], 'f64');
943
- addOptions(opt_dropdown, [ 0, 1, 2, 3 ], 1);
944
-
945
- examples_dropdown.oninput = () => {
946
- code = examples[examples_dropdown.value];
947
- editor.setValue(code);
948
- comp();
949
- };
950
-
951
- valtype_dropdown.oninput = opt_dropdown.oninput = () => comp();
952
-
953
- window.editor = monaco.editor.create(monacoContainer, {
954
- value: code,
955
- codeLens: false,
956
- language: 'javascript',
957
- theme: 'vs-dark',
958
- minimap: {
959
- enabled: false
960
- }
961
- });
962
-
963
- const debounce = (handler, timeout) => {
964
- let timer;
965
- return (...args) => {
966
- clearTimeout(timer);
967
- timer = setTimeout(() => handler(...args), timeout);
968
- };
969
- };
970
-
971
- const compile = (await import('../compiler/wrap.js')).default;
972
-
973
- const comp = async () => {
974
- globalThis.process = {
975
- argv: ['', '', ...args.value.split(' '), `-valtype=${valtype_dropdown.value}`, `-O${opt_dropdown.value}`]
976
- };
977
-
978
- jsSize.textContent = `${new Blob([code]).size} bytes`;
979
-
980
- let cache = '';
981
- const print = str => {
982
- cache += str;
983
-
984
- if (str === '\n') {
985
- // output.textContent += cache;
986
- // cache = '';
987
- }
988
- };
989
-
990
- output.textContent = '';
991
- wasmView.innerHTML = '';
992
- status.textContent = 'compiling...';
993
-
994
- let wasm, exports, times, decomps;
995
- try {
996
- 0, { wasm, exports, times, decomps } = await compile(code, [ 'module', 'decomp' ], {}, print);
997
- } catch (e) {
998
- console.error(e);
999
- status.textContent = `${e.constructor.name}: ${e.message}`;
1000
- return;
1001
- }
1002
-
1003
- wasmView.innerHTML = `<div id="wasm-size">${wasm.byteLength} bytes</div>` + decomps.join('\n').replaceAll('\x1B[0m', '</span>').replace(/\x1B\[([0-9]{2})m/g, (_, esc) => `<span class="ansi-${esc}">`);
1004
- status.textContent = `compiled in ${times[0].toFixed(2)}ms`;
1005
-
1006
- await new Promise(res => setTimeout(res, 10));
1007
-
1008
- const t2 = performance.now();
1009
- try {
1010
- exports.main();
1011
- } catch (e) {
1012
- console.error(e);
1013
- status.textContent = `${e.constructor.name}: ${e.message}`;
1014
- return;
1015
- }
1016
-
1017
- print('\n');
1018
-
1019
- const execTime = performance.now() - t2;
1020
- status.textContent += `. executed in ${execTime.toFixed(2)}ms`;
1021
-
1022
- const t3 = performance.now();
1023
- try {
1024
- eval(code);
1025
- } catch {}
1026
-
1027
- const evalTime = performance.now() - t3;
1028
- status.textContent += `. eval took ${evalTime.toFixed(2)}ms (${(evalTime / execTime).toFixed(1)}x)`;
1029
-
1030
- output.textContent = cache;
1031
- };
1032
-
1033
- const compDebounce = debounce(comp, 500);
1034
-
1035
- editor.getModel().onDidChangeContent(e => {
1036
- code = editor.getValue();
1037
- compDebounce();
1038
- });
1039
-
1040
- args.oninput = () => compDebounce();
1041
-
1042
- comp();
1043
-
1044
- const niceDate = x => {
1045
- let hours = x.getHours();
1046
- let ind = 'am';
1047
- if (hours >= 12) {
1048
- hours = hours % 12;
1049
- if (hours === 0) hours = 12;
1050
- ind = 'pm';
1051
- }
1052
-
1053
- return `${x.toLocaleString('default', { month: 'long' })} ${x.getDate()}, ${x.getFullYear()}`;
1054
- // return `${hours}:${x.getMinutes().toString().padStart(2, '0')} ${ind} · ${x.toLocaleString('default', { month: 'long' })} ${x.getDate()}, ${x.getFullYear()}`;
1055
- };
1056
-
1057
- const getCommits = async pages => {
1058
- let out = [];
1059
- for (let i = 1; i <= pages; i++) {
1060
- out.push(...(await (await fetch('https://api.github.com/repos/canadahonk/porffor/commits?per_page=100&page=' + i)).json()));
1061
- }
1062
-
1063
- return out;
1064
- };
1065
- let commits = await getCommits(3);
1066
-
1067
- const getCommitPercent = x => parseFloat(x.commit.message.trim().split('\n').pop().match(/([0-9]+(\.[0-9]+)?)%/)?.[1]);
1068
- const getCommitDetails = x => x.commit.message.trim().split('\n').pop().split(' | ').slice(1).map(x => x.split(' ')[1]);
1069
-
1070
- const graphData = {};
1071
- for (let i = 0; i < commits.length; i++) {
1072
- const x = commits[i];
1073
- const msg = x.commit.message.trim().split('\n');
1074
- const el = document.createElement('div');
1075
-
1076
- const textEl = document.createElement('div');
1077
- textEl.textContent = msg[0].slice(0, 42) + (msg[0].length > 42 ? '...' : '');
1078
-
1079
- const when = new Date(x.commit.committer.date);
1080
- const whenEl = document.createElement('div');
1081
- whenEl.textContent = niceDate(when);
1082
-
1083
- const percent = getCommitPercent(x);
1084
- if (isNaN(percent)) continue;
1085
-
1086
- let prevPercent = NaN;
1087
- for (let j = i + 1; j < commits.length; j++) {
1088
- prevPercent = getCommitPercent(commits[j]);
1089
- if (!isNaN(prevPercent)) break;
1090
- }
1091
-
1092
- let change = 0;
1093
- if (!isNaN(prevPercent)) change = percent - prevPercent;
1094
- if (change === 0) continue;
1095
-
1096
- const percentEl = document.createElement('div');
1097
- percentEl.innerHTML = `${percent.toFixed(2)}%${change !== 0 ? `<span>(${change > 0 ? '+' : ''}${change.toFixed(2)})</span>` : ''}`;
1098
-
1099
- // textEl.append(percentEl);
1100
- percentEl.append(whenEl);
1101
-
1102
- el.append(textEl, percentEl);
1103
- commit_log.append(el);
1104
-
1105
- let details = getCommitDetails(x);
1106
- if (!details || details.length === 0) continue;
1107
-
1108
- // add 0 timeouts if not included
1109
- if (details.length === 7) details = [ ...details.slice(0, 6), 0, details[6] ];
1110
-
1111
- const key = `${when.getDate().toString().padStart(2, '0')}/${(when.getMonth() + 1).toString().padStart(2, '0')}`;
1112
- if (graphData[key]) continue;
1113
- graphData[key] = details;
1114
- }
1115
-
1116
- let last = [];
1117
- for (let i = 8; i <= (new Date()).getDate(); i++) {
1118
- const key = `${i.toString().padStart(2, '0')}/07`;
1119
- if (!graphData[key]) graphData[key] = last;
1120
- else last = graphData[key];
1121
- }
1122
-
1123
- for (const x of Object.keys(graphData).sort((a, b) => parseInt(a.slice(0, 2)) - parseInt(b.slice(0, 2)))) {
1124
- const details = graphData[x];
1125
- const [ total, passes, fails, runtimeErrors, wasmErrors, compileErrors, timeouts, todos ] = details;
1126
-
1127
- const containerEl = document.createElement('div');
1128
- const barEl = document.createElement('div');
1129
-
1130
- let i = 0;
1131
- for (const y of details.slice(1)) {
1132
- const el = document.createElement('div');
1133
- el.style.height = `${(y / total) * 100}%`;
1134
- el.className = `graph-${i}`;
1135
-
1136
- el.title = (['Pass', 'Fail', 'Runtime error', 'Wasm error', 'Compile error', 'Timeout', 'Todo'])[i] + `: ${y} (${((y / total) * 100).toFixed(2)}%)`;
1137
-
1138
- barEl.appendChild(el);
1139
-
1140
- i++;
1141
- }
1142
-
1143
- const keyEl = document.createElement('div');
1144
- keyEl.textContent = x;
1145
-
1146
- containerEl.append(barEl, keyEl);
1147
-
1148
- graph.appendChild(containerEl);
1149
- }
1150
-
1151
- const benches = async () => {
1152
- const SAMPLES = 10;
1153
- const results = {};
1154
-
1155
- const avg = arr => arr.reduce((acc, x) => acc + x, 0) / arr.length;
1156
-
1157
- const bench = (which, what, run) => {
1158
- let times = [];
1159
-
1160
- for (let i = 0; i < SAMPLES; i++) {
1161
- const t = performance.now();
1162
- run();
1163
- times.push(performance.now() - t);
1164
- }
1165
-
1166
- if (!results[which]) results[which] = {};
1167
- results[which][what] = avg(times);
1168
- };
1169
-
1170
- function randoms(max) {
1171
- let sum = 0;
1172
- for (let i = 0; i < max; i++) {
1173
- sum += Math.random();
1174
- }
1175
-
1176
- return sum;
1177
- }
1178
-
1179
- function countPrimes(max) {
1180
- function isPrime(number) {
1181
- if (number < 2) return false;
1182
-
1183
- for (let i = 2; i < number; i++) {
1184
- if (number % i == 0) return false;
1185
- }
1186
-
1187
- return true;
1188
- }
1189
-
1190
- let counter = 0, primes = 0;
1191
- while (counter <= max) {
1192
- if (isPrime(counter)) primes++;
1193
- counter++;
1194
- }
1195
-
1196
- return primes;
1197
- }
1198
-
1199
- function factorial(n) {
1200
- if (n === 0) return 1;
1201
-
1202
- return n * factorial(n - 1);
1203
- }
1204
-
1205
- const maxes = [ 1000000, 10000, 100 ];
1206
- const funcs = [ randoms, countPrimes, factorial ];
1207
-
1208
- for (let i = 0; i < funcs.length; i++) {
1209
- const func = funcs[i];
1210
- const max = maxes[i];
1211
-
1212
- bench(i, 'your browser', () => {
1213
- func(max);
1214
- });
1215
-
1216
- globalThis.process = { argv: [] };
1217
- const compiled = (await compile('export ' + func.toString())).exports[func.name];
1218
-
1219
- bench(i, 'porffor', () => {
1220
- compiled(max);
1221
- });
1222
-
1223
- /* try {
1224
- process.argv.push('-valtype=i32');
1225
- if (['factorial'].includes(func.name)) throw 'overflow';
1226
- const compiledI32 = (await compile('export ' + func.toString())).exports[func.name];
1227
-
1228
- bench(i, 'porffor (i32)', () => {
1229
- compiledI32(max);
1230
- });
1231
- } catch {
1232
- // ignore as some things are unsupported in i32 mode
1233
- } finally {
1234
- process.argv.pop();
1235
- } */
1236
- }
1237
-
1238
- for (let i = 0; i < funcs.length; i++) {
1239
- const maxTime = Math.max(...Object.values(results[i])) * 1.1;
1240
-
1241
- const parentEl = document.getElementById(`bench_${i}`);
1242
-
1243
- const keys = Object.keys(results[i]).sort((a, b) => results[i][a] - results[i][b]);
1244
- for (const x of keys) {
1245
- const result = results[i][x];
1246
- const el = document.createElement('div');
1247
-
1248
- const labelEl = document.createElement('div');
1249
- labelEl.textContent = x;
1250
-
1251
- const barEl = document.createElement('div');
1252
- barEl.textContent = result.toFixed(2) + 'ms';
1253
- barEl.style.width = `calc((100% - 140px) * ${(result / maxTime)})`;
1254
- barEl.className = x;
1255
-
1256
- el.append(labelEl, barEl);
1257
- parentEl.append(el);
1258
- }
1259
- }
1260
- };
1261
-
1262
- setTimeout(benches, 3000);
1263
- })();</script>
1264
- </body>