[No Audio]
In this tutorial, we will be implementing the
final part of Expression Evaluation, and that
is to compute the final result from the
postfix expression. This tutorial will be
relatively short and easy, because we have
already done the hard part of implementation.
This is the same script that we used in the
last tutorial, I will add the rules for
evaluating postfix. Let us quickly revise
these rules. The first rule is that, if we
have an operand then we will be pushing it
onto the stack. And the second rule is that
if we have an operation, then we will pop two
elements, perform operations and then push it
back onto the stack. Let's define a function
for implementing the evaluation of expression
form postfix form, I will name this function
is postfix_evaluation.
[No Audio]
The input to the function will be the vector of strings
containing the postfix expression.
[No Audio]
The output will be a floating number
representing the evaluation result.
[No Audio]
I will write some dummy
f32 value for now as a return
value, so that I do not see the red warning messages.
Once I am done with the function, I will remove it.
Let us first declare some variables.
I will need to store the size of
the postfix expression, I will define a
variable size_expr, and we'll
assign to it the length of the postfix expression.
[No Audio]
Next, I will declare a stack which
will be used during the computation. I will
name it result_stack, and we'll
initialize it using the new_stack function.
[No Audio]
I am next going to iterate through
all the elements of the postfix expression,
for which I will write a for loop.
[No Audio]
Inside the loop, I am going to use a match statement to
implement the two rules. The match will be on
the looping variable i
where the variable line represents the
tokens or symbols in the postfix expression.
To determine which rule to execute, we need
to identify if the current symbol is an
operation or symbol. First, I will check if
the symbol is an operation or not. So I will
include its relevant arm definition.
[No Audio]
Please note that, I did not mention the
opening and closing parenthesis, because they
are not part of the postfix expression,
I will add the code later on to this arm. If we
do not have an operation, then it means that
it will be an operand. So I will write a
default arm which will corresponds to an operand.
[No Audio]
Now, let us add code to the first arm, this arm
corresponds to the second rule, so let us
revise the rule. The second rule is that, if
the current symbol is an operation, then we
will pop two elements, perform the operation,
and then push the result back onto the stack.
This means that the current symbol is an
operation, so let me store it in a variable called oper.
[No Audio]
Next I will pop up the top most
elements and they will be our operands.
[No Audio]
The element which is being popped first, will be
the second operand for the operation and the
element which is being popped second, will be
the first operand for the operation.
So let me add the code.
[No Audio]
Next to perform the operation, I will define a
function called Operation.
[No Audio]
There will be three
inputs to this function, consisting of two
operands and one operation are of type
string. Let me add the inputs.
[No Audio]
The output will be a floating value.
[No Audio]
Inside the function, I will change the type of the
two operands from string to date of f32.
This can be done, with the help of the parse function.
[No Audio]
We need to unwrap the result of the parse,
because it returns an option. Next, I will
perform the operation to check the type of
the operation I will use a match statement on
the operation variable, and I will use it as a
string reference. First, I will add the arm
for the addition.
[No Audio]
Next, we will have an arm for the subtraction.
[No Audio]
Next, for the multiplication, division, and exponent.
[No Audio]
You may note that, the compiler is not happy and this
is, because the match needs to be
exhaustive, which means it needs to cover all
possible types of strings. To overcome the
error, we will add a default case also.
[No Audio]
Of course, the default case is not very
meaningful, and what you can do is that, you
can mention the last term as a default case.
But in that case, the code may be a bit
confusing, so let us leave it as it is for now.
Since we know that the default case will
never be true based on our inputs. Finally, I
will assign result from the match to a
variable of, let's say result.
[No Audio]
At the end of the match, I will also write a semicolon,
because the whole match is now an assignment statement.
Finally, I will return the
variable result by writing result without a semicolon.
[No Audio]
Let us now use this function
inside the postfix evaluation function.
I will call this function with the two operands,
and the corresponding operation, and we'll
store its result value in the variable of result.
[No Audio]
Next, we need to push the result into
the stack, the result needs to be to be
converted into string type.
[No Audio]
Now let us look
at the default arm which corresponds to an
operand. In this case, we will just push it
into the stack. Let me add the suitable code here.
[No Audio]
Now when all the symbols are being scanned,
and the loop, and anything that is being
left in the stack is the final result. So we
will pop the final result from the stack, and
we'll return that. Please note that, since this
function returns an f32 value, so I will
convert the final value to that of f32.
[No Audio]
Finally, I will delete the dummy return value that is 0.0.
Okay, we are done. Now let us
call this function from the main, I will call
it inside the print statement.
[No Audio]
Let us cargo run this.
[No Audio]
The final result seems correct. The main objective in this
example was to give you some practice, and
make you a bit more familiar with the coding
style and syntax of Rust. I hope you would
have enjoyed doing coding with me.
Of course, there are many optimizations that we
can perform in this code to make it more
efficient, but we will not cover that right now.
We will rather come to the topic of code
optimization, in possibly later on videos.
For now our focus is to learn the basics and
familiarize ourselves with programming in Rust.
Once we have sufficient skills, then we
will be in a better position to write and
optimize the code. With this, we end this
tutorial, do come back again for more, and until
then happy Rust programming.
[No Audio]