All right we go quite a journey ahead of us in terms of implementing the different visitors but we need
to start somewhere right.
So I'm going to present you a very simple scenario where we're going to evaluate numeric expressions
so we're going to have this tree of literals or double values and some addition operations.
That's the only kind of operation we're going to support.
And we're going to try and evaluate the whole thing and we're going to be doing it using different kind
of visitor approaches.
So let's suppose that you have some sort of base class called expression.
Now at the moment I don't have anything to add to it so let's just stick a virtual structure in here
like so.
Now let's suppose that we have two types of expressions.
What we want to have is we want to have representation of expressions like one plus two plus three for
example.
So the only two things that we're going to have is parts of this expression are individual values.
And let's keep them as double values for a change as well as addition operations which have the left
and right hand side.
So let's actually implement those two things so we'll have a double expression which is an expression.
And here what we're going to do is we're going to keep the value that we've got and we may as well have
some slow constructor for initializing that value.
And that's pretty much it for now.
OK.
And then when we're going to do is we're going to have an additional expression which is also a type
expression.
And here the expression has a left side and a right side whatever that happens to be because we can
have expressions of expression.
So for example one plus two plus three you can represent this has a root having a plus.
And then on the left and right you would have maybe you might have a one here and you would have another
plus here and down here you would have.
Well I'm not that great at drawing but essentially you would have something like two here and three
here so this kind of tree and we want to actually kind of be able to represent this tree and process
it.
So that is that and that's the expression.
So the left and right hand side can themselves be expressions.
And as a consequence all we can do is we can define both of them as expressions expression left expression
left and right pointers like so we're going to have a constructor is always to initialize both of them.
And we might also add the side that for example the addition expression happens to be the owner of those
expressions so we may make these structure where we actually delete the left hand the right parts of
that expression something like this.
OK so we've got this set up now.
And that's the main function here.
And what we wanted to do for example I don't even want to evaluate those expressions right now.
It doesn't really matter.
Let's suppose I just wanted to print them.
I just want to take an expression and printed to the console.
So let's make an expression so I'll say.
Although he calls new addition expression.
So I will make an addition expression did I make a mistake somewhere x or there we go.
So I think an additional expression made up of the value of 1 one made up on the value 1 as well as
another addition expression
where all have the values 2 and 3.
So an expression too.
And you double expression three now of course I have to remember to delete at some point.
That's also going to be important but I have this expression it's because I want to print it.
So typically what I'm expecting is I'm expecting to print one plus two plus three when I'm going to
mess around with round brackets or.
Well maybe why not.
Why don't we mess around with round brackets.
In this case we expect to print one plus two plus three in round brackets.
Something like that so maybe we'll have the overall set of round brackets as well.
So whatever it is that we want to print now the question is how do we print it or do we actually print
the whole thing.
And this is where the approach really depends on whether you're allowed to modify the existing structures
or not because it would be very difficult if not impossible to devise a kind of printer which would
actually print a generic expression.
So writing a function which takes the expression pointer and printed it something we're going to take
a look at but not now.
So now we are considering the situation where we're prepared to break the open closed principle to jump
into the code that we have over there and actually start modifying it.
So if we were to do that's what I would do is I would go into the base class and I would for example
and by the way why don't I have my headers here headers.
MIKE So what I would do here is I would make an you function virtual void print which would print the
expression to some sort of stream like stream for example.
So this is something that I would require every single component to implement and then you can go ahead
and you can implement it here for example.
So in this case what's happening is the stream is effectively a visitor so the stream is the component
that's actually visiting every single element of our tree.
And here for the expression We'll just print the value.
Nothing particularly smart here.
And for the addition expression what we would do is we would print the left and right hand sides and
maybe we'll surround them with round brackets as well.
So let's actually implement this here.
And what I'm going to do is I will first of all print the opening round bracket and then I would print
because I know that expression implements print I would call print on the left side so I would say left
Prince and then I would add maybe the plus where we need to add the plus.
No choice here.
And then I would print the right hand side of the expression and then I would add the closing round
brackets like so.
So that is my implementation.
And now what I can do is I can go ahead and take this whole thing and actually print it so I can make
an postering screen.
I can say here's my expression can you please print it into the stream and then I can see out the stream
that we get.
So let's see what we got here.
Ah.
So I'm running tests.
Well never mind.
Here is the output.
Here is the output and as you can see we're getting the correct output here.
So everything is fine and the only thing which is not fine is this idea that we've had to go into existing
code modified and this is why this kind of visiter approach is called an intrusive visitor it's intrusive
because you go into classes that you've already written and you add stuff to it.
You add for example this print function all over your entire hierarchy and that was easy here.
But imagine if you have 20 classes as part of this hierarchy it would be really difficult to go into
20 different files and and print to every single one of them.
It would be much nicer to have them in a separate component that also goes towards the single responsibility
principle as well.
So printing is a separate concern so why not implement the printing for every single kind of expression
in a separate file.
Well we can certainly try doing it.
And that's going to be the subject of the next lecture as well as not just the next lecture but the
next few lectures in actual fact.