def visit_declaration(self, node: ASTDeclaration) -> None: """ Private method: Used to visit a single declaration, update its scope and return the corresponding set of symbols :param node: a declaration AST node :return: the scope is updated without a return value. """ expression = node.get_expression() if node.has_expression() else None visitor = ASTDataTypeVisitor() node.get_data_type().accept(visitor) type_name = visitor.result # all declarations in the state block are recordable is_recordable = (node.is_recordable or self.block_type_stack.top() == BlockType.STATE) init_value = node.get_expression() if self.block_type_stack.top( ) == BlockType.STATE else None # split the decorators in the AST up into namespace decorators and other decorators decorators = [] namespace_decorators = {} for d in node.get_decorators(): if isinstance(d, ASTNamespaceDecorator): namespace_decorators[str(d.get_namespace())] = str( d.get_name()) else: decorators.append(d) # now for each variable create a symbol and update the scope block_type = None if not self.block_type_stack.is_empty(): block_type = self.block_type_stack.top() for var in node.get_variables( ): # for all variables declared create a new symbol var.update_scope(node.get_scope()) type_symbol = PredefinedTypes.get_type(type_name) vector_parameter = var.get_vector_parameter() symbol = VariableSymbol(element_reference=node, scope=node.get_scope(), name=var.get_complete_name(), block_type=block_type, declaring_expression=expression, is_predefined=False, is_inline_expression=False, is_recordable=is_recordable, type_symbol=type_symbol, initial_value=init_value, vector_parameter=vector_parameter, variable_type=VariableType.VARIABLE, decorators=decorators, namespace_decorators=namespace_decorators) symbol.set_comment(node.get_comment()) node.get_scope().add_symbol(symbol) var.set_type_symbol(Either.value(type_symbol)) # the data type node.get_data_type().update_scope(node.get_scope()) # the rhs update if node.has_expression(): node.get_expression().update_scope(node.get_scope()) # the invariant update if node.has_invariant(): node.get_invariant().update_scope(node.get_scope())
def visit_ode_function(self, node): """ Private method: Used to visit a single ode-function, create the corresponding symbol and update the scope. :param node: a single ode-function. :type node: ast_ode_function """ data_type_visitor = ASTDataTypeVisitor() node.get_data_type().accept(data_type_visitor) type_symbol = PredefinedTypes.get_type(data_type_visitor.result) # now a new symbol symbol = VariableSymbol(element_reference=node, scope=node.get_scope(), name=node.get_variable_name(), block_type=BlockType.EQUATION, declaring_expression=node.get_expression(), is_predefined=False, is_function=True, is_recordable=node.is_recordable, type_symbol=type_symbol, variable_type=VariableType.VARIABLE) symbol.set_comment(node.get_comment()) # now update the scopes node.get_scope().add_symbol(symbol) node.get_data_type().update_scope(node.get_scope()) node.get_expression().update_scope(node.get_scope())
def endvisit_input_port(self, node): if not node.has_datatype(): return type_symbol = node.get_datatype().get_type_symbol() 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=BlockType.INPUT, vector_parameter=node.get_index_parameter(), is_predefined=False, is_inline_expression=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_declaration(self, node): """ Private method: Used to visit a single declaration, update its scope and return the corresponding set of symbols :param node: a declaration object. :type node: ast_declaration :return: the scope is update without a return value. :rtype: void """ expression = node.get_expression() if node.has_expression() else None visitor = ASTDataTypeVisitor() node.get_data_type().accept(visitor) type_name = visitor.result # all declarations in the state block are recordable is_recordable = (node.is_recordable or self.block_type_stack.top() == BlockType.STATE or self.block_type_stack.top() == BlockType.INITIAL_VALUES) init_value = node.get_expression() if self.block_type_stack.top( ) == BlockType.INITIAL_VALUES else None vector_parameter = node.get_size_parameter() # now for each variable create a symbol and update the scope for var in node.get_variables( ): # for all variables declared create a new symbol var.update_scope(node.get_scope()) type_symbol = PredefinedTypes.get_type(type_name) symbol = VariableSymbol(element_reference=node, scope=node.get_scope(), name=var.get_complete_name(), block_type=self.block_type_stack.top(), declaring_expression=expression, is_predefined=False, is_function=node.is_function, is_recordable=is_recordable, type_symbol=type_symbol, initial_value=init_value, vector_parameter=vector_parameter, variable_type=VariableType.VARIABLE) symbol.set_comment(node.get_comment()) node.get_scope().add_symbol(symbol) var.set_type_symbol(Either.value(type_symbol)) # the data type node.get_data_type().update_scope(node.get_scope()) # the rhs update if node.has_expression(): node.get_expression().update_scope(node.get_scope()) # the invariant update if node.has_invariant(): node.get_invariant().update_scope(node.get_scope()) return
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_declaration(self, node): """ Private method: Used to visit a single declaration, update its scope and return the corresponding set of symbols :param node: a declaration object. :type node: ast_declaration :return: the scope is update without a return value. :rtype: void """ expression = node.get_expression() if node.has_expression() else None visitor = ASTDataTypeVisitor() node.get_data_type().accept(visitor) type_name = visitor.result # all declarations in the state block are recordable is_recordable = (node.is_recordable or self.block_type_stack.top() == BlockType.STATE or self.block_type_stack.top() == BlockType.INITIAL_VALUES) init_value = node.get_expression() if self.block_type_stack.top() == BlockType.INITIAL_VALUES else None vector_parameter = node.get_size_parameter() # now for each variable create a symbol and update the scope for var in node.get_variables(): # for all variables declared create a new symbol var.update_scope(node.get_scope()) type_symbol = PredefinedTypes.get_type(type_name) symbol = VariableSymbol(element_reference=node, scope=node.get_scope(), name=var.get_complete_name(), block_type=self.block_type_stack.top(), declaring_expression=expression, is_predefined=False, is_function=node.is_function, is_recordable=is_recordable, type_symbol=type_symbol, initial_value=init_value, vector_parameter=vector_parameter, variable_type=VariableType.VARIABLE ) symbol.set_comment(node.get_comment()) node.get_scope().add_symbol(symbol) var.set_type_symbol(Either.value(type_symbol)) # the data type node.get_data_type().update_scope(node.get_scope()) # the rhs update if node.has_expression(): node.get_expression().update_scope(node.get_scope()) # the invariant update if node.has_invariant(): node.get_invariant().update_scope(node.get_scope()) return
def visit_ode_shape(self, node): """ Private method: Used to visit a single ode-shape, create the corresponding symbol and update the scope. :param node: a single ode-shape. :type node: ast_ode_shape """ if node.get_variable().get_differential_order() == 0 and \ node.get_scope().resolve_to_symbol(node.get_variable().get_complete_name(), SymbolKind.VARIABLE) is None: symbol = VariableSymbol(element_reference=node, scope=node.get_scope(), name=node.get_variable().get_name(), block_type=BlockType.EQUATION, declaring_expression=node.get_expression(), is_predefined=False, is_function=False, is_recordable=True, type_symbol=PredefinedTypes.get_real_type(), variable_type=VariableType.SHAPE) symbol.set_comment(node.get_comment()) node.get_scope().add_symbol(symbol) node.get_variable().update_scope(node.get_scope()) node.get_expression().update_scope(node.get_scope())
def visit_kernel(self, node): """ Private method: Used to visit a single kernel, create the corresponding symbol and update the scope. :param node: a kernel. :type node: ASTKernel """ for var, expr in zip(node.get_variables(), node.get_expressions()): if var.get_differential_order() == 0 and \ node.get_scope().resolve_to_symbol(var.get_complete_name(), SymbolKind.VARIABLE) is None: symbol = VariableSymbol(element_reference=node, scope=node.get_scope(), name=var.get_name(), block_type=BlockType.EQUATION, declaring_expression=expr, is_predefined=False, is_inline_expression=False, is_recordable=True, type_symbol=PredefinedTypes.get_real_type(), variable_type=VariableType.KERNEL) symbol.set_comment(node.get_comment()) node.get_scope().add_symbol(symbol) var.update_scope(node.get_scope()) expr.update_scope(node.get_scope())