document.write('
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. # -*- coding: utf-8 -*-
  2. from threading import currentThread
  3.  
  4. class TailRecursiveCall(Exception):
  5.     pass
  6.  
  7. class Rec_f(object):
  8.     def __init__(self, func):
  9.         self.tr_d = {}
  10.         self.func = func
  11.  
  12.     def __call__(self, *args, **kw):
  13.         self.args = args
  14.         self.kw = kw
  15.         thread = currentThread()
  16.         if thread not in self.tr_d:
  17.             self.tr_d[thread] = {}
  18.             self.tr_d[thread]["depth"] = 0
  19.         self.tr_d[thread]["depth"] += 1
  20.         # Record the arguments passed to function on this thread
  21.         self.tr_d[thread]["args"] = args
  22.         self.tr_d[thread]["kw"] = kw
  23.         depth =  self.tr_d[thread]["depth"]
  24.         # If we are re-entering the same function on the same thread:
  25.         if depth > 1:
  26.             # Effectively detours execution to the "Landing Point",
  27.             # but two execution frames above the current one:
  28.             raise TailRecursiveCall
  29.         over = False
  30.         while not over:
  31.             over = True
  32.             args = self.tr_d[thread]["args"]
  33.             kw = self.tr_d[thread]["kw"]
  34.             try:
  35.                 # Execute the function with the latest arguments for this thread.
  36.                 result = self.func(*args, **kw)
  37.             except TailRecursiveCall:
  38.                 # Landing point if the function tried to recurse itself.
  39.                 # Two execution frames above.
  40.                 self.tr_d[thread]["depth"] -= 1
  41.                 over = False
  42.         self.tr_d[thread]["depth"] -= 1
  43.         return result
  44.  
  45.  
  46. def tailrecursive(func):
  47.     return Rec_f(func)
  48.  
  49.  
  50. def fatorial (n):
  51.     if n == 1:
  52.         return 1
  53.     return n * fatorial(n -1)
  54.  
  55.  
  56. @tailrecursive
  57. def tail_fatorial (n, a=1):
  58.     if n == 1:
  59.         return a * 1
  60.     return tail_fatorial(n -1, n * a)
  61.  
  62.  
  63. if __name__ == "__main__":
  64.        
  65.     try:
  66.         print "999! %d" % fatorial(999)
  67.         print "2000! %d" % fatorial (2000)
  68.     except RuntimeError, error:
  69.         print "Fatorial normal quebrou: %s " % str(error)
  70.  
  71.  
  72.     try:
  73.         print "999! %d" % tail_fatorial(999)
  74.         print "2000! %d" % tail_fatorial (3000)
  75.     except RuntimeError, error:
  76.         print "Fatorial tail tambem quebrou: %s" %str(error)
');