summaryrefslogtreecommitdiffstats
path: root/2022/captions/emacsconf-2022-asmblox--asmblox-a-game-based-on-webassembly-that-no-one-asked-for--zachary-romero--main.vtt
blob: ef640bf36842e78666686f07368e391cc98b406b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
WEBVTT captioned by sachac

00:00:00.000 --> 00:00:03.800
Hi, I'm Zach and today I'll be giving

00:00:03.800 --> 00:00:05.320
a presentation on asm-blox,

00:00:05.320 --> 00:00:08.960
a programming game inspired by WebAssembly.

00:00:08.960 --> 00:00:10.840
So programming games came into prominence

00:00:10.840 --> 00:00:13.160
about a decade ago and are loved for providing

00:00:13.160 --> 00:00:14.760
interesting programming challenges

00:00:14.760 --> 00:00:17.160
without all the messiness of real world programming.

00:00:17.160 --> 00:00:19.960
I wanted to make a programming game

00:00:19.960 --> 00:00:24.880
and I decided to base it off of TIS-100,

00:00:24.880 --> 00:00:28.240
having a pretty basic UI.

00:00:28.240 --> 00:00:30.680
It seemed pretty doable in Emacs.

00:00:30.680 --> 00:00:33.160
TIS 100 is a programming game

00:00:33.160 --> 00:00:35.760
where you write a fictional assembly language

00:00:35.760 --> 00:00:37.280
into a grid of cells which can each

00:00:37.280 --> 00:00:39.480
communicate with one another,

00:00:39.480 --> 00:00:41.200
you're tasked with solving

00:00:41.200 --> 00:00:44.960
fairly simple CS 101 like problems.

00:00:44.960 --> 00:00:48.440
To mix things up a bit I decided to base

00:00:48.440 --> 00:00:49.800
the language of asm-blox off of

00:00:49.800 --> 00:00:52.520
WebAssembly, which is stack based,

00:00:52.520 --> 00:00:55.360
as opposed to TIS-100 which is registered based.

00:00:55.360 --> 00:00:59.200
Here you can see the same program

00:00:59.200 --> 00:01:01.680
written in the game TIS-100,

00:01:01.680 --> 00:01:03.960
what it looks like in asm-blox,

00:01:03.960 --> 00:01:08.040
and the original WebAssembly that it's based off of.

00:01:08.040 --> 00:01:10.640
With that said, let's get into a demo.

00:01:10.640 --> 00:01:12.240
This is the game board.

00:01:12.240 --> 00:01:14.120
It's a 4 by 3 grid.

00:01:14.120 --> 00:01:16.840
Each cell has a stack of size 4.

00:01:16.840 --> 00:01:20.280
First off, I'll show some of the stack editing commands.

00:01:20.280 --> 00:01:23.760
We can add a value with the const function.

00:01:23.760 --> 00:01:27.480
Here we're adding two values to this stack

00:01:27.480 --> 00:01:33.400
to get added, and eventually the stack gets overflowed.

00:01:33.400 --> 00:01:37.360
We can fix that as follows with the clear command,

00:01:37.360 --> 00:01:40.720
so that clears the stack.

00:01:40.720 --> 00:01:43.200
We can duplicate values on the stack.

00:01:43.200 --> 00:01:45.600
This duplicates the item at the bottom of the stack.

00:01:45.600 --> 00:01:48.880
10 gets put on, 20 gets put on,

00:01:48.880 --> 00:01:50.200
then 10 will get duplicated

00:01:50.200 --> 00:01:52.680
and put on the top of the stack.

00:01:52.680 --> 00:01:55.920
We can increment. For example, this increments

00:01:55.920 --> 00:01:58.760
the second to bottom, the second to bottom

00:01:58.760 --> 00:01:59.920
from the stack.

00:01:59.920 --> 00:02:04.400
So 10, 20, increment that, clear.

