Creating an Interpreter for Monty Bytecodes Using C Programming Language

Robert Amoah
6 min readJun 17, 2023

--

PART SIX

This is the link to the previous part (PART FIVE), in case you missed it: https://medium.com/@mr_robertamoah/mcreating-an-interpreter-for-monty-bytecodes-using-c-programming-language-916d1837546

We have had a lot of fun so far while writing some interesting code. Please try as much as possible to leave a comment behind. Let me know what you think about these serial articles as well as my writing style. Do you think I should explain something in more detail? Is there something I missed? Let me know about it and I would love to address it.

For this part of the series, we will start with the implementation of the pchar opcode. The opcode pchar prints the char at the top of the stack (last node to be added to the stack), followed by a new line.

print the ASCII character representation of the head node
pchar.c

There is an error when the linked list is empty. Also, there is an error when the integer cannot be treated as an ASCII value of char. We know the ASCII values range from 0 to 126. Once the n member has a value outside of this range, then we need to print an error and exit from our program. Otherwise, we print the character representation of the n member variable followed by a newline. We can test our code with the bytecode shown in the image below. The output shows that our implementation works.

standard output

The next opcode to implement is pstr. The opcode pstr prints a string starting at the top of the stack, followed by a new line. What this means is that we will loop through the linked list, printing the ASCII character representation of the n member of each node in the linked list until the list ends, a n value falls outside of the range of ASCII values or n is equal to 0. We then print an additional newline. Below is a code for the implementation. A temporary value (tmp1) allows me to loop through the linked list. And while I go through the list, I either break out to print a newline or print the ASCII character representation of the value of n member of the node tmp1 variable currently holds based on the conditions mentioned above.

pstr.c

I tested the code with the contents of the file below. The output can be seen as well.

standard output

The next opcode to implement is the rotl. The opcode rotl rotates the stack to the top such that the last node of the linked list becomes the first one, and the last but one node of the linked list becomes the last. Look at the code below to see how I implemented this.

head node should become the last node in the linked list
rotl.c

If a linked list has less than 2 nodes, then it cannot be rotated hence we return from the function because this function does not fail. What I also did here was to set tmp1 to the last node of the linked list. Whereas tmp2 points to the last but one node of the linked list. I then make the last but one node the last node by making the head member of out arguments pointer point to tmp2. What I did next was to loop through the list starting from the last but one which is now the last while trying to find the first node node to be inserted (the last node in the linked list), which is the node with its next member being NULL. Once I find that node, I set its next to tmp1 which used to be the last. Hence it becomes the new first node. But to set the link properly, tmp1’s next must be NULL whereas it’s prev points to the current tmp2, which is the node that used to be the first node in the stack. The looping only works if I keep switching to the next node using the “tmp2 = tmp2->next” statement. Without this statement, our loop will be infinite. Below shows the content of the file I used to test this opcode as well as the output after running the newly compiled program.

standard output

Looking at the numbers pushed, it is obvious our last node will initially be zero, with the first node being 1. Once rotl opcode is run successfully, our last node should now become 9, which previously was the las but one, with our first now being 0, which previously was the last node. So, our program correctly prints numbers 0, 9, 8 to 1 for the first pall execution. For the second pall execution, our program prints numbers from 9, 8, 7 to 0. This is the correct output. For clarity, last node here means the last node to be added to stack.

The last opcode to implement for this Part will be the rotr opcode. The opcode rotr rotates the stack to the bottom. What this means is the first node (first to be added to the stack or the last node of the linked list) becomes the last node (last to be added to the stack or the first node of the linked list which will be pointed to by head member of arguments). How would you implement this? Can we disconnect the first node from the end of the linked list, and then insert it afresh at the other end? To make you better understand this, we are using stack data structure, and we are inserting each new node that the beginning of a linked list. Knowing your linked lists, you will remember there are few types of insertion, two of which are insertion at the beginning and insertion at the end. We are using insertion at the beginning in this case. So, our first node in the stack, based on our mode of insertion will the last node in the linked list (which is the first node to be added). The last node in our stack will be the first node in the linked list (which is the last node to be added to the linked list).

the last node in the linked list should become the head of the list
rotr.c

What I did here was to look for the last item in the linked list (the first item to be added or the first item in the stack). I got the node by searching for the node which has its next member being NULL.

standard output

Just like that of rotl, the first node in the linked list is the node with its n member being 1 while the last is 0. Therefore, the first pall will print from the last which is 0 to first which is 1. After rotr, the last node in the linked list (the first to enter the stack) should become the first node in the linked list (the last node in the stack). This means the node with the value 1 will be disconnected from the end of the linked list, and reinserted at the beginning of the linked list. Hence, the last pall should print 1 before 0, which used to be the last node, down to 2. The new first node in the stack (or last node in the linked list) will now be 2.

This brings us to the end of Part Six. In the next article (Part Seven), we will look at how to implement the queue. All that we have done so far deals with the implementation with stack. See you in the next part. Do not forget to comment (criticisms, questions, etc). They are welcome.

This is the link to the next part (PART SEVEN) of the series: https://medium.com/@mr_robertamoah/creating-an-interpreter-for-monty-bytecodes-using-c-programming-language-287a2c2aa706

--

--

Robert Amoah

Full-stack web developer #laravel #nestjs #vue #react Mobile Application Development #reactnative DevOps and Cloud enthusiast #linux #bash Love Data Science