class ClosureGiverNodeBase(CodeNodeBase): """ Mixin for nodes that provide variables for closure takers. """ def __init__(self, name, code_prefix, source_ref): CodeNodeBase.__init__( self, name = name, code_prefix = code_prefix, source_ref = source_ref ) self.providing = OrderedDict() self.keeper_variables = OrderedSet() self.temp_variables = OrderedDict() self.temp_scopes = OrderedDict() def hasProvidedVariable(self, variable_name): return variable_name in self.providing def getProvidedVariable(self, variable_name): if variable_name not in self.providing: self.providing[variable_name] = self.createProvidedVariable( variable_name = variable_name ) return self.providing[variable_name] def createProvidedVariable(self, variable_name): # Virtual method, pylint: disable=R0201 assert type(variable_name) is str return None def registerProvidedVariables(self, *variables): for variable in variables: self.registerProvidedVariable(variable) def registerProvidedVariable(self, variable): assert variable is not None self.providing[variable.getName()] = variable def getProvidedVariables(self): return self.providing.values() def allocateTempScope(self, name, allow_closure = False): self.temp_scopes[name] = self.temp_scopes.get(name, 0) + 1 # TODO: Instead of using overly long code name, could just visit parents # and make sure to allocate the scope at the top. if allow_closure: return "%s_%s_%d" % ( self.getCodeName(), name, self.temp_scopes[name] ) else: return "%s_%d" % ( name, self.temp_scopes[name] ) def allocateTempVariable(self, temp_scope, name): if temp_scope is not None: full_name = "%s__%s" % ( temp_scope, name ) else: assert name != "result" full_name = name del name assert full_name not in self.temp_variables, full_name result = Variables.TempVariable( owner = self, variable_name = full_name ) self.temp_variables[full_name] = result addVariableUsage(result, self) return result def getTempVariable(self, temp_scope, name): if temp_scope is not None: full_name = "%s__%s" % (temp_scope, name) else: full_name = name return self.temp_variables[full_name] def getTempVariables(self): return tuple(self.temp_variables.values()) def removeTempVariable(self, variable): del self.temp_variables[variable.getName()]
class ClosureGiverNodeMixin(CodeNodeMixin): """ Blass class for nodes that provide variables for closure takers. """ def __init__(self, name, code_prefix): CodeNodeMixin.__init__(self, name=name, code_prefix=code_prefix) self.providing = OrderedDict() self.temp_variables = OrderedDict() self.temp_scopes = OrderedDict() self.preserver_id = 0 def hasProvidedVariable(self, variable_name): return variable_name in self.providing def getProvidedVariable(self, variable_name): if variable_name not in self.providing: self.providing[variable_name] = self.createProvidedVariable( variable_name=variable_name) return self.providing[variable_name] def createProvidedVariable(self, variable_name): # Virtual method, pylint: disable=no-self-use assert type(variable_name) is str return None def registerProvidedVariable(self, variable): assert variable is not None self.providing[variable.getName()] = variable def getProvidedVariables(self): return self.providing.values() def allocateTempScope(self, name, allow_closure=False): self.temp_scopes[name] = self.temp_scopes.get(name, 0) + 1 # TODO: Instead of using overly long code name, could just visit parents # and make sure to allocate the scope at the top. if allow_closure: return "%s_%s_%d" % (self.getCodeName(), name, self.temp_scopes[name]) else: return "%s_%d" % (name, self.temp_scopes[name]) def allocateTempVariable(self, temp_scope, name): if temp_scope is not None: full_name = "%s__%s" % (temp_scope, name) else: assert name != "result" full_name = name # No duplicates please. assert full_name not in self.temp_variables, full_name result = self.createTempVariable(temp_name=full_name) return result def createTempVariable(self, temp_name): if temp_name in self.temp_variables: return self.temp_variables[temp_name] result = Variables.TempVariable(owner=self, variable_name=temp_name) self.temp_variables[temp_name] = result return result def getTempVariable(self, temp_scope, name): if temp_scope is not None: full_name = "%s__%s" % (temp_scope, name) else: full_name = name return self.temp_variables[full_name] def getTempVariables(self): return tuple(self.temp_variables.values()) def removeTempVariable(self, variable): del self.temp_variables[variable.getName()] def allocatePreserverId(self): if python_version >= 300: self.preserver_id += 1 return self.preserver_id