00:02:04.400 --> 00:02:07.640
That's basic stack operations.

00:02:07.640 --> 00:02:11.000
Next up, we have numeric commands.

00:02:11.000 --> 00:02:12.560
For example, here, if we add "add",

00:02:12.560 --> 00:02:14.680
it pops two values off the stack,

00:02:14.680 --> 00:02:17.080
adds them, and pushes the result on.

00:02:17.080 --> 00:02:20.680
Another way we can write this is as follows.

00:02:20.680 --> 00:02:22.480
We can have the add here

00:02:22.480 --> 00:02:26.400
and then nest the two constants,

00:02:26.400 --> 00:02:28.520
and then this does the same thing.

00:02:28.520 --> 00:02:31.720
First, the inner constant operations run,

00:02:31.720 --> 00:02:35.520
and then the outer add operation runs.

00:02:35.520 --> 00:02:40.280
We can nest as deeply as we want.

00:02:40.280 --> 00:02:44.680
There's also subtraction, multiplication, and whatnot.

00:02:44.680 --> 00:02:46.480
Next up are Boolean operations.

00:02:46.480 --> 00:02:49.080
Zero counts as true.

00:02:49.080 --> 00:02:51.720
Anything else--sorry, zero counts as false.

00:02:51.720 --> 00:02:52.760
Anything else is true.

00:02:52.760 --> 00:03:01.840
For example, this would give us false and true,

00:03:01.840 --> 00:03:04.040
so that result should be false.

00:03:04.040 --> 00:03:06.120
Zero gets put on the stack,

00:03:06.120 --> 00:03:08.160
one gets put on, and then the "and" operation.

00:03:08.160 --> 00:03:12.840
So there's also or, not,

00:03:12.840 --> 00:03:17.760
and various numerical comparison operations

00:03:17.760 --> 00:03:21.400
like greater than and less than.

00:03:21.400 --> 00:03:22.880
Next up are the port operations.

00:03:22.880 --> 00:03:27.320
We can send values to other cells as follows.

00:03:27.320 --> 00:03:29.600
Here we create a value

00:03:29.600 --> 00:03:33.640
and then send it right.

00:03:33.640 --> 00:03:35.040
Let's run this.

00:03:35.040 --> 00:03:37.480
The 10 goes on the stack,

00:03:37.480 --> 00:03:38.480
and then it gets sent to the right.

00:03:38.480 --> 00:03:41.360
Here it's waiting for this cell to pick it up.

00:03:41.360 --> 00:03:44.360
It can pick it up just as follows.

00:03:44.360 --> 00:03:47.480
So left... and then why don't we have it

00:03:47.480 --> 00:03:49.520
drop that value after it gets it.

00:03:49.520 --> 00:03:53.920
So the 10 gets sent to the right.

00:03:53.920 --> 00:04:00.240
This one picks it up and drops it.

00:04:00.240 --> 00:04:03.200
Lastly, we have control flow,

00:04:03.200 --> 00:04:04.280
which is a bit tricky,

00:04:04.280 --> 00:04:06.880
but with this visual,

00:04:06.880 --> 00:04:08.440
it helps explain it.

00:04:08.440 --> 00:04:12.280
There are two block constructs, "block" and "loop",

00:04:12.280 --> 00:04:16.880
and there's two jumping constructs, "br" and "brif".

00:04:16.880 --> 00:04:23.120
So if "loop" is jumped to,

00:04:23.120 --> 00:04:25.360
the control flow goes to the beginning,

00:04:25.360 --> 00:04:26.520
the top of the loop.

00:04:26.520 --> 00:04:28.640
If a block is jumped to,

00:04:28.640 --> 00:04:31.520
it goes to the end of the block,

00:04:31.520 --> 00:04:33.640
and these various blocks

00:04:33.640 --> 00:04:36.520
are identified by their level of nestedness.

00:04:36.520 --> 00:04:40.640
From the point of view of this jump statement,

