4
\$\begingroup\$

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:
            #"INVALID DIGITS FOR ADDITION"
            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
ADD
5-2:
PUSH 5
PUSH 2
SUB
birds:
FAIL
12+23:
PUSH 2
PUSH 2
ADD
Press any key to continue . . .

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

\$\endgroup\$
1
\$\begingroup\$

I'm reading the 2nd requirement:

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].

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.