Advertisement
Guest User

Untitled

a guest
Nov 21st, 2018
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.12 KB | None | 0 0
  1.  
  2. class Environment(EnvironmentInterface):
  3.     """
  4.    Contains the name bindings for the current scope and points to a linked-list of parent scopes; push() and pop()
  5.    return a different environment (either a new one or the parent). To find a name (see __locate__), use the given
  6.    path to iterate through the parents and retrieve the index.
  7.    """
  8.     _immutable_ = True
  9.     _virtualizable_ = ['parent', 'expressions[*]', 'types[*]']
  10.  
  11.     def __init__(self, parent, expressions, types):
  12.         #self = hint(self, access_directly=True, fresh_virtualizable=True)
  13.         self.parent = parent
  14.         self.expressions = expressions
  15.         self.types = types
  16.  
  17.     def __str__(self):
  18.         return 'Environment(expressions=%s, types=%s)' % (self.expressions, self.types)
  19.  
  20.     @staticmethod
  21.     def empty(parent=None, number_of_names=0):
  22.         assert isinstance(number_of_names, int)
  23.         expressions = [None] * number_of_names  # TODO should be (total - types)
  24.         types = [None] * number_of_names  # TODO should be (total - variables)
  25.         return Environment(parent, expressions, types)
  26.  
  27.     def push(self, number_of_names):
  28.         """Create a new environment level (i.e. frame)"""
  29.         return Environment(self, [None] * number_of_names, [None] * number_of_names)
  30.  
  31.     def pop(self):
  32.         """Remove and forget the topmost environment level (i.e. frame)"""
  33.         assert self.parent is not None
  34.         return self.parent
  35.  
  36.     def add(self, index, expression):
  37.         """
  38.        Add a name to the current level
  39.        """
  40.         assert 0 >= index > len(self.expressions)
  41.         self.expressions[index] = expression
  42.  
  43.     def set(self, path, expression):
  44.         """
  45.        Set 'name' to 'expression'; if it exists in a prior level, modify it there; otherwise, add it to the current
  46.        level
  47.        """
  48.         found_level, found_index = self.__locate__(path, self)
  49.         # location found, modify it (otherwise locate will raise)
  50.         found_level.expressions[found_index] = expression
  51.  
  52.     def set_type(self, path, type):
  53.         found_level, found_index = self.__locate__(path, self)
  54.         # location found, modify it (otherwise locate will raise)
  55.         found_level.types[found_index] = type
  56.  
  57.     def get(self, path):
  58.         """Retrieve 'name' from the environment stack by searching through all levels"""
  59.         found_level, found_index = self.__locate__(path, self)
  60.         return found_level.expressions[found_index]
  61.  
  62.     def get_type(self, path):
  63.         found_level, found_index = self.__locate__(path, self)
  64.         return found_level.types[found_index]
  65.  
  66.     def unset(self, path):
  67.         """Unset 'name' only in the current level; will not search through the entire environment"""
  68.         found_level, found_index = self.__locate__(path, self)
  69.         found_expression = found_level.expressions[found_index]
  70.         found_level.expressions[found_index] = None
  71.         return found_expression
  72.  
  73.     def size(self):
  74.         """Non-optimized convenience method; count the number of slots in the entire environment"""
  75.         level = self
  76.         number_of_slots = 0
  77.         while level:
  78.             number_of_slots += len(level.expressions)
  79.             level = level.parent
  80.         return number_of_slots
  81.  
  82.     def clone(self):
  83.         """Clone an environment by copying the stack shallowly"""
  84.         return self
  85.         #return Environment(self.parent, [e for e in self.expressions], [t for t in self.types])
  86.  
  87.     @staticmethod
  88.     @unroll_safe
  89.     def __locate__(path, level):
  90.         assert isinstance(level, Environment)
  91.  
  92.         hops, index = path
  93.         assert isinstance(hops, int)
  94.         assert isinstance(index, int)
  95.  
  96.         while hops >= 0 and level:
  97.             if hops == 0:
  98.                 if not 0 <= index < len(level.expressions):
  99.                     break  # in this case we have not found a valid slot for the path and should throw an error
  100.                 return level, index
  101.             hops -= 1
  102.             level = level.parent
  103.  
  104.         raise EnvironmentError('Expected path (%d, %d) to lead to a valid scope but it did not' % (path[0], index))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement