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)