DEV Community

sma
sma

Posted on • Edited on

Lets build a simple interpreter from scratch in python, pt.07: Break, Continue

In this post we are implementing 'Break' and 'Continue':

class Interpreter:

    # Modified constructor:
    # loop_stack holds "break" and "continue" status of
    # inner loops:

    def __init__(self):
        self.scope=[{}]
        self.loop_stack=[]

    #....(previous code)....

    def Break(self,xs):
        self.loop_stack[-1]["break"]=True

    def Continue(self,xs):
        self.loop_stack[-1]["continue"]=True

    def While(self,xs):
        # New:
        self.loop_stack.append({"break":False,"continue":False})
        _ , cond , block = xs
        while self.eval(cond):
            if isinstance(block[0],list):
                for x in block:
                    # While evaluating block,
                    self.eval(x)
                    # If break is called, exit from python loop
                    if self.loop_stack[-1]["break"]:
                        self.loop_stack.pop()
                        return
                    # If continue is called, break this for loop :)
                    if self.loop_stack[-1]["continue"]:
                        self.loop_stack[-1]["continue"]=False
                        break
            else:
                self.eval(block)
        self.loop_stack.pop()


# This is AST, not for humans, this is for interpreters
# I think it is very readable :P

ast =[

    ["Set","i",0],

    ["While", ["Lt", ["Get","i"], 100], [
        ["Set","i",["Add",["Get","i"],1]],

        ["If", ["Eq", ["Get", "i"], 5], 
             ["Break"],[]
        ],
        ["Print",["Get","i"]],

    ]],

    ["Print",["Mul","-",40]],

    ["Set","i",0],

    ["While", ["Lt", ["Get","i"], 100], [       
        ["Set","i",["Add",["Get","i"],1]],

        ["If", ["Lt", ["Get", "i"], 95], 
             ["Continue"],[]
        ],
        ["Print",["Get","i"]],

    ]],    

    ["Print",["Mul","-",40]],

    ["Set","i",0],

    ["While", ["Lt", ["Get","i"], 100], [       

        ["Set","i",["Add",["Get","i"],1]],

        ["If", ["Gte", ["Get", "i"], 5], 
             ["Break"],[]
        ],        

        ["Set","j",0],

        ["While", ["Lt", ["Get","j"], 100], [       
            ["Set","j",["Add",["Get","j"],1]],

            ["If", ["Gte", ["Get", "j"], 5], 
                ["Break"],[]
            ],
            ["Print",["Mul",["Get","i"],["Get","j"]], ","],

        ]],

        ["Print"]

    ]],     
]

interpreter=Interpreter()

interpreter.run(ast)
Enter fullscreen mode Exit fullscreen mode

Output:

1
2
3
4
----------------------------------------
95
96
97
98
99
100
----------------------------------------
1,2,3,4,
2,4,6,8,
3,6,9,12,
4,8,12,16,
Enter fullscreen mode Exit fullscreen mode

Link to complete code.

Part 8: For loop

Top comments (0)