Beispiel #1
0
 def visit_declaration(self, node):
     """
     Checks the coco for a declaration.
     :param node: a single declaration.
     :type node: ASTDeclaration
     """
     assert isinstance(node, ASTDeclaration)
     if node.has_invariant():
         invariant_type = node.get_invariant().type
         if invariant_type is None or isinstance(invariant_type,
                                                 ErrorTypeSymbol):
             code, message = Messages.get_type_could_not_be_derived(
                 str(node.get_invariant()))
             Logger.log_message(
                 error_position=node.get_invariant().get_source_position(),
                 code=code,
                 message=message,
                 log_level=LoggingLevel.ERROR)
         elif not invariant_type.equals(PredefinedTypes.get_boolean_type()):
             code, message = Messages.get_type_different_from_expected(
                 PredefinedTypes.get_boolean_type(), invariant_type)
             Logger.log_message(
                 error_position=node.get_invariant().get_source_position(),
                 code=code,
                 message=message,
                 log_level=LoggingLevel.ERROR)
     return
Beispiel #2
0
def handle_unit(unit_type):
    """
    Handles a handed over unit by creating the corresponding unit-type, storing it in the list of predefined
    units, creating a type symbol and returning it.
    :param unit_type: a single sympy unit symbol
    :type unit_type: Symbol (sympy)
    :return: a new type symbol
    :rtype: type_symbol
    """
    # first ensure that it does not already exists, if not create it and register it in the set of predefined units
    # first clean up the unit of not required components, here it is the 1.0 in front of the unit
    # e.g., 1.0 * 1 / ms. This step is not mandatory for correctness, but makes  reporting easier
    if isinstance(unit_type, units.Quantity) and unit_type.value == 1.0:
        to_process = unit_type.unit
    else:
        to_process = unit_type
    if str(to_process) not in PredefinedUnits.get_units().keys():
        unit_type_t = UnitType(name=str(to_process), unit=to_process)
        PredefinedUnits.register_unit(unit_type_t)
    # now create the corresponding type symbol if it does not exists
    if PredefinedTypes.get_type(str(to_process)) is None:
        type_symbol = UnitTypeSymbol(
            unit=PredefinedUnits.get_unit(str(to_process)))
        PredefinedTypes.register_type(type_symbol)
    return PredefinedTypes.get_type(name=str(to_process))
 def endvisit_function(self, node):
     symbol = self.symbol_stack.pop()
     scope = self.scope_stack.pop()
     assert isinstance(symbol, FunctionSymbol), 'Not a function symbol'
     for arg in node.get_parameters():
         # given the fact that the name is not directly equivalent to the one as stated in the model,
         # we have to get it by the sub-visitor
         data_type_visitor = ASTDataTypeVisitor()
         arg.get_data_type().accept(data_type_visitor)
         type_name = data_type_visitor.result
         # first collect the types for the parameters of the function symbol
         symbol.add_parameter_type(PredefinedTypes.get_type(type_name))
         # update the scope of the arg
         arg.update_scope(scope)
         # create the corresponding variable symbol representing the parameter
         var_symbol = VariableSymbol(element_reference=arg, scope=scope, name=arg.get_name(),
                                     block_type=BlockType.LOCAL, is_predefined=False, is_function=False,
                                     is_recordable=False,
                                     type_symbol=PredefinedTypes.get_type(type_name),
                                     variable_type=VariableType.VARIABLE)
         assert isinstance(scope, Scope)
         scope.add_symbol(var_symbol)
     if node.has_return_type():
         data_type_visitor = ASTDataTypeVisitor()
         node.get_return_type().accept(data_type_visitor)
         symbol.set_return_type(PredefinedTypes.get_type(data_type_visitor.result))
     else:
         symbol.set_return_type(PredefinedTypes.get_void_type())
     self.block_type_stack.pop()  # before leaving update the type
