def visit_for_stmt(self, node): """ Visits a single for stmt and checks that all it parts are correctly defined. :param node: a single for stmt :type node: ASTForStmt """ if node.get_source_position().equals( ASTSourceLocation.get_added_source_position()): # no type checks are executed for added nodes, since we assume correctness return # check that the from stmt is an integer or real from_type = node.get_start_from().type if isinstance(from_type, ErrorTypeSymbol): code, message = Messages.get_type_could_not_be_derived( node.get_start_from()) Logger.log_message( code=code, message=message, error_position=node.get_start_from().get_source_position(), log_level=LoggingLevel.ERROR) elif not (from_type.equals(PredefinedTypes.get_integer_type()) or from_type.equals(PredefinedTypes.get_real_type())): code, message = Messages.get_type_different_from_expected( PredefinedTypes.get_integer_type(), from_type) Logger.log_message( code=code, message=message, error_position=node.get_start_from().get_source_position(), log_level=LoggingLevel.ERROR) # check that the to stmt is an integer or real to_type = node.get_end_at().type if isinstance(to_type, ErrorTypeSymbol): code, message = Messages.get_type_could_not_be_derived( node.get_end_at()) Logger.log_message( code=code, message=message, error_position=node.get_end_at().get_source_position(), log_level=LoggingLevel.ERROR) elif not (to_type.equals(PredefinedTypes.get_integer_type()) or to_type.equals(PredefinedTypes.get_real_type())): code, message = Messages.get_type_different_from_expected( PredefinedTypes.get_integer_type(), to_type) Logger.log_message( code=code, message=message, error_position=node.get_end_at().get_source_position(), log_level=LoggingLevel.ERROR) return
def visit_simple_expression(self, node): """ Visit a simple rhs and update the type of a numeric literal. :param node: a single meta_model node :type node: ast_node :return: no value returned, the type is updated in-place :rtype: void """ assert node.get_scope() is not None, "Run symboltable creator." # if variable is also set in this rhs, the var type overrides the literal if node.get_variable() is not None: scope = node.get_scope() var_name = node.get_variable().get_name() variable_symbol_resolve = scope.resolve_to_symbol(var_name, SymbolKind.VARIABLE) if variable_symbol_resolve is not None: node.type = variable_symbol_resolve.get_type_symbol() else: type_symbol_resolve = scope.resolve_to_symbol(var_name, SymbolKind.TYPE) if type_symbol_resolve is not None: node.type = type_symbol_resolve else: node.type = ErrorTypeSymbol() node.type.referenced_object = node return if node.get_numeric_literal() is not None and isinstance(node.get_numeric_literal(), float): node.type = PredefinedTypes.get_real_type() node.type.referenced_object = node return elif node.get_numeric_literal() is not None and isinstance(node.get_numeric_literal(), int): node.type = PredefinedTypes.get_integer_type() node.type.referenced_object = node return
def visit_simple_expression(self, node): """ Visit a simple rhs and update the type of a numeric literal. :param node: a single meta_model node :type node: ast_node :return: no value returned, the type is updated in-place :rtype: void """ assert node.get_scope() is not None, "Run symboltable creator." # if variable is also set in this rhs, the var type overrides the literal if node.get_variable() is not None: scope = node.get_scope() var_name = node.get_variable().get_name() variable_symbol_resolve = scope.resolve_to_symbol(var_name, SymbolKind.VARIABLE) if not variable_symbol_resolve is None: node.type = variable_symbol_resolve.get_type_symbol() else: node.type = scope.resolve_to_symbol(var_name, SymbolKind.TYPE) node.type.referenced_object = node return if node.get_numeric_literal() is not None and isinstance(node.get_numeric_literal(), float): node.type = PredefinedTypes.get_real_type() node.type.referenced_object = node return elif node.get_numeric_literal() is not None and isinstance(node.get_numeric_literal(), int): node.type = PredefinedTypes.get_integer_type() node.type.referenced_object = node return
def __register_random_int_function(cls): """ Registers the random method as used to generate a random integer-typed value. """ symbol = FunctionSymbol(name=cls.RANDOM_INT, param_types=list(), return_type=PredefinedTypes.get_integer_type(), element_reference=None, is_predefined=True) cls.name2function[cls.RANDOM_INT] = symbol
def __register_random_int_function(cls): """ Registers the random method as used to generate a random integer-typed value. """ symbol = FunctionSymbol(name=cls.RANDOM_INT, param_types=list(), return_type=PredefinedTypes.get_integer_type(), element_reference=None, is_predefined=True) cls.name2function[cls.RANDOM_INT] = symbol
def __register_time_steps_function(cls): """ Registers the time-resolution. """ params = list() params.append(PredefinedTypes.get_type('ms')) symbol = FunctionSymbol(name=cls.TIME_STEPS, param_types=params, return_type=PredefinedTypes.get_integer_type(), element_reference=None, is_predefined=True) cls.name2function[cls.TIME_STEPS] = symbol return
def __register_time_steps_function(cls): """ Registers the time-resolution. """ params = list() params.append(PredefinedTypes.get_type('ms')) symbol = FunctionSymbol(name=cls.TIME_STEPS, param_types=params, return_type=PredefinedTypes.get_integer_type(), element_reference=None, is_predefined=True) cls.name2function[cls.TIME_STEPS] = symbol return
def visit_data_type(self, node): """ Visits a single data type meta_model node and updates, checks correctness and updates its type symbol. This visitor can also be used to derive the original name of the unit. :param node: a single datatype node. :type node: ast_data_type """ if node.is_integer: self.symbol = PredefinedTypes.get_integer_type() node.set_type_symbol(self.symbol) elif node.is_real: self.symbol = PredefinedTypes.get_real_type() node.set_type_symbol(self.symbol) elif node.is_string: self.symbol = PredefinedTypes.get_string_type() node.set_type_symbol(self.symbol) elif node.is_boolean: self.symbol = PredefinedTypes.get_boolean_type() node.set_type_symbol(self.symbol) elif node.is_void: self.symbol = PredefinedTypes.get_void_type() node.set_type_symbol(self.symbol)
def visit_data_type(self, node): """ Visits a single data type meta_model node and updates, checks correctness and updates its type symbol. This visitor can also be used to derive the original name of the unit. :param node: a single datatype node. :type node: ast_data_type """ if node.is_integer: self.symbol = PredefinedTypes.get_integer_type() node.set_type_symbol(self.symbol) elif node.is_real: self.symbol = PredefinedTypes.get_real_type() node.set_type_symbol(self.symbol) elif node.is_string: self.symbol = PredefinedTypes.get_string_type() node.set_type_symbol(self.symbol) elif node.is_boolean: self.symbol = PredefinedTypes.get_boolean_type() node.set_type_symbol(self.symbol) elif node.is_void: self.symbol = PredefinedTypes.get_void_type() node.set_type_symbol(self.symbol)