2105 lines
88 KiB
Plaintext
2105 lines
88 KiB
Plaintext
0:00
|
|
thought I was um I was talking. Sorry. It turns out I I was muted. So, hello. Is is is is the
|
|
0:08
|
|
screen readable? If you could make it a little larger,
|
|
0:14
|
|
that might be helpful. But yes, we can see it. We can read it. Uh making it a
|
|
0:19
|
|
little larger might be a bit difficult now because I had to font. Okay. No
|
|
0:25
|
|
worries. On with the show. Okay. Great. Thanks. It's it's fine as it is.
|
|
0:30
|
|
Great. Thanks. So, um, hello everybody. My name is Onat and, um, I've been
|
|
0:36
|
|
working on this language for the last decade. And, um, what you're looking at
|
|
0:42
|
|
is a, um, blockbased for I mean, I'm I'm not
|
|
0:48
|
|
actually really like, you know, good at presentations and I haven't really prepared for the talk. So, excuse if if
|
|
0:55
|
|
the talk is like a little bit um anyway a train wreck, but let's see. Let's see
|
|
1:01
|
|
what happens, you know. So, um the thing is this is actually like a
|
|
1:09
|
|
Ford editor that's encoded in another Ford editor that look like um hold up
|
|
1:17
|
|
that look like this. So um this is a previous version of of
|
|
1:24
|
|
that um editor and this is a text base for it. Um so you can just type anywhere
|
|
1:31
|
|
on the screen. This is like just um 4K blocks per screen. um 64 by
|
|
1:40
|
|
64 and um text base for takes about 60
|
|
1:46
|
|
milliseconds to compile the editor which you're looking at here. So that's number
|
|
1:53
|
|
that you're seeing here. That's like 17 um 8 millisecond. That's the textbased
|
|
2:00
|
|
performance like you know when you're um processing text uh to
|
|
2:07
|
|
compile and this takes 8.24 24 milliseconds for
|
|
2:14
|
|
uh two platforms Windows and Linux and I
|
|
2:20
|
|
can I cannot I can say like okay let's um let's see let's yeah it takes four
|
|
2:28
|
|
milliseconds per uh platform as you can see here um if I don't compile for Windows
|
|
2:36
|
|
and 8.2 two milliseconds for the entire program that's looks like this.
|
|
2:45
|
|
So um this is vamp and this is the first series program that I um coded in for
|
|
2:53
|
|
that's like um you know beyond a certain complexity that like okay this editor uh
|
|
3:01
|
|
that we were looking at um was manageable uh in text based for but to
|
|
3:07
|
|
do this in text would have been much more difficult for uh a lot of reasons
|
|
3:13
|
|
that we're going to get into and um yeah this this is based on uh a binary
|
|
3:19
|
|
encoding which is why this is so fast and it gets translated directly into
|
|
3:25
|
|
machine code. So um yeah
|
|
3:31
|
|
um let's let's start with like why fort uh is actually not um you know um I mean
|
|
3:42
|
|
fort does a lot of stuff right but it's actually still um I'm going to create it
|
|
3:48
|
|
as a runtime opinionated language and that means the language is u has a
|
|
3:55
|
|
defined runtime which is in the case of forge it's it's a data stack and a uh
|
|
4:01
|
|
return stack right and um you know anything that you
|
|
4:07
|
|
could configure um per your own for of course um like um you know I I like to
|
|
4:16
|
|
have global memory for instance so um the thing is how do you run a fort on
|
|
4:23
|
|
on a GPU right because like this program that we're looking here, it also has like shaders and like it's it's actually
|
|
4:30
|
|
just compute shaders and um rendering text like this and running Fort on the
|
|
4:38
|
|
GPU um in the traditional sense is kind of like impossible because um you have
|
|
4:45
|
|
to maintain that stack with registers and it it's it's not that you know it's
|
|
4:52
|
|
it's not that good. um versus um
|
|
4:57
|
|
like because I mean I I've been I I've been uh programming this for 10 years uh
|
|
5:04
|
|
more than 10 years actually and um the thing is it it had to be the most
|
|
5:12
|
|
performant language ever also and um the fourth overhead just by this example uh
|
|
5:19
|
|
the um 16 like 60 milliseconds versus
|
|
5:24
|
|
like 4 milliseconds. That's like for difference between using data stack
|
|
5:30
|
|
versus using registers only, right? So this for is uh like the stack is just
|
|
5:37
|
|
two uh there's there's only two uh items on the stack. So um and you can see the
|
|
5:43
|
|
stack is visible on the top left corner here. Um so you can go anywhere in code
|
|
5:49
|
|
and say okay what does the stack look like here um or here for instance it's like um all
|
|
5:59
|
|
the instances that this definition is is being called from um the stack is
|
|
6:05
|
|
visualized but why why do we need stacks right
|
|
6:12
|
|
stacks are there so that we can pass information in a convenient way.
|
|
6:17
|
|
Otherwise, we would have to use variables and having to name variables all the time is a lot of well, a lot of
|
|
6:24
|
|
bookkeeping that you have to do versus just using stacks, right? And um let's
|
|
6:30
|
|
see um I mean this
|
|
6:36
|
|
is in instead of using stacks, we can just use global memory. Um, for
|
|
6:43
|
|
instance, we don't have to use stacks even at the runtime, but I use stacks at
|
|
6:48
|
|
the compile time uh because it makes passing arguments a lot easier.
|
|
6:56
|
|
Um, sorry. I'm just scrolling through the code to find like
|
|
7:02
|
|
um an interesting place, but cuz cuz this this subject is actually like um uh
|
|
7:08
|
|
maybe we should just stay on this screen for a while. Um
|
|
7:14
|
|
I because this is like the uh the first screen of of this environment and um
|
|
7:22
|
|
there's a bunch of numbers here and um like a structure here. So um in in in my
|
|
7:33
|
|
in an old forge I I made there was this um like begin and end definitions like
|
|
7:41
|
|
um begin definition and end definition like that versus
|
|
7:46
|
|
uh this means the beginning of the definition and end of the previous
|
|
7:52
|
|
definition. Right? So you don't have to um remember to close your words, right?
|
|
8:00
|
|
Uh the definition closes each definition closes itself or if there's no
|
|
8:05
|
|
definition, if there's just space um then that means that's an execution which we're going to get also um you
|
|
8:14
|
|
know later. Um so actually this is the perfect place to mention execution.
|
|
8:22
|
|
So um I think we have to code in the
|
|
8:29
|
|
simplest way and I don't think it involves a lot of abstractions right so
|
|
8:36
|
|
um I think we should just code everything in assembly including the language and the editor itself um and
|
|
8:44
|
|
how do we write that assembly is um of course we don't have to write it like uh
|
|
8:50
|
|
we don't have to write it instruction by instruction Actually, we can use a macro language uh like this for to
|
|
8:58
|
|
implement that other fort core if we wanted to or other u language extensions
|
|
9:05
|
|
if we wanted to because that's the other point, right? Like it it has to be a foundational language that's um that can
|
|
9:13
|
|
last um forever because uh it's it's the simplest that it gets. And um the the
|
|
9:21
|
|
design space for that um is like two
|
|
9:27
|
|
registers is I think the optimal point because if you have four registers that's a lot of shuffling
|
|
9:34
|
|
and most operations are like they they just use two um operands. So two
|
|
9:42
|
|
registers for stack size at compile time is enough for a program of this
|
|
9:48
|
|
complexity. Oh yeah, I could just open this of course.
|
|
9:53
|
|
um for for like the um and um this program is
|
|
10:01
|
|
um so I can basically title the screen anyway I want and
|
|
10:07
|
|
um it does not use stacks at all like I mean it uses stacks at some places but
|
|
10:15
|
|
not in the way that you would think like you know uh there there is no like the stack overhead of like you know uh
|
|
10:23
|
|
traditional forge it's all compiled down to assembly because in a way it's all programmed in assembly but you know the
|
|
10:30
|
|
assembly is um highle macro uh for style and I got uh basically anywhere uh
|
|
10:39
|
|
anywhere I have um like okay there we go
|
|
10:45
|
|
uh I have like exact assembly output that I'm interested in for the architecture that
|
|
10:51
|
|
I'm compiling compiling to. So, um this is x64 for now, but um you could compile
|
|
10:58
|
|
to ARM 64 or any of the microcontrollers or whatever. Um you could use any
|
|
11:04
|
|
computer to transpile to any other computer. So as long as you can communicate with that other computer via
|
|
11:12
|
|
like sending the compiled code that you just wrote uh I mean that you just generated via execution which is like
|
|
11:20
|
|
the um yeah the subject that that I wanted to get to is like we don't have to think
|
|
11:28
|
|
code as like some complicated um you know like structure. It's it's
|
|
11:36
|
|
just pure execution uh that generates a very simple that
|
|
11:42
|
|
maps to very simple assembly and then you execute that code. So you have um
|
|
11:48
|
|
exact definitions and simple definitions and the execution is also very efficient
|
|
11:53
|
|
and um so a question about your your screen is the um the the color is is is
|
|
12:00
|
|
uh highlighting or is there is there some encoding for the coloring? Oh yeah, there is um there's semantics
|
|
12:08
|
|
associated with color. It's it's like color for but you know um it's it's
|
|
12:14
|
|
compile time color for like I mean color for is as far as I know it's still uh
|
|
12:20
|
|
text encoding based which is still uh valid by the way it's like it's just
|
|
12:26
|
|
slower and it has some disadvantages also but you might want to do text based
|
|
12:31
|
|
color for it instead of like this index based color for so the index based part
|
|
12:36
|
|
is there is a dictionary that maps each word to you know each of those words is
|
|
12:42
|
|
like I mean I could I could just go to this loop and I could call this like uh loop for instance and it will change
|
|
12:49
|
|
everywhere because um it's it's like I see so you're storing you're storing a
|
|
12:54
|
|
central index for each for each uh word in the I see interesting exactly exactly
|
|
13:00
|
|
and how many how many how big are how how big are each is is each word like
|
|
13:06
|
|
how big is the index space um Well, there is 24bit indices because
|
|
13:12
|
|
I want to pack each instruction to four bytes. So 24 bits of that four bytes is
|
|
13:17
|
|
dedicated to that. But in the next iteration actually I'm going to do four bytes for indices and then I'm going to
|
|
13:24
|
|
store one byte tag in a separate block. So you have like I mean this is going to
|
|
13:31
|
|
get faster you know this is just back baseline. I see. So so it's so it's it's
|
|
13:36
|
|
a index and then a tag. Got it. Got it. Thanks. Yes. Yes. Exactly. And um
|
|
13:42
|
|
because if you're if you don't have that index, that means you're hashing and then you had to do that hash lookup
|
|
13:49
|
|
which gives you like uh dynamic local context. But I I like global context
|
|
13:56
|
|
more than local context because I have exact mappings, you know, exact semantics instead of like, oh, maybe I
|
|
14:03
|
|
called this word in a different context. So that word has like a different that
|
|
14:08
|
|
word maps to a different cell like different index and like you know that kind of like problems I don't want to
|
|
14:14
|
|
have to deal with like with text space but uh like still text base is uh valid
|
|
14:21
|
|
in certain context like maybe you want to do I don't know
|
|
14:28
|
|
um it's I mean it's it maybe you want to do like free form
|
|
14:35
|
|
programming I mean without having to require a complex editor because instead
|
|
14:40
|
|
of like having the complexity of text in the language, you've embedded that complexity in the editor. Uh because um
|
|
14:48
|
|
you know when you're writing you you're like looking up this um you know word
|
|
14:53
|
|
like loop for instance and um that's I'm I'm pulling from this concept that I
|
|
14:59
|
|
call the deck. So I have like a deck of cards and I have a bunch of words that are like for these are my walcon words
|
|
15:07
|
|
for instance and these are ffmpeg words when I'm like dealing with ffmpeg and like a lot of words now I put in a to-do
|
|
15:13
|
|
list to implement later and I just never got around to it's not even like a
|
|
15:18
|
|
problem and this is just one encoding right this is not central to the
|
|
15:24
|
|
execution this is just for printing this is not the core language so In the
|
|
15:30
|
|
future, if you're like doing open source for instance, you you have the option to say like um just ship the source but not
|
|
15:39
|
|
the symbols, not this like dictionary part. So um in a sense you still have
|
|
15:44
|
|
the source and the numbers and um you know but you can still protect your IP
|
|
15:51
|
|
and like you know symbols for instance uh for like I don't know and um there is
|
|
15:59
|
|
also the possibility of um embedding this whole thing into the program
|
|
16:04
|
|
itself. So the core language is 2 to 4 kilobytes. It's actually should be two
|
|
16:11
|
|
kilobytes. I haven't checked recently, but yeah. Um it's it's very simple
|
|
16:16
|
|
because what I'm doing is I'm just looking um like I'm just generating a
|
|
16:23
|
|
template based like um code so that I can execute it
|
|
16:29
|
|
efficiently instead of like having to incur the um interpreter cost, right? So
|
|
16:36
|
|
um I mean that's like also happening in this textbased language and that's why
|
|
16:42
|
|
it's 16 milliseconds. I mean it's still fast but you know having to hash and
|
|
16:48
|
|
having to look up that overhead is like easily like yeah
|
|
16:54
|
|
uh easily um yeah eight like 12 milliseconds of cost. How how how do you
|
|
17:02
|
|
manage the the index space? Like that's the main thing that's kept me from going down that road is sort of like is there
|
|
17:09
|
|
a lot of complexity in managing? Yeah, that was um that grew to be a
|
|
17:15
|
|
problem because like um after a while there is just a lot of words and like um
|
|
17:21
|
|
so I I solved that via like tags. So I have these 16 uh word scrolls and I can
|
|
17:30
|
|
paint them with tags and then I can select tags um over here while a deck.
|
|
17:36
|
|
So each of those are like tags. I mean it's it's kind of complex. I'm not going
|
|
17:42
|
|
to do four tags in the next iteration. I'm going to do just 16 bit index plus some predefined tags instead like API
|
|
17:51
|
|
implementation you know uh that sort of thing like um you know this is not the
|
|
17:57
|
|
um end iteration I mean there's a lot of UX improvements
|
|
18:03
|
|
uh to be you know to to be imagined right there's to
|
|
18:10
|
|
be explored I mean that's that's very exciting about this language is like um
|
|
18:15
|
|
it's it's also going to run on Steam Deck and also uh VR and also phones and
|
|
18:21
|
|
tablets, right? Um because um why not? We we're not like constrained to the
|
|
18:28
|
|
keyboard keyboard anymore. It's it's just like picking up symbols. I mean you
|
|
18:33
|
|
could essentially draw on the screen instead of like typing on the keyboard. And you said like how do you manage I
|
|
18:39
|
|
mean you can just type words like you know let's say ABC
|
|
18:44
|
|
DF I mean you could just uh like define words like this you can move them around
|
|
18:52
|
|
um you know and then when you when you insert them into the into the source base then you you you have to use the
|
|
18:59
|
|
selection on the left or you you can type you do the lookup at that point to yeah I mean um you can actually I mean
|
|
19:07
|
|
you used to be able I mean I I used to be uh I used to just have this
|
|
19:12
|
|
dictionary space and now I just type something and if I need like something
|
|
19:18
|
|
like uh index for instance index for something I just press control space and
|
|
19:24
|
|
that gets redefined wherever uh it gets redefined which is like uh configurable
|
|
19:30
|
|
like you know I I want to define index ABC here for instance and then it gets
|
|
19:36
|
|
defined here. You're kind of consciously pl managing the index space as you place new add new
|
|
19:43
|
|
things. And I I see Yeah. Yeah. I mean, it's it's like you you can move stuff
|
|
19:49
|
|
around and the only thing that you have to do is like walk through the whole source and patch, you know, numbers.
|
|
19:56
|
|
It's it's simple. I mean the editor is also very simple which is um you know
|
|
20:02
|
|
important if you want to import the editor for open source programs like you know you don't have to install 4 GB of
|
|
20:09
|
|
Visual Studio like 200 megabytes of PHP or whatever it's just 64 kilobytes of
|
|
20:15
|
|
editor if even that like and um you know
|
|
20:20
|
|
it's it's portable to anywhere because it's it's so simple. Um so yeah there is
|
|
20:28
|
|
a lot of stuff here that makes programming easier which you can see as structure in the code um like um a new
|
|
20:37
|
|
syntax for like conditionals and loops and like like this loop for instance how
|
|
20:44
|
|
it's implemented is like I can jump I got like um jump to definition right so
|
|
20:52
|
|
let me what this loop does is like it increments depth by one and whatever
|
|
20:57
|
|
depth is like it's usually zeros as you can see over here it's it's like um and
|
|
21:04
|
|
then you plus one that and then you see like oh it's plus one I mean you can
|
|
21:10
|
|
just see all the code flowing um at compile time right and that's the stack
|
|
21:18
|
|
uh over here and what's interesting about this um
|
|
21:24
|
|
Like another interesting thing about this language is like um you should be
|
|
21:30
|
|
also able to see the data flow as it's happening at runtime right so that's
|
|
21:36
|
|
also possible with with this language so I'm just like iterating through
|
|
21:42
|
|
um like okay what what was with play um for instance at setup here when I click
|
|
21:50
|
|
previous for instance I want to record like uh this with play uh index, right?
|
|
21:57
|
|
Uh so and that shows up over here just by by this um corner. So um that's like
|
|
22:06
|
|
68 for instance or um we could
|
|
22:12
|
|
say okay let's let's let's for instance run this and then like press like
|
|
22:18
|
|
previous or next uh three four times I think I pressed five six okay let's
|
|
22:25
|
|
let's count it how many times we pressed so okay so let's see one two three four
|
|
22:34
|
|
five six seven here we press seven times and you can see like the data flow as
|
|
22:41
|
|
it's happening through runtime um and you know this is the most basic form you could imagine like moving over
|
|
22:49
|
|
the mouse and seeing the full data flow which I'm going to implement for the next editor and so on but you know it
|
|
22:54
|
|
works um and you can even embed more met metadata there and I mean this is
|
|
23:02
|
|
essentially free printf like um you don't even have to type print f you just
|
|
23:07
|
|
say like okay what was like hot slot as like this code was running and if I'm
|
|
23:14
|
|
like creating some stuff then I'm going to
|
|
23:20
|
|
yeah so the hotspot was like 3D for instance like you know or 31 3D
|
|
23:31
|
|
3D you know it's it's like it's when when you're debugging it's
|
|
23:36
|
|
it's instant visualization which is um all you need essentially for fast
|
|
23:43
|
|
debugging the um so for the the the index indexes into some sort of a
|
|
23:50
|
|
some sort of like a name table. What's do you have how how is how is that built like is it a fixed fixed sized space for
|
|
23:59
|
|
the the names or what how do you manage that piece of oh yeah that's eight bytes
|
|
24:04
|
|
per um like cell I mean I I I call them cells uh like they have indices right
|
|
24:12
|
|
but they're essentially like uh compile time cells right um and you know you're
|
|
24:19
|
|
just defining names here you treat them as memory essentially. Uh,
|
|
24:25
|
|
and they're eight bytes per cell. Got it. And when you also but the name you
|
|
24:31
|
|
could make like 16 bytes if you want and it doesn't have to be but the definition of the language says that each cell is
|
|
24:39
|
|
going to be eight bytes per like you know because that's that's the one that
|
|
24:44
|
|
uh you know I think that makes sense because u I mean you could put in type
|
|
24:49
|
|
information into eight bytes if you you know um take care of it in many ways. I
|
|
24:55
|
|
mean um you don't need 16 bytes I think but 16 bytes names I mean sure maybe if
|
|
25:01
|
|
you want to let's see and and is the um um let's see when you when you
|
|
25:09
|
|
uh what about for like comments are you how do you
|
|
25:18
|
|
right um so comments are um I'm so there's 24 bits of data per instruction
|
|
25:25
|
|
on this iteration. So it's three characters. So I can just write comments like this. They're essentially like
|
|
25:32
|
|
strings, you know, they're just like encoding the string in in the U bite instead of like using like an external
|
|
25:39
|
|
string table. I see. So those are stored direct in instead of Right. Right. I see. Yeah. Because you don't want to you
|
|
25:45
|
|
don't want to pollute your your dictionary space with I I see. Yeah. Yeah. I mean you could store it in the
|
|
25:50
|
|
dictionary also if you want or you could pull it externally. I mean this language is free form. It's implemented in the
|
|
25:57
|
|
Sony. So whatever you want to do, you're free. I mean and um it doesn't have to
|
|
26:03
|
|
like I mean um I see like you know um I I I didn't want the language to be
|
|
26:11
|
|
like rigid like all the other languages out there. Like Rust for instance is is
|
|
26:16
|
|
a very rigid language that says like okay you know what this is the language and like you have to fill out these tax
|
|
26:22
|
|
forms and these all rules and if you don't abide we don't even compile your code or whatever like it's it's versus
|
|
26:30
|
|
you're free to do whatever you want and um you know it's it's like there's so
|
|
26:37
|
|
little abstractions that you can implement your own abstractions or like
|
|
26:42
|
|
your own um extensions if if you want. I mean it's
|
|
26:48
|
|
it's it's like yeah it's it's super simple compared to like all those
|
|
26:53
|
|
runtime opinionated languages that are like um that have to cater to all kinds
|
|
26:59
|
|
of um concerns, right? versus um
|
|
27:04
|
|
defining like a simple language that can still solve all those problems by being flexible enough by thinking about the
|
|
27:12
|
|
output instead of like you know being dogmatic about the runtime right
|
|
27:19
|
|
um so yeah I mean
|
|
27:24
|
|
um there is let's see let's see um there's a lot to talk
|
|
27:32
|
|
about for like you know how to program an assembly and um I mean how to like
|
|
27:41
|
|
program an assembly efficiently right um assembly for what for
|
|
27:48
|
|
well that's what processor are you on um X64 for for this iteration but that's
|
|
27:56
|
|
actually like a great question I mean for what is like it could be ARM 64 also
|
|
28:02
|
|
And um the portability is one of the um you know concerns in this like style is
|
|
28:10
|
|
like um you know each of like all of this is like programmed in x64 assembly
|
|
28:17
|
|
but through these um highle words. So I could replace those highle words for ARM
|
|
28:23
|
|
64 or Commodore 64 if I had to and emulate uh somehow. On Commodore X64 I'd
|
|
28:31
|
|
had to emulate the registers through dedicated memory. On ARM 64 you have so
|
|
28:37
|
|
much registers that emulating is not a problem and you're still like you know
|
|
28:43
|
|
um within that register budget. So you're still as fast as like
|
|
28:48
|
|
um you know uh as if you had like all those registers. It's it's like it
|
|
28:55
|
|
doesn't really cost you to not use registers, right? It's so are you are
|
|
29:01
|
|
you wanting to uh release this to to uh others or
|
|
29:07
|
|
uh Sure. Um I mean um at some like I think
|
|
29:14
|
|
um I'm gonna start a stream soon um where I'm going to build this language
|
|
29:21
|
|
uh again and this editor uh again for um
|
|
29:26
|
|
all kinds of like different stuff like Steam Deck and VR and you know desktop
|
|
29:33
|
|
of course and tablets too. Um so yeah this is like
|
|
29:40
|
|
um you know it's it's not ready for prime time. There's a lot of like UX
|
|
29:46
|
|
improvements to be made to this whole thing is is like you know the the situation but u as also like a
|
|
29:56
|
|
um you know proof of concept for like how fast you could compile and how fast you could run. I mean um and also how
|
|
30:05
|
|
expressive uh it is and um how debugable it is, how scalable it is, right? This
|
|
30:12
|
|
is like a very um I mean it's it's it
|
|
30:18
|
|
takes about thousand times more times to compile this program in C
|
|
30:25
|
|
um than in this language. So, and also it's more code in C even
|
|
30:33
|
|
though C has like all those pre-ompiled headers for walcon
|
|
30:39
|
|
ffmpeg and so on. um because this is a um for instance I'm just going to say
|
|
30:46
|
|
like um this is a macro language so I can say
|
|
30:53
|
|
div I can just have like say 29 device
|
|
30:59
|
|
to say we wk device which means like okay what does it mean it means get swap
|
|
31:06
|
|
chain images you know which is which gives you the images for the uh you know
|
|
31:13
|
|
for the swap chain. So uh in C I would have to write
|
|
31:18
|
|
this as like we can get image swap chain get swap chain
|
|
31:25
|
|
images car etc etc um and then I would have to say like
|
|
31:31
|
|
um GPU because like it's not global and then device versus just you know just
|
|
31:39
|
|
device I mean the difference in usability and
|
|
31:44
|
|
also readability is u huge compared to like all those other languages that are
|
|
31:50
|
|
bound by um having to be text based right instead of like execution based um
|
|
31:57
|
|
you know this have you started uh have you started making a manual or documentation
|
|
32:04
|
|
well uh the documentation will be the streams that I'm going to do uh as I built the language and the editor you
|
|
32:11
|
|
know that's the documentation that's going to be happening that's it's going to be happening live
|
|
32:18
|
|
you know um and it it doesn't even need that much documentation the whole thing
|
|
32:24
|
|
is so simple so um the thing is okay let's get to the language semantics
|
|
32:29
|
|
right so we said like oops there's a here's a bug that sometimes crashes the
|
|
32:35
|
|
editor when I go to the top like you know It's It's a stupid thing, but you
|
|
32:41
|
|
know, sometimes it happens. I haven't had the motiv motivation to fix it. So,
|
|
32:47
|
|
um anyway, oh yeah, there it happened again.
|
|
32:53
|
|
Funny. Think I'm not doing like balance checking, which is like happens when you're programming in assembly.
|
|
32:58
|
|
Sometimes you forget to do balance checking on somewhere after some subtracting or whatever which is again
|
|
33:06
|
|
um you know dependent on how you program assembly right so okay let's let's read
|
|
33:14
|
|
this so this means defining right so I'm defining like call first I seem to lost
|
|
33:20
|
|
your screen there uh oh okay
|
|
33:26
|
|
you still sharing oh Yeah, I think it's okay. It's back,
|
|
33:31
|
|
right? Okay, cool. Thanks. Thanks for reminding. I mean, I I thought we were sharing screen still, but yeah.
|
|
33:39
|
|
So, Oh, okay. Okay. I think I I know what happened there. It crashes and then
|
|
33:46
|
|
I I quit and then that closes the share. So, after Yeah, if you share just the if
|
|
33:52
|
|
you share the whole the whole screen then it'll get then it'll stick. But if you skip share just the one window then
|
|
33:58
|
|
when that window goes away it will Yeah. Yeah. I I So um so call is like
|
|
34:06
|
|
FF0. So what does FF0 right? Let's see. XX
|
|
34:12
|
|
FF0. Oops. Oh yeah. I see FFE0. That's jump to racks, right? Um,
|
|
34:21
|
|
so call becomes jump to racks because there's already a return address on the
|
|
34:27
|
|
stack. So I don't want to call I just want to jump to the top of the stack like that I want to call. So um it means
|
|
34:35
|
|
that we're passing um at every word the top of the stack is going to be racks
|
|
34:43
|
|
right and the second item on the stack is going to be RDX. So out at looks like
|
|
34:50
|
|
48.92. So that's like exchange RDX racks. So that's a
|
|
34:58
|
|
trick actually uh that's occurs um everywhere in this um in this code
|
|
35:06
|
|
generation. Before I start the definition, I say exchange racks
|
|
35:13
|
|
RDX. So depending on which like
|
|
35:19
|
|
um which one you're calling which um like
|
|
35:27
|
|
um depending on whether RDX is on top of the stack or whether rax is on top of
|
|
35:32
|
|
the stack you call um you know just before or just after exchange RDX
|
|
35:39
|
|
racks. So that means that each calls are just single instructions instead of requiring a potential exchange
|
|
35:46
|
|
instruction to align the racks and RDX for top of stack,
|
|
35:52
|
|
right? So um so yeah, all of this is like extremely efficient and
|
|
35:58
|
|
um yeah, I mean this is also like in the definition of the language, right? And all of this is like public domain by the
|
|
36:05
|
|
way. Um I'm not going to like you know encumber this like with patents and I
|
|
36:10
|
|
ask you not to also like this is just pure foundational stuff relates to like
|
|
36:17
|
|
public domain for like public uh you know knowledge. I mean uh as far as I
|
|
36:23
|
|
know this is like the most fundamental way of like writing in a um JIT style
|
|
36:31
|
|
assembly because um yeah every instruction just compiles
|
|
36:36
|
|
to a single instruction right like this um load for instance these green words
|
|
36:43
|
|
are like just um load from this cell
|
|
36:48
|
|
index um into racks or RDX depending on whether RAX is on top of stack or RDX is
|
|
36:55
|
|
on top of stack. So, um,
|
|
37:01
|
|
yeah. Does that make sense in terms of like semantics, language
|
|
37:07
|
|
semantics? I'm a little little fuzzy on on so you're saying you're just you have
|
|
37:13
|
|
a two element stack that you're alternating. Maybe I'm not understanding the what if you could go through the
|
|
37:18
|
|
register what what the how you're using each register that would be helpful. Uh, yeah. So um racks and RDX are used for
|
|
37:27
|
|
um you know those the it's the stack registers and um like
|
|
37:35
|
|
top of the stack and a and a stack pointer or some other arrangement. Oh no, they're they're just those two uh
|
|
37:42
|
|
stack items. You know there's only two items on the stack. Got it. Got it.
|
|
37:48
|
|
And um you know this compiles move rax 256 and this compiles move rdx 512 and
|
|
37:56
|
|
this compiles move racks 1024 you know and uh when it's like when you read this
|
|
38:05
|
|
um then you know this becomes top of stack and then you can do another like you know uh write into like salt for
|
|
38:13
|
|
example or whatever and you know that's I mean it it works you know um it's just
|
|
38:19
|
|
you can do this by just using one bit actually is our racks on top of stack or
|
|
38:25
|
|
not that's the one bit that you're interested in like it's it's super efficient
|
|
38:34
|
|
um so yeah so sorry still not quite get following it you're saying that the so
|
|
38:39
|
|
you're keep you're keeping a single bit to keep track of whether rax or rdx is is the top of stack is that Yes. So then
|
|
38:47
|
|
so then you you've got a two and you've got a two element stack basically. Is it? Yes. Exactly. Exactly. Got it. Okay.
|
|
38:54
|
|
Yeah. I mean um two element stack because uh four elements gets very um
|
|
39:02
|
|
yeah I mean if if you're calling with four elements you have to deal with a lot of permutations to align the stack
|
|
39:10
|
|
layout you know as you expected. Um, or maybe you could run like two parallel
|
|
39:16
|
|
stacks, but I don't see the point. It just makes everything so much more complex than like just having two items.
|
|
39:22
|
|
And most of the time, I mean, two two items is just enough for um all the
|
|
39:28
|
|
things that you might want to express with this language. And if you need more
|
|
39:34
|
|
than two items then you read it into I mean you write it into a variable and then you read it uh when you need it you
|
|
39:42
|
|
know like um for example the uh for example there's like this uh free
|
|
39:49
|
|
list definition right let's see I think I'm using free list for example oh
|
|
39:56
|
|
there it is so um the free list for example uses
|
|
40:03
|
|
this variable called stride which is stride in shifts you know uh so you have
|
|
40:10
|
|
to define it before you call this word and other than that it takes like okay
|
|
40:16
|
|
how much free list items that I'm going to have and that's like 32 kilobytes for directory entries for example and then
|
|
40:23
|
|
like free list I define as like I'm going to read into the max like uh I'm
|
|
40:29
|
|
going to read top of stack onto max right which is this 33 kilobytes and
|
|
40:36
|
|
then into base which is directory entries and then I generate code like
|
|
40:42
|
|
for allocation free previous index and append. So that's like five items that I
|
|
40:47
|
|
don't have to pass on top of stack that I can read anytime, you know, if if I
|
|
40:52
|
|
care to, you know, I don't even have to like deal with it. It's just there if I if I care to like I might care about
|
|
40:59
|
|
allocation of free, but maybe not other stuff or whatever for particular um free
|
|
41:06
|
|
list, for example. And it it would be helpful if you could go through the the tags that you're using because that's
|
|
41:12
|
|
also challenging to Oh yeah, sorry. Sorry. Yeah, that's like um so green is
|
|
41:18
|
|
load and red is store. So I'm loading
|
|
41:24
|
|
previous onto like or say I'm loading the allocation um function on top of
|
|
41:31
|
|
stack and then I'm uh writing that to plus tab which allocates like a tab for
|
|
41:37
|
|
instance right which are like you know which happens when you roll a new tab
|
|
41:44
|
|
like uh you know like this it allocates like a new tab and we can like verify
|
|
41:52
|
|
that when it when this runs by like saying like okay you know what let's look at those variables and
|
|
41:59
|
|
see what happens if I allocate one two and three
|
|
42:05
|
|
tabs and you know yeah you got like three times
|
|
42:14
|
|
the and cx is like one dx is five and
|
|
42:19
|
|
you know etc etc So, um, yeah.
|
|
42:27
|
|
What about the other? So, red is red is read and and green is or green is right.
|
|
42:33
|
|
What what are the other Oh, yeah. Yeah. Sorry. Um, so white is call. So, call
|
|
42:40
|
|
means that you compile a call instruction literally uh at uh JIT time
|
|
42:48
|
|
though. So um whatever address that you had inside grow like you know which is
|
|
42:55
|
|
like eight bytes uh which you can jump to the definition right. So um this
|
|
43:01
|
|
address gets compiled in the instruction stream in here
|
|
43:07
|
|
and the the the pipe the pipe in front of the definition. So magenta is is uh
|
|
43:15
|
|
is definition is is the pipe just styling or is that
|
|
43:21
|
|
so that also gets compiled you know that's the definition beginning so that gets compiled to a return because it
|
|
43:28
|
|
needs to return from the previous instruction which is setup you know I mean the previous definition which is
|
|
43:35
|
|
setup and um and then there's exchange racks rdx X and then um you know that's
|
|
43:44
|
|
the definition uh beginning right so and then you compile these you jit these
|
|
43:50
|
|
other uh instructions one by one so this this is a compile this is a load this is
|
|
43:55
|
|
a number like uh this is a call call and like numbers and this is
|
|
44:03
|
|
um this compiles and and sorry the the the number so the the the numbers is
|
|
44:09
|
|
there a single the the numbers are the cyan numbers are compile of the number or some
|
|
44:16
|
|
other sorry they're compile move into into rax or or rdx depending on
|
|
44:23
|
|
who's top of stack oh yeah I mean for example this stuff they generate nothing
|
|
44:29
|
|
at the output right but when they get compiled this like this gets translated
|
|
44:35
|
|
to uh move rax 4 move rdx 104 for and
|
|
44:40
|
|
move rax 32 and then this is like puts cx which is defined here you know it's
|
|
44:47
|
|
just um some number that's like 1,003 which is like the
|
|
44:54
|
|
type and then like the register which is one you know um and then sorry the
|
|
45:01
|
|
yellow the yellow is what again oh the yellow is um runtime okay so
|
|
45:09
|
|
That's like runtime store. So that generates a move RCX020 if if you can like you know is
|
|
45:16
|
|
there is there a comp is there runtime read? Is that the the blue or no?
|
|
45:22
|
|
Uh sorry can you repeat that? U so yellow is runtime runtime write. What's
|
|
45:28
|
|
the run is there runtime read? Oh yeah, runtime read is uh CX dot like the dot
|
|
45:35
|
|
syntax. Or you could just say CX at you know it's it says like move racks to RDX
|
|
45:42
|
|
uh move racks to RCX like or you could say
|
|
45:49
|
|
um move RDX or CX if you want like CX at the you know sorry I said run I meant I
|
|
45:56
|
|
meant at at u sorry yellow is yellow is is is execute time read or is it it's
|
|
46:03
|
|
compile time read? Uh, I'm getting them mixed up. I'm
|
|
46:09
|
|
sorry. No, it would be helpful if you could go through each tag one by one so that we Yes. Yes. Yes. Yes. Um, sorry
|
|
46:16
|
|
about that because like you know the it can be a bit confusing. Uh, I just got
|
|
46:21
|
|
used to it like you know the way it looks. Um, so uh each so
|
|
46:28
|
|
if so yeah the the red ones the these are like calls, right? The white ones
|
|
46:33
|
|
are calls uh at and they are compile time calls and the red ones are compile
|
|
46:38
|
|
time writes. Okay. And green ones are compile time read and yellow ones are
|
|
46:46
|
|
execution or rather like runtime uh you know uh so it's so this is indexing. So
|
|
46:55
|
|
uh each directory path is like 256 256 characters for instance and um I'm
|
|
47:03
|
|
indexing directory path which I've defined here as like maxers which is
|
|
47:08
|
|
sorry the yellow the yellow the yellow is execute time read is that is that right or execute time
|
|
47:16
|
|
invocation call yellow is used for a bunch of stuff I mean sometimes it's uh
|
|
47:23
|
|
there's also So um a prefix like this equals here, you know. Mhm. So or this
|
|
47:30
|
|
dot here or postfix when it's a load or it's a prefix. I see. So okay, you've
|
|
47:35
|
|
got the color the color is overload. Is that is that all different tags or is that Yes, they're all different. Okay,
|
|
47:42
|
|
got it. Okay, so you got you've got several several things that are yellow that depend on the t on the Yes. Yes.
|
|
47:48
|
|
Sorry about that. Ran out of colors. Okay. Some Yes. When it's like yellow, then uh
|
|
47:55
|
|
if there's like nothing, then that's a um like runtime uh call, you know. So if
|
|
48:05
|
|
if if it's like a um so there was like plus tab that Oh, there's also like undo for by the way because you really need
|
|
48:12
|
|
undo if you're like doing like a custom editor, right? Yeah. So, so, so why
|
|
48:17
|
|
didn't you use the I'm surprised that you use color for compile time read and write, but then you use different
|
|
48:24
|
|
prefixes and suffixes for the for execute time.
|
|
48:29
|
|
Yeah, because I mean execute time code like you know has to kind of stick out
|
|
48:36
|
|
you know because I want to see at a glance which pieces of code are generating code versus like which are
|
|
48:43
|
|
like you know um I mean these are all generating code at some point right oh
|
|
48:51
|
|
sorry I had to I was doing some steam integration yesterday so that's like
|
|
48:56
|
|
undo and and you Haven't Let's see. So, you uh you haven't explained the blue yet.
|
|
49:03
|
|
Sorry. You haven't explained blue yet. What's blue? The blue's comments. The blue's comments. Blue
|
|
49:09
|
|
comments. Okay. Like um and the green the orange reds are uh
|
|
49:19
|
|
strings, right? So, comments and strings can be converted
|
|
49:24
|
|
um you know. So this would be like a string um but it's not a runtime string
|
|
49:30
|
|
because um I cannot assume anything about the runtime. This is a pure compile time language that you can use
|
|
49:37
|
|
to implement any kind of logic to implement whatever you need to generate for at runtime
|
|
49:45
|
|
like um so it's omniflexible right like you can um just say like I mean this
|
|
49:53
|
|
won't generate anything at all like no assembly you can just you know be
|
|
49:59
|
|
irresponsible on the stack and like it won't matter like you can just
|
|
50:05
|
|
um you know um let's see and what what are the what
|
|
50:12
|
|
are the uh the hard brackets? Oh yeah, the hard brackets are um the
|
|
50:18
|
|
notation that I have for managing uh basic blocks as I call them. I mean
|
|
50:24
|
|
they're also like terminology but yeah um so the basic blocks are defined here
|
|
50:31
|
|
and they're like um they define
|
|
50:38
|
|
um ranges of code that like um that you
|
|
50:43
|
|
can have like you know a beginning and a link and a end jump targets for. So
|
|
50:51
|
|
yeah, so um with this notation, you don't need ifs anymore because you can have an if
|
|
51:00
|
|
like conditional anywhere, right? So um let's see a place where
|
|
51:09
|
|
um say like a conditional say um for example I'm here decoding like
|
|
51:17
|
|
each vi packet at if I'm calling like I'm def okay okay let's look at this actually this is an interesting piece of
|
|
51:23
|
|
code like what happens when you flush a video for instance when you have to like flush a video um which means like when
|
|
51:31
|
|
you're changing in the video you had to like go through the remaining like uh packets and stuff that ffmpeg has to um
|
|
51:40
|
|
you know and release them. Mhm. So what happens here is like I'm looping forever
|
|
51:46
|
|
basically which what this loop does until I break and I call V packet decode
|
|
51:54
|
|
you know which is like um a Q which gives me a video packet and I assign
|
|
52:01
|
|
that to uh video v V packet uh variable you know which generates this code here.
|
|
52:08
|
|
Mhm. So, um I'm sorry, what are the curly the curly braces and why are they yellow?
|
|
52:17
|
|
So, yeah, these are uh these are lambdas. That's that's a great question
|
|
52:22
|
|
actually. Thank you for I mean I haven't I'm doing like a terrible job explaining the language. This is like very all over
|
|
52:31
|
|
the place, but thanks for asking these questions about like you know I mean these are lambdas and um you know if you
|
|
52:38
|
|
you can call you can choose to call them or not. I mean lambdas in the sense that
|
|
52:44
|
|
they that they they they do they bind any variables or they just they're just they're just an invocable thing that
|
|
52:51
|
|
leaves an address. Yeah, it's it's just an invocable thing that's an address like you know it jumps over. Got it. Got
|
|
52:57
|
|
it. That and like I don't like locals. It's it's everything is global, you
|
|
53:03
|
|
know. I mean, got it. Got it. I I figured I just thought I'd ask because L means things to people. Does does the um
|
|
53:10
|
|
And sorry, why I'm confused why in that lambda why are you using a yellow a
|
|
53:15
|
|
yellow symbol there? Isn't that it that doesn't get happen at runtime because it's in a lambda or what's the
|
|
53:22
|
|
uh so yellow is also used for I mean it's not that much stuff you know it's
|
|
53:27
|
|
also used for immediate time words I mean um so that's when you invoke that
|
|
53:36
|
|
definition when it's like jitting you know and that's like defined outside in the language itself it's it's very
|
|
53:43
|
|
simple assembly code you know it's just like appending that um you know um panning like what this
|
|
53:51
|
|
does is um basically um say like I want to execute
|
|
53:56
|
|
this piece of code um otherwise nothing executes you know only the things that
|
|
54:02
|
|
that are like uh within this yellow execute and all of the other ones are like uh definitions right so you know
|
|
54:09
|
|
exactly what you're executing if it's like following this um yellow um bar
|
|
54:16
|
|
here. Yeah. So, it's either definition or execution. I see. And yeah, I mean
|
|
54:23
|
|
you could got a lot of stuff overloaded on the yellow there. Okay.
|
|
54:28
|
|
Yeah. I mean, uh I don't know. I I like the color, but you can choose color, you
|
|
54:34
|
|
know, it's I mean, if when the editor is released, you'll be able to
|
|
54:39
|
|
um well, you'll be able to uh attend
|
|
54:45
|
|
like within code, you know? I mean, we can just ditch Zoom and just attend the
|
|
54:51
|
|
meeting in inside the code editor, right? Like because you can integrate
|
|
54:58
|
|
multiplayer here. um easily and you know um also a multiplayer version control
|
|
55:04
|
|
system that's like um you know that's scalable to any kind of users like git
|
|
55:12
|
|
is not the end all of like version control systems I think like
|
|
55:17
|
|
um but yeah we were looking at with flesh here and like the the code and I
|
|
55:24
|
|
mean this calls you know this is just a single call and then this is Um and then
|
|
55:30
|
|
the result of that is stored in rax and I move that to we packet and then if rax
|
|
55:36
|
|
is zero I break and I move that we packet because ffmpeg requires me to
|
|
55:43
|
|
pass it in a pointer. So I have to pass it in a pointer and 18 is like you know
|
|
55:49
|
|
what is 18 18 is a packet free which frees the packet right. So I mean I I could just and sir
|
|
55:58
|
|
how are you how are you actually hooking you're hooking into to to AV codec and and ffmpeg and stuff like how is that
|
|
56:05
|
|
binding how are you how are you bridging that divide? Yeah. Yeah. Well I assume
|
|
56:10
|
|
that I don't have any uh floating point arguments. So uh the calling convention
|
|
56:18
|
|
is like um just this. So um implement is
|
|
56:24
|
|
this. So you have to align the SP which I do by reading SP like the old stack
|
|
56:30
|
|
pointer into B. Like this is so stupid you know having to align the SP but you have to do it because the operating
|
|
56:38
|
|
system requires you to um I I don't even use stack pointer like for any data
|
|
56:45
|
|
anymore. Um I just use it as a call stack. And you know when you think about
|
|
56:51
|
|
it um that could have tremendous benefits. You just eliminate a lot of like stack overflow like um uh return
|
|
57:01
|
|
oriented programming like right there right. Um it's it's
|
|
57:07
|
|
like I this whole program runs without any runtime stacks. It's it's totally
|
|
57:13
|
|
possible to program without having to use any stacks at runtime at all. Um
|
|
57:21
|
|
yeah, I mean way we could open some demos
|
|
57:27
|
|
maybe. So yeah this whole program I mean it's
|
|
57:32
|
|
not just also CPU side code right there is also u GPU code which is
|
|
57:40
|
|
um like which most other languages for most other languages it's an afterthought right
|
|
57:47
|
|
um and in this language it's it's so expressive that you
|
|
57:53
|
|
can like define the whole spare wheel like generation in
|
|
58:01
|
|
like just this much code essentially like
|
|
58:09
|
|
it's it's not that much and by the way even even like the fonts are defined in this language is is my screen showing by
|
|
58:15
|
|
the way or is oh okay it's like stuck on my screen so I wasn't sure
|
|
58:22
|
|
I'd be curious to to to see that how you define the fonts it looks like they're kind of a bit of a vector something that
|
|
58:29
|
|
yes yes so um say we're redefining m for
|
|
58:34
|
|
example to be like you know um so m is here so
|
|
58:40
|
|
um I start from bottom left right to top left to center to top right to bottom
|
|
58:48
|
|
right so what if I went to bottom center but I had to switch to the other uh deck
|
|
58:56
|
|
you know. So, yeah. Yeah. So, now it's like, can you
|
|
59:03
|
|
see the difference? Maybe I can make it change the font size
|
|
59:10
|
|
here. So, yeah, it looks um like this now. Or, you know, I could I could
|
|
59:17
|
|
just make it something entirely different. Denmos like it's it's just um encoding stuff at
|
|
59:28
|
|
um you know it's it's so simple it's it's like it's just this much code
|
|
59:34
|
|
to yeah it's it's just all this code is like this much for for that
|
|
59:41
|
|
language and you know yeah and that's like the font definition
|
|
59:48
|
|
right I'm going to undo do that. Okay. So, um and that's Are you hitting
|
|
59:55
|
|
something to rebuild the system each time? Is that Oh, yeah. It's that's the enter. Okay. Whenever I I press enter,
|
|
1:00:02
|
|
uh it rebuilds. You know, you you you get like you get very
|
|
1:00:08
|
|
um how to say it, you know, you get very used to it. Like 8 milliseconds is so
|
|
1:00:14
|
|
fast. I I I can't even like wait for C to compile anymore. Yeah. It's but yeah
|
|
1:00:21
|
|
um it's also includes all this shader stuff also that I'm defining inside the language Paul says he can't Paul can you
|
|
1:00:29
|
|
see the screen you were indicating in the chat you couldn't I can currently see it but
|
|
1:00:36
|
|
I can't see those on my other stream okay never mind so um yeah I mean that rendering code
|
|
1:00:44
|
|
looks like this you know it's a bunch of shader codes which uh um which is not
|
|
1:00:50
|
|
that hard to write actually you know and you can do um you know the the the cool thing about
|
|
1:00:58
|
|
this language is you can redefine stuff like this for instance and there I just redefined
|
|
1:01:05
|
|
filter you know there can be two definitions that's fine and I can say like okay um you know what if I did this
|
|
1:01:14
|
|
instead or okay that didn't change anything
|
|
1:01:20
|
|
because what if I didn't do okay crash but I
|
|
1:01:25
|
|
shouldn't. Yeah, it doesn't look on the stream because like the difference is
|
|
1:01:30
|
|
very subtle. Maybe I should see like look at it more. Oh yeah, I I know. I
|
|
1:01:36
|
|
know. Hold on. There's like the dark modes here. I can show you dark
|
|
1:01:44
|
|
modes which
|
|
1:01:50
|
|
or how to implement the dark mode. And this is I assume that little
|
|
1:01:55
|
|
green dot is your curs is your mouse cursor. Yes. Yes, that's mouse
|
|
1:02:01
|
|
cursor. Where is the dark mode? I'm looking for a comment that looks like
|
|
1:02:06
|
|
Oh, there it is. Dark mode. There we go. So, it's not exposed yet, but I just
|
|
1:02:13
|
|
enabled dark mode. So I'm going to open graphics conference talks like the
|
|
1:02:20
|
|
um you know and if I close dark modes it looks
|
|
1:02:26
|
|
like this for instance like a lot brighter you know versus
|
|
1:02:34
|
|
um versus with the dark mode. So the way that this dark loop
|
|
1:02:42
|
|
works is um I've defined like I have this
|
|
1:02:47
|
|
floating um point constant here you know 32 bits but I have 24 bits currently so I have
|
|
1:02:54
|
|
to encoded with two items on the stack you know I swap and shift by eight and or oh I was gonna clarify so for for
|
|
1:03:03
|
|
compiled numbers you're you're you're just using the one the one 24bit the
|
|
1:03:08
|
|
cell with 24 bits of of Yes. Yes. Yes. That means also 24bit floats which has
|
|
1:03:15
|
|
precision issues unfortunately but you know whatever it's fine it's um
|
|
1:03:23
|
|
so yeah I I I sample from four planes like y u vi and um you know I had
|
|
1:03:31
|
|
defined samplers here um as like zero sampler into sampler Y and one sampler
|
|
1:03:37
|
|
into sampler U and sampler V and you The sampler at requires a sampler ID you
|
|
1:03:45
|
|
know. So uh because you know you have to like like the sampler handler rather. So
|
|
1:03:52
|
|
you have to set that and the results like that samples from that
|
|
1:03:59
|
|
um like Y plane right the luma plane and the UV chroma planes uh separately. And
|
|
1:04:08
|
|
if the chroma is like I mean sorry if the luma is
|
|
1:04:13
|
|
um beyond some threshold. Oh wait hold on there it is.
|
|
1:04:21
|
|
I'm looking like where wait that that's not that code. So if the luma is beyond
|
|
1:04:27
|
|
some threshold if the luma is greater than 0.6 six um which you had to assign as like
|
|
1:04:36
|
|
condition. You know in this language before you call ifs you had to assign the conditionals to this condition
|
|
1:04:43
|
|
variable. Um you know instead of if you could also call if else but you have to
|
|
1:04:49
|
|
pass like two lambdas. Oh okay. So your your your conditional is taking a taking
|
|
1:04:54
|
|
lambda's the thing to conditionally. I see. Yes. And the condition is this
|
|
1:05:00
|
|
variable here that I read into the condition you know and the the the the
|
|
1:05:06
|
|
like GT question for example like that's what can you explain what that's taking where is it where is it doing the
|
|
1:05:12
|
|
comparison between and where is it putting its result. Oh yeah. So um the
|
|
1:05:18
|
|
same syntax that we used before like the dot syntax I'm reading from the luma
|
|
1:05:23
|
|
variable luma dot and then 0.599 f. So in this language you have to
|
|
1:05:30
|
|
define your floats. So um f does that and then if luma is greater than 0.6 six
|
|
1:05:39
|
|
that generates like this variable you know uh 26E uh that's say uh ID uh and
|
|
1:05:47
|
|
that's the condition variable and then you know
|
|
1:05:53
|
|
um if if that condition is true this this code gets run which is like inverse
|
|
1:05:58
|
|
the luma essentially and sorry the the the red the red is
|
|
1:06:06
|
|
reading from the condition variable and then putting it in rx or dx depending on
|
|
1:06:11
|
|
the oh the red is re the red is uh storing into the condition variable
|
|
1:06:18
|
|
sorry storing into I see and then I see and then if you consumes that yes yes
|
|
1:06:23
|
|
yes it consumes the result of the greater than which is like uh generates
|
|
1:06:28
|
|
like a spare result and all of that is defined as like you know this is just um
|
|
1:06:35
|
|
a binary instruction All right. And I read into source and destination, you
|
|
1:06:40
|
|
know, always two stuff like two items on top of stack. And um if I need more than
|
|
1:06:47
|
|
that then like condition for example that's fine you know or maybe sampler ID
|
|
1:06:53
|
|
that's that's like uh that's actually better because like um you can like
|
|
1:07:02
|
|
define this condition programmatically at compile time if you care to without
|
|
1:07:07
|
|
having to pass it on stack even right like
|
|
1:07:12
|
|
um I the restriction of two stack items is
|
|
1:07:19
|
|
definitely worth it. Um in the worst case you just read in I mean you just
|
|
1:07:24
|
|
write it into another variable and read it when you have
|
|
1:07:30
|
|
to which makes also the code a lot more readable. So
|
|
1:07:35
|
|
um so yeah that's like you know a bit about how you can also program shaders
|
|
1:07:42
|
|
in this and you know and and and sorry you didn't quite maybe I didn't quite
|
|
1:07:48
|
|
follow so you're you're targeting Vulcan um how are you how are you actually getting getting into the formats that
|
|
1:07:54
|
|
Vulcan uses and like yeah um the formats that Vulcan
|
|
1:08:01
|
|
uses as like like are You are you using a um what what kind of
|
|
1:08:08
|
|
a you're you're compiling to to one of the Vulcan shading languages or what's the what's the problem? Oh yeah, this is
|
|
1:08:15
|
|
compiling directly into spare. So um okay so you're generating raw spir uh
|
|
1:08:22
|
|
bits. Got it. Yes. Otherwise I would depend on another tool the gllang
|
|
1:08:28
|
|
compiler which is huge. I mean that's like at least 100 megabytes. I think a
|
|
1:08:34
|
|
lot more than that now with all the debug symbols and so on and all of that is unnecessary. The rules are so big
|
|
1:08:40
|
|
now. Yeah. I mean in in C only like even though you
|
|
1:08:50
|
|
have all those headers and like for you know all those struck
|
|
1:08:56
|
|
definitions all all that convenience stuff that you have in C. It was like um
|
|
1:09:03
|
|
I think 150 kilobytes of C code for a much more early prototype version of
|
|
1:09:09
|
|
this idea. And um this is now around 200 256 kilobytes
|
|
1:09:16
|
|
of code including the shader stuff like all that font definition shaders the
|
|
1:09:22
|
|
ffmpeg vulcan uh initialization the UI and you know um
|
|
1:09:30
|
|
the interaction the folder iteration stuff etc like you know a lot of stuff
|
|
1:09:36
|
|
actually in 200 kilobytes I mean the expressivity of fort is insane at
|
|
1:09:44
|
|
compile time. It's it's a lot better than like you know um the restraints of
|
|
1:09:50
|
|
like runtime for it right which is like I mean it has to pass through the stack
|
|
1:09:55
|
|
and like question is like h how how can it run on the GPU right there is like um
|
|
1:10:02
|
|
a lot of like expressivity loss just because we want to pass through a stack but that information passing um I mean
|
|
1:10:10
|
|
you could also achieve that through like global variables Um and with that it
|
|
1:10:16
|
|
becomes much more simpler, faster and it also becomes you know more um how to say
|
|
1:10:26
|
|
I forgot it's it's easily it's it's much
|
|
1:10:32
|
|
more easily debugable because like um the state is just laid bare you know
|
|
1:10:37
|
|
that's that's just like um global state that's not like um you know you're not
|
|
1:10:43
|
|
try to uh juggle like local state space at all. So it becomes a lot more
|
|
1:10:50
|
|
manageable compared to like you know all the other languages. So um I don't know what else
|
|
1:10:58
|
|
can I say actually um the fort stuff for instance for uh sorry the welcome stuff
|
|
1:11:05
|
|
is like um Vulcan is walcon usage is mostly like
|
|
1:11:10
|
|
filling uh forms right so if I if I look at some walcon stuff
|
|
1:11:17
|
|
um like okay for instance I'm creating like images for each um for like 420 20
|
|
1:11:25
|
|
YUV 420 format.
|
|
1:11:30
|
|
Nice. So, um the way that I generate this is like
|
|
1:11:37
|
|
14 info which is like um which fills the information structure. I mean it selects
|
|
1:11:44
|
|
it and then fills the information structure with the type and then what's a dollar what's a dollar sign?
|
|
1:11:51
|
|
Um the dollar sign that's just a variable. Okay. Yeah, it's it's all it's
|
|
1:11:57
|
|
all cells here, you know. If it's not a string or if it's not in number, then it
|
|
1:12:02
|
|
has to be like a cell and the tag is like, you know, if it's red, then it's
|
|
1:12:08
|
|
um it's reading into that uh you know, whatever it is. There there's no single
|
|
1:12:16
|
|
like end all definition for anything any of this. You know, it's not going to complain like, oh, this was a definition
|
|
1:12:22
|
|
before. You can't read it. No, I just I just wasn't quite following like in in this context though, you're so you're
|
|
1:12:27
|
|
you're um writing into it. Why are you writing into it at at you're defining these and
|
|
1:12:35
|
|
then you're read and then you're reading out of it one like on that lock lock inc
|
|
1:12:40
|
|
one? Oh, sure. Yeah. So, let's see. Let's read this code. Uh I was up up at
|
|
1:12:46
|
|
the top of the block on Yes. Yes. So uh if I press enter we can
|
|
1:12:52
|
|
see like okay it's reading zero mostly and then dollar is like whatever information ID it's it is you know
|
|
1:12:59
|
|
because in walcon you have these okay hold on you have these um
|
|
1:13:05
|
|
w say so can create info for instance or
|
|
1:13:14
|
|
or create info oh wait types populating one of the
|
|
1:13:21
|
|
structures that they use and then yes so 14 would be image create info right so
|
|
1:13:27
|
|
instead of having to type all of that like we can I I you don't have to import
|
|
1:13:32
|
|
that it's just an ID right um I mean this these kind of binary interfaces
|
|
1:13:39
|
|
simplify a lot versus like having to you know if if this was like a string based
|
|
1:13:46
|
|
interface like open XR that would be awful, right? Could be worse. Could be goods or something, but
|
|
1:13:53
|
|
yeah. I mean, uh, in Vulcan, you had to always do this shenanigan where you you
|
|
1:13:59
|
|
go like we image create info info equals and then you
|
|
1:14:07
|
|
copy this structure type, you know, and then zero. You had to do this for every
|
|
1:14:13
|
|
single time versus uh I can just say if in zero for first information or if one
|
|
1:14:22
|
|
for the second one. Mhm. Or if because sometimes you need more than one information structures that are
|
|
1:14:28
|
|
referring to each other and they're like 256 bytes apart and you know they're
|
|
1:14:35
|
|
just a bunch of words. And the last one is info which is like okay if you want any kind of info like you know any kind
|
|
1:14:42
|
|
of offset for this like structure that I defined here as like 8 kilobytes you
|
|
1:14:48
|
|
know that's all this is like 8 kilobytes of globally accessible data from anywhere essentially and um what I'm
|
|
1:14:56
|
|
saying is like okay let's get the in info ID which is mostly zero right so
|
|
1:15:02
|
|
and then add that to that address and then load that load that to uh RDI which
|
|
1:15:09
|
|
generates this Leah RDI bit here you know and then it writes some index which
|
|
1:15:18
|
|
is like in this in this case it's 3B 9A cde 9 you know uh which is like the type
|
|
1:15:26
|
|
information what is that 3B 9B
|
|
1:15:31
|
|
9 wait what that's weird
|
|
1:15:37
|
|
Oh, that's that's interesting actually. What am I even writing here?
|
|
1:15:47
|
|
Okay, you're searching in the header for is it is it is it in decimal instead or
|
|
1:15:52
|
|
maybe it's in another header. It's but it should be there. Oh, sorry. Did we
|
|
1:15:58
|
|
lose? Okay, we lose the screen. Okay. So,
|
|
1:16:04
|
|
um, info. So, so actually I when I was asking about the dollar sign, I was actually looking up. Can you go back to
|
|
1:16:11
|
|
block 50? I think it was block 54 there with the
|
|
1:16:17
|
|
There we go. Yeah. So, up at the very top that lock inc bang uh word. What
|
|
1:16:23
|
|
What's going on with the the red dollar sign and the green? Like why why are you you're reading you're you're writing
|
|
1:16:28
|
|
into dollars from the and then oh I mean yeah it doesn't have to be it could be
|
|
1:16:34
|
|
just this oh okay yeah I see okay
|
|
1:16:40
|
|
yeah I was surprised that you needed that seemed like an unnecessary step that was why I was yeah yeah yeah totally totally um and
|
|
1:16:48
|
|
just like like it seems like you've got a convention like convention for how you're using dollar sign in several of
|
|
1:16:53
|
|
these words is that maybe I'm not getting the the idiom. It's just a temporary variable that I really don't
|
|
1:16:59
|
|
care about, you know. Got it. You're good.
|
|
1:17:04
|
|
Temporary just just for temporary contextes. And um you know, sometimes that causes troubles too like that
|
|
1:17:11
|
|
happened. If you call like two of those words that are like using those variables at the same time, then you
|
|
1:17:18
|
|
know it's it could be trouble. But you know, you just define another one. There's there's so many of them like
|
|
1:17:24
|
|
those Yeah. And it it really doesn't matter like you can they're essentially free. I mean um if if you were to be
|
|
1:17:31
|
|
like um it it doesn't cost anything at runtime. So you can have as many
|
|
1:17:38
|
|
variables as you need it. Um and this is also interesting. So this is compile
|
|
1:17:46
|
|
like this is defining memory for runtime but all that memory is global
|
|
1:17:52
|
|
memory. So uh I dedicate a single register to be able to access all memory
|
|
1:17:57
|
|
of the program that are stored in this single register which gives you like
|
|
1:18:03
|
|
gigabytes of state which is huge. I mean you shouldn't have to need like
|
|
1:18:08
|
|
gigabytes of space actually. Um or you could uh allocate like you know virtual
|
|
1:18:14
|
|
memory if you needed to um instead of like using this global
|
|
1:18:20
|
|
space which is anti antithetical to all conventional programming wisdom which
|
|
1:18:26
|
|
says like don't use globals I mean you know as if like if if if you're like
|
|
1:18:34
|
|
accessing them in a responsible manner like I can just say like okay where am I using upload buffers for instance
|
|
1:18:41
|
|
And suddenly it's not that like scary, you know, because like I know exactly
|
|
1:18:46
|
|
where I'm using those. And um it's not like I mean I I'm very
|
|
1:18:53
|
|
critical of Rust's memory safe attitude where you have to fill tax forms to be able to access a piece of memory which
|
|
1:19:00
|
|
is just there. Like it's free to access and you don't even have to pass anything on a register to be able to access it.
|
|
1:19:06
|
|
It's just like it's just there and somehow like you know people are like oh
|
|
1:19:13
|
|
that's unsafe you know pass it in a functional context or whatever. So you
|
|
1:19:19
|
|
end up having these like stacks of state you know pass through like 20 30 layers
|
|
1:19:27
|
|
of call stack like the same state over and over again which is insane. So, so
|
|
1:19:32
|
|
for you're you're going to target uh Sphere V like um I haven't looked deeply
|
|
1:19:38
|
|
the how bad is the encoding like is it it it's a fairly simple instruction
|
|
1:19:43
|
|
encoding or what how bad is sphere v? Uh sorry what what is encoding for what
|
|
1:19:50
|
|
exactly? For for you were going to encode sphere v instructions right? Oh
|
|
1:19:55
|
|
yeah. Are are they like I I don't have a good sense. Are they are they hard to encode or is it a fairly straightforward
|
|
1:20:02
|
|
format? I mean uh they're they're kind of hard to encode but not really. I mean
|
|
1:20:08
|
|
you just have to like define it in a um you know you read the spir spec uh which
|
|
1:20:15
|
|
is like spir which looks like
|
|
1:20:21
|
|
this. I'm going to save your eyes. So it it defines the whole thing here you know
|
|
1:20:28
|
|
uh the binary encoding and all the instructions. So um say like how would
|
|
1:20:34
|
|
you encode um an instruction? Let's see bit instructions
|
|
1:20:40
|
|
for example shift right logical right let's
|
|
1:20:45
|
|
see where are where is shift right
|
|
1:20:51
|
|
logical okay there it is so 194 194 not too bad so it's just a it's just a bite
|
|
1:20:58
|
|
code kind of okay yes yes I mean once you have like those words it's just like
|
|
1:21:03
|
|
194 binary I mean I I get I don't know how much header header header and footer and what all you got to wrap around it.
|
|
1:21:09
|
|
But yeah, I mean binary is just this oneliner, right? And vector is just that
|
|
1:21:17
|
|
four lines. I mean it's it's very simple code really like and that vector stuff
|
|
1:21:24
|
|
is for when you have for instance um when you want to shift right four item
|
|
1:21:30
|
|
vectors you know uh by MD vector or by one it like by like uh just a single I
|
|
1:21:40
|
|
mean four component vectors by a single component like float for I mean uh single component integer sorry we can't
|
|
1:21:46
|
|
shift by float of course got it got like like ver. Yeah, I see. Yeah. Yeah. Yeah.
|
|
1:21:52
|
|
And this ve thing is like just that abstraction for that, you know, like reading um like it's just com comparing
|
|
1:21:59
|
|
like destination component count with source component count and if they're not equal like I mean that state gets
|
|
1:22:06
|
|
written to C CX and this if else works on this condition CX, you know, so
|
|
1:22:12
|
|
that's why it's there or like actually that's is is that running even? Oh yeah,
|
|
1:22:17
|
|
it's it's a if false within and if else of course. So yeah, how are how are you um
|
|
1:22:25
|
|
displaying the state when you're on top of a word? Like what how do you how do you have the opportunity to hook that
|
|
1:22:32
|
|
in? Uh sorry, how do you mean you were
|
|
1:22:38
|
|
showing this? you're showing the state of the the stacks of the plate when you're sitting on top of a word like
|
|
1:22:43
|
|
what how do you actually do that injection of the the instrumentation or
|
|
1:22:49
|
|
oh uh well it's the state is just sorting racks and rdx so if you store that in an array you know you you can
|
|
1:22:56
|
|
visualize that um in reverse order and you get this but but I mean how are you
|
|
1:23:03
|
|
you're doing that only when that word is getting executed right like how do you are you modifying how you compiled it to
|
|
1:23:09
|
|
have a moment to update the this update. Oh, right. Right. I forgot. I I've had
|
|
1:23:16
|
|
to look how I implemented it, but I'm probably doing like um yeah, code
|
|
1:23:21
|
|
injection where if the cursor is here, like the active cursor,
|
|
1:23:26
|
|
um do a code injection where you're recording racks and RDX into this global array that's like storing the state of
|
|
1:23:33
|
|
the stack. Okay, that that should be it. But I'd have to read the code now. Okay.
|
|
1:23:39
|
|
Okay. I was just curious if you were if you
|
|
1:23:44
|
|
had some But it's it's all like it's all straight line assembly that's coming out. So you're like you're not actually
|
|
1:23:49
|
|
you must something to get get in there, right? Yeah, it's it's all straightforward assembly. Very
|
|
1:23:55
|
|
straightforward assembly. It's it's just generating the required instructions in JIT which is compiles to a single call
|
|
1:24:03
|
|
for those white words and like you know a return exchange racks RDX for
|
|
1:24:09
|
|
definitions and for these it's just a single jump and for loads it's just a
|
|
1:24:15
|
|
single move uh to racks or RDX or for writes it's again back to the global
|
|
1:24:20
|
|
memory uh a single move um you know it's it's it's all very simple
|
|
1:24:27
|
|
So, how do you um how do you keep how do you keep uh flaws and bugs from entering
|
|
1:24:34
|
|
your codebase? Do you have tests around it or do you have asserts? I mean, what do you do to to try to um Yeah, don't
|
|
1:24:43
|
|
make bugs. That's that's the like um when you have
|
|
1:24:49
|
|
bugs uh what I do is like I um I triage
|
|
1:24:54
|
|
the bug first by okay let's say like I'm triaging why a shader would be crashing
|
|
1:25:01
|
|
you know uh say here so this shader crashes I disabled this and does it still crash uh yes it still crashes okay
|
|
1:25:09
|
|
and then I disable this too does it still crash no okay that must be in in color you know does that make sense? I
|
|
1:25:17
|
|
mean that's uh the fastest way that I can like there's no reliable way to
|
|
1:25:22
|
|
prevent bugs is is like you know my experience you just have to
|
|
1:25:29
|
|
um I mean there there are ways that you can use like um I had memory overflows
|
|
1:25:35
|
|
um you know where I was corrupting memory and or sometimes I passed the wrong stride or wrong number or whatever
|
|
1:25:44
|
|
and it's you learn to discover it at some point. I mean, um, and you fix it.
|
|
1:25:53
|
|
Trying to prevent it is more effort than it's worth in my opinion. And a lot of languages try and fail at that because
|
|
1:26:00
|
|
like at the end of the day, who's going to prevent logic box? You know, there's no compiler that can execute your code
|
|
1:26:07
|
|
for you and tell you like, oh, you know what, that's not what you meant. I mean you just have to
|
|
1:26:12
|
|
um you know write simple code and think simple data transformations to express
|
|
1:26:18
|
|
your uh code and most of the time you'll be fine and if something goes wrong um
|
|
1:26:24
|
|
usually it goes wrong immediately and you know you can just undo and see like okay you know um as as as soon as you
|
|
1:26:31
|
|
can replicate the bug then you just do a triage where you can just undo or you can just uh enable disable stuff uh and
|
|
1:26:39
|
|
you find uh the source like you know fast and sometimes yeah in uh in um
|
|
1:26:48
|
|
sometimes the bugs are like so hard to find it it persists for a while but they're there they're still fixable I
|
|
1:26:55
|
|
mean it just I've had good experiences with uh design by contract which is in
|
|
1:27:01
|
|
the Eiffel language so um you you you document you you
|
|
1:27:09
|
|
basically ally um you do mathematical things with okay what does
|
|
1:27:16
|
|
this code need the preconditions and the postcond conditions and the invariance
|
|
1:27:22
|
|
and then if something's violated it tells you right away and then uh it's it's a way of
|
|
1:27:31
|
|
um injecting integrity into the code that where the code actually sort of
|
|
1:27:36
|
|
fixes itself in many ways So, I've had good experiences with that. And I was just wondering if uh anybody
|
|
1:27:44
|
|
else did that. So, I mean, if you wanted to, you could still do that kind of stuff also in in this style of
|
|
1:27:51
|
|
programming, right? You could just do checks that are like you express with
|
|
1:27:56
|
|
macros. Um, and you can compress that whatever you're going to write with this
|
|
1:28:02
|
|
very efficiently. And, um, if you want to do contracts, sure, go ahead. I mean this is a um metarogramming language
|
|
1:28:09
|
|
that doesn't impose you anything. I mean um you can say like okay you know what
|
|
1:28:16
|
|
these are like I have for instance um say these are my
|
|
1:28:25
|
|
constraints constraints you know um had to like compress that down to nine
|
|
1:28:31
|
|
characters. So um and you can say like okay you know
|
|
1:28:38
|
|
the constraint is um a x should be like this b should be that or like you know
|
|
1:28:44
|
|
should could be like v 0 should be zero and v1 should be always
|
|
1:28:52
|
|
um should be 14 or whatever you know
|
|
1:28:58
|
|
like we should be like whatever less than 64. You know, like if if this
|
|
1:29:06
|
|
was like your constraint space, you you just like
|
|
1:29:11
|
|
um condensed that like constraint that contract stuff that you were talking
|
|
1:29:16
|
|
about into work that you can use where you're like, you know, using those
|
|
1:29:22
|
|
contracts if if you want to. Um for me, I I just Thank you. I just try to not
|
|
1:29:29
|
|
make that many um you know errors instead like and try to maintain the
|
|
1:29:35
|
|
state consistent uh all the time instead of like relying on like you know checks
|
|
1:29:41
|
|
everywhere like because relying on checks is like you know it's it's kind
|
|
1:29:46
|
|
of like uh safe programming um but yeah I mean I I really like L safe
|
|
1:29:52
|
|
programming rather than safe programming. I I had a question about the um the
|
|
1:29:59
|
|
dictionary visualizer on the left. Um you you said that the the capacity you've got is for eight eight characters
|
|
1:30:05
|
|
in the current system. I'm curious why you only show the six the six characters. Is that just a space
|
|
1:30:10
|
|
constraint or Yeah, space constraint like uh nine it's actually nine characters and nine characters by seven
|
|
1:30:18
|
|
bit and there Yeah. And there are uh other like encodings also that I've um
|
|
1:30:26
|
|
come up with that that's not present in this language which is um say 16 bit
|
|
1:30:34
|
|
plus 16 bit plus 16 bit plus 15 bit. So that's like that gives you 64k words and
|
|
1:30:42
|
|
you can concatenate up to four of them together in just 64 bits like um that's should be a much
|
|
1:30:49
|
|
more efficient and much more expressive. Um and the thing is you can also since
|
|
1:30:57
|
|
you have defined all words from concatenation of four words that opens
|
|
1:31:02
|
|
up the possibility of doing say like voice recognition in the editor. So you can just bring the words on the screen
|
|
1:31:09
|
|
and say like oh I want say um instead of having to like say sampler
|
|
1:31:17
|
|
ID for instance and then I don't have to go to sampler ID it just selects it and which becomes important because it's not
|
|
1:31:24
|
|
going to be um keyboard only or desktop only and also I I also want to port this
|
|
1:31:30
|
|
to um phones tablets steam deck likes you know hand handhelds
|
|
1:31:36
|
|
um VR headsets everywhere and um even watches or like smart glasses or
|
|
1:31:43
|
|
whatever like um you know and it is portable to everywhere I think um just
|
|
1:31:49
|
|
the UX changes but the codes and the whole idea remains simple for all kinds
|
|
1:31:55
|
|
of environments is um I I'm also curious how how often do you end up using the
|
|
1:32:01
|
|
facility to to uh rename uh to rename name words as you refactor things. Oh,
|
|
1:32:09
|
|
renaming, right? Yeah. So, um for instance, non ouiji is like nonwork
|
|
1:32:16
|
|
groups, but it's like, you know, non work G, let's say. It's just as simple
|
|
1:32:22
|
|
as that. I'm curious how often you find yourself using that. I It's a new facility. Like,
|
|
1:32:29
|
|
is it Right. Right. Sometimes, I mean, sometimes I come up with a better um
|
|
1:32:35
|
|
like better name. You know, naming is hard and you can say like, "Okay, you
|
|
1:32:40
|
|
know, I'm just going to name this temporarily and then come up with a better name later." But yeah, it doesn't
|
|
1:32:45
|
|
happen that often. You're right. Well, yeah. I was I was curious because it it seems like a neat facility that Yeah. I
|
|
1:32:52
|
|
I guess you on the other hand, like once you're used to a name, you're used to a name. Cool. Yeah. Yeah. It's that's the
|
|
1:32:58
|
|
thing. I mean um it has downsides to compare to text. I mean text would be contextual right? So you can just type
|
|
1:33:05
|
|
anywhere. So um and with this you had to bring up like the dictionary that you
|
|
1:33:12
|
|
want because like otherwise it's a huge search space that you have to search through like at scale right if you build
|
|
1:33:19
|
|
like more and more complex software with this. I mean um you're going to need more dictionary space or maybe not even
|
|
1:33:26
|
|
that. I mean, all of this is like how many words? It's not even that many
|
|
1:33:31
|
|
words. I mean, I noticed you very carefully kind of curated the layout of it. How much do you find yourself
|
|
1:33:37
|
|
fussing fussing with that? That's actually It's kind of interesting stylistically, though, to be that
|
|
1:33:43
|
|
they're laid out in in an ordered way. Oh, yeah. Yeah, that was intentional.
|
|
1:33:49
|
|
Um, so 16 per scroll, 16 words per scroll, which is like this. And
|
|
1:33:56
|
|
um so thing is I I I I'm not really sure about any of this.
|
|
1:34:04
|
|
So this is uh where it's it's like you know more open to um imagination,
|
|
1:34:10
|
|
reimagination perhaps. And um the way that I like the way that I
|
|
1:34:17
|
|
organize those scrolls is like I have tags per scroll. So this is like packs
|
|
1:34:24
|
|
and to-do and I can just go around and say like what are XAs words which are
|
|
1:34:30
|
|
like uh the x64 assembly and these are X assembly API words for instance right
|
|
1:34:37
|
|
and what are like the free rewards are here for instance like this uh yeah it's
|
|
1:34:45
|
|
surprisingly organized like I I I think when I've thought of using indexes before I've always feared that it if I
|
|
1:34:51
|
|
just sort of randomly dump dump them in in the order I created things that would be disorganized, but this idea of
|
|
1:34:56
|
|
placing them explicitly is is pretty cool. That's that's really neat idea. Oh, thanks. Yeah, I mean, um,
|
|
1:35:03
|
|
organization with indexing is like, you know, the the hard part. I I thought a
|
|
1:35:09
|
|
lot about this problem. Uh, it's it's it's I was thinking about 64 verse
|
|
1:35:14
|
|
scrolls and maybe I will go back to 64 scrolls. I mean, it gets a lot of like
|
|
1:35:22
|
|
Maybe this was too granular. I I don't know. All all of this is like open to
|
|
1:35:28
|
|
you know re reimagination basically by anyone. Uh because the language doesn't
|
|
1:35:33
|
|
depend on it. The specific editor does right. So you can have as many editors
|
|
1:35:39
|
|
as you want and code interrupt without having to explicitly say like okay you
|
|
1:35:44
|
|
know uh this has to be that and that. If you're like mixing source, I mean, uh,
|
|
1:35:50
|
|
they can interrupt at the source level, but not at the editor level. But that's fine. I mean, you know,
|
|
1:35:56
|
|
um, I I think, um, this language can
|
|
1:36:01
|
|
host any kind of like language um because it offers u pure assembly
|
|
1:36:08
|
|
execution, right? there's no um blocks there that you have to like go through
|
|
1:36:14
|
|
or that I have to define uh so that you can do whatever you want if you can
|
|
1:36:20
|
|
express that logic in assembly then which is like you know which you compile through this macro assembly right uh so
|
|
1:36:26
|
|
it's not like you know pure like hardcore assembly that we're used to it's much more uh approachable and
|
|
1:36:35
|
|
um yeah what was I saying I I forgot That's where I was going with this. I I
|
|
1:36:41
|
|
I think I I asked a question. I I had a different question. I'm curious how you bootstrapped the system.
|
|
1:36:47
|
|
All right. Um bootstrap the system. I mean, it used to be this and then um
|
|
1:36:57
|
|
from that system I I mean it still uses C unfortunately, but the next version is
|
|
1:37:03
|
|
going to be standalone and entirely self uh Bootstrap. So um this is this
|
|
1:37:09
|
|
compiles into assembly um and I host that in a C project to uh
|
|
1:37:18
|
|
make this editor which compiles uh you know web and all the other stuff and uh
|
|
1:37:26
|
|
the next version is going to be also programmed in this and like it's we're going to program
|
|
1:37:32
|
|
program it live basically uh all of it so that um you know it can
|
|
1:37:39
|
|
a something that can be like passed on from generation to generation, you know,
|
|
1:37:44
|
|
like as foundational bootstrapping knowledge like okay, you know, this is how you can build this uh editor uh if
|
|
1:37:51
|
|
you had to. It's it's so simple. Um and language is much simpler than the editor
|
|
1:37:57
|
|
of course like all the complexity is just just editor. Uh and you know um other
|
|
1:38:05
|
|
than that like um yeah the the font
|
|
1:38:10
|
|
rendering but you can also have the editor stand alone which means like if
|
|
1:38:16
|
|
you want to embed the editor to say into a game you can have the game have its own
|
|
1:38:23
|
|
text rendering and just expose the editor and its interaction and so on. So
|
|
1:38:28
|
|
yeah, I mean I expect a ton of editors for this programming language for sure. Like
|
|
1:38:34
|
|
hopefully I mean if people find it
|
|
1:38:39
|
|
interesting. So what else I can say like about so what have you built games or or
|
|
1:38:46
|
|
like what what are the things that you build with this? So I built before vamp I built um this
|
|
1:38:55
|
|
going to go back and wait did I open the tab there? No sorry. So I built those u
|
|
1:39:04
|
|
biological um stuff um that's going to ship also in web. So
|
|
1:39:13
|
|
um this was also done in the previous iteration. So which looks like this.
|
|
1:39:28
|
|
Okay, hold on. All
|
|
1:39:35
|
|
right. Okay. So, yeah,
|
|
1:39:41
|
|
it's it's like this galaxy like structure that expands. Um, it's it's
|
|
1:39:48
|
|
just a shader. Um, unfortunately, it's it's running a bit slow because I'm trying to stream it
|
|
1:39:54
|
|
at the same time. So, sorry about that. Maybe I can open
|
|
1:40:00
|
|
up. And other than other than that, the editor itself like this. So, this was
|
|
1:40:05
|
|
the previous version. And you can see like I don't know if you can read the text, but I was still opening and
|
|
1:40:12
|
|
closing definitions back then. So, there's that. And if I change this to something much
|
|
1:40:22
|
|
more dynamic so that we don't have to wait so much. Oh, okay. Let's
|
|
1:40:30
|
|
this. So, yeah. Is that
|
|
1:40:39
|
|
Yeah. So, you can use this philosophy for any kind of like coding I think.
|
|
1:40:46
|
|
Um it's like what you can do with this is boundless. You just think about
|
|
1:40:52
|
|
what's the code that I want to generate and what's the logic that's required to
|
|
1:40:57
|
|
generate that code. You know that's that's all that's required. That's all this is. Uh all the rest is just
|
|
1:41:04
|
|
implementation details. I mean you could still have a stack larger than two. it's
|
|
1:41:09
|
|
going to run slower because you have to manage all that stack back and forth all
|
|
1:41:14
|
|
the time versus you could have it in global memory which works a lot better in my opinion.
|
|
1:41:22
|
|
um like just do exact opposite of programming knowledge and you know
|
|
1:41:30
|
|
um you you'll do fine basically like uh
|
|
1:41:35
|
|
don't do locals or don't do like I mean you can still do locals if you had to
|
|
1:41:40
|
|
but um yeah I just like passing stuff globally instead of
|
|
1:41:47
|
|
um having to red like reaccess the in context locally all the time and you
|
|
1:41:55
|
|
know programming assembly gives you a lot of uh freedom. So compared to like
|
|
1:42:03
|
|
um so that's that's like the new stuff and that's the older stuff
|
|
1:42:09
|
|
basically. So um assembly is essentially much more
|
|
1:42:16
|
|
free form than uh dealing with compilers. So, Spurby is dealing with
|
|
1:42:21
|
|
compilers, right? So, I had to be explicit about everything. I had to read stuff into variables and I had to um you
|
|
1:42:30
|
|
know, if I had to use a result, there is no implicit place I can go for that
|
|
1:42:36
|
|
result versus an assembly um all the registers are passed all the time. So,
|
|
1:42:42
|
|
you don't have to pass stuff on the stack. it's implicitly passed for you by
|
|
1:42:47
|
|
the processor for free. Right? So, um that's the major difference between a
|
|
1:42:53
|
|
server and compiler. Like apart from the whole complexity difference,
|
|
1:42:59
|
|
um there's also a lot of implicitness uh intrinsic to the assembly language
|
|
1:43:06
|
|
for you know I mean I target x64 you could target another architecture.
|
|
1:43:12
|
|
Ultimately, it depends on where you're going to run this code. Like I highly doubt that I'm going to run the same
|
|
1:43:18
|
|
code on a like a Commodore 64 on a 6502 or like you know um but if I had to I
|
|
1:43:26
|
|
could totally emulate it you know um it's just like going to be slower than
|
|
1:43:33
|
|
having like programming directly to the specific architecture. Um but you know
|
|
1:43:40
|
|
you can do binary retargeting or in this case execution retargeting because you
|
|
1:43:46
|
|
haven't produced the binary yet. you're like you can execute logic before you produce the binary uh instead of like
|
|
1:43:53
|
|
having to translate back from you know binary and um so yeah there is that
|
|
1:44:00
|
|
implicitness about assembly and um it makes stuff a lot less code than uh if
|
|
1:44:08
|
|
you had to write everything with a compiler where you had to pass all all
|
|
1:44:13
|
|
the values explicitly instead of like in assembly
|
|
1:44:18
|
|
I can just say cursor at b and then bx greater than oh I know that I read bx
|
|
1:44:24
|
|
here I don't I didn't have to pass it you know I didn't have to define like a new variable it's just bx I mean and
|
|
1:44:32
|
|
that generates like just a compare and a jump um it's all super efficient
|
|
1:44:40
|
|
um yeah I mean let me look at my notes to see if if we miss something uh I
|
|
1:44:47
|
|
think we got to the most important stuff. Anyway, do we have questions, comments? You know,
|
|
1:44:56
|
|
it's it it's a really neat system. I a lot of cool ideas, a lot of uh stuff
|
|
1:45:01
|
|
that it's very thoughtprovoking. Thank you. Thank you. Oh, I just thought
|
|
1:45:07
|
|
something that we didn't get to was conditionals, right? How do conditionals with the block like basic block? I love
|
|
1:45:14
|
|
the look of it. It's uh it's a really cool system and I like how responsive it is. Thank you. I mean
|
|
1:45:23
|
|
um it's I I didn't actual motivation was
|
|
1:45:29
|
|
I I wanted like a system that looked super cool when I was um you know dropping acid
|
|
1:45:37
|
|
basically. I mean um like it had to be simple enough. It had to be like, you
|
|
1:45:43
|
|
know, um it had to also look cool. And this is
|
|
1:45:48
|
|
going to look even cooler than this. I mean, this is um like the the font
|
|
1:45:55
|
|
here. It looks like, you know, you can get many different
|
|
1:46:00
|
|
looks. This style of like, you know, font design or my favorite look is like
|
|
1:46:07
|
|
this. There you go. Yeah, kind of
|
|
1:46:17
|
|
like and um okay, how do we do
|
|
1:46:23
|
|
conditionals? So um the conditionals work within basic
|
|
1:46:29
|
|
blocks and um so you can open up a basic block and
|
|
1:46:35
|
|
it will constrain the um it will constrain the assembly output
|
|
1:46:41
|
|
to that basic block. So for instance here I'm loading the temporary address
|
|
1:46:46
|
|
which is just this top me layout to rax and then I'm reading that into R11. Um,
|
|
1:46:56
|
|
and if if I didn't have this, then the assembly output would get like very
|
|
1:47:03
|
|
um I mean the like it's it's it's nice you know because you can see within a
|
|
1:47:09
|
|
single basic block what's what's the generate assembly for this basic block right and
|
|
1:47:15
|
|
um within a basic block as soon as you do a conditional if that conditional
|
|
1:47:22
|
|
passes then the block continues, you know. So, um let's
|
|
1:47:28
|
|
see. For instance, if okay, let's let's find a conditional.
|
|
1:47:35
|
|
It's like
|
|
1:47:45
|
|
okay. Okay. Yeah. Let's let's go back here. So if the packet is not zero then
|
|
1:47:52
|
|
I free that packet you know if if there was like more conditionals after this
|
|
1:47:58
|
|
um you know I I I see that if it if it's
|
|
1:48:03
|
|
not if the focus video is not zero then I execute this rest of the code until I
|
|
1:48:11
|
|
encounter this here which is the link you know which is the else part. So
|
|
1:48:17
|
|
instead of else's I have these uh you know links here that are like all across
|
|
1:48:23
|
|
the code actually um that can be also used for se calls
|
|
1:48:28
|
|
can be used for conditionals uh they can be overridden um you know hold on I'm going
|
|
1:48:35
|
|
to try to find like a conditional most of the time it's used for C calls which
|
|
1:48:41
|
|
is which confuses right now but yeah so right Here for example I'm I'm saying
|
|
1:48:48
|
|
like if I'm full screen I'm not going to do anything and if I'm not full screen I'm going to call this function called
|
|
1:48:54
|
|
UI tally and then I'm going to call setup which sets the slot ID to zero and
|
|
1:49:00
|
|
then slot live count to zero and then it iterates through all the slots and then
|
|
1:49:06
|
|
it does a check you know and the check is like if this is live you know if this
|
|
1:49:11
|
|
slot is live uh you increment the slots live count by one and
|
|
1:49:18
|
|
then if this slot is a leaf you know so you keep filtering. So if this is live
|
|
1:49:24
|
|
then it's it's passed this filter you know and then you check for leaf and you
|
|
1:49:31
|
|
know uh if that if it's also leaf then I check uh I decode the balance you know I
|
|
1:49:38
|
|
I get the balance of the slot and then I decode it which um you know reads it
|
|
1:49:43
|
|
into local variables and then um and then I do a hot check which is like
|
|
1:49:50
|
|
doing like a mouse check for between the mouse and the slots bounce you know and
|
|
1:49:57
|
|
um if if it's hot then the hot slot index is the slot ID which I passed
|
|
1:50:04
|
|
implicitly by the way this is R12D you know it's R12 passed implicitly I didn't
|
|
1:50:11
|
|
have to define the slot index for this function um it's it's just there it's global and
|
|
1:50:18
|
|
this hot slot is also global so Um you don't have to define these you know
|
|
1:50:26
|
|
arguments all the time. You can just you know um use stuff anywhere use memory any
|
|
1:50:33
|
|
memory anywhere basically. And so yeah I set the hot slot and then I get the video of the
|
|
1:50:39
|
|
slot and then I set it as a hot bit and then I return one in a or zero if if it
|
|
1:50:47
|
|
was not hot you know. So yeah, it it basically checks
|
|
1:50:53
|
|
all the slots if I'm not full screen and so I can get the hot slot index which
|
|
1:50:58
|
|
gives me like what my mouse is hovering, right? So I can do stuff with it. But I
|
|
1:51:04
|
|
I don't have to pass that like everywhere in code, you know, all the time. It's it's it's just free. I mean
|
|
1:51:12
|
|
um it's it's a lot faster and simpler to pass it globally unlike you know what
|
|
1:51:19
|
|
everybody else does um you know C rust um
|
|
1:51:25
|
|
yeah so yeah that's that's uh basically how I do conditionals
|
|
1:51:32
|
|
um and how I pass state around I mean like using uh state everywhere I can um
|
|
1:51:40
|
|
you know and yes you had to care about lifetimes. If you modify the same states
|
|
1:51:46
|
|
from like multiple threads, you're going to have troubles, especially on like
|
|
1:51:51
|
|
platforms where you have to synchronize that access. But you know, I I care
|
|
1:51:56
|
|
about lifetimes. I'm just accessing this data from a single thread. there cannot be like a um race condition because like
|
|
1:52:05
|
|
I'm not writing it from two threads like reads from multiple threads is fine but
|
|
1:52:12
|
|
as soon as it's right from multiple threads then you have to use like um locks and you know stuff like that um
|
|
1:52:21
|
|
you know locks as in just this keyword called lock I
|
|
1:52:28
|
|
mean wait what where's lock. Oh, I'm I'm looking at I still have the square. Um
|
|
1:52:35
|
|
yeah, so lock is just a single um bite on x64 and you can use it on a bunch of
|
|
1:52:42
|
|
instructions including bit test reset. So if you have to set or reset like a single bit from multiple uh threads then
|
|
1:52:50
|
|
yeah that's totally possible. Um I mean in C you would have to like
|
|
1:52:58
|
|
ask the compiler specifically to generate it or use like intrinsics.
|
|
1:53:03
|
|
Um, yeah. I like I like being able to just say like Oh, not this. Sorry. I
|
|
1:53:09
|
|
like being able to just say like lock just being able to append like you know
|
|
1:53:14
|
|
if if I append this then it becomes a lock lock ad you
|
|
1:53:20
|
|
know if I don't call that then it's just a single ad.
|
|
1:53:29
|
|
So yeah, it's it's very powerful, but you're responsible for all the code
|
|
1:53:36
|
|
generated. Um, you know, you can still use compilers like uh like in spare. Um,
|
|
1:53:43
|
|
but yeah, I I prefer to use assembly because I like the full control and the freedom that assembly gives instead of
|
|
1:53:49
|
|
like compilers and explicit parameter passing. So yeah, that was a lot of
|
|
1:53:57
|
|
stuff. Let me check my notes if we missed anything. Um, I have like I have like a word here
|
|
1:54:05
|
|
called stack fetishism which we didn't get to like I
|
|
1:54:12
|
|
I just don't use any stack juggling words except for swap which you need. Right. So you're you're releasing it
|
|
1:54:19
|
|
tomorrow. Is that what you said? Um, not tomorrow. Um, I'm gonna start a
|
|
1:54:27
|
|
live stream where we build live on live stream and then we're going to release it after we're building we're building
|
|
1:54:34
|
|
it on live stream, you know, because it's it's not uh like I just need one
|
|
1:54:40
|
|
last iteration, but I can I can u maybe release it earlier than like it's it's
|
|
1:54:48
|
|
going to take one month I think to recode this uh live. Maybe a lot less
|
|
1:54:54
|
|
than that. I don't know. We'll we'll see. Not too
|
|
1:55:02
|
|
long. And the application itself is Yeah, right now I'm waiting for Steam to
|
|
1:55:08
|
|
review it. Um but yeah, um the thing
|
|
1:55:14
|
|
is there are like when I like this is not the final
|
|
1:55:20
|
|
form also. This is the 24-bit version. Uh but it's going to be 32 bits plus uh
|
|
1:55:27
|
|
8 bits for tags and you know um stuff. Um,
|
|
1:55:33
|
|
so yeah, there there you know it it wasn't the final form like this this was
|
|
1:55:41
|
|
I knew that I this wouldn't be the final form and like because this was my first
|
|
1:55:46
|
|
binary attempt um before this I had like two other text fors and this this was
|
|
1:55:53
|
|
the first like binary form and I thought 24 bits would be enough but you know uh
|
|
1:55:59
|
|
in the end it's slower. than using 32 bits. Um, and the reason
|
|
1:56:06
|
|
for that is if you have tags together side by side like compact on an array,
|
|
1:56:13
|
|
single bite tags, um, then you get fast skips, you know, so empty blocks you can
|
|
1:56:20
|
|
skip super fast by just reading eight eight tags at a time and check for a zero. Like read eight bytes and check
|
|
1:56:27
|
|
for a zero and if it's zero, then you can skip it. There are no instructions there versus you had to read 32 bytes
|
|
1:56:33
|
|
and do like eight compares to see at least if this was like a um yeah comment
|
|
1:56:39
|
|
or not, you know, basically because tag zero is essentially comments. Yeah.
|
|
1:56:49
|
|
Cool. Well, that that was really awesome. Um thank you. All right. Um
|
|
1:56:55
|
|
well, I I think that concludes our our meeting. I I'm going to hit the stop button on the recording and uh see you
|
|
1:57:03
|
|
all next month.
|