Beispiel #4
0
 def visit_while_stmt(self, node):
     """
     Visits a single while stmt and checks that its condition is of boolean type.
     :param node: a single while stmt
     :type node: ASTWhileStmt
     """
     if node.get_source_position().equals(
             ASTSourceLocation.get_added_source_position()):
         # no type checks are executed for added nodes, since we assume correctness
         return
     cond_type = node.get_condition().type
     if isinstance(cond_type, ErrorTypeSymbol):
         code, message = Messages.get_type_could_not_be_derived(
             node.get_condition())
         Logger.log_message(
             code=code,
             message=message,
             error_position=node.get_condition().get_source_position(),
             log_level=LoggingLevel.ERROR)
     elif not cond_type.equals(PredefinedTypes.get_boolean_type()):
         code, message = Messages.get_type_different_from_expected(
             PredefinedTypes.get_boolean_type(), cond_type)
         Logger.log_message(
             code=code,
             message=message,
             error_position=node.get_condition().get_source_position(),
             log_level=LoggingLevel.ERROR)
     return
 def setUp(self):
     Logger.init_logger(LoggingLevel.INFO)
     SymbolTable.initialize_symbol_table(ASTSourceLocation(start_line=0, start_column=0, end_line=0, end_column=0))
     PredefinedUnits.register_units()
     PredefinedTypes.register_types()
     PredefinedVariables.register_variables()
     PredefinedFunctions.register_functions()
 def endvisit_function(self, node):
     symbol = self.symbol_stack.pop()
     scope = self.scope_stack.pop()
     assert isinstance(symbol, FunctionSymbol), 'Not a function symbol'
     for arg in node.get_parameters():
         # given the fact that the name is not directly equivalent to the one as stated in the model,
         # we have to get it by the sub-visitor
         data_type_visitor = ASTDataTypeVisitor()
         arg.get_data_type().accept(data_type_visitor)
         type_name = data_type_visitor.result
         # first collect the types for the parameters of the function symbol
         symbol.add_parameter_type(PredefinedTypes.get_type(type_name))
         # update the scope of the arg
         arg.update_scope(scope)
         # create the corresponding variable symbol representing the parameter
         var_symbol = VariableSymbol(
             element_reference=arg,
             scope=scope,
             name=arg.get_name(),
             block_type=BlockType.LOCAL,
             is_predefined=False,
             is_function=False,
             is_recordable=False,
             type_symbol=PredefinedTypes.get_type(type_name),
             variable_type=VariableType.VARIABLE)
         assert isinstance(scope, Scope)
         scope.add_symbol(var_symbol)
     if node.has_return_type():
         data_type_visitor = ASTDataTypeVisitor()
         node.get_return_type().accept(data_type_visitor)
         symbol.set_return_type(
             PredefinedTypes.get_type(data_type_visitor.result))
     else:
         symbol.set_return_type(PredefinedTypes.get_void_type())
     self.block_type_stack.pop()  # before leaving update the type
    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 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 __register_random_normal_function(cls):
     """
     Registers the random method as used to generate a random normal (Gaussian) distributed variable with first parameter "mean" and second parameter "standard deviation".
     """
     symbol = FunctionSymbol(name=cls.RANDOM_NORMAL, param_types=[PredefinedTypes.get_template_type(0), PredefinedTypes.get_template_type(0)],
                             return_type=PredefinedTypes.get_template_type(0),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.RANDOM_NORMAL] = symbol
 def __register_random_uniform_function(cls):
     """
     Registers the random method as used to generate a random sample from a uniform distribution in the interval [offset, offset + scale).
     """
     symbol = FunctionSymbol(name=cls.RANDOM_UNIFORM, param_types=[PredefinedTypes.get_template_type(0), PredefinedTypes.get_template_type(0)],
                             return_type=PredefinedTypes.get_template_type(0),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.RANDOM_UNIFORM] = symbol
