Creating an Interpreter for Monty Bytecodes Using C Programming Language

Robert Amoah
4 min readJun 17, 2023

--

PART FIVE

This is a link to the previous part (PART FOUR), in case you missed it: https://medium.com/@mr_robertamoah/creating-an-interpreter-for-monty-bytecodes-using-c-programming-language-1bd363ed924f

Having seen the implementation of add opcode, the implementation of sub, div and mul opcodes becomes easier. The only changes made with respect to these functions are the names of the functions, the error messages and the change of the operator “+” to “-“, “/” and “*” respectively. It is only the div opcode implementation that we will see the addition of some new code to deal with the division by 0. Let us look at the implementation of these three functions.

add.c
subtract the head from its next node
sub.c
find the product of the head node and its next node
mul.c
find the quotient of the head’s next node and the head node
div.c

You can see the similarities these functions have. Let us just look at the _div function. The last node’s n is the divisor of the division operation. For this reason, we need to check if it is zero prior to the division. If it is, there is an error message that is printed, and the program exited. Otherwise, a normal division of the n of the last but one node by the n of the last node is performed and the result assigned to the n member of the last but one node. Quite simple, isn’t it?

Now let’s implement the nop opcode. The opcode nop doesn’t do anything. So, its function will simply contain voids of the arguments we passed to the function. Mind you, it needs to have these variables come in because it should have similar prototype as the other functions of the opcodes.

nothing done
nop.c

The next opcode to implement is the mod opcode. This opcode computes the remainder of the division of the last but one node of the stack by the last node of the stack. The implementation of this opcode is similar to the implementation of the div opcode. We will have to prevent the division by zero just as we did when we implemented the div opcode. The only difference being the change of “/” operator to “%” operator. The code is found below.

mod.c

The next thing to implement is comments. When the first non-spaced character of the line read is “#” then the line is comment which means we are not to do anything. There are a number of ways I can implement this. First of all, I will check if the first character of the first token in the tokens array is “#, then I can choose to do a number of things. I can choose to assign to the opcode and f members of the instruction pointer member of our global arguments variable with “nop” and nop function respectively. I can also, create an is_comment member in the arg_s struct which will be 0 on initialization. I will set it to 0 before doing the checking if the line is a comment, inside of the get_instruction function. When the line is a comment, is_comment becomes 1. This will also require an update to the run_instruction. In that, we will have to return from the run_instruction function if is_comment member of the arguments pointer is 1. For both options, we will return from the get_instruction function before the for loop is used to try getting the valid instruction. Think carefully about these two options. I will go for the first option. This is how our get_instruction will look like:

update get_instruction to handle comments
get_instruction.c

So, after checking if there are no tokens, the next check is if the first token starts with “#”. Now let me add a comment to our last bytecode file and then run our program with it and see if it works. If it works, we should get the same output as we did. If it doesn’t work, then there will be an error from the invalid_instruction function. Look at the bytecodes and output below, after compiling and running the program.

standard output

We get the same output as we did. Hence, commenting works fine. You can try out the second option I described and let me know if it works as well. Or do you have another way of implementing it altogether? Please let me know about it in the comment section. We will end Part Five here. In the next Part, we will handle the pchar, pstr, rotl and rotr opcodes. Stay tuned 💪.

This is the link to the next part (PART SIX): https://medium.com/@mr_robertamoah/creating-an-interpreter-for-monty-bytecodes-using-c-programming-language-67c374b1c8f0

--

--

Robert Amoah

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