# Python basic arithmetic compiler

I am attempting to follow the "Let's build a compiler" tutorials, in order to build a basic language compiler for a custom assembly language.

Currently the specs of my compiler are:

• Accepts a single positive integer of any length as input
• Accepts two single digit numbers† with a "+" or "-" in between them as input
• If the program was just an integer, then generate assembly to push it to the stack
• If the program contained addition or subtraction, then generate assembly to find the sum, and push it to the stack

In the future, I would like to expand the compiler, by adding other operators, logic, variables, and more. So the question is, how can I improve my compiler in such a way, that it will be easier to expand, and add new features to in future?

Here is the code:

def runProgram(program):
if "+" in program:
index = program.index("+")
try:
return "PUSH " + program[index-1] + "\nPUSH " + program[index+1] + "\nADD"
except:
return "FAIL"
elif "-" in program:
index = program.index("-")
try:
return "PUSH " + program[index-1] + "\nPUSH " + program[index+1] + "\nSUB"
except:
#"INVALID DIGITS FOR SUBTRACTION"
return "FAIL"
else:
try:
int(program)
except:
#INVALID PROGRAM NOT INTERGER
return "FAIL"
return "PUSH " + program

testPrograms = ["3", "19", "5+2", "5-2", "birds", "12+23"]
for x in testPrograms:
print(x + ":\n" + runProgram(x))


Output in this test:

3:
PUSH 3
19:
PUSH 19
5+2:
PUSH 5
PUSH 2
5-2:
PUSH 5
PUSH 2
SUB
birds:
FAIL
12+23:
PUSH 2
PUSH 2
Press any key to continue . . .


† NOTE: The program will just add the two digits on either side of the operand

Accepts two single digit numbers† with a "+" or "-" in between them as input

in conjunction with the "12+23" test case. It's a very nice test case, but the double digit numbers are clearly beyond what the spec described. Behavior is unspecified in this case, though your program behaves very sensibly.

In runProgram(), the + and - cases are very similar. Can you break out a helper method that takes + / - as a parameter?

I recommend phrasing the last portion of the function in this way:

else:
try:
return 'PUSH ' + int(program)
except ValueError:
return 'FAIL'


The in program aproach seems fragile, especially if you have to handle programs like 5 + -3. You might want to tokenize early on, and pass in a list like [5, '+', -3]. Or perhaps define functions like add & subtract, and pass in [5, add, -3].