Beispiel #11
0
    def visit_kernel(self, node):
        """
        Checks the coco on the current node.
        :param node: AST kernel object
        :type node: ASTKernel
        """
        for var, expr in zip(node.variables, node.expressions):
            # check kernel type
            if (var.get_differential_order() == 0
                and not type(expr.type) in [IntegerTypeSymbol, RealTypeSymbol]) \
                or (var.get_differential_order() > 0
                    and not expr.type.is_castable_to(PredefinedTypes.get_type("ms")**-var.get_differential_order())):
                actual_type_str = str(expr.type)
                if 'unit' in dir(expr.type) \
                        and expr.type.unit is not None \
                        and expr.type.unit.unit is not None:
                    actual_type_str = str(expr.type.unit.unit)
                code, message = Messages.get_kernel_wrong_type(
                    var.get_name(), var.get_differential_order(),
                    actual_type_str)
                Logger.log_message(error_position=node.get_source_position(),
                                   log_level=LoggingLevel.ERROR,
                                   code=code,
                                   message=message)

            # check types of the state variables
            for order in range(var.get_differential_order()):
                iv_name = var.get_name() + order * "'"
                decl = ASTUtils.get_declaration_by_name(
                    self._neuron.get_state_blocks(), iv_name)
                if decl is None:
                    code, message = Messages.get_variable_not_defined(iv_name)
                    Logger.log_message(
                        node=self._neuron,
                        code=code,
                        message=message,
                        log_level=LoggingLevel.ERROR,
                        error_position=node.get_source_position())
                    continue
                assert len(
                    self._neuron.get_state_blocks().get_declarations()
                    [0].get_variables()
                ) == 1, "Only single variables are supported as targets of an assignment."
                iv = decl.get_variables()[0]
                if not iv.get_type_symbol().get_value().is_castable_to(
                        PredefinedTypes.get_type("ms")**-order):
                    actual_type_str = DebugTypeConverter.convert(
                        iv.get_type_symbol())
                    expected_type_str = "s^-" + str(order)
                    code, message = Messages.get_kernel_iv_wrong_type(
                        iv_name, actual_type_str, expected_type_str)
                    Logger.log_message(
                        error_position=node.get_source_position(),
                        log_level=LoggingLevel.ERROR,
                        code=code,
                        message=message)
 def __register_print_function(cls):
     """
     Registers the print function.
     """
     params = list()
     params.append(PredefinedTypes.get_string_type())
     symbol = FunctionSymbol(name=cls.PRINT, param_types=params,
                             return_type=PredefinedTypes.get_void_type(),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.PRINT] = symbol
 def __register_delta_function(cls):
     """
     Registers the delta function.
     """
     params = list()
     params.append(PredefinedTypes.get_type('ms'))
     symbol = FunctionSymbol(name=cls.DELTA, param_types=params,
                             return_type=PredefinedTypes.get_real_type(),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.DELTA] = symbol
    def setUp(self):
        PredefinedUnits.register_units()
        PredefinedTypes.register_types()
        PredefinedFunctions.register_functions()
        PredefinedVariables.register_variables()
        SymbolTable.initialize_symbol_table(ASTSourceLocation(start_line=0, start_column=0, end_line=0, end_column=0))
        Logger.init_logger(LoggingLevel.INFO)

        self.target_path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join(
            os.pardir, 'target'))))
 def __register_exp1_function(cls):
     """
     Registers the alternative version of the exponent function, exp1.
     """
     params = list()
     params.append(PredefinedTypes.get_real_type())  # the argument
     symbol = FunctionSymbol(name=cls.EXPM1, param_types=params,
                             return_type=PredefinedTypes.get_real_type(),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.EXPM1] = symbol
 def __register_logger_warning_function(cls):
     """
     Registers the logger warning method.
     """
     params = list()
     params.append(PredefinedTypes.get_string_type())  # the argument
     symbol = FunctionSymbol(name=cls.LOGGER_WARNING, param_types=params,
                             return_type=PredefinedTypes.get_void_type(),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.LOGGER_WARNING] = symbol
 def __register_logger_warning_function(cls):
     """
     Registers the logger warning method.
     """
     params = list()
     params.append(PredefinedTypes.get_string_type())  # the argument
     symbol = FunctionSymbol(name=cls.LOGGER_WARNING, param_types=params,
                             return_type=PredefinedTypes.get_void_type(),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.LOGGER_WARNING] = symbol
 def __register_logger_info_function(cls):
     """
     Registers the logger info method into the scope.
     """
     params = list()
     params.append(PredefinedTypes.get_string_type())  # the argument
     symbol = FunctionSymbol(name=cls.LOGGER_INFO, param_types=params,
                             return_type=PredefinedTypes.get_void_type(),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.LOGGER_INFO] = symbol
 def __register_abs_function(cls):
     """
     Registers the absolute value function.
     """
     params = list()
     params.append(PredefinedTypes.get_template_type(0))
     symbol = FunctionSymbol(name=cls.ABS, param_types=params,
                             return_type=PredefinedTypes.get_template_type(0),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.ABS] = symbol
 def __register_ln_function(cls):
     """
     Registers the natural logarithm function, i.e. the logarithm function of base :math:`e`.
     """
     params = list()
     params.append(PredefinedTypes.get_real_type())  # the argument
     symbol = FunctionSymbol(name=cls.LN, param_types=params,
                             return_type=PredefinedTypes.get_real_type(),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.LN] = symbol
 def __register_logger_info_function(cls):
     """
     Registers the logger info method into the scope.
     """
     params = list()
     params.append(PredefinedTypes.get_string_type())  # the argument
     symbol = FunctionSymbol(name=cls.LOGGER_INFO, param_types=params,
                             return_type=PredefinedTypes.get_void_type(),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.LOGGER_INFO] = symbol
 def __register_tanh_function(cls):
     """
     Registers the hyperbolic tangent function.
     """
     params = list()
     params.append(PredefinedTypes.get_real_type())  # the argument
     symbol = FunctionSymbol(name=cls.TANH, param_types=params,
                             return_type=PredefinedTypes.get_real_type(),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.TANH] = symbol
 def __register_log10_function(cls):
     """
     Registers the logarithm function of base 10.
     """
     params = list()
     params.append(PredefinedTypes.get_real_type())  # the argument
     symbol = FunctionSymbol(name=cls.LOG10, param_types=params,
                             return_type=PredefinedTypes.get_real_type(),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.LOG10] = symbol