00:04:40.640 --> 00:04:45.160
this "br" statement, this is block level 0,

00:04:45.160 --> 00:04:46.440
this is 1, this is 2.

00:04:46.440 --> 00:04:49.560
So here, "br 1" would be referring to this loop.

00:04:49.560 --> 00:04:51.080
What this [br 1] would do is,

00:04:51.080 --> 00:04:54.000
it would jump to this loop right here.

00:04:54.000 --> 00:04:57.360
If we were to do this [br 2], what this would do is,

00:04:57.360 --> 00:05:02.680
this would jump past this block right here.

00:05:02.680 --> 00:05:09.880
So as another example, this right here,

00:05:09.880 --> 00:05:15.720
this is a loop that generates increasing numbers.

00:05:15.720 --> 00:05:22.640
Let's see. Next up, we have modules.

00:05:22.640 --> 00:05:26.280
This is an example of a stack module.

00:05:26.280 --> 00:05:28.760
In addition to stack, there's also heaps.

00:05:28.760 --> 00:05:34.560
What this does is it allows us to create

00:05:34.560 --> 00:05:38.080
an extra stack that we can push and pop items onto.

00:05:38.080 --> 00:05:41.240
This one can have as large size as we need.

00:05:41.240 --> 00:05:43.800
Here it has a size of 20.

00:05:43.800 --> 00:05:46.400
It's taking values from up

00:05:46.400 --> 00:05:51.080
and exposing those values on the left.

00:05:51.080 --> 00:05:57.080
This loop right here, it generates numbers,

00:05:57.080 --> 00:05:59.160
and it's putting them onto the stack.

00:05:59.160 --> 00:06:00.920
We can see here that those numbers

00:06:00.920 --> 00:06:03.200
are being exposed to this cell right here.

00:06:03.200 --> 00:06:07.040
It's just taking values, and eventually,

00:06:07.040 --> 00:06:11.200
it's going to overflow and cause an error.

00:06:11.200 --> 00:06:14.480
That finishes the basic commands.

00:06:14.480 --> 00:06:16.480
Why don't we try solving this puzzle.

00:06:16.480 --> 00:06:21.320
The puzzle description is right here.

00:06:21.320 --> 00:06:23.280
We want to read a value from I.

00:06:23.280 --> 00:06:28.480
Send 1 to G if I is greater than 0.

00:06:28.480 --> 00:06:30.800
Send 1 to E if it's equal to 0.

00:06:30.800 --> 00:06:32.440
Send 1 to L if it's less than 0.

00:06:32.440 --> 00:06:35.360
And then all the other ones, we send 0 to.

00:06:35.360 --> 00:06:40.920
First things first, let's send the value we get

00:06:40.920 --> 00:06:44.400
from the input down as follows.

00:06:44.400 --> 00:06:49.680
Let's send that value right.

00:06:49.680 --> 00:06:51.240
You get from up.

00:06:51.240 --> 00:06:54.320
Okay. So next, we're getting a value on the left.

00:06:54.320 --> 00:06:58.040
Now we want to compare if this number is greater than 0.

00:06:58.040 --> 00:06:59.800
If it's greater than 0, we send 1 to G.

00:06:59.800 --> 00:07:03.280
Let's perform the greater than operation

00:07:03.280 --> 00:07:08.080
on that item we just got, and we're comparing it to 0.

00:07:08.080 --> 00:07:11.680
Now that result, we're going to send down,

00:07:11.680 --> 00:07:13.880
and we're going to send this original value

00:07:13.880 --> 00:07:16.880
we got from here to the right.

00:07:16.880 --> 00:07:19.000
Here, we do a similar step.

00:07:19.000 --> 00:07:20.240
We get the value from the left,

00:07:20.240 --> 00:07:22.920
but this time, we have to do an equal operation.

00:07:22.920 --> 00:07:25.760
Is that number we got equal to 0?

