def visit_declaration(self, node: ASTDeclaration):

        variables = node.get_variables()
        for variable in variables:
            vector_parameter = variable.get_vector_parameter()
            if vector_parameter is not None:
                vector_parameter_var = ASTVariable(vector_parameter,
                                                   scope=node.get_scope())
                symbol = vector_parameter_var.get_scope().resolve_to_symbol(
                    vector_parameter_var.get_complete_name(),
                    SymbolKind.VARIABLE)
                vector_parameter_val = None
                if symbol is not None:
                    if isinstance(symbol.get_type_symbol(), IntegerTypeSymbol):
                        vector_parameter_val = int(
                            str(symbol.get_declaring_expression()))
                else:
                    vector_parameter_val = int(vector_parameter)

                if vector_parameter_val is not None and vector_parameter_val <= 0:
                    code, message = Messages.get_vector_parameter_wrong_size(
                        vector_parameter_var.get_complete_name(),
                        str(vector_parameter_val))
                    Logger.log_message(
                        error_position=node.get_source_position(),
                        log_level=LoggingLevel.ERROR,
                        code=code,
                        message=message)
Exemplo n.º 2
0
        def replace_function_call_through_var(_expr=None):
            if _expr.is_function_call() and _expr.get_function_call().get_name(
            ) == "convolve":
                convolve = _expr.get_function_call()
                el = (convolve.get_args()[0], convolve.get_args()[1])
                sym = convolve.get_args()[0].get_scope().resolve_to_symbol(
                    convolve.get_args()[0].get_variable().name,
                    SymbolKind.VARIABLE)
                if sym.block_type == BlockType.INPUT_BUFFER_SPIKE:
                    el = (el[1], el[0])
                var = el[0].get_variable()
                spike_input_port = el[1].get_variable()
                kernel = neuron.get_kernel_by_name(var.get_name())

                _expr.set_function_call(None)
                buffer_var = construct_kernel_X_spike_buf_name(
                    var.get_name(), spike_input_port,
                    var.get_differential_order() - 1)
                if is_delta_kernel(kernel):
                    # delta kernel are treated separately, and should be kept out of the dynamics (computing derivates etc.) --> set to zero
                    _expr.set_variable(None)
                    _expr.set_numeric_literal(0)
                else:
                    ast_variable = ASTVariable(buffer_var)
                    ast_variable.set_source_position(
                        _expr.get_source_position())
                    _expr.set_variable(ast_variable)
Exemplo n.º 3
0
 def replace_kernel_var(node):
     if type(node) is ASTSimpleExpression \
             and node.is_variable() \
             and node.get_variable().get_name() == variable_name_to_replace:
         var_order = node.get_variable().get_differential_order()
         new_variable_name = construct_kernel_X_spike_buf_name(
             kernel_var.get_name(), spike_buf, var_order - 1, diff_order_symbol="'")
         new_variable = ASTVariable(new_variable_name, var_order)
         new_variable.set_source_position(node.get_variable().get_source_position())
         node.set_variable(new_variable)
Exemplo n.º 4
0
 def get_numeric_vector_size(cls, variable: VariableSymbol) -> int:
     """
     Returns the numerical size of the vector by resolving any variable used as a size parameter in declaration
     :param variable: vector variable
     :return: the size of the vector as a numerical value
     """
     vector_parameter = variable.get_vector_parameter()
     vector_variable = ASTVariable(vector_parameter, scope=variable.get_corresponding_scope())
     symbol = vector_variable.get_scope().resolve_to_symbol(vector_variable.get_complete_name(), SymbolKind.VARIABLE)
     if symbol is not None:
         # vector size is a variable. Get the value from RHS
         return symbol.get_declaring_expression().get_numeric_literal()
     return int(vector_parameter)