Beispiel #24
0
    def setUp(self) -> None:
        PredefinedUnits.register_units()
        PredefinedTypes.register_types()
        PredefinedFunctions.register_functions()
        PredefinedVariables.register_variables()
        SymbolTable.initialize_symbol_table(ASTSourceLocation(start_line=0, start_column=0, end_line=0, end_column=0))
        Logger.init_logger(LoggingLevel.INFO)

        self.target_path = str(os.path.realpath(os.path.join(os.path.dirname(__file__),
                                                             os.path.join(os.pardir, 'target'))))
 def __register_log_function(cls):
     """
     Registers the logarithm function (to base 10).
     """
     params = list()
     params.append(PredefinedTypes.get_real_type())  # the argument
     symbol = FunctionSymbol(name=cls.LOG, param_types=params,
                             return_type=PredefinedTypes.get_real_type(),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.LOG] = symbol
 def __register_exp1_function(cls):
     """
     Registers the alternative version of the exponent function, exp1.
     """
     params = list()
     params.append(PredefinedTypes.get_real_type())  # the argument
     symbol = FunctionSymbol(name=cls.EXPM1, param_types=params,
                             return_type=PredefinedTypes.get_real_type(),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.EXPM1] = symbol
 def __register_print_ln_function(cls):
     """
     Registers the print-line function.
     """
     params = list()
     params.append(PredefinedTypes.get_string_type())
     symbol = FunctionSymbol(name=cls.PRINTLN, param_types=params,
                             return_type=PredefinedTypes.get_void_type(),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.PRINTLN] = symbol
 def __register_min_function(cls):
     """
     Registers the minimum function.
     """
     params = list()
     params.append(PredefinedTypes.get_template_type(0))
     params.append(PredefinedTypes.get_template_type(0))
     symbol = FunctionSymbol(name=cls.MIN, param_types=params,
                             return_type=PredefinedTypes.get_template_type(0),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.MIN] = symbol
 def __register_predefined_type_variables(cls):
     """
     Registers all predefined type variables, e.g., mV and integer.
     """
     for name in PredefinedTypes.get_types().keys():
         symbol = VariableSymbol(name=name, block_type=BlockType.PREDEFINED,
                                 is_predefined=True,
                                 type_symbol=PredefinedTypes.get_type(name),
                                 variable_type=VariableType.TYPE)
         cls.name2variable[name] = symbol
     return
 def __register_convolve(cls):
     """
     Registers the convolve function into the system.
     """
     params = list()
     params.append(PredefinedTypes.get_real_type())
     params.append(PredefinedTypes.get_real_type())
     symbol = FunctionSymbol(name=cls.CONVOLVE, param_types=params,
                             return_type=PredefinedTypes.get_real_type(),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.CONVOLVE] = symbol
 def __register_cond_sum_function(cls):
     """
     Registers the cond_sum function into scope.
     """
     params = list()
     params.append(PredefinedTypes.get_type('nS'))
     params.append(PredefinedTypes.get_real_type())
     symbol = FunctionSymbol(name=cls.COND_SUM, param_types=params,
                             return_type=PredefinedTypes.get_type('nS'),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.COND_SUM] = symbol
 def __register_min_bounded_function(cls):
     """
     Registers the minimum (bounded) function.
     """
     params = list()
     params.append(PredefinedTypes.get_real_type())
     params.append(PredefinedTypes.get_real_type())
     symbol = FunctionSymbol(name=cls.BOUNDED_MIN, param_types=params,
                             return_type=PredefinedTypes.get_real_type(),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.BOUNDED_MIN] = symbol
 def __register_max_function(cls):
     """
     Registers the maximum function.
     """
     params = list()
     params.append(PredefinedTypes.get_real_type())
     params.append(PredefinedTypes.get_real_type())
     symbol = FunctionSymbol(name=cls.MAX, param_types=params,
                             return_type=PredefinedTypes.get_real_type(),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.MAX] = symbol
 def __register_delta_function(cls):
     """
     Registers the delta function.
     """
     params = list()
     params.append(PredefinedTypes.get_type('ms'))
     params.append(PredefinedTypes.get_type('ms'))
     symbol = FunctionSymbol(name=cls.DELTA, param_types=params,
                             return_type=PredefinedTypes.get_real_type(),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.DELTA] = 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 __register_power_function(cls):
     """
     Registers the power function.
     """
     params = list()
     params.append(PredefinedTypes.get_real_type())  # the base type
     params.append(PredefinedTypes.get_real_type())  # the exponent type
     symbol = FunctionSymbol(name=cls.POW, param_types=params,
                             return_type=PredefinedTypes.get_real_type(),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.POW] = symbol
 def __register_predefined_type_variables(cls):
     """
     Registers all predefined type variables, e.g., mV and integer.
     """
     for name in PredefinedTypes.get_types().keys():
         symbol = VariableSymbol(name=name, block_type=BlockType.PREDEFINED,
                                 is_predefined=True,
                                 type_symbol=PredefinedTypes.get_type(name),
                                 variable_type=VariableType.TYPE)
         cls.name2variable[name] = symbol
     return
 def __register_convolve(cls):
     """
     Registers the convolve function into the system.
     """
     params = list()
     params.append(PredefinedTypes.get_real_type())
     params.append(PredefinedTypes.get_real_type())
     symbol = FunctionSymbol(name=cls.CONVOLVE, param_types=params,
                             return_type=PredefinedTypes.get_real_type(),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.CONVOLVE] = symbol
 def __register_min_bounded_function(cls):
     """
     Registers the minimum (bounded) function.
     """
     params = list()
     params.append(PredefinedTypes.get_real_type())
     params.append(PredefinedTypes.get_real_type())
     symbol = FunctionSymbol(name=cls.BOUNDED_MIN,
                             param_types=params,
                             return_type=PredefinedTypes.get_real_type(),
                             element_reference=None,
                             is_predefined=True)
     cls.name2function[cls.BOUNDED_MIN] = symbol
 def __register_max_function(cls):
     """
     Registers the maximum function.
     """
     params = list()
     params.append(PredefinedTypes.get_real_type())
     params.append(PredefinedTypes.get_real_type())
     symbol = FunctionSymbol(name=cls.MAX,
                             param_types=params,
                             return_type=PredefinedTypes.get_real_type(),
                             element_reference=None,
                             is_predefined=True)
     cls.name2function[cls.MAX] = symbol
 def __register_power_function(cls):
     """
     Registers the power function.
     """
     params = list()
     params.append(PredefinedTypes.get_real_type())  # the base type
     params.append(PredefinedTypes.get_real_type())  # the exponent type
     symbol = FunctionSymbol(name=cls.POW,
                             param_types=params,
                             return_type=PredefinedTypes.get_real_type(),
                             element_reference=None,
                             is_predefined=True)
     cls.name2function[cls.POW] = symbol
 def __register_cond_sum_function(cls):
     """
     Registers the cond_sum function into scope.
     """
     params = list()
     params.append(PredefinedTypes.get_type('nS'))
     params.append(PredefinedTypes.get_real_type())
     symbol = FunctionSymbol(name=cls.COND_SUM,
                             param_types=params,
                             return_type=PredefinedTypes.get_type('nS'),
                             element_reference=None,
                             is_predefined=True)
     cls.name2function[cls.COND_SUM] = symbol