00:07:25.760 --> 00:07:28.960
We send that result down,

00:07:28.960 --> 00:07:32.880
and then send this number to the right.

00:07:32.880 --> 00:07:38.040
Lastly, we get this number from the left.

00:07:38.040 --> 00:07:42.400
Here, we need to compare if it's less than 0.

00:07:42.400 --> 00:07:45.640
We send that result down,

00:07:45.640 --> 00:07:50.280
and now lastly, we drop that remaining value.

00:07:50.280 --> 00:07:53.080
Okay, let's--oh, and then lastly,

00:07:53.080 --> 00:07:56.040
we need to send down the value we get up.

00:07:56.040 --> 00:08:02.560
Send down, up, send down, up.

00:08:02.560 --> 00:08:04.760
Okay, so let's try running this.

00:08:04.760 --> 00:08:08.920
Let's see. We notice that

00:08:08.920 --> 00:08:10.360
the numbers are coming in from I.

00:08:10.360 --> 00:08:14.200
They're going through our various conditions

00:08:14.200 --> 00:08:18.160
and should be sending all the correct values.

00:08:18.160 --> 00:08:23.560
It looks like we're not getting any errors so far.

00:08:23.560 --> 00:08:26.680
Let's speed this up.

00:08:26.680 --> 00:08:33.040
That completes the puzzle.

00:08:33.040 --> 00:08:42.000
Now let's get into some of the implementation details.

00:08:42.000 --> 00:08:46.320
The first thing is the game loop.

00:08:46.320 --> 00:08:50.560
The game loop is... So this is actually extremely simple.

00:08:50.560 --> 00:08:52.320
All the state for the entire game

00:08:52.320 --> 00:08:54.400
is stored in just a few variables.

00:08:54.400 --> 00:08:56.480
There's one variable storing

00:08:56.480 --> 00:09:01.400
the text of each cell as a vector of strings.

00:09:01.400 --> 00:09:06.280
There's a single function

00:09:06.280 --> 00:09:09.080
that renders the entire game, the entire board.

00:09:09.080 --> 00:09:11.120
There's a single function that would render

00:09:11.120 --> 00:09:13.920
this entire screen based off of the state,

00:09:13.920 --> 00:09:19.240
and then the game waits for you to press a key.

00:09:19.240 --> 00:09:24.120
The key usually, depending on what action you perform,

00:09:24.120 --> 00:09:27.040
updates the state and causes a re-render.

00:09:27.040 --> 00:09:29.360
It's an extremely simple game loop,

00:09:29.360 --> 00:09:32.800
but it makes implementing it pretty easy.

00:09:32.800 --> 00:09:35.200
To demonstrate how this game loop works,

00:09:35.200 --> 00:09:38.400
I have a simple demo prepared.

00:09:38.400 --> 00:09:41.880
This is a game of tic-tac-toe.

00:09:41.880 --> 00:09:44.800
Let me show this real fast.

00:09:44.800 --> 00:09:49.200
It's an extremely simple implementation,

00:09:49.200 --> 00:09:51.465
but it follows the same principles

00:09:51.466 --> 00:09:53.600
that I used in asm-blox.

00:09:53.600 --> 00:09:57.680
First, we have the state defined in variables.

00:09:57.680 --> 00:09:59.560
Here we have two pieces of state.

00:09:59.560 --> 00:10:01.600
We have which player's turn it is

00:10:01.600 --> 00:10:03.120
and the state of the game board.

00:10:03.120 --> 00:10:06.640
The player turn can be nil if it's empty,

00:10:06.640 --> 00:10:08.760
the string "x" or the string "o".

00:10:08.760 --> 00:10:14.240
Then the game board is a list of nine board elements.

00:10:14.240 --> 00:10:16.960
So that's the state.

00:10:16.960 --> 00:10:18.120
Then we have a helper function.

