|
1 | | -# NTU Introduction to Computer 2023 Fall Final Project |
| 1 | +# NTU Introduction to Computer 2023 Fall Final Project - Assembler & VM Translator |
| 2 | + |
| 3 | +In this final project, I implemented projects 6 through 8 of the textbook, namely the Hack assembler and VM-to-Hack translator. I chose C++ as my programming language and opted for an object-oriented approach, not fully complying with the suggestions from the textbook. |
| 4 | + |
| 5 | +I learned several software development tools through the process of doing this project. [CMake](https://cmake.org/), a cross-platform build system generator, is used to build this project, as it allows code to be compiled on various platforms with different compilers, and also simplifies testing and binary distribution. I chose [Abseil](https://github.com/abseil/abseil-cpp) as my support library, utilizing it's logging library, flags library and string utilities. For unit testing, [GoogleTest](https://github.com/google/googletest) is the framework of choice. |
| 6 | + |
| 7 | +## Assembler |
| 8 | + |
| 9 | +assembler - An assembler for the Hack platform. |
| 10 | + |
| 11 | +### Usage |
| 12 | + |
| 13 | +``` |
| 14 | +assembler SOURCE |
| 15 | +``` |
| 16 | + |
| 17 | +*`SOURCE`*: Source assembly file to be assembled. |
| 18 | + |
| 19 | +### Description |
| 20 | + |
| 21 | +The assembler is a rather simple program. It translates Hack assembly code into Hack machine code with a two-pass approach, processing labels in the first pass and translating code in the second pass. |
| 22 | + |
| 23 | +### Build and test |
| 24 | + |
| 25 | +#### Requirements |
| 26 | + |
| 27 | +- CMake 3.20 or later |
| 28 | +- A C++ compiler supporting at least C++17 |
| 29 | + |
| 30 | +#### Build |
| 31 | + |
| 32 | +To build the assembler, run the following commands: |
| 33 | + |
| 34 | +```sh |
| 35 | +cd assembler |
| 36 | +cmake -B build |
| 37 | +cmake --build build --target install |
| 38 | +``` |
| 39 | + |
| 40 | +The compiled binary should appear under the `assembler` directory. |
| 41 | + |
| 42 | +#### Test |
| 43 | + |
| 44 | +At the time of writing the assembler, I didn't think of writing unit tests and automated tests, so I tested each test program from the textbook manually. |
| 45 | + |
| 46 | +To test that the assembler is working correctly, compare the machine code output of our assembler to that of the textbook's assembler. |
| 47 | + |
| 48 | +## VM translator |
| 49 | + |
| 50 | +vmtranslator - A VM code to Hack assembly code translator. |
| 51 | + |
| 52 | +### Usage |
| 53 | + |
| 54 | +``` |
| 55 | +vmtranslator [-v] [-d] SOURCE |
| 56 | +``` |
| 57 | + |
| 58 | +- *`SOURCE`*: Source VM program to be translated. |
| 59 | +- `-v`: Verbose output. Print translated assembly code to console. |
| 60 | +- `-d`: Debug mode. Write VM source lines as comments in assembly output. |
| 61 | + |
| 62 | +If *`SOURCE`* is a single VM file (for example, `MyProgram.vm`), the translator will output the assembly file in the same directory as *`SOURCE`* (for example, `Program.asm`). If *`SOURCE`* is a directory (for example, `MyProgram`), the translator will gather and translate each VM file under the directory and output the assembly file under the directory (for example, `MyProgram/MyProgram.asm`). |
| 63 | + |
| 64 | +### Description |
| 65 | + |
| 66 | +The VM translator is the primary focus of the final project. It is comprised of four modules—`command`, `addressing`, `parser`, and the main program. |
| 67 | + |
| 68 | +The `commands` module contains classes for each of the 17 VM commands of the Hack platform. The `ToAssembly()` method returns assembly code of the command. Thanks to an object-oriented design, it also offers abstract base classes for extensibility. If developers want to extend the VM command set, they could inherit from base classes such as `BinaryArithmeticCommand` and `UnaryArithmeticCommand` and override the virtual function `ToAssembly()`. |
| 69 | + |
| 70 | +The `addressing` module contains classes for each of the 8 memory segments of the Hack platform. The `AddressingAssembly()` methods returns assembly code that stores the address of the value to be accessed in registers specified in its argument `destination`. Developers could also introduce custom memory segments by inheriting from an appropriate abstract base class and overriding `AddressingAssembly()`. |
| 71 | + |
| 72 | +The `parser` module parses an VM file and provides a friendly interface for accessing the commands. |
| 73 | + |
| 74 | +The main program drives the entire translation using the other 3 modules. It has a verbose mode, which also prints the translated assembly to the console, and a debug mode, which write VM source lines as comments in assembly output, both of which can be enabled via command-line flags. |
| 75 | + |
| 76 | +### Build and test |
| 77 | + |
| 78 | +#### Requirements |
| 79 | + |
| 80 | +- CMake 3.20 or later |
| 81 | +- A C++ compiler supporting at least C++17 |
| 82 | +- A Java runtime environment that can run nand2tetris's CPU emulator (used in testing) |
| 83 | + |
| 84 | +#### Build |
| 85 | + |
| 86 | +To build the VM translator, run the following commands: |
| 87 | + |
| 88 | +```sh |
| 89 | +cd vmtranslator |
| 90 | +cmake -B build |
| 91 | +cmake --build build --target install |
| 92 | +``` |
| 93 | + |
| 94 | +The compiled binary should appear under the `vmtranslator` directory. |
| 95 | + |
| 96 | +#### Test |
| 97 | + |
| 98 | +This project contains unit tests for the `addressing` and `commands` modules, as well as automated tests of test programs provided from the textbook. |
| 99 | + |
| 100 | +To run the tests after building, run the `ctest` command under the `build` directory. The output is similar to the following: |
| 101 | + |
| 102 | +``` |
| 103 | +Test project /tmp2/b12902110/ntu-introcs-2023-fall-final-project/vmtranslator/build |
| 104 | + Start 1: DestinationTest.DestinationString |
| 105 | + 1/62 Test #1: DestinationTest.DestinationString ............................ Passed 0.01 sec |
| 106 | + Start 2: AddressingTest.ArgumentAddress |
| 107 | + 2/62 Test #2: AddressingTest.ArgumentAddress ............................... Passed 0.01 sec |
| 108 | + Start 3: AddressingTest.LocalAddress |
| 109 | + 3/62 Test #3: AddressingTest.LocalAddress .................................. Passed 0.01 sec |
| 110 | +... |
| 111 | + Start 59: Translation: test_programs/FunctionCalls/FibonacciElement/ |
| 112 | +59/62 Test #59: Translation: test_programs/FunctionCalls/FibonacciElement/ ... Passed 0.01 sec |
| 113 | + Start 60: Comparison: test_programs/FunctionCalls/FibonacciElement/ |
| 114 | +60/62 Test #60: Comparison: test_programs/FunctionCalls/FibonacciElement/ .... Passed 0.21 sec |
| 115 | + Start 61: Translation: test_programs/FunctionCalls/StaticsTest/ |
| 116 | +61/62 Test #61: Translation: test_programs/FunctionCalls/StaticsTest/ ........ Passed 0.01 sec |
| 117 | + Start 62: Comparison: test_programs/FunctionCalls/StaticsTest/ |
| 118 | +62/62 Test #62: Comparison: test_programs/FunctionCalls/StaticsTest/ ......... Passed 0.21 sec |
| 119 | +
|
| 120 | +100% tests passed, 0 tests failed out of 62 |
| 121 | +
|
| 122 | +Total Test time (real) = 2.57 sec |
| 123 | +``` |
0 commit comments