Created
December 6, 2017 15:46
-
-
Save Zheaoli/507056ff34c42c20dae7601379ab5c6a to your computer and use it in GitHub Desktop.
tail_call.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from ast import * | |
| from inspect import getsource | |
| class TailCall(NodeTransformer): | |
| def visit_Return(self, node): | |
| temp_return = node.value | |
| if temp_return.__class__ == Call: | |
| func = temp_return.func | |
| func_args = temp_return.args | |
| return copy_location( | |
| Return( | |
| value=Tuple(elts=[ | |
| Str(s="__tail"), | |
| func, | |
| List(elts=func_args, ctx=Load()) | |
| ], ctx=Load()), ctx=Load() | |
| ), node | |
| ) | |
| return node | |
| def tail_call(func): | |
| ret = func() | |
| while isinstance(ret, tuple) and ret[0] == '__tail': | |
| _, func, args = ret | |
| ret = func(*args) | |
| return ret | |
| def compile_tco(f): | |
| ast = parse(getsource(f)) | |
| tco_ast = fix_missing_locations(TailCall().visit(ast)) | |
| return compile(tco_ast, __name__, 'exec') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment