def visitBlockWithVariables(self, ctx): declarations = list() if ctx.declaration() is not None: for child in ctx.declaration(): declarations.append(self.visit(child)) block_type = ctx.blockType.text # the text field stores the exact name of the token, e.g., state source_pos = create_source_pos(ctx) if block_type == 'state': ret = ASTNodeFactory.create_ast_block_with_variables( True, False, False, False, declarations, source_pos) elif block_type == 'parameters': ret = ASTNodeFactory.create_ast_block_with_variables( False, True, False, False, declarations, source_pos) elif block_type == 'internals': ret = ASTNodeFactory.create_ast_block_with_variables( False, False, True, False, declarations, source_pos) elif block_type == 'initial_values': ret = ASTNodeFactory.create_ast_block_with_variables( False, False, False, True, declarations, source_pos) else: raise RuntimeError( '(PyNestML.ASTBuilder) Unspecified type (=%s) of var-block.' % str(ctx.blockType)) update_node_comments(ret, self.__comments.visit(ctx)) return ret
def make_trivial_assignment(var, order, equations_block, is_shape=False): from pynestml.meta_model.ast_variable import ASTVariable from pynestml.meta_model.ast_equations_block import ASTEquationsBlock from pynestml.meta_model.ast_node import ASTNode # type: (ASTVariable,int,ASTEquationsBlock,bool) -> ASTNode lhs_variable = ASTNodeFactory.create_ast_variable( name=var.get_name(), differential_order=order + 1, source_position=ASTSourceLocation.get_added_source_position()) rhs_variable = ASTNodeFactory.create_ast_variable( name=convert_variable_name_to_generator_notation(var).get_name(), differential_order=order, source_position=ASTSourceLocation.get_added_source_position()) expression = ASTNodeFactory.create_ast_simple_expression( variable=rhs_variable, source_position=ASTSourceLocation.get_added_source_position()) source_loc = ASTSourceLocation.get_added_source_position() if is_shape: node = ASTNodeFactory.create_ast_ode_shape(lhs=lhs_variable, rhs=expression, source_position=source_loc) else: node = ASTNodeFactory.create_ast_ode_equation( lhs=lhs_variable, rhs=expression, source_position=source_loc) equations_block.get_declarations().append(node) return node
def create_empty_update_block(self): """ Create an empty update block. Only makes sense if one does not already exist. """ assert self.get_update_blocks() is None or len(self.get_update_blocks( )) == 0, "create_empty_update_block() called although update block already present" from pynestml.meta_model.ast_node_factory import ASTNodeFactory block = ASTNodeFactory.create_ast_block([], ASTSourceLocation.get_predefined_source_position()) update_block = ASTNodeFactory.create_ast_update_block(block, ASTSourceLocation.get_predefined_source_position()) self.get_body().get_body_elements().append(update_block)
def visitOutputBlock(self, ctx): source_pos = create_source_pos(ctx) if ctx.isSpike is not None: ret = ASTNodeFactory.create_ast_output_block(s_type=ASTSignalType.SPIKE, source_position=source_pos) update_node_comments(ret, self.__comments.visit(ctx)) return ret elif ctx.isCurrent is not None: ret = ASTNodeFactory.create_ast_output_block(s_type=ASTSignalType.CURRENT, source_position=source_pos) update_node_comments(ret, self.__comments.visit(ctx)) return ret else: raise RuntimeError('(PyNestML.ASTBuilder) Type of output buffer not recognized.')
def add_assignment_to_update_block(assignment, neuron): """ Adds a single assignment to the end of the update block of the handed over neuron. :param assignment: a single assignment :param neuron: a single neuron instance :return: the modified neuron """ small_stmt = ASTNodeFactory.create_ast_small_stmt(assignment=assignment, source_position=ASTSourceLocation.get_added_source_position()) stmt = ASTNodeFactory.create_ast_stmt(small_stmt=small_stmt, source_position=ASTSourceLocation.get_added_source_position()) neuron.get_update_blocks().get_block().get_stmts().append(stmt) return neuron
def add_declaration_to_update_block(declaration, neuron): # type: (ASTDeclaration, ASTNeuron) -> ASTNeuron """ Adds a single declaration to the end of the update block of the handed over neuron. :param declaration: ASTDeclaration node to add :param neuron: a single neuron instance :return: a modified neuron """ small_stmt = ASTNodeFactory.create_ast_small_stmt(declaration=declaration, source_position=ASTSourceLocation.get_added_source_position()) stmt = ASTNodeFactory.create_ast_stmt(small_stmt=small_stmt, source_position=ASTSourceLocation.get_added_source_position()) neuron.get_update_blocks().get_block().get_stmts().append(stmt) return neuron
def add_assignment_to_update_block(assignment, neuron): """ Adds a single assignment to the end of the update block of the handed over neuron. :param assignment: a single assignment :param neuron: a single neuron instance :return: the modified neuron """ small_stmt = ASTNodeFactory.create_ast_small_stmt( assignment=assignment, source_position=ASTSourceLocation.get_added_source_position()) stmt = ASTNodeFactory.create_ast_stmt( small_stmt=small_stmt, source_position=ASTSourceLocation.get_added_source_position()) neuron.get_update_blocks().get_block().get_stmts().append(stmt) return neuron
def visitStmt(self, ctx): small = self.visit( ctx.smallStmt()) if ctx.smallStmt() is not None else None compound = self.visit( ctx.compoundStmt()) if ctx.compoundStmt() is not None else None return ASTNodeFactory.create_ast_stmt(small, compound, create_source_pos(ctx))
def visitElifClause(self, ctx): condition = self.visit(ctx.expression()) if ctx.expression() is not None else None block = self.visit(ctx.block()) if ctx.block() is not None else None node = ASTNodeFactory.create_ast_elif_clause(condition=condition, block=block, source_position=create_source_pos(ctx)) update_node_comments(node, self.__comments.visit(ctx)) return node
def visitOdeShape(self, ctx): lhs = self.visit(ctx.lhs) if ctx.lhs is not None else None rhs = self.visit(ctx.rhs) if ctx.rhs is not None else None shape = ASTNodeFactory.create_ast_ode_shape( lhs=lhs, rhs=rhs, source_position=create_source_pos(ctx)) update_node_comments(shape, self.__comments.visit(ctx)) return shape
def visitSynapse(self, ctx): from pynestml.generated.PyNestMLLexer import PyNestMLLexer name = str(ctx.NAME()) if ctx.NAME() is not None else None body = self.visit( ctx.synapseBody()) if ctx.synapseBody() is not None else None # after we have constructed the meta_model of the neuron, # we can ensure some basic properties which should always hold # we have to check if each type of block is defined at most once (except for function), and that input,output # and update are defined once if hasattr(ctx.start.source[1], 'fileName'): artifact_name = ntpath.basename(ctx.start.source[1].fileName) else: artifact_name = 'parsed from string' synapse = ASTNodeFactory.create_ast_synapse( name=name + FrontendConfiguration.suffix, body=body, source_position=create_source_pos(ctx), artifact_name=artifact_name) # update the comments update_node_comments(synapse, self.__comments.visit(ctx)) # in order to enable the logger to print correct messages set as the source the corresponding neuron Logger.set_current_node(synapse) CoCoEachSynapseBlockUniqueAndDefined.check_co_co(node=synapse) # now the meta_model seems to be correct, return it Logger.set_current_node(synapse) return synapse
def visitOdeEquation(self, ctx): lhs = self.visit(ctx.lhs) if ctx.lhs is not None else None rhs = self.visit(ctx.rhs) if ctx.rhs is not None else None ode_equation = ASTNodeFactory.create_ast_ode_equation( lhs=lhs, rhs=rhs, source_position=create_source_pos(ctx)) update_node_comments(ode_equation, self.__comments.visit(ctx)) return ode_equation
def visitVariable(self, ctx): differential_order = (len(ctx.DIFFERENTIAL_ORDER()) if ctx.DIFFERENTIAL_ORDER() is not None else 0) return ASTNodeFactory.create_ast_variable( name=str(ctx.NAME()), differential_order=differential_order, source_position=create_source_pos(ctx))
def visitLogicalOperator(self, ctx): is_logical_and = (True if ctx.logicalAnd is not None else False) is_logical_or = (True if ctx.logicalOr is not None else False) return ASTNodeFactory.create_ast_logical_operator( is_logical_and=is_logical_and, is_logical_or=is_logical_or, source_position=create_source_pos(ctx))
def visitInputPort(self, ctx): name = str(ctx.name.text) if ctx.name is not None else None size_parameter = str( ctx.sizeParameter.text) if ctx.sizeParameter is not None else None input_qualifiers = [] if ctx.inputQualifier() is not None: for qual in ctx.inputQualifier(): input_qualifiers.append(self.visit(qual)) data_type = self.visit( ctx.dataType()) if ctx.dataType() is not None else None if ctx.isCurrent: signal_type = ASTSignalType.CURRENT elif ctx.isSpike: signal_type = ASTSignalType.SPIKE else: signal_type = None ret = ASTNodeFactory.create_ast_input_port( name=name, size_parameter=size_parameter, data_type=data_type, input_qualifiers=input_qualifiers, signal_type=signal_type, source_position=create_source_pos(ctx)) update_node_comments(ret, self.__comments.visit(ctx)) return ret
def visitInputQualifier(self, ctx): is_inhibitory = True if ctx.isInhibitory is not None else False is_excitatory = True if ctx.isExcitatory is not None else False return ASTNodeFactory.create_ast_input_qualifier( is_inhibitory=is_inhibitory, is_excitatory=is_excitatory, source_position=create_source_pos(ctx))
def visitBlock(self, ctx): stmts = list() if ctx.stmt() is not None: for stmt in ctx.stmt(): stmts.append(self.visit(stmt)) block = ASTNodeFactory.create_ast_block(stmts=stmts, source_position=create_source_pos(ctx)) return block
def add_declaration_to_update_block(declaration, neuron): # type: (ASTDeclaration, ASTNeuron) -> ASTNeuron """ Adds a single declaration to the end of the update block of the handed over neuron. :param declaration: ASTDeclaration node to add :param neuron: a single neuron instance :return: a modified neuron """ small_stmt = ASTNodeFactory.create_ast_small_stmt( declaration=declaration, source_position=ASTSourceLocation.get_added_source_position()) stmt = ASTNodeFactory.create_ast_stmt( small_stmt=small_stmt, source_position=ASTSourceLocation.get_added_source_position()) neuron.get_update_blocks().get_block().get_stmts().append(stmt) return neuron
def get_lhs_variable_as_expression(self): from pynestml.meta_model.ast_node_factory import ASTNodeFactory # TODO: maybe calculate new source positions exactly? result = ASTNodeFactory.create_ast_simple_expression(variable=self.get_variable(), source_position=self.get_variable().get_source_position()) result.update_scope(self.get_scope()) return result
def visitCompoundStmt(self, ctx): if_stmt = self.visit(ctx.ifStmt()) if ctx.ifStmt() is not None else None while_stmt = self.visit(ctx.whileStmt()) if ctx.whileStmt() is not None else None for_stmt = self.visit(ctx.forStmt()) if ctx.forStmt() is not None else None node = ASTNodeFactory.create_ast_compound_stmt(if_stmt, while_stmt, for_stmt, create_source_pos(ctx)) update_node_comments(node, self.__comments.visit(ctx)) return node
def visitUnitType(self, ctx): left_parenthesis = True if ctx.leftParentheses is not None else False compound_unit = self.visit( ctx.compoundUnit) if ctx.compoundUnit is not None else None is_encapsulated = left_parenthesis and True if ctx.rightParentheses is not None else False base = self.visit(ctx.base) if ctx.base is not None else None is_pow = True if ctx.powOp is not None else False exponent = int(str( ctx.exponent.getText())) if ctx.exponent is not None else None if ctx.unitlessLiteral is not None: lhs = int(str(ctx.unitlessLiteral.text)) else: lhs = self.visit(ctx.left) if ctx.left is not None else None is_times = True if ctx.timesOp is not None else False is_div = True if ctx.divOp is not None else False rhs = self.visit(ctx.right) if ctx.right is not None else None unit = str(ctx.unit.text) if ctx.unit is not None else None return ASTNodeFactory.create_ast_unit_type( is_encapsulated=is_encapsulated, compound_unit=compound_unit, base=base, is_pow=is_pow, exponent=exponent, lhs=lhs, rhs=rhs, is_div=is_div, is_times=is_times, unit=unit, source_position=create_source_pos(ctx))
def visitBody(self, ctx): """ Here, in order to ensure that the correct order of elements is kept, we use a method which inspects a list of elements and returns the one with the smallest source line. """ body_elements = list() # visit all var_block children if ctx.blockWithVariables() is not None: for child in ctx.blockWithVariables(): body_elements.append(child) if ctx.updateBlock() is not None: for child in ctx.updateBlock(): body_elements.append(child) if ctx.equationsBlock() is not None: for child in ctx.equationsBlock(): body_elements.append(child) if ctx.inputBlock() is not None: for child in ctx.inputBlock(): body_elements.append(child) if ctx.outputBlock() is not None: for child in ctx.outputBlock(): body_elements.append(child) if ctx.function() is not None: for child in ctx.function(): body_elements.append(child) elements = list() while len(body_elements) > 0: elem = get_next(body_elements) elements.append(self.visit(elem)) body_elements.remove(elem) body = ASTNodeFactory.create_ast_body(elements, create_source_pos(ctx)) return body
def construct_equivalent_direct_assignment_rhs(self, operator, lhs_variable, rhs_in_brackets): from pynestml.meta_model.ast_node_factory import ASTNodeFactory # TODO: maybe calculate new source positions exactly? result = ASTNodeFactory.create_ast_compound_expression(lhs=lhs_variable, binary_operator=operator, rhs=rhs_in_brackets, source_position=self.get_source_position()) result.update_scope(self.get_scope()) return result
def get_bracketed_rhs_expression(self): from pynestml.meta_model.ast_node_factory import ASTNodeFactory # TODO: maybe calculate new source positions exactly? result = ASTNodeFactory.create_ast_expression(is_encapsulated=True, expression=self.get_expression(), source_position=self.get_expression().get_source_position()) result.update_scope(self.get_scope()) return result
def visitParameter(self, ctx): name = str(ctx.NAME()) if ctx.NAME() is not None else None data_type = self.visit( ctx.dataType()) if ctx.dataType() is not None else None return ASTNodeFactory.create_ast_parameter( name=name, data_type=data_type, source_position=create_source_pos(ctx))
def get_lhs_variable_as_expression(self): from pynestml.meta_model.ast_node_factory import ASTNodeFactory # TODO: maybe calculate new source positions exactly? result = ASTNodeFactory.create_ast_simple_expression( variable=self.get_variable(), source_position=self.get_variable().get_source_position()) result.update_scope(self.get_scope()) return result
def visitUnaryOperator(self, ctx): is_unary_plus = (True if ctx.unaryPlus is not None else False) is_unary_minus = (True if ctx.unaryMinus is not None else False) is_unary_tilde = (True if ctx.unaryTilde is not None else False) return ASTNodeFactory.create_ast_unary_operator(is_unary_plus=is_unary_plus, is_unary_minus=is_unary_minus, is_unary_tilde=is_unary_tilde, source_position=create_source_pos(ctx))
def visitIfStmt(self, ctx): if_clause = self.visit(ctx.ifClause()) if ctx.ifClause() is not None else None elif_clauses = list() if ctx.elifClause() is not None: for clause in ctx.elifClause(): elif_clauses.append(self.visit(clause)) else_clause = self.visit(ctx.elseClause()) if ctx.elseClause() is not None else None return ASTNodeFactory.create_ast_if_stmt(if_clause=if_clause, elif_clauses=elif_clauses, else_clause=else_clause, source_position=create_source_pos(ctx))
def visitInputBlock(self, ctx): input_ports = [] if ctx.inputPort() is not None: for port in ctx.inputPort(): input_ports.append(self.visit(port)) ret = ASTNodeFactory.create_ast_input_block(input_definitions=input_ports, source_position=create_source_pos(ctx)) update_node_comments(ret, self.__comments.visit(ctx)) return ret
def visitOnReceiveBlock(self, ctx): block = self.visit(ctx.block()) if ctx.block() is not None else None port_name = ctx.inputPortName.text const_parameters = {} for el in ctx.constParameter(): const_parameters[el.name.text] = el.value.text ret = ASTNodeFactory.create_ast_on_receive_block(block=block, port_name=port_name, const_parameters=const_parameters, source_position=create_source_pos(ctx)) update_node_comments(ret, self.__comments.visit(ctx)) return ret
def visitInputBlock(self, ctx): input_lines = list() if ctx.inputLine() is not None: for line in ctx.inputLine(): input_lines.append(self.visit(line)) ret = ASTNodeFactory.create_ast_input_block(input_definitions=input_lines, source_position=create_source_pos(ctx)) update_node_comments(ret, self.__comments.visit(ctx)) return ret
def get_bracketed_rhs_expression(self): from pynestml.meta_model.ast_node_factory import ASTNodeFactory # TODO: maybe calculate new source positions exactly? result = ASTNodeFactory.create_ast_expression( is_encapsulated=True, expression=self.get_expression(), source_position=self.get_expression().get_source_position()) result.update_scope(self.get_scope()) return result
def deconstruct_assignment(cls, lhs=None, is_plus=False, is_minus=False, is_times=False, is_divide=False, _rhs=None): """ From lhs and rhs it constructs a new rhs which corresponds to direct assignment. E.g.: a += b*c -> a = a + b*c :param lhs: a lhs rhs :type lhs: ast_expression or ast_simple_expression :param is_plus: is plus assignment :type is_plus: bool :param is_minus: is minus assignment :type is_minus: bool :param is_times: is times assignment :type is_times: bool :param is_divide: is divide assignment :type is_divide: bool :param _rhs: a rhs rhs :type _rhs: ASTExpression or ASTSimpleExpression :return: a new direct assignment rhs. :rtype: ASTExpression """ from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor from pynestml.meta_model.ast_node_factory import ASTNodeFactory assert ((is_plus + is_minus + is_times + is_divide) == 1), \ '(PyNestML.CodeGeneration.Utils) Type of assignment not correctly specified!' if is_plus: op = ASTNodeFactory.create_ast_arithmetic_operator( is_plus_op=True, source_position=_rhs.get_source_position()) elif is_minus: op = ASTNodeFactory.create_ast_arithmetic_operator( is_minus_op=True, source_position=_rhs.get_source_position()) elif is_times: op = ASTNodeFactory.create_ast_arithmetic_operator( is_times_op=True, source_position=_rhs.get_source_position()) else: op = ASTNodeFactory.create_ast_arithmetic_operator( is_div_op=True, source_position=_rhs.get_source_position()) var_expr = ASTNodeFactory.create_ast_simple_expression( variable=lhs, source_position=lhs.get_source_position()) var_expr.update_scope(lhs.get_scope()) op.update_scope(lhs.get_scope()) rhs_in_brackets = ASTNodeFactory.create_ast_expression( is_encapsulated=True, expression=_rhs, source_position=_rhs.get_source_position()) rhs_in_brackets.update_scope(_rhs.get_scope()) expr = ASTNodeFactory.create_ast_compound_expression( lhs=var_expr, binary_operator=op, rhs=rhs_in_brackets, source_position=_rhs.get_source_position()) expr.update_scope(lhs.get_scope()) # update the symbols expr.accept(ASTSymbolTableVisitor()) return expr
def visitOdeFunction(self, ctx): is_recordable = (True if ctx.recordable is not None else False) variable_name = (str(ctx.variableName.text) if ctx.variableName is not None else None) data_type = (self.visit(ctx.dataType()) if ctx.dataType() is not None else None) expression = (self.visit(ctx.expression()) if ctx.expression() is not None else None) ode_function = ASTNodeFactory.create_ast_ode_function(is_recordable=is_recordable, variable_name=variable_name, data_type=data_type, expression=expression, source_position=create_source_pos(ctx)) update_node_comments(ode_function, self.__comments.visit(ctx)) return ode_function
def visitComparisonOperator(self, ctx): is_lt = (True if ctx.lt is not None else False) is_le = (True if ctx.le is not None else False) is_eq = (True if ctx.eq is not None else False) is_ne = (True if ctx.ne is not None else False) is_ne2 = (True if ctx.ne2 is not None else False) is_ge = (True if ctx.ge is not None else False) is_gt = (True if ctx.gt is not None else False) return ASTNodeFactory.create_ast_comparison_operator(is_lt, is_le, is_eq, is_ne, is_ne2, is_ge, is_gt, create_source_pos(ctx))
def visitBlockWithVariables(self, ctx): declarations = list() if ctx.declaration() is not None: for child in ctx.declaration(): declarations.append(self.visit(child)) block_type = ctx.blockType.text # the text field stores the exact name of the token, e.g., state source_pos = create_source_pos(ctx) if block_type == 'state': ret = ASTNodeFactory.create_ast_block_with_variables(True, False, False, False, declarations, source_pos) elif block_type == 'parameters': ret = ASTNodeFactory.create_ast_block_with_variables(False, True, False, False, declarations, source_pos) elif block_type == 'internals': ret = ASTNodeFactory.create_ast_block_with_variables(False, False, True, False, declarations, source_pos) elif block_type == 'initial_values': ret = ASTNodeFactory.create_ast_block_with_variables(False, False, False, True, declarations, source_pos) else: raise RuntimeError('(PyNestML.ASTBuilder) Unspecified type (=%s) of var-block.' % str(ctx.blockType)) update_node_comments(ret, self.__comments.visit(ctx)) return ret
def visitBitOperator(self, ctx): is_bit_and = (True if ctx.bitAnd is not None else False) is_bit_xor = (True if ctx.bitXor is not None else False) is_bit_or = (True if ctx.bitOr is not None else False) is_bit_shift_left = (True if ctx.bitShiftLeft is not None else False) is_bit_shift_right = (True if ctx.bitShiftRight is not None else False) return ASTNodeFactory.create_ast_bit_operator(is_bit_and=is_bit_and, is_bit_xor=is_bit_xor, is_bit_or=is_bit_or, is_bit_shift_left=is_bit_shift_left, is_bit_shift_right=is_bit_shift_right, source_position=create_source_pos(ctx))
def visitFunctionCall(self, ctx): name = (str(ctx.calleeName.text)) args = list() if type(ctx.expression()) == list: for arg in ctx.expression(): args.append(self.visit(arg)) elif ctx.expression() is not None: args.append(self.visit(ctx.expression())) node = ASTNodeFactory.create_ast_function_call(callee_name=name, args=args, source_position=create_source_pos(ctx)) return node
def visitSmallStmt(self, ctx): assignment = self.visit(ctx.assignment()) if ctx.assignment() is not None else None function_call = self.visit(ctx.functionCall()) if ctx.functionCall() is not None else None declaration = self.visit(ctx.declaration()) if ctx.declaration() is not None else None return_stmt = self.visit(ctx.returnStmt()) if ctx.returnStmt() is not None else None node = ASTNodeFactory.create_ast_small_stmt(assignment=assignment, function_call=function_call, declaration=declaration, return_stmt=return_stmt, source_position=create_source_pos(ctx)) # update_node_comments(node, self.__comments.visit(ctx)) update_node_comments(node, self.__comments.visit(ctx)) return node
def extract_operator_from_compound_assignment(self): from pynestml.meta_model.ast_node_factory import ASTNodeFactory assert not self.is_direct_assignment # TODO: maybe calculate new source positions exactly? result = None if self.is_compound_minus: result = ASTNodeFactory.create_ast_arithmetic_operator(is_minus_op=True, source_position=self.get_source_position()) elif self.is_compound_product: result = ASTNodeFactory.create_ast_arithmetic_operator(is_times_op=True, source_position=self.get_source_position()) elif self.is_compound_quotient: result = ASTNodeFactory.create_ast_arithmetic_operator(is_div_op=True, source_position=self.get_source_position()) elif self.is_compound_sum: result = ASTNodeFactory.create_ast_arithmetic_operator(is_plus_op=True, source_position=self.get_source_position()) else: raise RuntimeError('Type of compound operator not recognized!') result.update_scope(self.get_scope()) return result
def visitNestMLCompilationUnit(self, ctx): # now process the actual model neurons = list() for child in ctx.neuron(): neurons.append(self.visit(child)) # extract the name of the artifact from the context artifact_name = ntpath.basename(ctx.start.source[1].fileName) compilation_unit = ASTNodeFactory.create_ast_nestml_compilation_unit(list_of_neurons=neurons, source_position=create_source_pos(ctx), artifact_name=artifact_name) # first ensure certain properties of the neuron CoCosManager.check_neuron_names_unique(compilation_unit) return compilation_unit
def make_trivial_assignment(var, order, equations_block, is_shape=False): from pynestml.meta_model.ast_variable import ASTVariable from pynestml.meta_model.ast_equations_block import ASTEquationsBlock from pynestml.meta_model.ast_node import ASTNode # type: (ASTVariable,int,ASTEquationsBlock,bool) -> ASTNode lhs_variable = ASTNodeFactory.create_ast_variable(name=var.get_name(), differential_order=order + 1, source_position=ASTSourceLocation. get_added_source_position()) rhs_variable = ASTNodeFactory.create_ast_variable(name=convert_variable_name_to_generator_notation(var).get_name(), differential_order=order, source_position=ASTSourceLocation. get_added_source_position()) expression = ASTNodeFactory.create_ast_simple_expression(variable=rhs_variable, source_position=ASTSourceLocation. get_added_source_position()) source_loc = ASTSourceLocation.get_added_source_position() if is_shape: node = ASTNodeFactory.create_ast_ode_shape(lhs=lhs_variable, rhs=expression, source_position=source_loc) else: node = ASTNodeFactory.create_ast_ode_equation(lhs=lhs_variable, rhs=expression, source_position=source_loc) equations_block.get_declarations().append(node) return node
def visitFunction(self, ctx): name = str(ctx.NAME()) if ctx.NAME() is not None else None parameters = list() if type(ctx.parameter()) is list: for par in ctx.parameter(): parameters.append(self.visit(par)) elif ctx.parameters() is not None: parameters.append(ctx.parameter()) block = self.visit(ctx.block()) if ctx.block() is not None else None return_type = self.visit(ctx.returnType) if ctx.returnType is not None else None node = ASTNodeFactory.create_ast_function(name=name, parameters=parameters, block=block, return_type=return_type, source_position=create_source_pos(ctx)) update_node_comments(node, self.__comments.visit(ctx)) return node
def visitDataType(self, ctx): is_int = (True if ctx.isInt is not None else False) is_real = (True if ctx.isReal is not None else False) is_string = (True if ctx.isString is not None else False) is_bool = (True if ctx.isBool is not None else False) is_void = (True if ctx.isVoid is not None else False) unit = self.visit(ctx.unitType()) if ctx.unitType() is not None else None ret = ASTNodeFactory.create_ast_data_type(is_integer=is_int, is_boolean=is_bool, is_real=is_real, is_string=is_string, is_void=is_void, is_unit_type=unit, source_position=create_source_pos(ctx)) # now update the type ret.accept(ASTDataTypeVisitor()) # self.data_type_visitor.visit_datatype(ret) return ret
def create_internal_block(cls, neuron): """ Creates a single internal block in the handed over neuron. :param neuron: a single neuron :type neuron: ast_neuron :return: the modified neuron :rtype: ast_neuron """ from pynestml.meta_model.ast_node_factory import ASTNodeFactory if neuron.get_internals_blocks() is None: internal = ASTNodeFactory.create_ast_block_with_variables(False, False, True, False, list(), ASTSourceLocation.get_added_source_position()) neuron.get_body().get_body_elements().append(internal) return neuron
def visitForStmt(self, ctx): variable = str(ctx.NAME()) if ctx.NAME() is not None else None start_from = self.visit(ctx.start_from) if ctx.start_from is not None else None end_at = self.visit(ctx.end_at) if ctx.end_at is not None else None step_scalar = -1 if ctx.negative is not None else 1 if ctx.UNSIGNED_INTEGER() is not None: value = int(str(ctx.UNSIGNED_INTEGER())) else: value = float(str(ctx.FLOAT())) step = step_scalar * value block = self.visit(ctx.block()) if ctx.block() is not None else None node = ASTNodeFactory.create_ast_for_stmt(variable=variable, start_from=start_from, end_at=end_at, step=step, block=block, source_position=create_source_pos(ctx)) update_node_comments(node, self.__comments.visit(ctx)) return node
def visitAssignment(self, ctx): lhs = self.visit(ctx.lhs_variable) if ctx.lhs_variable is not None else None is_direct_assignment = True if ctx.directAssignment is not None else False is_compound_sum = True if ctx.compoundSum is not None else False is_compound_minus = True if ctx.compoundMinus is not None else False is_compound_product = True if ctx.compoundProduct is not None else False is_compound_quotient = True if ctx.compoundQuotient is not None else False expression = self.visit(ctx.expression()) if ctx.expression() is not None else None node = ASTNodeFactory.create_ast_assignment(lhs=lhs, is_direct_assignment=is_direct_assignment, is_compound_sum=is_compound_sum, is_compound_minus=is_compound_minus, is_compound_product=is_compound_product, is_compound_quotient=is_compound_quotient, expression=expression, source_position=create_source_pos(ctx)) update_node_comments(node, self.__comments.visit(ctx)) return node
def deconstruct_assignment(cls, lhs=None, is_plus=False, is_minus=False, is_times=False, is_divide=False, _rhs=None): """ From lhs and rhs it constructs a new rhs which corresponds to direct assignment. E.g.: a += b*c -> a = a + b*c :param lhs: a lhs rhs :type lhs: ast_expression or ast_simple_expression :param is_plus: is plus assignment :type is_plus: bool :param is_minus: is minus assignment :type is_minus: bool :param is_times: is times assignment :type is_times: bool :param is_divide: is divide assignment :type is_divide: bool :param _rhs: a rhs rhs :type _rhs: ASTExpression or ASTSimpleExpression :return: a new direct assignment rhs. :rtype: ASTExpression """ from pynestml.visitors.ast_symbol_table_visitor import ASTSymbolTableVisitor from pynestml.meta_model.ast_node_factory import ASTNodeFactory assert ((is_plus + is_minus + is_times + is_divide) == 1), \ '(PyNestML.CodeGeneration.Utils) Type of assignment not correctly specified!' if is_plus: op = ASTNodeFactory.create_ast_arithmetic_operator(is_plus_op=True, source_position=_rhs.get_source_position()) elif is_minus: op = ASTNodeFactory.create_ast_arithmetic_operator(is_minus_op=True, source_position=_rhs.get_source_position()) elif is_times: op = ASTNodeFactory.create_ast_arithmetic_operator(is_times_op=True, source_position=_rhs.get_source_position()) else: op = ASTNodeFactory.create_ast_arithmetic_operator(is_div_op=True, source_position=_rhs.get_source_position()) var_expr = ASTNodeFactory.create_ast_simple_expression(variable=lhs, source_position=lhs.get_source_position()) var_expr.update_scope(lhs.get_scope()) op.update_scope(lhs.get_scope()) rhs_in_brackets = ASTNodeFactory.create_ast_expression(is_encapsulated=True, expression=_rhs, source_position=_rhs.get_source_position()) rhs_in_brackets.update_scope(_rhs.get_scope()) expr = ASTNodeFactory.create_ast_compound_expression(lhs=var_expr, binary_operator=op, rhs=rhs_in_brackets, source_position=_rhs.get_source_position()) expr.update_scope(lhs.get_scope()) # update the symbols expr.accept(ASTSymbolTableVisitor()) return expr
def visitDeclaration(self, ctx): is_recordable = (True if ctx.isRecordable is not None else False) is_function = (True if ctx.isFunction is not None else False) variables = list() for var in ctx.variable(): variables.append(self.visit(var)) data_type = self.visit(ctx.dataType()) if ctx.dataType() is not None else None size_param = str(ctx.sizeParameter.text) if ctx.sizeParameter is not None else None expression = self.visit(ctx.rhs) if ctx.rhs is not None else None invariant = self.visit(ctx.invariant) if ctx.invariant is not None else None declaration = ASTNodeFactory.create_ast_declaration(is_recordable=is_recordable, is_function=is_function, variables=variables, data_type=data_type, size_parameter=size_param, expression=expression, invariant=invariant, source_position=create_source_pos(ctx)) update_node_comments(declaration, self.__comments.visit(ctx)) return declaration
def visitUnitType(self, ctx): left_parenthesis = True if ctx.leftParentheses is not None else False compound_unit = self.visit(ctx.compoundUnit) if ctx.compoundUnit is not None else None is_encapsulated = left_parenthesis and True if ctx.rightParentheses is not None else False base = self.visit(ctx.base) if ctx.base is not None else None is_pow = True if ctx.powOp is not None else False exponent = int(str(ctx.exponent.getText())) if ctx.exponent is not None else None if ctx.unitlessLiteral is not None: lhs = int(str(ctx.unitlessLiteral.text)) else: lhs = self.visit(ctx.left) if ctx.left is not None else None is_times = True if ctx.timesOp is not None else False is_div = True if ctx.divOp is not None else False rhs = self.visit(ctx.right) if ctx.right is not None else None unit = str(ctx.unit.text) if ctx.unit is not None else None return ASTNodeFactory.create_ast_unit_type(is_encapsulated=is_encapsulated, compound_unit=compound_unit, base=base, is_pow=is_pow, exponent=exponent, lhs=lhs, rhs=rhs, is_div=is_div, is_times=is_times, unit=unit, source_position=create_source_pos(ctx))