Hello! today you and i are going to make an interpreter in Python! They're not that hard, also, we're making an interpreter, nod an interpreted language. So, to start off, we will need instructions that our interpreter understands. we will only have 3 instructions for now:
LOAD
ADD
PRINT_RES
so, let's start making the interpreter!
class Interpreter:
def __init__(self):
self.stack = []
we define an init() method which creates the stack. We will use the stack to add and remove numbers from it. that's what the LOAD() method will do:
def LOAD(self, num):
self.stack.append(num)
next is ADD(). ADD() takes the last 2 numbers from the stack and pushes their sum to the stack. Now let's make the ADD() method:
def ADD(self):
b = self.stack.pop()
a = self.stack.pop()
self.stack.append(a + b)
We invert a and b because pop() removes the last item of the stack, not the item at a specific index of the stack:
stack:
[
6, <--- This is a (popped after b)
14 <--- And this is b (popped first)
]
now we have to do the PRINT_RES() method, which prints the last item of the stack:
def PRINT_RES(self):
r = self.stack.pop()
print(r)
finally, we will put it all together using a run() method:
def run(self, code):
instructions = code["Instructions"]
data = code["Data"]
for i in instructions:
action, arg = i
if action == "LOAD":
self.LOAD(arg)
if action == "ADD":
self.ADD()
if action == "PRINT_RES":
self.PRINT_RES()
We have one if statement for each instruction: one for LOAD, one for ADD and one for PRINT_RES. Here is the finished code:
class Interpreter:
def __init__(self):
self.stack = []
def LOAD(self, num):
self.stack.append(num)
def ADD(self):
b = self.stack.pop()
a = self.stack.pop()
self.stack.append(a + b)
def PRINT_RES(self):
r = self.stack.pop()
print(r)
def run(self, code):
instructions = code["Instructions"]
data = code["Data"]
for i in instructions:
action, arg = i
if action == "LOAD":
self.LOAD(arg)
if action == "ADD":
self.ADD()
if action == "PRINT_RES":
self.PRINT_RES()
With that, here is a test run:
code = {
"Instructions": [
["LOAD", 6],
["LOAD", 14],
["ADD", None],
["PRINT_RES", None]
],
"Data": []
}
i = Interpreter()
i.run(code) # Output: 20
And here, the same interpreter, written in JavaScript:
let interpreter = {
"stack": [ ],
"instr": [ ],
"data" : [ ],
"init": function (i, d) {
this.instr = i;
this.data = d;
},
"load": function (x) { this.stack.push(x); },
"add": function () {
let b = this.stack.pop();
let a = this.stack.pop();
this.load(a + b);
},
"print": function () { console.log(this.stack.pop()); }
};
And a test run:
let i = interpreter;
i.init(["print", "s0"], { "numbers": [], "strings": ["hi"], "names": [] });
And with this, goodbye! Have a nice day of programming!
Top comments (0)