def assume_call_semantics(self, stmt: Call, state: State, manager: PyManager = None) -> State: argument = self.semantics(stmt.arguments[0], state).result state.assume(argument, manager=manager) state.result = set() return state
def _unary_operation(self, stmt: Call, operator: UnaryOperation.Operator, state: State): """Semantics of a call to a unary operation. :param stmt: call to unary operation to be executed :param operator: unary operator :param state: state before executing the call statements :return: state modified by the call statement """ assert len( stmt.arguments) == 1 # unary operations have exactly one argument argument = self.semantics(stmt.arguments[0], state).result result = set() if isinstance(operator, UnaryArithmeticOperation.Operator): for expression in argument: operation = UnaryArithmeticOperation(operator, expression) result.add(operation) elif isinstance(operator, UnaryBooleanOperation.Operator): for expression in argument: operation = UnaryBooleanOperation(operator, expression) result.add(operation) else: error = f"Semantics for unary operation {operator} is not yet implemented!" raise NotImplementedError(error) state.result = result return state
def input_call_semantics(self, _: Call, state: State) -> State: """Semantics of a calls to 'input'. :param stmt: call to 'input' to be executed :param state: state before executing the call statement :return: state modified by the call statement """ state.result = {Input()} return state
def variable_access_semantics(self, stmt: VariableAccess, state: State) -> State: """Semantics of a variable access. :param stmt: variable access statement to be executed :param state: state before executing the variable access :return: state modified by the variable access """ state.result = {stmt.variable} return state
def literal_evaluation_semantics(self, stmt: LiteralEvaluation, state: State) -> State: """Semantics of a literal evaluation. :param stmt: literal evaluation statement to be executed :param state: state before executing the literal evaluation :return: stated modified by the literal evaluation """ state.result = {stmt.literal} return state
def assignment_semantics(self, stmt: Assignment, state: State) -> State: """Forward 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.assign(lhs, rhs)
def _binary_operation(self, stmt: Call, operator: BinaryOperation.Operator, state: State): """Semantics of a call to a binary operation. :param stmt: call to binary operation to be executed :param operator: binary operator :param state: state before executing the call statements :return: state modified by the call statement """ arguments = list() updated = state for i in range(len(stmt.arguments)): updated = self.semantics(stmt.arguments[i], updated) arguments.append(updated.result) assert len( arguments) >= 2 # binary operations have at least two arguments result = set() if isinstance(operator, BinaryArithmeticOperation.Operator): for product in itertools.product(*arguments): operation = product[0] for i in range(1, len(arguments)): right = product[i] operation = BinaryArithmeticOperation( operation, operator, right) result.add(operation) elif isinstance(operator, BinaryComparisonOperation.Operator): for product in itertools.product(*arguments): operation = product[0] for i in range(1, len(arguments)): right = product[i] operation = BinaryComparisonOperation( operation, operator, right) result.add(operation) elif isinstance(operator, BinaryBooleanOperation.Operator): for product in itertools.product(*arguments): operation = product[0] for i in range(1, len(arguments)): right = product[i] operation = BinaryBooleanOperation(operation, operator, right) result.add(operation) else: error = f"Semantics for binary operator {operator} is not yet implemented!" raise NotImplementedError(error) state.result = result return state
def float_call_semantics(self, stmt: Call, state: State) -> State: """Semantics of a call to 'float'. :param stmt: call to 'float' to be executed :param state: state before executing the call statement :return: state modified by the call statement """ if len(stmt.arguments) != 1: error = f"Semantics for multiple arguments of {stmt.name} is not yet implemented!" raise NotImplementedError(error) argument = self.semantics(stmt.arguments[0], state).result result = set() for expression in argument: if isinstance(expression, Input): result.add(Input()) elif isinstance(expression, Literal): result.add(Literal(expression.val)) elif isinstance(expression, VariableIdentifier): result.add(VariableIdentifier(expression.name)) else: error = f"Argument of type {expression.typ} of {stmt.name} is not yet supported!" raise NotImplementedError(error) state.result = result return state