Beispiel #1
0
 def __init__(self, compiler, namespace, statement):
     State.__init__(self, compiler, namespace, statement)
     self._result = None
     self._child_statements = {}
     self.__attributes = {}
     
     self._refs = {}
     self._resolved = False
     
     self._result_ref = ResultVariable(self)
Beispiel #2
0
class DynamicState(State):
    """
        Represents a dynamic state
    """
    def __init__(self, compiler, namespace, statement):
        State.__init__(self, compiler, namespace, statement)
        self._result = None
        self._child_statements = {}
        self.__attributes = {}
        
        self._refs = {}
        self._resolved = False
        
        self._result_ref = ResultVariable(self)

    def add_to_graph(self, graph):
        """
            @see State#add_to_graph
            
            This method ensures that the statement can be statically executed,
            which means that all types have been resolved.
        """
        State.add_to_graph(self, graph)
        
        # make sure all types are resolved
        if not State.resolved(self):
            # provide a meaningful error
            for req_type in self._required_types:
                if req_type not in self._resolved_types:
                    type_name = str(self._required_types[req_type])
                    raise Exception("Unable to resolve %s for statement %s in file %s:%d" %
                                    (type_name, self.statement, self.statement.filename, self.statement.line))
            
            raise Exception("Unable to resolve all required types")
        
        # get all references this statement needs
        for ref_def in self.statement.references():
            name = ref_def[0]
            value = ref_def[1]
            ref_type = "use"
            
            if len(ref_def) > 2:
                ref_type = ref_def[2]
            
            if ref_type == "use":
                value_ref = get_ref(self, value)
                self._refs[name] = value_ref
                
            elif ref_type == "def":
                scope = self.get_local_scope()
                scope.add_placeholder(name.name)
                
            else:
                raise Exception("Unknown ref type given by %s" % self)
            
        # add any statements under this node to the graph as well
        self.statement.new_statements(self)
        
    def resolved(self):
        """
            Are all dynamic references of this statement resolved?
        """
        if self._resolved:
            return True
        
        scope = self.get_local_scope()
        for ref in self._refs.values():
            if not ref.is_available(scope):
                return False
        
        self._resolved = True
        self.graph.add_actions(self, self.statement.actions(self))
        return True
    
    def can_evaluate(self):
        """
            Can this statement be evaluated in the current state it is in?
        """
        if not self.graph.can_evaluate(self):
            return False
        
        return self.statement.can_evaluate(self)
    
    def get_ref(self, name):
        """
            Get a reference
        """
        reference = self._refs[name]
        
        if reference.__class__ == Reference:
            return self.get_local_scope().resolve_reference(reference)
        
        return reference
    
    def get_result(self):
        """
            Get the result of evaluating this statement
        """
        return self._result
    
    def get_result_reference(self):
        """
            This method returns a reference to a result
        """
        return self._result_ref
    
    def set_evaluated(self):
        """
            Mark this state as evaluated
        """
        State.set_evaluated(self)
    
    def evaluate(self):
        """
            Evaluate this statement and if successful mark it as evaluated.
            
            @param force: Force the evaluation even if the statement is lazy.
        """
        local_scope = self.get_local_scope()
        
        value = self.statement.evaluate(self, local_scope)
        
        if hasattr(value, "_get_instance"):
            value = value._get_instance()
        
        if not isinstance(value, Variable):
            value = Variable(value)
            
        self._result = value
        
        if self._result is not None:
            self._result_ref.value_available()
    
        self.set_evaluated()
        
    def get_state(self, statement):
        """
            Get the state of a statement that has been added to the graph by
            this state.
        """
        if statement in self._child_statements:
            return self._child_statements[statement]
        
        raise KeyError()
        
    def add_statement(self, statement, child_ns = False):
        """
            Add a new statement that is generated or included by the statement
            linked to this state. The new statement is defined in the 
            same namespace as this statement or in a child namespace.
            
            @param statement: The new statement
            @param child_ns: Optional can be set to true to define it in a child
                namespace.
        """
        if statement in self._child_statements:
            raise Exception("Statement %s already added by %s" % 
                            (statement, self))
        
        namespace = self.namespace
        if child_ns:
            object_id = Scope.object_to_name(self)
            namespace = Namespace(object_id, self.namespace)
            
        child_state = DynamicState(self.compiler, namespace, statement)
        child_state.add_to_graph(self.graph)
        self._child_statements[statement] = child_state
        
        return child_state
    
    def get_attribute(self, name):
        """
            Get an attribute that is stored in this state
        """
        if name in self.__attributes:
            return self.__attributes[name]
        
        raise KeyError(name)
    
    def set_attribute(self, name, value):
        """
            Set a value in this state
        """
        self.__attributes[name] = value
        
    def has_attribute(self, name):
        """
            Is the attribute with name set?
        """
        return name in self.__attributes