Exemplo n.º 5
0
        def replace_var(_expr=None):
            if isinstance(_expr, ASTSimpleExpression) and _expr.is_variable():
                var = _expr.get_variable()
                if variable_in_solver(to_ode_toolbox_processed_name(var.get_complete_name()), solver_dicts):
                    ast_variable = ASTVariable(to_ode_toolbox_processed_name(
                        var.get_complete_name()), differential_order=0)
                    ast_variable.set_source_position(var.get_source_position())
                    _expr.set_variable(ast_variable)

            elif isinstance(_expr, ASTVariable):
                var = _expr
                if variable_in_solver(to_ode_toolbox_processed_name(var.get_complete_name()), solver_dicts):
                    var.set_name(to_ode_toolbox_processed_name(var.get_complete_name()))
                    var.set_differential_order(0)
Exemplo n.º 6
0
    def convert_name_reference(self, variable: ASTVariable, prefix: str = ''):
        """
        Converts a single name reference to a gsl processable format.
        :param ast_variable: a single variable
        :type ast_variable: ASTVariable
        :return: a gsl processable format of the variable
        :rtype: str
        """

        if variable.get_name() == PredefinedVariables.E_CONSTANT:
            return 'numerics::e'

        symbol = variable.get_scope().resolve_to_symbol(
            variable.get_complete_name(), SymbolKind.VARIABLE)
        if symbol is None:
            # test if variable name can be resolved to a type
            if PredefinedUnits.is_unit(variable.get_complete_name()):
                return str(
                    UnitConverter.get_factor(
                        PredefinedUnits.get_unit(
                            variable.get_complete_name()).get_unit()))

            code, message = Messages.get_could_not_resolve(variable.get_name())
            Logger.log_message(log_level=LoggingLevel.ERROR,
                               code=code,
                               message=message,
                               error_position=variable.get_source_position())
            return ''

        if symbol.is_state():
            return GSLNamesConverter.name(symbol)

        if symbol.is_buffer():
            if isinstance(symbol.get_type_symbol(), UnitTypeSymbol):
                units_conversion_factor = UnitConverter.get_factor(
                    symbol.get_type_symbol().unit.unit)
            else:
                units_conversion_factor = 1
            s = ""
            if not units_conversion_factor == 1:
                s += "(" + str(units_conversion_factor) + " * "
            s += prefix + 'B_.' + NestNamesConverter.buffer_value(symbol)
            if symbol.has_vector_parameter():
                s += '[i]'
            if not units_conversion_factor == 1:
                s += ")"
            return s

        variable_name = NestNamesConverter.convert_to_cpp_name(
            variable.get_name())

        if symbol.is_local() or symbol.is_inline_expression:
            return variable_name

        if symbol.has_vector_parameter():
            return prefix + 'get_' + variable_name + '()[i]'

        return prefix + 'get_' + variable_name + '()'
Exemplo n.º 7
0
    def visit_declaration(self, node: ASTDeclaration):

        variables = node.get_variables()
        for var in variables:
            vector_parameter = var.get_vector_parameter()
            if vector_parameter is not None:
                vector_parameter_var = ASTVariable(vector_parameter, scope=node.get_scope())
                symbol = vector_parameter_var.get_scope().resolve_to_symbol(vector_parameter_var.get_complete_name(),
                                                                            SymbolKind.VARIABLE)
                # vector parameter is a variable
                if symbol is not None:
                    if not symbol.block_type == BlockType.PARAMETERS and not symbol.block_type == BlockType.INTERNALS:
                        code, message = Messages.get_vector_parameter_wrong_block(vector_parameter_var.get_complete_name(),
                                                                                  str(symbol.block_type))
                        Logger.log_message(error_position=node.get_source_position(), log_level=LoggingLevel.ERROR,
                                           code=code, message=message)
Exemplo n.º 8
0
 def print_variable(self, node: ASTVariable) -> str:
     symbol = node.get_scope().resolve_to_symbol(
         node.lhs.get_complete_name(), SymbolKind.VARIABLE)
     ret = self.print_origin(symbol) + node.name
     for i in range(1, node.differential_order + 1):
         ret += "__d"
     return ret