Beispiel #44
0
 def __register_deliver_spike(cls):
     """
     Registers the deliver-spike function.
     """
     params = list()
     params.append(PredefinedTypes.get_real_type())
     params.append(PredefinedTypes.get_type('ms'))
     symbol = FunctionSymbol(name=cls.DELIVER_SPIKE,
                             param_types=params,
                             return_type=PredefinedTypes.get_real_type(),
                             element_reference=None,
                             is_predefined=True)
     cls.name2function[cls.DELIVER_SPIKE] = symbol
    def __register_clip_function(cls):
        """
        Registers the clip function (bound a number between a minimum and a
        maximum value).
        """
        params = list()

        params.append(PredefinedTypes.get_template_type(0))  # value
        params.append(PredefinedTypes.get_template_type(0))  # min
        params.append(PredefinedTypes.get_template_type(0))  # max

        symbol = FunctionSymbol(name=cls.CLIP, param_types=params,
                                return_type=PredefinedTypes.get_template_type(0),
                                element_reference=None, is_predefined=True)
        cls.name2function[cls.CLIP] = symbol
 def endvisit_input_line(self, node):
     buffer_type = BlockType.INPUT_BUFFER_SPIKE if node.is_spike() else BlockType.INPUT_BUFFER_CURRENT
     if node.is_spike() and node.has_datatype():
         type_symbol = node.get_datatype().get_type_symbol()
     elif node.is_spike():
         type_symbol = PredefinedTypes.get_type('nS')
     else:
         type_symbol = PredefinedTypes.get_type('pA')
     type_symbol.is_buffer = True  # set it as a buffer
     symbol = VariableSymbol(element_reference=node, scope=node.get_scope(), name=node.get_name(),
                             block_type=buffer_type, vector_parameter=node.get_index_parameter(),
                             is_predefined=False, is_function=False, is_recordable=False,
                             type_symbol=type_symbol, variable_type=VariableType.BUFFER)
     symbol.set_comment(node.get_comment())
     node.get_scope().add_symbol(symbol)