00:10:18.120 --> 00:10:19.440
You can go into the details,

00:10:19.440 --> 00:10:21.000
but it just returns true

00:10:21.000 --> 00:10:25.600
if the board has a winning player.

00:10:25.600 --> 00:10:30.040
Part two is the rendering function.

00:10:30.040 --> 00:10:32.800
Only based off of the game state,

00:10:32.800 --> 00:10:36.720
we have a function that erases the buffer

00:10:36.720 --> 00:10:40.280
and draws this from scratch.

00:10:40.280 --> 00:10:45.320
That's this part right here.

00:10:45.320 --> 00:10:46.720
Lastly, we have the action.

00:10:46.720 --> 00:10:51.920
We have one action which is bound to RET,

00:10:51.920 --> 00:10:55.840
and it places a player token.

00:10:55.840 --> 00:10:59.920
Once it places a player token,

00:10:59.920 --> 00:11:03.120
it rerenders the board,

00:11:03.120 --> 00:11:06.880
and all the rerendering is handled by this function.

00:11:06.880 --> 00:11:12.480
Then we have just creating of the mode

00:11:12.480 --> 00:11:14.680
and initialization function.

00:11:14.680 --> 00:11:16.680
With these three steps

00:11:16.680 --> 00:11:20.640
it clearly separates out all of the state,

00:11:20.640 --> 00:11:22.960
the rendering, and the actions,

00:11:22.960 --> 00:11:25.880
and it makes implementing it very simple.

00:11:25.880 --> 00:11:29.640
One trick that's used here and that I use

00:11:29.640 --> 00:11:32.382
in my asm-blox game is that

00:11:32.383 --> 00:11:33.316
when I render the board,

00:11:33.317 --> 00:11:40.800
I propertize the text to contain extra information.

00:11:40.800 --> 00:11:45.080
For example, here, each cell has

00:11:45.080 --> 00:11:49.400
a tic-tac-toe index to indicate which number cell it is.

00:11:49.400 --> 00:11:53.640
This has index 0, 1, 2, all the way up to 8.

00:11:53.640 --> 00:11:58.640
That way, for placing, the only thing it has to do

00:11:58.640 --> 00:12:01.200
is just look at its position

00:12:01.200 --> 00:12:04.960
based off of the text property.

00:12:04.960 --> 00:12:07.800
It makes implementation extremely simple.

00:12:07.800 --> 00:12:14.360
Next up, we have the implementation of the code cells.

00:12:14.360 --> 00:12:16.960
If you notice, here it's kind of weird

00:12:16.960 --> 00:12:21.000
how it's like a buffer, but each cell kind of acts

00:12:21.000 --> 00:12:25.760
like its own buffer, and it has its own limits.

00:12:25.760 --> 00:12:27.600
All of the Emacs editing--

00:12:27.600 --> 00:12:30.760
well, some of the Emacs editing commands kind of work,

00:12:30.760 --> 00:12:35.360
like beginning-of-line, end-of-line, end-of-buffer.

00:12:35.360 --> 00:12:38.240
How is that done?

00:12:38.240 --> 00:12:41.760
Well, it's all just a trick, actually.

00:12:41.760 --> 00:12:47.280
Each cell has text properties of which line it's at

00:12:47.280 --> 00:12:48.800
and its cell coordinates.

00:12:48.800 --> 00:12:54.360
Whenever a key is pressed for editing, moving lines--

00:12:54.360 --> 00:12:58.360
there's even kind of more complicated things

00:12:58.360 --> 00:13:00.600
like switching cells around--

00:13:00.600 --> 00:13:03.360
so all of that,

00:13:03.360 --> 00:13:05.200
it knows which position it's in,

00:13:05.200 --> 00:13:08.080
it knows what cell it's in,

00:13:08.080 --> 00:13:12.880
and then it copies the text of the cell,

00:13:12.880 --> 00:13:16.320
because remember, the contents of the cell

