Hello and welcome everyone.
This is the course overview lecture where I just describe what you're going to get from this course
and why it will be useful to you.
So a little about me.
I'm the best selling author in kernel development fields.
Okay, I have the best selling courses for kernel related content, uh, on the internet.
I hold a master's degree in advanced computer science.
I'm director of a programming academy, uh, called Dragons app, where we help teach, uh, people
all around the world, uh, computer programming.
I have over 15 years of programming experience, and I'm the creator of three compilers and one assembler.
So the fact that I've created three compilers, I am definitely the right person to be teaching you
how to create a compiler.
So let's explain the project.
So in this course we're going to create a C compiler that can compile a majority of the C programming
language.
So all major functionality is supported.
So some of the things that our compiler will compile are structures unions.
Every single C statement is included.
So we have for loops if statements else if switch go to while do while and so on.
Uh all bitwise operators are supported.
So bitwise and bitwise xor and so on.
All logical operators are supported okay.
All numerical operators are supported.
So multiply plus minus divide.
All of that is supported in our compiler uh C functions are supported C pointers are supported.
So we have uh structure pointers union pointers primitive pointers uh arrays are supported.
Uh function calls are supported and the macro system and preprocessor are supported.
So we basically support 95% of the language.
so majority of the C programming language can be compiled with our C compiler.
Okay.
So in module one we're going to create a lexer that is responsible for taking a C source file that we
want to compile.
And it converts it into a bunch of tokens.
And then we have those tokens to put through a parser to produce an abstract syntax tree.
So this is what we cover in module one.
Okay.
An abstract syntax tree is essentially this.
Okay.
So we have uh our source input here.
It goes through our compiler.
It gets converted to a bunch of tokens.
Those tokens go through a parser to produce a tree like this.
So we can see after after this simple program has been parsed, our compiler will see a function node
that has a main function name.
It has a body node, which is everything between these brackets.
It has a vector of arguments okay, which are the function arguments, and in our body node we can see
we have a variable node which is equal to a number node okay.
So this is this is what parsing is.
It takes a complicated input and it breaks it down into a tree that we can just follow.
Okay.
A bit like a linked list if you will.
Uh, apart from uh, you can have many different types of nodes.
Okay.
So in module two and three this is where the fun really begins.
We actually start creating programs that work and we can run them okay.
So we create a resolver which is responsible for taking an expression such as this.
For example a dot b dot c pointer axis e equals 50.
And it will essentially break down that expression into a bunch of rules.
So the code generator can follow.
And these rules tell the code generator exactly the type of code it needs to generate, and exactly
what it needs to do to be able to find the address in memory of a dot b dot c pointer x e.
Okay, so the resolve is very important.
It helps break down uh, a difficult problem that our code generator would otherwise have to deal with
itself.
Okay.
So by creating a resolver and this sort of abstraction, we take away the difficulty from the code generator
and move it into a different part of our compiler, which makes it much easier, uh, for us to write
clean code.
So our code generator will take in the abstract syntax tree we created, which I showed you here.
And it will essentially go through there.
And it will generate a bunch of assembly language and stack frames and so on.
Uh, and it will create assembly language output.
Okay.
And then we can take that assembly language output and create an executable binary that we can actually
run.
Now don't worry if you don't know these these terms that I'm talking about.
This is just the course overview.
Every single thing I talk about here will be taught to you okay.
so our code generator will support source files that cover all major functions of the C programming
language.
Okay.
So we'll be able to call printf.
We'll be able to do pretty much everything that C compilers can do already.
So our C compiler pretty much covers the majority of the C programming language.
It'll pretty much be able to compile most files you throw at it.
So our code generator will support source files that cover all major functions of the C programming
language, including the ability to call C standard library functions such as printf.
So in module four, we create a semantic validator that ensures we aren't going to do anything illegal.
Okay, so for example we don't want to set variables that don't exist.
If you try to set A to 50 in a GCC compiler, right.
It's going to say variable A does not exist in module four.
We make those rules.
So when the programmer makes mistakes we tell them you can't do this, you're setting a variable that
doesn't exist.
Okay.
So that's very important because the alternative is that our C compiler crashes.
Okay.
And obviously we want to provide some feedback to the user.
So semantic validation is very important.
So also in module four we create a preprocessor macro system.
This is where we really make the include the ifdef and the define.
And all the other C macros work okay including sizeof.
By the way all of that is done in the preprocessor.
So now I'm going to show you some example programs that will work in our compiler once you finish this
course.
So we can see we have a simple book program here.
We include Stdio Stdlib.
And we define an array for the name that's equal to 20 okay.
So it holds 20 bytes for the book name.
And we basically say how many books do you want to process.
They enter a number of how many books.
We create memory for those books.
And we basically load those books into memory and then print it back to them.
Okay.
So yeah, that is a very simple program, but you can see just how much your C compiler will be able
to do already.
You can see that it works with pointers.
It works with primitive types.
It works with structures.
As you can see, majority of the C programming language is working in our compiler.
Okay, here's another example program we can see we include Stdio.h tells you if you entered a negative
number, it tells you if you entered zero or if you entered a positive number.
So this is an example to show you that sign numbers work in our compiler.
Here's an example of the macro system working in our compiler.
So we can see we define a macro function ABC sum.
It accepts x and y and it just adds them together.
Okay.
So now what we say if five plus ten is 15 then create integer x equals 50 as a variable in the global
scope.
Otherwise create integer x equals 20.
So obviously you can see this will return 50 because it will generate this this variable declaration
here.
So this is proof that even the macro system is fully supported in our compiler.
Okay.
And we can't forget about being crazy with pointers and casting them in weird ways.
Obviously I have to show that this works.
We can cast a type into a pointer and then access the value of that pointer, or from all from C, okay.
So our compiler is very powerful.
It can compile complex programs like this.
Get the address of x.
Cast the integer pointer.
Grab the value.
Okay.
So this is definitely the course for you if you want to learn compiler development.
This course took two years to build and I very much hope you will love every module.
Thanks for watching.