Beispiel #47
0
 def endvisit_input_line(self, node):
     buffer_type = BlockType.INPUT_BUFFER_SPIKE if node.is_spike() else BlockType.INPUT_BUFFER_CURRENT
     if node.is_spike() and node.has_datatype():
         type_symbol = node.get_datatype().get_type_symbol()
     elif node.is_spike():
         type_symbol = PredefinedTypes.get_type('nS')
     else:
         type_symbol = PredefinedTypes.get_type('pA')
     type_symbol.is_buffer = True  # set it as a buffer
     symbol = VariableSymbol(element_reference=node, scope=node.get_scope(), name=node.get_name(),
                             block_type=buffer_type, vector_parameter=node.get_index_parameter(),
                             is_predefined=False, is_function=False, is_recordable=False,
                             type_symbol=type_symbol, variable_type=VariableType.BUFFER)
     symbol.set_comment(node.get_comment())
     node.get_scope().add_symbol(symbol)
    def visit_expression(self, node):
        """
        Visits an expression which uses a binary logic operator and updates the type.
        :param node: a single expression.
        :type node: ast_expression
        """
        lhs_type = node.get_lhs().type
        rhs_type = node.get_rhs().type

        lhs_type.referenced_object = node.get_lhs()
        rhs_type.referenced_object = node.get_rhs()

        if isinstance(lhs_type, BooleanTypeSymbol) and isinstance(rhs_type, BooleanTypeSymbol):
            node.type = PredefinedTypes.get_boolean_type()
        else:
            if isinstance(lhs_type, BooleanTypeSymbol):
                offending_type = lhs_type
            else:
                offending_type = rhs_type
            code, message = Messages.get_type_different_from_expected(BooleanTypeSymbol(), offending_type)
            Logger.log_message(code=code, message=message,
                               error_position=lhs_type.referenced_object.get_source_position(),
                               log_level=LoggingLevel.ERROR)
            node.type = ErrorTypeSymbol()
        return
 def visit_neuron(self, node):
     """
     Private method: Used to visit a single neuron and create the corresponding global as well as local scopes.
     :return: a single neuron.
     :rtype: ast_neuron
     """
     # set current processed neuron
     Logger.set_current_neuron(node)
     code, message = Messages.get_start_building_symbol_table()
     Logger.log_message(neuron=node, code=code, error_position=node.get_source_position(),
                        message=message, log_level=LoggingLevel.INFO)
     # before starting the work on the neuron, make everything which was implicit explicit
     # but if we have a model without an equations block, just skip this step
     if node.get_equations_blocks() is not None:
         make_implicit_odes_explicit(node.get_equations_blocks())
     scope = Scope(scope_type=ScopeType.GLOBAL, source_position=node.get_source_position())
     node.update_scope(scope)
     node.get_body().update_scope(scope)
     # now first, we add all predefined elements to the scope
     variables = PredefinedVariables.get_variables()
     functions = PredefinedFunctions.get_function_symbols()
     types = PredefinedTypes.get_types()
     for symbol in variables.keys():
         node.get_scope().add_symbol(variables[symbol])
     for symbol in functions.keys():
         node.get_scope().add_symbol(functions[symbol])
     for symbol in types.keys():
         node.get_scope().add_symbol(types[symbol])
 def check_co_co(cls, _neuron=None):
     """
     Checks the coco for the handed over neuron.
     :param _neuron: a single neuron instance.
     :type _neuron: ASTNeuron
     """
     assert (_neuron is not None and isinstance(_neuron, ASTNeuron)), \
         '(PyNestML.CoCo.FunctionCallsConsistent) No or wrong type of neuron provided (%s)!' % type(_neuron)
     cls.__neuronName = _neuron.get_name()
     for userDefinedFunction in _neuron.get_functions():
         cls.processed_function = userDefinedFunction
         symbol = userDefinedFunction.get_scope().resolve_to_symbol(userDefinedFunction.get_name(),
                                                                    SymbolKind.FUNCTION)
         # first ensure that the block contains at least one statement
         if symbol is not None and len(userDefinedFunction.get_block().get_stmts()) > 0:
             # now check that the last statement is a return
             cls.__check_return_recursively(symbol.get_return_type(),
                                            userDefinedFunction.get_block().get_stmts(), False)
         # now if it does not have a statement, but uses a return type, it is an error
         elif symbol is not None and userDefinedFunction.has_return_type() and \
                 not symbol.get_return_type().equals(PredefinedTypes.get_void_type()):
             code, message = Messages.get_no_return()
             Logger.log_message(neuron=_neuron, code=code, message=message,
                                error_position=userDefinedFunction.get_source_position(),
                                log_level=LoggingLevel.ERROR)
     return
 def visit_simple_expression(self, node):
     """
     Visits a singe simple rhs which consists of a string literal and updates the type.
     :param node: a simple rhs containing a string literal
     :type node: ast_simple_expression
     """
     node.type = PredefinedTypes.get_string_type()
     node.type.referenced_object = node
 def __register_emit_spike_function(cls):
     """
     Registers the emit-spike function.
     """
     symbol = FunctionSymbol(name=cls.EMIT_SPIKE, param_types=list(),
                             return_type=PredefinedTypes.get_real_type(),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.EMIT_SPIKE] = symbol
 def __register_print_ln_function(cls):
     """
     Registers the print-line function.
     """
     symbol = FunctionSymbol(name=cls.PRINTLN, param_types=list(),
                             return_type=PredefinedTypes.get_void_type(),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.PRINTLN] = 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_resolution_function(cls):
     """
     Registers the time resolution function.
     """
     symbol = FunctionSymbol(name=cls.TIME_RESOLUTION, param_types=list(),
                             return_type=PredefinedTypes.get_type('ms'),
                             element_reference=None, is_predefined=True, scope=None)
     cls.name2function[cls.TIME_RESOLUTION] = symbol
