Exemple #1
0
    def assignment_semantics(self, stmt: Assignment, state: State) -> State:
        """Backward semantics of an assignment.

        :param stmt: assignment statement to be executed
        :param state: state before executing the assignment
        :return: state modified by the assignment
        """
        lhs = self.semantics(stmt.left, state).result  # lhs evaluation
        rhs = self.semantics(stmt.right, state).result  # rhs evaluation
        return state.substitute(lhs, rhs)
Exemple #2
0
 def update_call_semantics(self, stmt: Call, state: State, interpreter: Interpreter) -> State:
     assert len(stmt.arguments) == 2
     targets = self.semantics(stmt.arguments[0], state, interpreter).result
     op = BinarySequenceOperation.Operator.Concat
     values = self.semantics(stmt.arguments[1], state, interpreter).result
     rhs = set()
     for target in targets:
         for value in values:
             display = SetDisplay(SetLyraType(value.typ), [value])
             rhs.add(BinarySequenceOperation(target.typ, target, op, display))
     return state.substitute(targets, rhs)
Exemple #3
0
    def return_semantics(self, stmt: Return, state: State, interpreter: Interpreter):
        """Backward semantics of an return statement.

        :param stmt: return statement to be executed
        :param state: state before executing the return statement
        :return: state modified by the return statement
        """
        if len(stmt.values) != 1:
            error = f"Semantics for multiple arguments of {stmt} is not yet implemented!"
            raise NotImplementedError(error)
        lhs = state.result
        rhs = self.semantics(stmt.values[0], state, interpreter).result
        return state.substitute(lhs, rhs)
Exemple #4
0
    def user_defined_call_semantics(self, stmt: Call, state: State, interpreter: Interpreter):
        """Backward semantics of a user-defined function/method call.

        :param stmt: call statement to be executed
        :param state: state before executing the call statement
        :return: state modified by the call statement
        """
        fname, fcfg, _ = stmt.name, interpreter.cfgs[stmt.name], deepcopy(state)
        # analyze the function
        fresult = interpreter.analyze(fcfg, state)
        fstate = fresult.get_node_result(fcfg.in_node)[state][-1]
        state = state.bottom().join(deepcopy(fstate))
        # substitute function actual to formal parameters
        for formal, actual in zip(interpreter.fargs[fname], stmt.arguments):
            if isinstance(actual, Call) and actual.name in interpreter.cfgs:
            # TODO: right might not be a Call but just contain a Call
                state.result = {formal}
                state = self.semantics(actual, state, interpreter)
            else:
                rhs = self.semantics(actual, state, interpreter).result
                state = state.substitute({formal}, rhs)
        return state