Exemplo n.º 9
0
 def create_ast_variable(cls,
                         name,
                         differential_order=0,
                         source_position=None):
     # type: (str,int,ASTSourceLocation) -> ASTVariable
     return ASTVariable(name,
                        differential_order,
                        source_position=source_position)
Exemplo n.º 10
0
        def replace_var(_expr, replace_var_name: str,
                        replace_with_var_name: str):
            if isinstance(_expr, ASTSimpleExpression) and _expr.is_variable():
                var = _expr.get_variable()
                if var.get_name() == replace_var_name:
                    ast_variable = ASTVariable(
                        replace_with_var_name +
                        '__d' * var.get_differential_order(),
                        differential_order=0)
                    ast_variable.set_source_position(var.get_source_position())
                    _expr.set_variable(ast_variable)

            elif isinstance(_expr, ASTVariable):
                var = _expr
                if var.get_name() == replace_var_name:
                    var.set_name(replace_with_var_name +
                                 '__d' * var.get_differential_order())
                    var.set_differential_order(0)
Exemplo n.º 11
0
    def print_vector_size_parameter(self, variable: VariableSymbol) -> str:
        """
        Prints NEST compatible vector size parameter
        :param variable: Vector variable
        :return: vector size parameter
        """
        vector_parameter = variable.get_vector_parameter()
        vector_parameter_var = ASTVariable(
            vector_parameter, scope=variable.get_corresponding_scope())
        symbol = vector_parameter_var.get_scope().resolve_to_symbol(
            vector_parameter_var.get_complete_name(), SymbolKind.VARIABLE)
        vector_param = ""
        if symbol is not None:
            # size parameter is a variable
            vector_param += self.print_origin(symbol) + vector_parameter
        else:
            # size parameter is an integer
            vector_param += vector_parameter

        return vector_param
    def visit_variable(self, node: ASTVariable):
        vector_parameter = node.get_vector_parameter()
        if vector_parameter is not None:
            vector_parameter_var = ASTVariable(vector_parameter, scope=node.get_scope())
            symbol = vector_parameter_var.get_scope().resolve_to_symbol(vector_parameter_var.get_complete_name(),
                                                                        SymbolKind.VARIABLE)

            # vector parameter is a variable
            if symbol is not None:
                if not isinstance(symbol.get_type_symbol(), IntegerTypeSymbol):
                    code, message = Messages.get_vector_parameter_wrong_type(vector_parameter_var.get_complete_name())
                    Logger.log_message(error_position=node.get_source_position(), log_level=LoggingLevel.ERROR,
                                       code=code, message=message)
Exemplo n.º 13
0
    def __convert_print_statement_str(self, stmt, scope):
        """
        Converts the string argument of the print or println function to NEST processable format
        Variables are resolved to NEST processable format and printed with physical units as mentioned in model, separated by a space

        .. code-block:: nestml

            print("Hello World")

        .. code-block:: C++

            std::cout << "Hello World";

        .. code-block:: nestml

            print("Membrane potential = {V_m}")

        .. code-block:: C++

            std::cout << "Membrane potential = " << V_m << " mV";

        :param stmt: argument to the print or println function
        :type stmt: str
        :param scope: scope of the variables in the argument, if any
        :type scope: Scope
        :return: the converted string to NEST
        :rtype: str
        """
        pattern = re.compile(r'\{[a-zA-Z_][a-zA-Z0-9_]*\}'
                             )  # Match the variables enclosed within '{ }'
        match = pattern.search(stmt)
        if match:
            var_name = match.group(0)[match.group(0).find('{') +
                                      1:match.group(0).find('}')]
            left, right = stmt.split(
                match.group(0),
                1)  # Split on the first occurrence of a variable
            fun_left = (
                lambda l: self.__convert_print_statement_str(l, scope) + ' << '
                if l else '')
            fun_right = (lambda r: ' << ' + self.__convert_print_statement_str(
                r, scope) if r else '')
            ast_var = ASTVariable(var_name, scope=scope)
            right = ' ' + self.__get_unit_name(
                ast_var
            ) + right  # concatenate unit separated by a space with the right part of the string
            return fun_left(left) + self.convert_name_reference(
                ast_var) + fun_right(right)
        else:
            return '"' + stmt + '"'  # format bare string in C++ (add double quotes)
