Skip to content

Instantly share code, notes, and snippets.

@Zheaoli
Created December 6, 2017 15:46
Show Gist options
  • Select an option

  • Save Zheaoli/507056ff34c42c20dae7601379ab5c6a to your computer and use it in GitHub Desktop.

Select an option

Save Zheaoli/507056ff34c42c20dae7601379ab5c6a to your computer and use it in GitHub Desktop.
tail_call.py
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