00:13:16.320 --> 00:13:18.360
are stored in internal state.

00:13:18.360 --> 00:13:23.000
It copies that cell contents into a temporary buffer.

00:13:23.000 --> 00:13:27.960
It then moves the point to whichever line it was

00:13:27.960 --> 00:13:31.160
in the game board.

00:13:31.160 --> 00:13:33.000
It performs the action.

00:13:33.000 --> 00:13:36.200
It makes sure that the resulting text isn't

00:13:36.200 --> 00:13:40.160
longer than the cell width or the cell height.

00:13:40.160 --> 00:13:42.040
If everything checks out,

00:13:42.040 --> 00:13:45.120
it updates the state and calls a re-render.

00:13:45.120 --> 00:13:48.440
So there's nothing going on in here

00:13:48.440 --> 00:13:51.080
that's, like, actually inserting a letter A.

00:13:51.080 --> 00:14:00.920
It's all updating the state and causing a re-render.

00:14:00.920 --> 00:14:03.640
So this makes things like certain

00:14:03.640 --> 00:14:06.480
internal Emacs editing constructs

00:14:06.480 --> 00:14:09.120
pretty hard to use, like undoing.

00:14:09.120 --> 00:14:12.200
Normally the undoing construct

00:14:12.200 --> 00:14:15.120
works off the contents of the buffer.

00:14:15.120 --> 00:14:17.840
But if your buffer is actually just

00:14:17.840 --> 00:14:20.080
a reflection of the internal state,

00:14:20.080 --> 00:14:21.440
then how does undoing work?

00:14:21.440 --> 00:14:24.880
Well, it pretty much is kind of a hack.

00:14:24.880 --> 00:14:27.040
I mean, undoing is here,

00:14:27.040 --> 00:14:32.680
but it's pretty much redone

00:14:32.680 --> 00:14:37.560
in a not so configurable, not so modifiable way.

00:14:37.560 --> 00:14:40.080
Pretty much everything is like that,

00:14:40.080 --> 00:14:42.440
from these parentheses highlighting...

00:14:42.440 --> 00:14:46.320
Normally, parentheses highlighting

00:14:46.320 --> 00:14:47.243
would be kind of weird,

00:14:47.244 --> 00:14:49.840
with cross-line parentheses and everything.

00:14:49.840 --> 00:14:52.360
All of that had to be redone.

00:14:52.360 --> 00:14:58.160
Another point about how this is implemented

00:14:58.160 --> 00:15:02.360
is the assembly text to executable code.

00:15:02.360 --> 00:15:05.800
If you're familiar with WebAssembly

00:15:05.800 --> 00:15:10.720
you might have encountered a tool wat-wasm.

00:15:10.720 --> 00:15:16.440
It basically converts the WebAssembly text format

00:15:16.440 --> 00:15:18.280
to byte code.

00:15:18.280 --> 00:15:22.440
And what I do here... It goes through a similar process.

00:15:22.440 --> 00:15:28.000
Normally, when you're writing this text format,

00:15:28.000 --> 00:15:30.360
you can nest things as deeply as you want.

00:15:30.360 --> 00:15:33.800
Basically, what happens is it flattens out everything.

00:15:33.800 --> 00:15:35.920
It kind of knows the order

00:15:35.920 --> 00:15:38.160
that all these things are going to get executed,

00:15:38.160 --> 00:15:40.680
and then it puts it into one single line

00:15:40.680 --> 00:15:44.120
that it can just run through and execute.

00:15:44.120 --> 00:15:48.360
The same thing for the loops and blocks.

00:15:48.360 --> 00:15:52.240
It internally generates labels and jump statements.

00:15:52.240 --> 00:15:58.640
So that concludes this presentation.

00:15:58.640 --> 00:15:59.666
Thank you for listening,

00:15:59.667 --> 00:16:07.440
and I hope you enjoy the rest of the conference.