Beispiel #56
0
 def visit_simple_expression(self, node):
     """
     Visits a single simple rhs containing an inf literal and updates its type.
     :param node: a simple rhs
     :type node: ast_simple_expression
     """
     node.type = PredefinedTypes.get_real_type()
     node.type.referenced_object = node
 def __register_euler_constant(cls):
     """
     Adds the euler constant e.
     """
     symbol = VariableSymbol(name='e', block_type=BlockType.STATE,
                             is_predefined=True, type_symbol=PredefinedTypes.get_real_type(),
                             variable_type=VariableType.VARIABLE)
     cls.name2variable[cls.E_CONSTANT] = symbol
     return
 def __register_time_constant(cls):
     """
     Adds the time constant t.
     """
     symbol = VariableSymbol(name='t', block_type=BlockType.STATE,
                             is_predefined=True, type_symbol=PredefinedTypes.get_type('ms'),
                             variable_type=VariableType.VARIABLE)
     cls.name2variable[cls.TIME_CONSTANT] = symbol
     return
 def __register_integrated_odes_function(cls):
     """
     Registers the integrate-odes function.
     """
     params = list()
     symbol = FunctionSymbol(name=cls.INTEGRATE_ODES, param_types=params,
                             return_type=PredefinedTypes.get_void_type(),
                             element_reference=None, is_predefined=True)
     cls.name2function[cls.INTEGRATE_ODES] = symbol
Beispiel #60
0
 def inverse_of_unit(cls, other):
     """
     :param other: the unit to invert
     :type other: unit_type_symbol
     :return: UnitTypeSymbol
     """
     from pynestml.symbols.predefined_types import PredefinedTypes
     result = PredefinedTypes.get_type(1 / other.astropy_unit)
     return result