Hello and welcome to part four of implementing the bodies.
As you know, in the part three of implementing the bodies, we implemented the parts of finalized body
function.
In this lecture, we are going to create the multiple statement bodies parsing because we can see that
we allow ourselves to parse single statements, but we have nothing for parsing multi statements yet.
So we're going to be making a start with that in this lecture.
Okay.
So in see above our parse body function, we're going to create a new function for parsing multiple
statements and we parse the single statements here.
Now it's time for the multiples.
So we're going to start by saying void, parse, body, multiple statements, size, DT variable size,
struct vector, body, vec struct history, history.
So we're going to start by creating a blank body note.
So we're going to do that by going make body note.
And we're basically just going to provide nulls in all of these
essentially guys.
And then we're going to pop that node off because we want to actually be able to use it, right?
So the idea is here that we don't know all of the variables to pass this function right now.
We don't know the body vec the size padded.
So we're just going to create a blank one and pop it off and set it as we go along.
That's basically why why we're doing that.
So we're going to start by doing body node dot bind ID to owner equals, parse the current body and
then we're going to say parse the current body equals the body node we now are.
And obviously when we're done doing what we need to do, we're going to set the current body.
Back to the previous one.
So that just allows the bodies to nest.
I believe I explained this when we went and implemented the single statements as well.
It's always important that you set it back so that it can go back up.
So it kind of acts as like a recursion type of thing.
You know, as we go through all the bodies, we'll always know what the parent body was.
Now we're going to create some temporary variables.
Statement Node.
Largest possible var note
largest line eligible var note.
And I've already explained a lot of this when we went to implement the single statements, the same
rules apply the same differences between the possible var node and align eligible var node.
Exactly the same rules apply here in multiple statements.
So we're parsing a body with multiple statements so we can expect to see something like this right now,
the left bracket and the right bracket.
Therefore, we need to actually pop that off.
So we're going to go a spec sim and we're going to pop off that left bracket.
Okay, we have a body, i.e. therefore we must pop off the left curly brace call.
So how do we know when we're done?
We know we're done when we see this right curly brace.
Therefore we'll have a wild loop that looks for that right curly brace.
So while token next is symbol is not symbol, I should say the right curly.
Then we're still parsing a statement.
So now we just say pause statement.
History down, history.
History flags.
So I'll just pass a history down to this parsed statement using the current flags that have been provided.
I know these flags will be things such as the history flag is global scope, history flag, inside structure.
So it's very important we pass those down as we're doing to the pause statement function.
So we're just going to say statement node equals no pop
and then we're just going to say if the largest possible var node is null or
the largest possible var node, var type size is below or equal the statement node size.
Then the largest possible var node is equal to the new statement node that we popped.
We're just going to right click and format document there as well.
Keep it a bit cleaner.
That's fine.
That could look a little tidier, but it's easy for me to show you with it like this on the on the second
line like that.
Okay.
So let me explain what's happening here.
Essentially, we're looking for the largest possible variable node.
Okay.
So what we're doing is when we go through a body such as in it, X in it, Y in it B, when we're going
through something like that, we'll find an X.
And because the largest possible var node is null, the in it x variable node will instantly become
the largest possible var node.
And then when we go to and Y, obviously at this point in time the largest possible var does not know
because we already set it to X.
So all we do is we basically check the size of the current largest possible var node and if it's below
or equal the size of the current variable node.
We popped off in this case in a way, then the largest possible var node will become the new statement
node.
So if we were to run this entire body here through this algorithm, we would end up with an IT B as
the largest variable node OC because of the blower equal clause.
So that's basically what we're doing.
We're trying to find the largest possible variable node inside of a body.
Nice.
Okay, but we forgot something very important.
We were supposed to check to see if the statement node type was a node type variable, because obviously
if it's like a function call or something like that, then how can we possibly deal with it here?
So we check if it's a variable that's very important.
So down here we now need to say if variable node is primitive are we're going to pass in the statement
node, then we're going to do the same rules for the largest aligned edge of our node.
So we can just copy and paste that in there.
And we're just going to copy and paste this name and just replace it.
The largest possible var node here with the largest align edge with var not I mean not the largest possible
var.
No, my mistake.
So yeah, that allows us to both check for the largest possible var node and the largest align eligible
var node.
Because remember I've told you before the structure alignment works a bit differently, right?
So we only care about the primitive alignment.
So that's why we do these two separate calculations.
So this, this algorithm will result in the largest aligned eligible var node being the largest possible
primitive variable and largest possible via.
And that will be the largest possible variable in the structure that includes structure variables.
Okay.
So outside of this F statement where we check for the variable, we're just going to push.
This statement?
No.
To the body vector.
So we're going to do body back ampersand statement node
plus the statement node to the body vector.
Nice.
Okay.
So obviously we also need to change the variable size provided to us.
This one as we did with the actual append size for node in the single statement.
We also need to do append size for Node in our actual multiple statements and we do that on a per variable
basis.
So inside the wild loop, just after we push, we're going to say change the variable size.
If this statement is a variable, we may have to change.
The size of this statement is a variable.
Nice parse append size for node we're going to pass in our history when a pass in our variable size
and we're going to say variable node.
Or last and we're just going to pass in the statement, no, they're okay and we haven't created this
function yet, so we're going to create it.
So let's just head over to Node C just down here.
We're going to say struck node, variable node or list struct node node.
And essentially what this function is going to do, if a variable list is being provided, it's just
going to return that node, the same node you provide it.
So we're going to say no type variable list, then just return node.
However, if it is not variable s, we're actually going to return variable node node, which will then
call the variable node function, which will go through here and figure out the actual variable node.
So if you do pass a structure declaration and it has a variable node, it will pull pull that variable
node from there.
We've already been over that, such as something like this.
For example, struct dog ABC.
We can see that if you were to pass this no type structure to this function, it would return the ABC
variable node, which basically holds an instance of dog.
Does that make sense?
So I know we've already been over that and just refreshing your memory.
So yeah, this function will basically say if the node provided is a variable list, just return that
node.
Otherwise we're going to call the variable node function and try and extract the variable node.
All right, now.
So let's copy and paste that into the header file.
And I'm just going to put mine the coal.
And now if we go back to parse it out.
See, that should be working.
Nice.
It does.
Okay.
So outside of the wall loop, at this point in time, we would have finished parsing all the statements
in the body because we found the right curly brace.
So, yeah, we need to expect the right curly brace basically says, you know, pop off the right curly
brace, you know, because we check here, we peak ahead.
Is that is it the right curly brace?
If it is, then we leave this wild loop.
And then obviously we need to pop that off, pop off the right curly brace.
And yeah, now we need to finalize the body
history.
Body node.
Body vac.
Variable size.
Largest align eligible.
Var Node.
Largest possible.
Var Node.
Let's make sure you got those in the right order guys as well because you don't want problems later
down the line.
So as you know, the same rules here apply as they did for the single statements.
The rules aren't different at all, so this will basically go through and finalize the body.
Same as you are shown in the actual single statement.
Okay, nice.
We can go back now.
And the final thing to do is to push.
This node, this body node to the stack well to the pass stack, so it becomes a node in the same text
tree.
Let's now push the body node back to the stack.
There we go.
So let's just scroll down the past body and now we're going to actually call this multiple statements
function.
So obviously here we check with a single statement.
If it is, we deal with it, finish and return.
So underneath that if statement, we can assume that it's a multiple statement because it is.
So then we're going to actually actually parse the multiple statements.
So we're going to pass in the variable size, the body vector and the history.
And just so no one gets confused, we're going to even put a little common here to explain what we're
doing.
Okay.
So just so no one gets confused, we're even going to write a comment.
So we're going to say we have some statements, some variables.
I should say no statements is right between curly braces and A and B and C.
So that just makes it very clear that we're parsing from these braces to this brace.
From this brace to this brace.
Right.
Cool.
So the final thing we need to do, we need to actually adjust the function stack size.
But since functions don't exist yet, there's not much we can do.
So we're just going to have to put a warning here.
Okay.
Don't forget to adjust the function stack size and obviously they'll make more sense when we go and
actually implement the functions, but we can't do everything all at once.
So I appreciate that there can be some confusion.
Unfortunately, we need to be able to start with the fundamentals and build our way up.
Okay?
And so I don't expect you to understand it all at once, but obviously fundamentals get done first and
then we work on the more higher level concepts and then everything will start to fall into place.
So just a nice little warning here to remind us to come back to it.
Well, be very sufficient.
So we're going to make clean make and yeah, apart from a few compile errors, you know, some warnings
that we've put there, we can see that that worked absolutely fine.
So we've now finished implementing the actual bodies.
We can now pass single statements and multiple statements.
So we're going to soon test this functionality to make sure everyone has done it correctly.
And obviously, if you haven't done it correctly, it's nothing to worry about.
You can do a git diff on the code repository at any time to see the differences between my code and
yours.
Thanks for watching.