Exemplo n.º 14
0
    def convert_name_reference(self, variable: ASTVariable, prefix='') -> str:
        """
        Converts a single variable to nest processable format.
        :param variable: a single variable.
        :type variable: ASTVariable
        :return: a nest processable format.
        """
        from pynestml.codegeneration.nest_printer import NestPrinter

        if isinstance(variable, ASTExternalVariable):
            _name = str(variable)
            if variable.get_alternate_name():
                # the disadvantage of this approach is that the time the value is to be obtained is not explicitly specified, so we will actually get the value at the end of the min_delay timestep
                return "((POST_NEURON_TYPE*)(__target))->get_" + variable.get_alternate_name(
                ) + "()"

            return "((POST_NEURON_TYPE*)(__target))->get_" + _name + "(_tr_t)"

        if variable.get_name() == PredefinedVariables.E_CONSTANT:
            return 'numerics::e'

        symbol = variable.get_scope().resolve_to_symbol(
            variable.get_complete_name(), SymbolKind.VARIABLE)
        if symbol is None:
            # test if variable name can be resolved to a type
            if PredefinedUnits.is_unit(variable.get_complete_name()):
                return str(
                    UnitConverter.get_factor(
                        PredefinedUnits.get_unit(
                            variable.get_complete_name()).get_unit()))

            code, message = Messages.get_could_not_resolve(variable.get_name())
            Logger.log_message(log_level=LoggingLevel.ERROR,
                               code=code,
                               message=message,
                               error_position=variable.get_source_position())
            return ''

        if symbol.is_local():
            return variable.get_name() + (
                '[' + variable.get_vector_parameter() +
                ']' if symbol.has_vector_parameter() else '')
        if symbol.is_buffer():
            if isinstance(symbol.get_type_symbol(), UnitTypeSymbol):
                units_conversion_factor = UnitConverter.get_factor(
                    symbol.get_type_symbol().unit.unit)
            else:
                units_conversion_factor = 1
            s = ""
            if not units_conversion_factor == 1:
                s += "(" + str(units_conversion_factor) + " * "
            s += NestPrinter.print_origin(
                symbol,
                prefix=prefix) + NestNamesConverter.buffer_value(symbol)
            if symbol.has_vector_parameter():
                s += '[' + variable.get_vector_parameter() + ']'
            if not units_conversion_factor == 1:
                s += ")"
            return s

        if symbol.is_inline_expression:
            return 'get_' + variable.get_name() + '()' + (
                '[i]' if symbol.has_vector_parameter() else '')

        if symbol.is_kernel():
            assert False, "NEST reference converter cannot print kernel; kernel should have been converted during code generation"

        if symbol.is_state():
            temp = ""
            temp += NestNamesConverter.getter(symbol) + "()"
            temp += ('[' + variable.get_vector_parameter() +
                     ']' if symbol.has_vector_parameter() else '')
            return temp

        variable_name = NestNamesConverter.convert_to_cpp_name(
            variable.get_complete_name())
        if symbol.is_local():
            return variable_name + ('[i]'
                                    if symbol.has_vector_parameter() else '')

        if symbol.is_inline_expression:
            return 'get_' + variable_name + '()' + (
                '[i]' if symbol.has_vector_parameter() else '')

        return NestPrinter.print_origin(symbol, prefix=prefix) + \
            NestNamesConverter.name(symbol) + \
            ('[' + variable.get_vector_parameter() + ']' if symbol.has_vector_parameter() else '')
Exemplo n.º 15
0
 def create_ast_variable(cls, name, differential_order=0, vector_parameter=None, is_homogeneous=False, source_position=None):
     # type: (str,int,ASTSourceLocation) -> ASTVariable
     return ASTVariable(name, differential_order, vector_parameter=vector_parameter, is_homogeneous=is_homogeneous, source_position=source_position)