python, pt.09: 함수 호출, 반환에서 처음부터 간단한 인터프리터를 빌드할 수 있습니다.
21999 단어 pythonfromscratchinterpreter
# This is required for returning without primitives
class Empty:
pass
class Interpreter:
# Updated constructor for holding our functions
def __init__(self):
self.scope= [{}]
self.loop_stack=[]
self.funcs = {}
#....(previous code)....
# Updated to check if we returned or not
def If(self,xs):
_,cond,trueblock,elseblock=xs
if self.eval(cond):
if isinstance(trueblock[0],list):
for x in trueblock:
self.eval(x)
# Return check
if "retval" in self.scope[-1]:
return
else:
self.eval(trueblock)
else:
if elseblock:
if isinstance(elseblock[0],list):
for x in elseblock:
self.eval(x)
# Return check
if "retval" in self.scope[-1]:
return
else:
self.eval(elseblock)
# Updated:
def While(self,xs):
self.loop_stack.append({"break":False,"continue":False})
_ , cond , block = xs
while self.eval(cond):
if isinstance(block[0],list):
for x in block:
self.eval(x)
# Return check
if "retval" in self.scope[-1]:
self.loop_stack.pop()
return
if self.loop_stack[-1]["break"]:
self.loop_stack.pop()
return
if self.loop_stack[-1]["continue"]:
self.loop_stack[-1]["continue"]=False
break
else:
self.eval(block)
self.loop_stack.pop()
# Updated:
def For(self,xs):
self.loop_stack.append({"break":False,"continue":False})
_, inits, cond, increments, block = xs
for x in inits:
self.eval(x)
while self.eval(cond):
if isinstance(block[0],list):
for x in block:
self.eval(x)
# Return check
if "retval" in self.scope[-1]:
self.loop_stack.pop()
return
if self.loop_stack[-1]["break"]:
self.loop_stack.pop()
return
if self.loop_stack[-1]["continue"]:
self.loop_stack[-1]["continue"]=False
break
else:
self.eval(block)
for x in increments:
self.eval(x)
self.loop_stack.pop()
#New: Define a function
def Function(self,xs):
_, name, params, block = xs
self.funcs[name]={"params":params,"block":block}
#New:
def Return(self,xs):
if len(self.scope)<2: # we are in global scope
print("error: 'return' must be in function")
exit(1)
# Return with value
if len(xs)>1:
self.scope[-1]["retval"]=self.eval(xs[1])
# Return without value
else:
self.scope[-1]["retval"]=Empty()
# New:
def Call(self,xs):
_, funcname, params = xs
# Before adding scope to scope list,
scope={}
func=self.funcs[funcname]
# we must evaluate function params in current scope,
for i,p in enumerate(func["params"]):
scope[p]=self.eval(params[i])
self.scope.append(scope)
# now we are in new scope,
for x in func["block"]:
self.eval(x)
if "retval" in self.scope[-1]:
break
retval=self.scope[-1]["retval"]
self.scope.pop()
return retval
code=[
["Function","fibonacci",["n"], [
["If",["Lte",["Get","n"],1],
["Return",["Get","n"]],[]
],
["Return",
["Add",
["Call","fibonacci",[["Sub",["Get","n"],1]]],
["Call","fibonacci",[["Sub",["Get","n"],2]]]
]
]
]],
["Print","fibonacci(15) = ", ["Call","fibonacci",[15]]],
["Return"]
]
interpreter=Interpreter()
interpreter.run(code)
산출:
fibonacci(15) = 610
error: 'return' must be in function
Link 코드를 완성합니다.
기타 링크: Patreon
Reference
이 문제에 관하여(python, pt.09: 함수 호출, 반환에서 처음부터 간단한 인터프리터를 빌드할 수 있습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/smadev/lets-build-a-simple-interpreter-from-scratch-in-python-pt-08-function-call-return-1p55텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)