0

So, I am making a really simple Python interpreter. But, there is a part in the interpreter that checks for if statements. But, whenever I use this interpreted if statement, it checks every other indented line (which is what code should be executed if the statement is true). My code is shown below.

def tof(c):
    if eval(c) == True:
        return True
    elif eval(c) == False:
        return False

def interpret(code):
    lines = code.splitlines()
    for line in lines:
        if line.startswith("//") or line.strip() == "" or line.startswith("   "):
            continue
        if line.startswith("write(") and line.endswith(")"):
            if line[6] == '"' and line[-2] == '"':
                print(line[7:-2])
            elif line[6:-1].isdigit():
                print(line[6:-1])
            else: # not done yet (variables)
                v = line[6:-1]
                exec(f"print({v})")
        if line.startswith("if ") and line.endswith(" then"):
            one = line.split("if ")[1]
            c = one.split(" then")[0]
            if tof(c) == True:
                for x in lines:
                    if x.startswith("    "):
                        interpret(x.split("    ")[1])
            elif tof(c) == False:
                continue
        if line[2] == "=" or line[1] == "=": # not done yet (variables)
            if line[2] == "=":
                a = line.split(" = ")[0]
                b = line.split(" = ")[1]
                exec(f"{a} = {b}")

code = '''
if 1 + 1 == 2 then
    write("This should execute once!")
if 1 + 3 == 4 then
    // asterisk are there to tell which message is which.
    write("This should execute once! **")
'''

interpret(code)

I tried breaking the loop as soon as it sees an unindented piece of code, but if I put something like this:

if True then
    write("Hello, World!")
write("Stops here :(")
    write("Never gets here..")

it doesn't get to the last line

12
  • 1
    for x in lines: is processing all the lines, not just the ones after the if line. Commented May 31, 2024 at 19:56
  • 1
    And when the loop continues, it starts with the next line after if, it doesn't skip all the indented lines. Commented May 31, 2024 at 19:57
  • 1
    But you can't use for line in lines: as your main loop, because that doesn't allow the code inside the loop to change your position. Commented May 31, 2024 at 20:01
  • 1
    Of course it will. When you do line = next(iterator) the line is the same string as when you do for line in lines: Commented May 31, 2024 at 20:19
  • 1
    interpret(x.split(" ")[1]) won't work if you have nested if statements. interpret() expects all the statements to be in its argument, but this will just call it with one line. Commented May 31, 2024 at 20:33

1 Answer 1

0

In this piece of code on line 24

for x in lines:
    if x.startswith("    "):
        interpret(x.split("    ")[1])

I noticed that you loop through the whole code from the first line just to interpret the if statement causing to reinterpreting the code again and that's why your code is run twice instead of once.

to fix it enumerate through lines in the interpret function to keep track of the index.

    for i, line in enumerate(lines):

and then in the code of the if statement just interpret the next line and break when there is no indent like this.

for x in lines[i+1:]:
    if x.startswith("    "):
        interpret(x.split("    ")[1])
    else:
        break

and now it will output this

This should execute once!
This should execute once! **
Sign up to request clarification or add additional context in comments.

2 Comments

This won't fix the problem with the main loop, which will continue with the next line rather than going to the end of the block.
Good point I didn't notice it. You can just remove the enumerate thing and do lines = iter(lines) and like that it won't loop from the first line and no need to slice lines. the problem is it won't interpret the next line right after the if statement block.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.