 Welcome to part 4 of the lecture on intermediate code generation, today we will continue with the intermediate code generation strategy for various types of constructs. So, in the last lecture we saw how to generate code for the loops, but we still have not covered the break and continue statements which can occur inside loops. So, for example, a break statement takes the control away from a loop or switch statement and of course, it can occur only within the while for do while and switch statements. If it occurs in any other type of statements it would be flagged as an error by the compiler. A continue statement simply skips the rest of the iteration of the loop and goes on to the next iteration and since I mentioned iteration obviously, a continue statements are valid only within while for and do while statements that is loops and others are flagged as error by the compiler. So, let us look at a couple of incorrect and correct programs with break and continue to understand how to generate code for these statements. Here is an incorrect program then in T i equal to 5 initialization, if a less than 5 then break print f hello 1 and outside is print f hello 2. This would be flagged as an error by the compiler and similarly, replacing this break with a continue will also be flagged as an error by the compiler. It is not as if the then part is skipped and it goes and prints hello 2 it does not do that. Now, a couple of programs which are correct. So, here is a main program with two variables a and b, b initialized to 10 and a is uninitialized. There is a loop for starting from a equal to 1 goes on till a less than 5 that means, it executes for a equal to 1, 2, 3, 4 a is incremented by 1 every time the loop body is completed and the body of the loop is simply decrement operation on b after the loop is over the value of b is printed out. So, as you can see this program will print 6 the reason being we start with a equal to 1 then b is decremented to 9, a equal to 2 it becomes 8, a equal to 3 it becomes 7 and a equal to 4 it becomes 6 and if a equal to 5 the loop terminates. So, the value is 6 and it is printed out. So, now let us introduce breaks and continues into this loop. So, the same loop, but the body says if a equal to 3 break. So, in other words for the value of a equal to 3 this loop is terminated and then it does not you know iterate any more. So, the loop would have executed for a equal to 1 and b would have become 9 it will execute for a equal to 2 and b becomes 8 and as soon as a becomes 3 the break comes into picture the loop is broken the control comes here and prints out the value of b which is 8. So, this is how the break statement works and you must also keep in mind that the break always breaks to the breaks control and brings it to the next nested loop. So, if there are 3 loops nested and from the innermost loop it will break to the next outer loop and if the break is in the next outer loop then it will break to the outermost loop and similarly in the outermost loop a break statement will carry it outside the loop nest itself. Similarly, let us introduce a continue statement instead of the break. So, here the program will print 7 the reason being with a equal to 1 the b value of b becomes 9 with a equal to 2 it becomes 8 and when a equal to 3 there is a continue. So, which implies that the control skips the rest of the iteration and goes to the next iteration by incrementing a. So, the value of a value of b instead of getting recommended you know 4 times it will get decremented only 3 times and thereby the value becomes 7 and the break statement can also be used to get out of infinite loops. So, for example, the same program as here there is a while loop with 1 which is always true. So, if there is no break this is an infinite loop, but because the break the while loop control goes out the control goes out of the while loop and it comes to the if then statement. So, the rest of the you know iteration is carried out as before. So, it again prints the value of 8. So, every time the control comes to the beginning the while loop tries to execute and because of the break it comes out goes to the if statement continues and so on and so forth. So, and this break of course, works as before and for a equal to 3 it gets out of the loop itself. So, this is how the you know continue and break statements work in C. So, let us see how to generate code for such statements. So, because of the special nature and the control flow you know because of the disruption of the control flow we need to maintain extra attributes for the non-terminal statement. One of them is statement dot break again these are synthesized attributes and other is statement dot continue. The attribute statement dot next which is already existing will of course, be present here as well. So, all these three actually are lists of quadruples with unfilled branch targets. For the production statement going to break we simply generate a go to statement and put it on the break list. Next becomes null because control cannot proceed to the next statement after break it goes out of the loop and similarly there is no continue this is a break statement. So, this is also null for the continue again we generate a go to statement and put it on the continue list next and break become null. So, even though these two you know statements generate the same code go to the patching that is required for the target of this go to will be different for the break and different for the continue. So, let us understand how that happens in the case of a while loop. So, here is the while x going to while m e and the statement goes to while x to statement 1. So, this part is same as before not much difference while x dot false list is next square and the next quadruple generated is the test on the result of e and while x dot begin is m dot quad. So, we remember the beginning of the expression e and the target here will be unfilled it will be field later. So, once we have parse the entire while statement will be at this point. So, now we execute the code go to while x dot begin. So, which brings you to which brings the control to the beginning of the while loop the statement back patch statement 1 dot next with while x dot begin is as before all the jumps out of statement 1 are brought to the beginning of the statement we do the same with continue. So, if there is a continue statement within the list of statements in statement 1 we patch them to the beginning of the while loop and statement dot continue becomes null statement dot break also becomes null and the statement dot next list now contains along with while x dot false list it will also contains statement 1 dot break. So, all the breaks out of statement 1 really bring the control out of the while loop and while x dot false list of course, brings the control out of the while loop. So, therefore, these two are together merged and put on to statement dot next m is a marker as usual. So, this is the code that is generated for why you know break statement and continue statement in the case of while loops. So, let us see how the code gets generated for loop in c. So, there are code template is almost the same, but the patching that is done for the breaks and continues slightly different. So, remember we generate a go to statement for the break and also a go to statement for the continue all the breaks out of s are patch to the exit. So, they are put actually on the statement dot next and all the continues and other jumps out of s really go to the beginning of e 3 which is to be executed after the code for s is executed. So, here is the production for statement the production you know with markers is the same the actions for generating code which we saw in the last lecture remain the same what is special for continue and break have been marked in while it. So, statement 1 dot continue is patch to n dot quad plus 1. So, this would be this go to is n dot quad and n dot quad plus 1 will be the beginning of e 3. So, that is correct you can see that here continue will be patch to the beginning of code for e 3. Then we put a statement 1 dot break and the q 1 you know q 1 is nothing, but the test and jump. So, these two are merged and put on statement dot next because they are the exit points of the for loop the exit can be because we have reached a 0 here or it could be because of the breaks within statement 1. And since the breaks and continues cannot go beyond the loop you know they actually cannot be transmitted to other loops. So, we make them null as before. So, this is how we you know generate code for break and continue. So, now let us look at the code generation using L attributed grammars for some of the constructs. So far we have concentrated on the S attributed grammars because they are very relevant to yawk, but you know the learning would be incomplete if we do not see how to generate code using L attributed grammars because they introduce a few extra facilities into the code generation schema. Let us consider the expressions without short circuit evaluation. So, the first one is the if expression, if expression S 1 L s S 2 the code template is the same as before. Obviously, there can be no change in the code template it is only the translation scheme which changes. So, the code for e then the test on the result of e the then part and then jump to the exit the else part and the exit itself. So, this is our schema which we use for S A T G as well here because we are permitted to introduce actions in between the production symbol as you know on the right hand side symbols on in the production on the right hand side. We can introduce these variables n and m instead of the marker non terminals n and m in the S A T G. How are we justified in using these variables and you know introducing them here and using them elsewhere in the production? We are justified because a single function or procedure is created for each non terminal. So, for this and this entire production the code for this entire production will lie within a single function or procedure. So, if these variables n and m are declared as local variables within the procedure for S they will be accessible anywhere within the procedure and therefore, we are justified in using them anywhere in the production as well. So, n equal to next quad. So, we remember the quadruple which is generated now which is the test quadruple for e and if the result is less than or equal to 0 we have to jump out of the then jump out and go to the else part. Otherwise we fall through and execute S 1. So, the code for when we call the procedure for e the code for e will get generated then this action is executed call to the procedure S will generate the code for this S 1. Then we have just before S 2 we can we generate another go to which is nothing but this go to then we back patch n with next quad n is this quadruple the test quadruple if the result is really falls then we need to go to S 2 which is the else part that is why this back patch is correct. Now, this code is similar to the SETG we merge the quadruple m the S 1 dot next and S 2 dot next. Now, we see how to generate code for the while loop which is very simple. So, we have code for e then the test then code for S and go back to the loop. So, again we remember the beginning of e with the m equal to next quad and after e we generate the test and then we generate the code for S 1 do the back patch as S 1 dot next comma m. So, all the jumps out of S 1 really go to the beginning of the expression finally, go to m at the end of S 1 will also generate jump to the beginning of e and S dot next will be just this quadruple. So, this is how we generate code for the while loop using the LATG. Now, what about the rest of the statements we have still not seen the most important assignment and expression etcetera we will see very soon. These are the other statements rather other productions and the code generation is not different from the you know SETG itself the compiler code appears here. So, a has no jumps so S dot next is null here we transfer whatever is in S L to S here again there is nothing for S L dot next and we generate many statements you must also observe that we use write recursion wherever we need to generate less of statements instead of using left recursion because using left recursion makes the grammar non L L 1. So, all the jumps out of S are patched to S L 1 using the back patch statement here and S L dot next will be S L 1 dot next as usual. When the when a function ends we generate function end quadruple, but since we have used S L going to epsilon as the last production remember write recursion. So, this would become epsilon for the last statement which is a null statement really rather nothing not even null statement null statement would be semicolon. So, at this point when if we have used S L going to epsilon for S L 1 we would have a null next list. So, there is no need for back patching anything to this quadruple at all there is nothing you know there it is a null list really and L A T G for function declaration call return they are very similar to the S A T G and they are left as exercises. So, now let us continue with the expressions. So, A going to L equal to E the code generation scheme is very similar there is no difference really it is the same and. So, if it is a simple I D we generate L dot place equal to E dot result and if it is a you know an array expression we generate an array expression we generate L dot place with L dot offset as E dot result. So, this is the assignment statement. So, now let us expand the expressions. So, observe that the expression uses an unnatural form because the original expression we had used was left recursive E going to E plus T or T etcetera. Now, this is right recursive because as I said left recursive grammars cannot be used for L L parsing. So, it becomes E going to T E prime E prime going to plus T E prime E prime going to epsilon etcetera. So, here we use an inherited attribute for E prime the reason is T is a an expression and its code would have been generated and it T dot result is the address of the result of T and then E prime is another expression and we have still not you know the operator between T and E prime that is for example, if we use E prime going to plus T E prime the operator is plus this plus is actually between this T and this T right. So, E prime expands to plus T E prime. So, we would really have T plus T E prime. So, we must generate code for T plus T somewhere else not in this case not in this particular production. So, what we really do is we pass T dot result as an inherited attribute to E prime. So, E prime dot left that is the left operand goes into E prime as an inherited attribute and E prime dot result would become E dot result eventually. So, within the production E prime going to plus T E prime we now generate temp equal to E prime dot left plus T dot result. So, remember E prime dot left is an inherited attribute and T dot result is a synthesized attribute again for this even prime the result of this entire left side expression is that is stored in temp will be passed as an inherited attribute and the same code generation scheme continues. So, at the end again E prime dot result that is the left hand side synthesized attribute is even prime dot result. So, I have not really shown checking for compatible types etcetera here that was shown in the SATG and that holds here as well. So, the appropriate code for checking types you know and conversion of types etcetera has to be inserted here and that is left as an exercise. If E prime generates epsilon so that means there is nothing more to it. So, for example, if this is E going to T E prime E prime going to plus T E prime. So, we would have generated T plus T E prime and if E prime goes to epsilon you would be left with T plus T. So, there is nothing to do we just say E prime dot result is E prime dot left because we have already completed the generation of code for T plus T in this case. Taking the other productions with star for example, T going to F T prime, T prime going to star F T prime or epsilon F going to parenthesis E parenthesis Boolean and relational expression they are all very similar to these productions. So, these are left as exercises. So, now let us concentrate on the expression. So, the F which is the right side of an assignment can go to L, L can generate an array expression. So, this part is very simple if it is offset is null that means it is a simple id. We transfer L dot place as F dot result otherwise if this is an array expression we need to generate code because as I already said both left hand side and right hand side of an arithmetic of an assignment statement cannot contain array expressions. So, we generate a new temporary and then generate the instruction F dot result equal to L dot place with L dot offset. Num of course, we generate a temporary and place the value num dot value into F dot result that is the new instruction which is generated. Now, the array part so if L going to id followed by index. So, if index goes to epsilon then the it is a simple id and with index goes to epsilon the offset of the expression subscript part would be null so which is correct. So, what we really do is search for the name here get its entry in the symbol table. So, v n is the pointer to it pass it as an inherited attribute to this index. So, because that will be required within the subscript to you know get the dimension of the array etcetera and then the index is passed. So, L dot place becomes the array pointer and L dot offset is index dot offset which is generated during this index parsing of this index. So, we already saw index going to epsilon. So, if index you know goes to right left bracket e list right bracket that means we have seen all the subscript so far e list is yet to be expanded of course. Now, e list contains the entire offset in terms of the number of elements of the array and we need to multiply that with the size of the array element. So, we generate an instruction temp equal to e list dot result star a l e size where a l e size is the size of the array element which is obtained using the array pointer pass to index as an inherited attribute. So, here e list gets a two inherited attributes one is the initialization initialized dime attribute. So, dime is set to one number of the first dimension is will be scanned first that is why e list dot dime is one array pointer is of course, obtained from index dot array pointer and pass to e list as an inherited attribute. Here we generate a new temporary and then you know generate the quadruple for that particular e list dot result star a l e size operation. So, here the expression list is being expanded. So, expression list will generate e followed by index list. So, if there is only one expression then index list goes to epsilon if there is more than one expression then it generates comma followed by e list and e list will again you know is guaranteed to generate at least one more expression. So, this is the way we generate a number of subscripts. So, this is obviously you know one of the subscripts. So, what we really do is for index list we increment the dimension e list dot dime and pass it as an inherited attribute because we have seen the assume that this is the first dimension. So, we have seen it now whatever is going to be seen in index list will be the second dimension. So, it will be added one will be added to it and pass to this the array pointer is just copied straight away and index list dot left would be e dot result. So, we get e dot result into index list as an inherited attribute and e list dot result would be index list dot result. So, that is the so here whatever is generated by index list will also take care of e because we have passed index list dot left you know equal we have this e dot result which is passed to index list lot left as an inherited attribute. If the index list is epsilon then you know index result is index list dot left. So, nothing to do really whereas, if it expands then we are guaranteed to generate at least one more expression. So, here after the comma we have an action have written it here simply to make it clearer not that it is required by the compiler that way. So, action one generates a temporary now there is a very important part here we must get the number of elements as the remaining number of elements in the subscript list. So, let us understand what that is. So, the function rem num l m is given the array pointer and the dimension at which it has to look at the data structure in the symbol table. So, it computes the product of the dimensions of the array starting from the dimension time. For example, if you have a i j k l four dimensional array and this is the these are the subscripts simple subscripts of course, and the declaration of this array is a 10 20 30 40 let us say int. Now, this expression will the subscripts will translate to i multiplied by the rest of the dimensions three of them 20 30 40. So, these are to be skipped then j star 30 40. So, again that is within j k star 40 within k k star 40 within k and then add l to it. So, this is the effective subscript you know that is necessary for translating a i j k l of course, this entire subscript has to be multiplied by the int size and then that becomes the index and address of a becomes the base address of the array. So, we really this rem num l m when the number of dimensions you know the dimension count is 2 it returns 20 into 30 into 40 that is 24000, when time is 3 it generates 1000 result it returns 1200 and when time is 3 it returns 40. So, this is the way rem num works. So, what we really do now is get the number of elements starting from this dimension and that is num l m we multiplied with index list dot left which is obtained as an in a written attribute here. So, that is this expression which is obtained. So, e star num l m that is what we would be doing. So, we would be really doing this is e star this is rem num l m. So, that is what we are going to do successively then we take j and do this multiplication and so on. We pass the array pointer index list dot array pointer to e list dot array pointer and index list dot dime is pass to e list dot dime. So, these are the inherited attributes of e list. So, now we have completed e list. So, we generate an instruction to add e list dot result to this temporary. So, that is the same temporary which was generated here. So, we did the index list dot left star num l m now we add e list dot result and that is passed back as index list dot result. So, in essence if we had two dimensions for the array this would take care of the first dimension and multiplying it with the number of elements that is the second dimension is done here. Then you know the second dimension is taken care of by index list which again goes to e list and then e. So, we generate the code e list dot temp equal to temp plus e list dot result. So, in you know we would really have done e star second number of elements in the second dimension plus e for the second dimension itself. So, that is the offset finally, we really have to pass it back and get the you know get into index where we generate the temp equal to e list dot result star e list size. So, this is how the code generation happens using L at rebooted grammars. So, that brings us to the end of intermediate code generation. So, now we will begin with the next part in compiler design. So, welcome to the lecture on runtime environments. So, so far we have seen you know the lexical analysis which takes care of processing characters and then we saw parsing which takes care of processing the tokens and producing the syntax tree etcetera etcetera. Then we saw semantic analysis which checks whether the semantics of the programming language are satisfied by the program and then recently we also saw intermediate code generation for various constructs of the language. Now, before we move on to the machine code generation we must understand what exactly is required for a program to execute at the time of you know when it is put into memory and the execution begins. So, this type of runtime arrangement is required and the code generator expects that these are available at runtime these services are available at runtime. So, we must understand what is runtime support and then we will understand the various parameter parsing methods different types of storage allocation the format of activation records the difference between static scope and dynamic scope how to pass functions as parameters finally, we will see heap memory management and garbage collection. So, these are the various things that are done at runtime. So, let us begin with the slide to understand what exactly is runtime support it is not enough if we simply generate machine code from intermediate code that is fairly easy. So, generating simple code from intermediate code is very easy, but the program is supposed to run in a computer which actually has an operating system. So, the program that we generate you know from the intermediate code cannot run in a computer system without getting the resources appropriately. So, in other words for example, there is a need to manage memory when a program is running. So, the when the program wants to run it must get as amount of memory necessary to place its instructions and it also requires memory to place its data and then the control has to be transferred to the beginning of the program and it runs. So, even within you know even when the program starts running the programs actually may request for memory blocks and they may release memory blocks. So, this happens in dynamic memory allocation when we use pointers and we want to build data structures such as link list etcetera etcetera. And the parameters must be passed to functions. So, the order in which the parameters are passed the way in which the result is passed back to the function all these actually require protocols which are part of the run time system and run time support. So, and we also have other sources such as printers, file systems etcetera which are required within our programs. So, the operating system provides support for all this and therefore, we must understand how to use these systems rather these operating system routines. So, all these are actually part of the run time support that is a method to manage memory, method to manage other resources and provide the services to you know allocate and deallocate memory blocks how to pass functions parameters to functions these are all the main tasks of the run time support. So, in this lecture we will mainly focus on memory management because the rest of the services such as printers how to use printers file systems etcetera are all provided by the operating system itself. So, let us begin with parameter passing methods. So, the first parameter passing method and the most popular one is the call by value method of passing parameters. So, I will give you examples of how to use different parameter passing methods after we discuss all the three methods of passing parameters rather four methods of passing parameters. So, call by value everybody understands it this is available in C and C plus plus the parameter which is passed as a call by value parameter is evaluated prior to the call and its actual value is put in a location which is private to the called procedure. So, in other words there is no way to change the original parameter which is the actual parameter. The value is copied into a local location and then used in the function and C has only call by value method whereas, C plus plus has call by value call by reference as well. So, in the case of C passing parameters does not constitute call by reference this is a you know misunderstood concept in C it is not that call by reference you know is possible by passing parameters. So, they are sorry passing pointers when we use pointers the pointers are also copied to another location. So, the effect of this is that there is no way to write a function to insert a node at the front of a link list just after the header without using double star that is pointers to pointers. Let me explain what I mean with the help of this picture here is a link list right and we want to insert a new node here before p and the first node. So, in other words this is the picture we want the node must be inserted here just before just after p and just before the first node. If we write a simple insert node function in C pass the header of this link list p as a parameter to it immediately call by value kicks in it makes a copy of p within the function as q. So, obviously q would also be pointing to this particular node the first node when we insert create a new node and inserted it would be inserted after q and just before the first node of the original list and, but this is not what we wanted. So, we wanted the modification to be like this all right. So, passing this pointer to the function which tries to insert a node here cannot be done because C a permits only call by value and copy of this pointer is made into a local location. Of course, this can be easily solved using pointers to pointers and that is something not necessary to be discussed at this point of time. So, what is call by reference call by reference is evaluate the parameter prior to the call and put it in a temporary location if the parameter itself is not a variable. So, for example, if the parameter is an expression then it is evaluated and put in a temporary location if it is a variable then there is no need to put it into a temporary location. So, now the address of the variable or the temporary is passed to the call procedure. So, why did I say put it in a temporary and pass the address of the temporary that is because if there is no way you can you know say an expression corresponds to a single location. So, we must evaluate the expression and then put it in put the value in a temporary location and pass the temporary location address of the temporary location, but if it is a single variable we do not do any of this we pass the address of the variable itself to the call function or procedure. This way, so the actual parameter may get changed due to the changes in the you know changes in the function that are done to the parameter itself. So, the parameter can also change of course, if it was an expression and we had put it in the value was put in a temporary location it does not matter because that value of the temporary location will change, but the original expression cannot be obviously changed because expressions do not have any single location to deal with. So, this is possible in C plus plus and java of course, then we have the third method of passing parameters known as call by value result. This is really a hybrid of call by value and call by reference what we really do what is the call by value part the actual parameter is evaluated before the procedure call is made and then its value is copied to a local location of the call procedure. So, this is the call by value part when we modify the you know the parameter within the function or procedure the parameter within the function or procedure we are really making changes to this local location and therefore, the original or actual parameters value is not affected during the execution of the function or procedure. Then how is it different from the call by value that is because at the end of the function or procedure the function or procedure final value of the formal parameter is actually copied to the actual parameter if the actual parameter is a variable otherwise it does not make sense to make a copy anyway. So, that is the result part. So, to begin with we have call by value we put the value into a temporary and then use it within the function, but when the function is supposed to return we copy the final value of that call by value result parameter into the actual parameter and then return. So, that is how the call by value result mechanism works, but how can this be different from a call by reference mechanism. Suppose you have global variables in the program and there are passed as parameters to the call procedure and of course, we change the global variables that is no problem, but the same global variables are also updated in another procedure invoked by the call procedure. So, we a calls b, b gets these global variables as parameters, but then b calls c and c changes the global variables directly. So, then the effects are going to be very different we will see this later and this mechanism is found in the language AIDA. So, let us understand the difference between call by value call by reference and call by value result. Here is a simple program written in c like syntax, but it is not really the c language, because c language does not have call by reference and call by value result. It is not even c plus plus, because c plus plus does not have call by value result. So, in the main program we have a global variable a this is assigned one then we call the function r. So, r takes a parameter. So, this is the parameter a and that becomes x inside x is added 10 here you know and then we call the function q which also increments a finally, we print a. So, let us assume that call by value is the only mechanism available. So, we set a equal to 1 call r with a. So, this is a, but a copy of a is made in x, because it is call by value. So, the x part is the local copy which is which now becomes 11 and then we call q, q modifies the global variable a. So, really speaking a was earlier 1 even though this became 11 this was the local copy. So, the original a is not modified a now becomes 2 the control comes back here and then it returns here and we print a. So, we get 2 for call by value call by reference this a and this x are the same. So, the original a really now becomes 11 and a call to q makes this 12. So, the call by reference mechanism prints out value of a as 12 call by value result. So, a is actually copied into the local variable x. So, this is now the local variable x which becomes 11 then we call q. So, q increments the global variable a to become 2 now we return to r and just before exiting the procedure r we copy the value of x back into the global variable a. So, x was 11 here now even though a was incremented here we have that is our copy will destroy the old value of a and put 11 into it and 11 is printed here. So, this is what I meant by the global variable a being modified independently by 2 routines 1 which takes it as a parameter and the other which takes it as a global variable. So, the effect is neither call by reference nor call by value it is very different. Now, let us look at a very complex parameter passing mechanism called call by name which is available in the programming language algal and also in functional programming languages. It is not used in C C plus plus or Pascal simply because it its effects are very difficult to predict and understand. How does it work use of a call by name parameter implies a textual substitution of the formal parameter name by the actual parameter. So, let us understand what it means we have a procedure r which returns nothing there are 2 parameters x and i. So, within the body it is all very innocent i equal to 2 then we assign x equal to 5 then we have reassignment i equal to 3 and another reassignment x equal to 1. So, let us say the procedure is called as r b of j star 2 comma j and let us assume call by name for all the parameters as we said here the effect is as if the each one of these parameters is you know there is a textual substitution for this parameter in terms of the actual parameter which is passed. So, in this case the parameter i corresponds to the actual parameter j here. So, in effect i equal to 2 is really j equal to 2. So, next one is x equal to 5 x corresponds to b of j star 2. So, the effect is as if we execute b of j star 2 equal to 5. So, now j is 2. So, this is b of 4 being assigned a value 5. The next i equal to 3 it again means textual substitution of i j you know i by j. So, we have j equal to 3 and x equal to 1 becomes b of j star 2 equal to 1. So, now this is b of 6 equal to 1 really because j has been changed. So, if we had just call by value of course. So, the effect is very simple to predict and if we had call by reference we would have evaluated the address of b of j star 2 and pass that. So, the element you know would have changed, but we would not really have here we have changed j b of 4 and here we have changed b of 6. This would not have happened in call by reference it would have happened it will happen only in call by name. So, the implication of this is that the actual parameter corresponding to x changes whenever j changes. Therefore, we cannot evaluate the address of the actual parameter just once like in the case of call by reference and then use it. It must be recomputed every time we reference the formal parameter within the procedure. So, in other words if you we must evaluate the parameter as if we have done a textual substitution. So, that is what really means. So, what we really do is we create a separate routine called thunk to evaluate the parameters whenever they are used. So, every time we refer to j we see what that parameter is that corresponds sorry the parameter i whenever we refer to i we see what that parameter is that would be j. So, the second parameter is now evaluated and then used here. Similarly, whenever we have x equal to 5 we evaluate the parameter x with the current values. So, b of j star 2 would be evaluated that becomes b of 4 here whereas, in this case j has changed. So, this would become b of 6. So, every occurrence of the formal parameter invokes a small routine to evaluate the actual parameter and then use it here. So, such routines are called thunks they are actually nameless sub-routines or nameless functions. So, these will be called whenever a parameter needs to be evaluated. So, we need to pass a thunk as a parameter in the whenever there is a call by name mechanism in place. So, for this parameter we create a thunk and pass that thunk as a parameter here. For this parameter we create another thunk and pass that thunk as a parameter here. So, passing functions or procedures as parameters would be necessary to implement call by name mechanism. Let us understand this example to see how the four parameter passing methods are different. This is a very simple swap routine and then we want to study the effect of swapping on i comma a i where i equal to 1 and a i equal to 10. So, with call by value swapping really does not happen. So, it prints out 1 and 10 with call by reference the swapping happens. So, 1 and 10 becomes 10 and 1 call by value result also the swapping will happen because the values are copied back to the original location. So, 1 and 10 and 10 and 1, but in the case of call by name there is an error. The first of course, we print 1 and 10, but then when we try to execute the body of swap temp equal to i becomes temp equal to 1, i equal to a i makes it i equal to 10 because a i equal to 10. Now, we try a i equal to temp that means we are trying a i which is a of 10, a of 10 does not exist because the array is only five locations long. So, this gives an error index out of bounds and stops the program. So, this is the difference between the four parameter passing methods. We will stop the lecture here and continue in the next lecture. Thank you.