def add_ode_shape_to_variable(ode_shape): """ Adds the shape as the defining equation. :param ode_shape: a single shape object. :type ode_shape: ast_ode_shape """ if ode_shape.get_variable().get_differential_order() == 0: # we only update those which define an ode return # we check if the corresponding symbol already exists, e.g. V_m' has already been declared existing_symbol = ode_shape.get_scope().resolve_to_symbol( ode_shape.get_variable().get_name_of_lhs(), SymbolKind.VARIABLE) if existing_symbol is not None: existing_symbol.set_ode_definition(ode_shape.get_expression()) existing_symbol.set_variable_type(VariableType.SHAPE) ode_shape.get_scope().update_variable_symbol(existing_symbol) code, message = Messages.get_ode_updated( ode_shape.get_variable().get_name_of_lhs()) Logger.log_message(error_position=existing_symbol. get_referenced_object().get_source_position(), code=code, message=message, log_level=LoggingLevel.INFO) else: code, message = Messages.get_no_variable_found( ode_shape.get_variable().get_name_of_lhs()) Logger.log_message(code=code, message=message, error_position=ode_shape.get_source_position(), log_level=LoggingLevel.ERROR) return
def visit_variable(self, node): """ Visits each shape and checks if it is used correctly. :param node: a single node. :type node: AST_ """ for shapeName in self.__shapes: # in order to allow shadowing by local scopes, we first check if the element has been declared locally symbol = node.get_scope().resolve_to_symbol(shapeName, SymbolKind.VARIABLE) # if it is not a shape just continue if symbol is None: code, message = Messages.get_no_variable_found(shapeName) Logger.log_message(neuron=self.__neuron_node, code=code, message=message, log_level=LoggingLevel.ERROR) continue if not symbol.is_shape(): continue if node.get_complete_name() == shapeName: parent = self.__neuron_node.get_parent(node) if parent is not None: if isinstance(parent, ASTOdeShape): continue grandparent = self.__neuron_node.get_parent(parent) if grandparent is not None and isinstance(grandparent, ASTFunctionCall): grandparent_func_name = grandparent.get_name() if grandparent_func_name == 'curr_sum' or grandparent_func_name == 'cond_sum' or \ grandparent_func_name == 'convolve': continue code, message = Messages.get_shape_outside_convolve(shapeName) Logger.log_message(error_position=node.get_source_position(), code=code, message=message, log_level=LoggingLevel.ERROR) return
def add_kernel_to_variable(kernel): """ Adds the kernel as the defining equation. If the definition of the kernel is e.g. `g'' = ...` then variable symbols `g` and `g'` will have their kernel definition and variable type set. :param kernel: a single kernel object. :type kernel: ASTKernel """ if len(kernel.get_variables()) == 1 \ and kernel.get_variables()[0].get_differential_order() == 0: # we only update those which define an ODE; skip "direct function of time" specifications return for var, expr in zip(kernel.get_variables(), kernel.get_expressions()): for diff_order in range(var.get_differential_order()): var_name = var.get_name() + "'" * diff_order existing_symbol = kernel.get_scope().resolve_to_symbol( var_name, SymbolKind.VARIABLE) if existing_symbol is None: code, message = Messages.get_no_variable_found( var.get_name_of_lhs()) Logger.log_message(code=code, message=message, error_position=kernel.get_source_position(), log_level=LoggingLevel.ERROR) return existing_symbol.set_ode_or_kernel(expr) existing_symbol.set_variable_type(VariableType.KERNEL) kernel.get_scope().update_variable_symbol(existing_symbol)
def add_ode_to_variable(ode_equation): """ Resolves to the corresponding symbol and updates the corresponding ode-declaration. In the case that :param ode_equation: a single ode-equation :type ode_equation: ast_ode_equation """ # the definition of a differential equations is defined by stating the derivation, thus derive the actual order diff_order = ode_equation.get_lhs().get_differential_order() - 1 # we check if the corresponding symbol already exists, e.g. V_m' has already been declared existing_symbol = (ode_equation.get_scope().resolve_to_symbol( ode_equation.get_lhs().get_name() + '\'' * diff_order, SymbolKind.VARIABLE)) if existing_symbol is not None: existing_symbol.set_ode_definition(ode_equation.get_rhs()) # todo added on merge ode_equation.get_scope().update_variable_symbol(existing_symbol) code, message = Messages.get_ode_updated( ode_equation.get_lhs().get_name_of_lhs()) Logger.log_message(error_position=existing_symbol. get_referenced_object().get_source_position(), code=code, message=message, log_level=LoggingLevel.INFO) else: code, message = Messages.get_no_variable_found( ode_equation.get_lhs().get_name_of_lhs()) Logger.log_message(code=code, message=message, error_position=ode_equation.get_source_position(), log_level=LoggingLevel.ERROR) return
def add_ode_to_variable(ode_equation): """ Resolves to the corresponding symbol and updates the corresponding ode-declaration. :param ode_equation: a single ode-equation :type ode_equation: ast_ode_equation """ for diff_order in range(ode_equation.get_lhs().get_differential_order()): var_name = ode_equation.get_lhs().get_name() + "'" * diff_order existing_symbol = ode_equation.get_scope().resolve_to_symbol( var_name, SymbolKind.VARIABLE) if existing_symbol is None: code, message = Messages.get_no_variable_found( ode_equation.get_lhs().get_name_of_lhs()) Logger.log_message( code=code, message=message, error_position=ode_equation.get_source_position(), log_level=LoggingLevel.ERROR) return existing_symbol.set_ode_or_kernel(ode_equation) ode_equation.get_scope().update_variable_symbol(existing_symbol) code, message = Messages.get_ode_updated( ode_equation.get_lhs().get_name_of_lhs()) Logger.log_message(error_position=existing_symbol. get_referenced_object().get_source_position(), code=code, message=message, log_level=LoggingLevel.INFO)
def visit_variable(self, node): """ Visits each shape and checks if it is used correctly. :param node: a single node. :type node: AST_ """ for shapeName in self.__shapes: # in order to allow shadowing by local scopes, we first check if the element has been declared locally symbol = node.get_scope().resolve_to_symbol( shapeName, SymbolKind.VARIABLE) # if it is not a shape just continue if symbol is None: code, message = Messages.get_no_variable_found(shapeName) Logger.log_message(neuron=self.__neuron_node, code=code, message=message, log_level=LoggingLevel.ERROR) continue if not symbol.is_shape(): continue if node.get_complete_name() == shapeName: parent = self.__neuron_node.get_parent(node) if parent is not None: if isinstance(parent, ASTOdeShape): continue grandparent = self.__neuron_node.get_parent(parent) if grandparent is not None and isinstance( grandparent, ASTFunctionCall): grandparent_func_name = grandparent.get_name() if grandparent_func_name == 'curr_sum' or grandparent_func_name == 'cond_sum' or \ grandparent_func_name == 'convolve': continue code, message = Messages.get_shape_outside_convolve(shapeName) Logger.log_message(error_position=node.get_source_position(), code=code, message=message, log_level=LoggingLevel.ERROR) return
def add_ode_to_variable(ode_equation): """ Resolves to the corresponding symbol and updates the corresponding ode-declaration. In the case that :param ode_equation: a single ode-equation :type ode_equation: ast_ode_equation """ # the definition of a differential equations is defined by stating the derivation, thus derive the actual order diff_order = ode_equation.get_lhs().get_differential_order() - 1 # we check if the corresponding symbol already exists, e.g. V_m' has already been declared existing_symbol = (ode_equation.get_scope().resolve_to_symbol(ode_equation.get_lhs().get_name() + '\'' * diff_order, SymbolKind.VARIABLE)) if existing_symbol is not None: existing_symbol.set_ode_definition(ode_equation.get_rhs()) # todo added on merge ode_equation.get_scope().update_variable_symbol(existing_symbol) code, message = Messages.get_ode_updated(ode_equation.get_lhs().get_name_of_lhs()) Logger.log_message(error_position=existing_symbol.get_referenced_object().get_source_position(), code=code, message=message, log_level=LoggingLevel.INFO) else: code, message = Messages.get_no_variable_found(ode_equation.get_lhs().get_name_of_lhs()) Logger.log_message(code=code, message=message, error_position=ode_equation.get_source_position(), log_level=LoggingLevel.ERROR) return
def visit_variable(self, node: ASTNode): """ Visits each kernel and checks if it is used correctly. :param node: a single node. """ for kernelName in self.__kernels: # in order to allow shadowing by local scopes, we first check if the element has been declared locally symbol = node.get_scope().resolve_to_symbol( kernelName, SymbolKind.VARIABLE) # if it is not a kernel just continue if symbol is None: if not isinstance(node, ASTExternalVariable): code, message = Messages.get_no_variable_found(kernelName) Logger.log_message(node=self.__neuron_node, code=code, message=message, log_level=LoggingLevel.ERROR) continue if not symbol.is_kernel(): continue if node.get_complete_name() == kernelName: parent = self.__neuron_node.get_parent(node) if parent is not None: if isinstance(parent, ASTKernel): continue grandparent = self.__neuron_node.get_parent(parent) if grandparent is not None and isinstance( grandparent, ASTFunctionCall): grandparent_func_name = grandparent.get_name() if grandparent_func_name == 'convolve': continue code, message = Messages.get_kernel_outside_convolve( kernelName) Logger.log_message(code=code, message=message, log_level=LoggingLevel.ERROR, error_position=node.get_source_position())
def add_ode_shape_to_variable(ode_shape): """ Adds the shape as the defining equation. :param ode_shape: a single shape object. :type ode_shape: ast_ode_shape """ if ode_shape.get_variable().get_differential_order() == 0: # we only update those which define an ode return # we check if the corresponding symbol already exists, e.g. V_m' has already been declared existing_symbol = ode_shape.get_scope().resolve_to_symbol(ode_shape.get_variable().get_name_of_lhs(), SymbolKind.VARIABLE) if existing_symbol is not None: existing_symbol.set_ode_definition(ode_shape.get_expression()) existing_symbol.set_variable_type(VariableType.SHAPE) ode_shape.get_scope().update_variable_symbol(existing_symbol) code, message = Messages.get_ode_updated(ode_shape.get_variable().get_name_of_lhs()) Logger.log_message(error_position=existing_symbol.get_referenced_object().get_source_position(), code=code, message=message, log_level=LoggingLevel.INFO) else: code, message = Messages.get_no_variable_found(ode_shape.get_variable().get_name_of_lhs()) Logger.log_message(code=code, message=message, error_position=ode_shape.get_source_position(), log_level=LoggingLevel.ERROR) return