So welcome to Project 8 in which we'll get our hands dirty and complete the construction of the VM Translator. Now, I wish to remind you that this is the second project in this course and yet it is numbered Project 8. Because we wanted to create a numbering scheme which continues the numbering of the projects in Nand to Tetris Part I. We don't assume that it took Nand to Tetris Part 1. But we just wanted to have some global numbering scheme going on. So to remind you, this is where you're at in our grand journey map. We want to build a VM translator which is capable of translating programs from the VM language into lower level programs, written in the Hack assembly language. And we decided to separate this substantial development task into two separate projects, project seven that you've already completed, and project eight that we are building now. And each project is responsible for handling a different subset of VM commands. So now, the challenge is to implement the branching and the function commands, and that's what Project 8 is all about. So suppose you've already developed your VM translator, and now you want to test it. How can you do it? Well, as usual, we're going to supply a whole set of VM programs. And request that you use them to test your translator. So you have to take every one of these programs, translate them using your translator and produce in the process another lower level program written in the Hack assembly code. And then, we can take this code and simply execute it on the target platform. After we translate it further into our binary code. Now, alternatively, instead of using the Hack platform, we can use the CPU emulator, which is significantly more user friendly, because you don't have to translate it into machine code, you can run the assembly as is and for other reasons, so that's what we recommend to do. And now you look at the results of the program, if the program performs what the VM code sought to perform originally, then we're happy and we say that the translator has passed the test. And in fact, we do much more than that, because we provide elaborate test groups and compare files, and so the testing procedure will be very well managed. You don't have to worry about it too much yourself. You just have to concentrate on writing a well-behaving VM translator. So here is the set of programs that we supply in Project 8. If you will look at the Project 8 folder on your computer, assuming that you've down all of the NAND to Tetris software suite, you will see two directories named ProgramFlow, and the FunctionCalls. And each one of these directories contains several sub directories. If we look for example at BasicLoop, you will see that BasicLoop contains four different files. The star of whom is the VM program, I mean that's the beef. That's what we want to translate. But we have as usual several other files. And here's what we recommend to do. Very similar to what we're doing in project seven. We recommend that you first invoke the VM emulator. And use the supplied XxxVME.tst script to load the VM program into the simulator and play with it a little bit. Even though it's a testing program, it makes sense to understand what the program seeks to do. This will just give you some background information about the test context. Once you understand what the problem wants to do, you don't have to get into the details. You just have to get the feeling of the program's intended operation. Then, you should use your translator to translate it into an Assembly file. Whose name, by default, will be XXX.ASM. When I say, by default, your VM translator has to make this default happen. And finally, you can now load and run the XXX test script in the CPU emulator. And this script will run the generated code. The code that was generated by your translator. It will execute it and it will compare the output to this code to our supplied compare file. If the comparison will be positive it will get a nice message and you can proceed to run the next test. If not, then presumably you have to fix a few things in your VM translator. So that's the basic routine. And with that, let's take a look at the Basicloop.vm test file. As you see from the documentation this is VM program that wants to sum up the numbers 1 plus 2 all the way up to argument 0 and push the result onto the stack. So presumably someone is going to initialize argument 0 for us. In particular, there is a test script called Basicloop.txt, and indeed as you see, this test script which is stored in a separate file is going to initialize the virtual memory segments, as well as argument 0. And then, it will execute the Machine code that will be generated after you translate the code that you are now going to see. It was good sentence. So here's the code. You can read it if you want. It's not terribly important because here's what this code is doing. It is a simple loop. That implements some sort of a while, if you will. As long as we begin with setting a counter variable to argument zero. As long as counter is greater than one, we add counter to our sum. And we then decrement counter. Go to check again if it's still greater than zero, and so on and so forth. So nothing sophisticated here, what is more important is that this program, or this file, is designed to test the ability of your VM translator to handle, label and if-goto commands. Now, this is the most important purpose of this test file, and everything else is irrelevant details. So this is a basic loop. And you can ask yourself where this VM code is coming from. Well, I don't remember if we wrote it ourself, or if we wrote a jack program and compiled it into this VM code, it's not terribly important. What's important, once again, is that this program is designed to perform a relatively simple test of Your ability to handle branching demands. So with that let's move forward and take a look at the Fibonacci Series test script. Sorry test files. So here's the VM program. It seeks to compute the first argument zero elements of the Fibonacci series. So if argument zero will be a, for example five, it will compute the first Fibonacci element, the second, the third all the way up to five. And if you put these values in the RAM, starting at the address which is stored in argument one. So once again, someone has to initialize argument zero and argument one for us. And in particular there is a test group called the bonacciseries.tst and it will do these initializations and then it will run the code that will be produced by your VM translator from what we are now going to see. So, we begin by approaching or manipulating some esoteric virtual segments like Pointer and Vet. And we don't really expect you to understand exactly what we're doing here because how to use pointer and Vet judiciously is something that we're going to explore later on in the course. So for not suffice to say, that what we do in this code is the following logic. We compute the Fibonacci array. So arr[i] = arr[i-1]+arr[i-2] which is the classical Fibonacci transformation or function. And once again, what's important for our purpose is that this VM program is designed to test the ability of your VM translator to handle label, go to, if go to, as well as many other commands in the VM language. So that's the story about Fibonacci series. I wish to emphasize once again that you don't have to spend too much time understanding the details of this program, because the details of the semantics are not terribly important for our translation task, which is what we're focusing on right now. All right, so this completes the testing of the branching commands. And now we move on to test your ability to handle functions. Which is far more challenging in terms of the time that you spent on implementing your Vm translator, I assume. All right, so simple function is a bunch of four familiar files and here is a simple function dot Vm. It performs a simple and completely meaningless and arbitrary calculation whose purpose is something that we'll see in a minute. And it returns the value of this calculation. And there's a text script that initializes the segments, and executes the code. So, here's the function and you see that he does some add, not, sub and so on. Not important, not interesting. What is interesting is that this function here, or this VM code is design to test the ability of your VM translator to handle the function and return VM commands. Now, this is a relatively simple test because there's no caller in the picture. The function is doing it's thing, but no one invokes the function, no one tries to pass parameters to this function. There is no return value that goes back to the caller. We decided to unit test first the function and return commands only and then test the call Command using a separate test file. And in fact that's the next thing that we are going to do. So actually the next thing if you look at the screen is a directory called nested call. I will skip this directory and go straight into Fibonacci element and then I will go back to to nested call, promised. So here's my FibonaccElement directory. And as you see there's something new here, and what is new is that this is the first time, I believe, that we see more than one vm program or vm file in the same directory. So, as you know, when we have more than one .vm file in the directory, we have to translate the entire directory. That's the contract that we requested that you implement in your vm translator. So once you see the prompt on your computer, it should vary from one computer to another. You write VM translator if you wrote this program let's say in Java, and then you provide the name of the directory. The result should be a single file called FibonacciEelement.asm. It is the responsibility of your VM translator to produce this file and now we can take this file and test it further. Alright, so with that, let us explore what we have in these two vm files beginning with. So contains a single function called and this function computes the nth element of and he does it recursively as opposed to what we did before which was using an array. And by the way, this program has nothing to do with the program that we used before which was called I think. Of course there's a mathematical relationship between them. But it's a completely different program in a rather different algorithm. So how do we compute the nth element of the Fibonacci series? Well, here is how we do it. We do it using recursion. So if you stop the tape and look carefully at the code you will see that we are calling the Fibonacci function, is calling the Fibonacci function twice. And thus what we do here is we implement the logic that you see here in this call out. And classical recursive computation of Fibonacci Element. There's nothing terribly important here as far as our limited context of testing your VM translator, but if you want, you can try to understand this code deeper. Not terribly important. What's important is that it serves to test our trans data. All right, so this is the same program abbreviated, and we have to invoke it somehow. We have to call this function. So, we do it using the Sys vm file, another test file in this directory. And this file, we decided that it will have a single function only, called Sys.init. Now, you may remember that according to our convention, Sys.init should call the function Main.main, and then the application starts running. However, in project eight we decided to use this function differently and in particular, we use Sys.init in order to invoke all sorts of this functions as we please. Now this whole setting is very useful because by convention, when you start running the vm implementation, it should call Sys.init and then Sys.init will call the test function. So things are well laid out. So, here's what we do. We decide to test the Fibonacci element function using, say, the number four. So we wanted to compute the fourth element of the Fibonacci series. So we push four, call the function and then we enter an infinite loop. Why? Because we decided that this will be the standard way to implement Sys.init. When we complete building the whole computer and the operating system and everything, Sys.init will be the first function that starts running. When the computer is booted up and it is the origin of everything so to speak. So Sys.init calls Main.main and then tetris starts, or your search engine starts, or whatever it is that you decided to write using our platform. So notice that this test here is designed to test the handling of the function, return and call commands, and as well as many other commands that can be found in these two VM files. And we all test that your VM implementation, the inference date that you wrote, initializes and handles the memory segments correctly. Up until now, we provided test scripts that have set the virtual segments and manually, now it is your responsibility to handle it using your VM translator. And finally, we also test that the bootstrap code of your VM implementation initializes the stack, the stack pointer, and calls Sys.init. If you're not sure what I'm talking about, you have to look back at the units that define what the translator is supposed to do, and you will see all the details there. So this is going to be quite an elaborate test and I hope that your VM translator will pass it without too much trouble. And yet, when we first release all these test to the public domain and people started using it, our colleague Mark Ambros who contributed tons of good stuff to this course, Mark pointed out that the testing gap between the simple function and the element is too big. And that we may need some additional testing done in the middle, between these two testing stages. And, so Mark went ahead and developed another test, which I now want to look at, and this test is called NestedCall, and everything that you see here was designed by Mark, so you see that we have a set of files. A single VM file, sys.vm, and then a set of corresponding test files as well as two HTML files. Now, this test once again it closes some gaps between simple function and the Fibonacci element, in terms of the different things that Mark decided to test. And we recommend that you do this test in case simple function passes and Fibonacci element fails. If that is the case, you may want to go back and use NestedCall in order to localize the problems in your VM translator better. And finally, this test is very well documented using the two HTML files here that Mark has written. So, we just suggest that you, if needed read those files and follow Mark's guidelines. So that's what I wanted to say about function calling and the last test that we have to run, is called statics test and that's what we see here. Once again, it consists of several VM files and therefore once again, we have to apply your VM translator to the entire directory and the result once again, will be a single file within HEC assembly language. And let's see, what is the problem to which this thing is the solution? Well, first of all, here is Class1.vm and we see that this program stores to supply the arguments in static zero and static one. So it's not a terribly interesting function, is it. And here's how it does it. It pushes argument 0, pops static 0, does the same with argument 1. And then before returning it pushes 0 onto the stack. Why we do it is not terribly important at this point, we'll discuss it at length later when we write the compiler. So don't worry about this strange looking push. Before the return. Then, there's one more function in this file called Class1.get. And this function computes and returns the difference between static 0 and static 1. And as you see, there's nothing mysterious here. Everything is straightforward. So that's Class1.vm. Now, what about Class2? Well, here is the code of Class2. And if you will stop the tape and look at it, you will realize that what we have here are two identical files, almost. I mean, they have exactly the same logic except for some maybe syntactic differences. And yet, remember that even though we have two separate VM files, each one of them has to maintain. It's own static segment, and that's what this test is all about. The test is going to call different functions from two files, and make sure that the static segments of these two files are handled appropriately. So, how do we do it? Well, here are the two files that we just abbreviated We introduce Sys.vm file that has Sys.init and Sys.init pushes 6 and 8 and then calls the set function of Class1. So we expect that Class1 will populate its static segment with a 6 and 8. And then notice that the caller also does a pop temp 0. Looks like a strange thing to do, don't worry about it. We'll deal with it when we're at the compiler. And then we do exactly the same with Class2. We also call the set function of Class2 with 23 and 15 as parameters. And once again, we dump, we do the pop temp 0. And finally, we call the two get methods of Class1 and Class2. And that's it, we enter this infinite loop. And if you go back to the logic that was presented before, at the end of all this fruit salad here, we should expect to see on the stack the results of 6 minus 8 and 23 minus 15, which I believe is 2 followed by 7, is it, or 8? So we should see on the stack 2 and 8. If we see something else, it means that either my arithmetic is not good or your VM translator is not well functioning. All right, so this test here is designed to check that the static segments of different files are handled correctly. And once you will pass this test, you are done with all the official tests of project 8. Obviously, we could have supplied additional testing materials for more complete tests. But this is probably more than enough in the context of this course. All right, now what tools and resources will you need? Well, first of all you will need all the test programs and the compare files and you will find them on your computer in the project directory. You can look at the chapter 8 in the book that covers everything that we did in this module in one place in a compact way. And then you will need a whole set of resources that we used also in project 7, so I'm not going to repeat them here. It's exactly the same stuff that we did in project 7. All right, so this has been a description of project 8. I wish you good luck with this project. And I will see you in the next unit.