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)
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,
Link to complete code.
Top comments (0)