From 5b8a154081e8dad4047ce157cf2e3679a7a6f0ba Mon Sep 17 00:00:00 2001 From: eshant742 Date: Wed, 5 Mar 2025 17:17:29 +0530 Subject: [PATCH 1/4] updating --- src/genn/genn/transpiler/prettyPrinter.cc | 828 ++++++++++++---------- 1 file changed, 435 insertions(+), 393 deletions(-) diff --git a/src/genn/genn/transpiler/prettyPrinter.cc b/src/genn/genn/transpiler/prettyPrinter.cc index d726ccc61..ece7429f6 100644 --- a/src/genn/genn/transpiler/prettyPrinter.cc +++ b/src/genn/genn/transpiler/prettyPrinter.cc @@ -22,471 +22,508 @@ using namespace GeNN::Transpiler::PrettyPrinter; //--------------------------------------------------------------------------- // Anonymous namespace //--------------------------------------------------------------------------- + namespace { -//--------------------------------------------------------------------------- -// EnvironmentCallArgument -//--------------------------------------------------------------------------- -class EnvironmentCallArgument : public EnvironmentBase -{ -public: - EnvironmentCallArgument(EnvironmentBase &enclosing) - : m_Enclosing(enclosing), m_CodeStream(m_Stream) - { - } - //--------------------------------------------------------------------------- - // EnvironmentBase virtuals + // EnvironmentCallArgument //--------------------------------------------------------------------------- - virtual std::string define(const std::string&) final - { - throw std::runtime_error("Cannot declare variable in call environment"); - } - virtual std::string getName(const std::string &name, std::optional type) final + class EnvironmentCallArgument : public EnvironmentBase { - return m_Enclosing.getName(name, type); - } + public: + EnvironmentCallArgument(EnvironmentBase &enclosing) + : m_Enclosing(enclosing), m_CodeStream(m_Stream) + { + } - virtual CodeStream &getStream() - { - return m_CodeStream; - } + //--------------------------------------------------------------------------- + // EnvironmentBase virtuals + //--------------------------------------------------------------------------- + virtual std::string define(const std::string &) final + { + throw std::runtime_error("Cannot declare variable in call environment"); + } - //--------------------------------------------------------------------------- - // Public API - //--------------------------------------------------------------------------- - std::string getString() const - { - return m_Stream.str(); - } + virtual std::string getName(const std::string &name, std::optional type) final + { + return m_Enclosing.getName(name, type); + } -private: - //--------------------------------------------------------------------------- - // Members - //--------------------------------------------------------------------------- - EnvironmentBase &m_Enclosing; - std::ostringstream m_Stream; - CodeStream m_CodeStream; -}; + virtual CodeStream &getStream() + { + return m_CodeStream; + } -//--------------------------------------------------------------------------- -// Visitor -//--------------------------------------------------------------------------- -class Visitor : public Expression::Visitor, public Statement::Visitor -{ -public: - Visitor(const Statement::StatementList &statements, EnvironmentInternal &environment, - const Type::TypeContext &context, const TypeChecker::ResolvedTypeMap &resolvedTypes, - StatementHandler forEachSynapseHandler) - : m_Environment(environment), m_Context(context), m_ResolvedTypes(resolvedTypes), m_ForEachSynapseHandler(forEachSynapseHandler) - { - for(auto &s : statements) { - s.get()->accept(*this); - m_Environment.get().getStream() << std::endl; + //--------------------------------------------------------------------------- + // Public API + //--------------------------------------------------------------------------- + std::string getString() const + { + return m_Stream.str(); } - } - Visitor(const Expression::ExpressionPtr &expression, EnvironmentInternal &environment, - const Type::TypeContext &context, const TypeChecker::ResolvedTypeMap &resolvedTypes) - : m_Environment(environment), m_Context(context), m_ResolvedTypes(resolvedTypes) , m_ForEachSynapseHandler(nullptr) - { - expression.get()->accept(*this); - } + private: + //--------------------------------------------------------------------------- + // Members + //--------------------------------------------------------------------------- + EnvironmentBase &m_Enclosing; + std::ostringstream m_Stream; + CodeStream m_CodeStream; + }; -private: //--------------------------------------------------------------------------- - // Expression::Visitor virtuals + // Visitor //--------------------------------------------------------------------------- - virtual void visit(const Expression::ArraySubscript &arraySubscript) final - { - // Cache reference to current reference - std::reference_wrapper oldEnvironment = m_Environment; - - // Create new call argument environment and set to current - EnvironmentCallArgument environment(oldEnvironment.get()); - m_Environment = environment; - - // Pretty print array index - arraySubscript.getIndex()->accept(*this); - - // Restore old environment - m_Environment = oldEnvironment; - - // Push arguments to top of stack - m_CallArguments.emplace(std::piecewise_construct, - std::forward_as_tuple(true), - std::forward_as_tuple()); - m_CallArguments.top().second.push_back(environment.getString()); - - // Pretty print array - // **NOTE** like with Expression::Call, when this reaches an - // Expression::Identifier, the indexing will get created from m_CallArguments - arraySubscript.getArray()->accept(*this); - - // Pop stack - m_CallArguments.pop(); - } - virtual void visit(const Expression::Assignment &assignement) final - { - assignement.getAssignee()->accept(*this); - m_Environment.get().getStream() << " " << assignement.getOperator().lexeme << " "; - assignement.getValue()->accept(*this); - } + class Visitor : public Expression::Visitor, public Statement::Visitor + { + public: + Visitor(const Statement::StatementList &statements, EnvironmentInternal &environment, + const Type::TypeContext &context, const TypeChecker::ResolvedTypeMap &resolvedTypes, + StatementHandler forEachSynapseHandler) + : m_Environment(environment), m_Context(context), m_ResolvedTypes(resolvedTypes), m_ForEachSynapseHandler(forEachSynapseHandler) + { + for (auto &s : statements) + { + s.get()->accept(*this); + m_Environment.get().getStream() << std::endl; + } + } - virtual void visit(const Expression::Binary &binary) final - { - binary.getLeft()->accept(*this); - m_Environment.get().getStream() << " " << binary.getOperator().lexeme << " "; - binary.getRight()->accept(*this); - } + Visitor(const Expression::ExpressionPtr &expression, EnvironmentInternal &environment, + const Type::TypeContext &context, const TypeChecker::ResolvedTypeMap &resolvedTypes) + : m_Environment(environment), m_Context(context), m_ResolvedTypes(resolvedTypes), m_ForEachSynapseHandler(nullptr) + { + expression.get()->accept(*this); + } + + private: + //--------------------------------------------------------------------------- + // Expression::Visitor virtuals + //--------------------------------------------------------------------------- + virtual void visit(const Expression::ArraySubscript &arraySubscript) final + { + // Cache reference to current reference + std::reference_wrapper oldEnvironment = m_Environment; - virtual void visit(const Expression::Call &call) final - { - // Cache reference to current reference - std::reference_wrapper oldEnvironment = m_Environment; - - // Loop through call arguments - std::vector arguments; - arguments.reserve(call.getArguments().size()); - for (const auto &a : call.getArguments()) { // Create new call argument environment and set to current EnvironmentCallArgument environment(oldEnvironment.get()); m_Environment = environment; - // Pretty print argument - a->accept(*this); - - // Add pretty printed argument to vector - arguments.push_back(environment.getString()); - } - - // Restore old environment - m_Environment = oldEnvironment; - - // Push arguments to top of stack - m_CallArguments.emplace(std::piecewise_construct, - std::forward_as_tuple(false), - std::forward_as_tuple(arguments)); - - // Pretty print callee - call.getCallee()->accept(*this); - - // Pop stack - m_CallArguments.pop(); + // Pretty print array index + arraySubscript.getIndex()->accept(*this); - } - - virtual void visit(const Expression::Cast &cast) final - { - m_Environment.get().getStream() << "(" << cast.getType().getName() << ")"; - cast.getExpression()->accept(*this); - } + // Restore old environment + m_Environment = oldEnvironment; - virtual void visit(const Expression::Conditional &conditional) final - { - conditional.getCondition()->accept(*this); - m_Environment.get().getStream() << " ? "; - conditional.getTrue()->accept(*this); - m_Environment.get().getStream() << " : "; - conditional.getFalse()->accept(*this); - } + // Push arguments to top of stack + m_CallArguments.emplace(std::piecewise_construct, + std::forward_as_tuple(true), + std::forward_as_tuple()); + m_CallArguments.top().second.push_back(environment.getString()); - virtual void visit(const Expression::Grouping &grouping) final - { - m_Environment.get().getStream() << "("; - grouping.getExpression()->accept(*this); - m_Environment.get().getStream() << ")"; - } + // Pretty print array + // **NOTE** like with Expression::Call, when this reaches an + // Expression::Identifier, the indexing will get created from m_CallArguments + arraySubscript.getArray()->accept(*this); - virtual void visit(const Expression::Literal &literal) final - { - // Write out lexeme - m_Environment.get().getStream() << literal.getValue().lexeme; - - // If literal is a float, add f suffix - if (literal.getValue().type == Token::Type::FLOAT_NUMBER){ - m_Environment.get().getStream() << "f"; + // Pop stack + m_CallArguments.pop(); } - // Otherwise, if it's an unsigned integer, add u suffix - else if (literal.getValue().type == Token::Type::UINT32_NUMBER) { - m_Environment.get().getStream() << "u"; + + virtual void visit(const Expression::Assignment &assignement) final + { + assignement.getAssignee()->accept(*this); + m_Environment.get().getStream() << " " << assignement.getOperator().lexeme << " "; + assignement.getValue()->accept(*this); } - // Otherwise, if literal is a scalar, return literal suffix of scalar type fro context - else if (literal.getValue().type == Token::Type::SCALAR_NUMBER) { - m_Environment.get().getStream() << m_Context.at("scalar").getNumeric().literalSuffix; + + virtual void visit(const Expression::Binary &binary) final + { + binary.getLeft()->accept(*this); + m_Environment.get().getStream() << " " << binary.getOperator().lexeme << " "; + binary.getRight()->accept(*this); } - } - virtual void visit(const Expression::Logical &logical) final - { - logical.getLeft()->accept(*this); - m_Environment.get().getStream() << " " << logical.getOperator().lexeme << " "; - logical.getRight()->accept(*this); - } + virtual void visit(const Expression::Call &call) final + { + // Cache reference to current reference + std::reference_wrapper oldEnvironment = m_Environment; + + // Loop through call arguments + std::vector arguments; + arguments.reserve(call.getArguments().size()); + for (const auto &a : call.getArguments()) + { + // Create new call argument environment and set to current + EnvironmentCallArgument environment(oldEnvironment.get()); + m_Environment = environment; + + // Pretty print argument + a->accept(*this); + + // Add pretty printed argument to vector + arguments.push_back(environment.getString()); + } - virtual void visit(const Expression::PostfixIncDec &postfixIncDec) final - { - postfixIncDec.getTarget()->accept(*this); - m_Environment.get().getStream() << postfixIncDec.getOperator().lexeme; - } + // Restore old environment + m_Environment = oldEnvironment; - virtual void visit(const Expression::PrefixIncDec &prefixIncDec) final - { - m_Environment.get().getStream() << prefixIncDec.getOperator().lexeme; - prefixIncDec.getTarget()->accept(*this); - } + // Push arguments to top of stack + m_CallArguments.emplace(std::piecewise_construct, + std::forward_as_tuple(false), + std::forward_as_tuple(arguments)); - virtual void visit(const Expression::Identifier &variable) final - { - // Get name of identifier - const auto &type = m_ResolvedTypes.at(&variable); - std::string name = m_Environment.get().getName(variable.getName().lexeme, type); - - // If identifier is function i.e. name is a function template - if (type.isFunction()) { - // Check that there are call arguments on the stack - assert(!m_CallArguments.empty()); - - // Loop through call arguments on top of stack - size_t i = 0; - for (i = 0; i < m_CallArguments.top().second.size(); i++) { - // If name contains a $(i) placeholder to replace with this argument, replace with pretty-printed argument - const std::string placeholder = "$(" + std::to_string(i) + ")"; - - // If placeholder isn't found at all, stop looking for arguments - size_t found = name.find(placeholder); - if(found == std::string::npos) { - break; - } - - // Keep replacing placeholders - do { - name.replace(found, placeholder.length(), m_CallArguments.top().second.at(i)); - found = name.find(placeholder, found); - } while(found != std::string::npos); - } + // Pretty print callee + call.getCallee()->accept(*this); - // If function is variadic - if (type.getFunction().hasFlag(Type::FunctionFlags::VARIADIC)) { - // If variadic placeholder is found - const std::string variadicPlaceholder = "$(@)"; - const size_t found = name.find(variadicPlaceholder); - if (found != std::string::npos) { - // Concatenate together all remaining arguments - std::ostringstream variadicArgumentsStream; - std::copy(m_CallArguments.top().second.cbegin() + i, m_CallArguments.top().second.cend(), - std::ostream_iterator(variadicArgumentsStream, ", ")); - - // Replace variadic placeholder with all remaining arguments (after trimming trailing ", ") - std::string variadicArguments = variadicArgumentsStream.str(); - name.replace(found, variadicPlaceholder.length(), - variadicArguments.substr(0, variadicArguments.length() - 2)); - } - else { - throw std::runtime_error("Variadic function template for '" + variable.getName().lexeme + "' (" + name + ") has " - "insufficient placeholders for " + std::to_string(m_CallArguments.top().second.size()) + " argument call and no variadic placeholder '$(@)'"); - } - } + // Pop stack + m_CallArguments.pop(); } - // Otherwise, if there are array subscript arguments on top of stack - else if(!m_CallArguments.empty() && m_CallArguments.top().first){ - assert(m_CallArguments.top().second.size() == 1); - // Add standard indexing to name - name += "[" + m_CallArguments.top().second.front() + "]"; + virtual void visit(const Expression::Cast &cast) final + { + m_Environment.get().getStream() << "(" << cast.getType().getName() << ")"; + cast.getExpression()->accept(*this); } - - // Print out name - // **NOTE** this will apply any remaining substitutions - m_Environment.get().print(name); - } - virtual void visit(const Expression::Unary &unary) final - { - m_Environment.get().getStream() << unary.getOperator().lexeme; - unary.getRight()->accept(*this); - } + virtual void visit(const Expression::Conditional &conditional) final + { + conditional.getCondition()->accept(*this); + m_Environment.get().getStream() << " ? "; + conditional.getTrue()->accept(*this); + m_Environment.get().getStream() << " : "; + conditional.getFalse()->accept(*this); + } - //--------------------------------------------------------------------------- - // Statement::Visitor virtuals - //--------------------------------------------------------------------------- - virtual void visit(const Statement::Break&) final - { - m_Environment.get().getStream() << "break;"; - } + virtual void visit(const Expression::Grouping &grouping) final + { + m_Environment.get().getStream() << "("; + grouping.getExpression()->accept(*this); + m_Environment.get().getStream() << ")"; + } - virtual void visit(const Statement::Compound &compound) final - { - // Cache reference to current reference - std::reference_wrapper oldEnvironment = m_Environment; + virtual void visit(const Expression::Literal &literal) final + { + // Write out lexeme + m_Environment.get().getStream() << literal.getValue().lexeme; - // Create new environment and set to current - EnvironmentInternal environment(m_Environment); - m_Environment = environment; + // If literal is a float, add f suffix + if (literal.getValue().type == Token::Type::FLOAT_NUMBER) + { + m_Environment.get().getStream() << "f"; + } + // Otherwise, if it's an unsigned integer, add u suffix + else if (literal.getValue().type == Token::Type::UINT32_NUMBER) + { + m_Environment.get().getStream() << "u"; + } + // Otherwise, if literal is a scalar, return literal suffix of scalar type from context + else if (literal.getValue().type == Token::Type::SCALAR_NUMBER) + { + m_Environment.get().getStream() << m_Context.at("scalar").getNumeric().literalSuffix; + } + } - CodeGenerator::CodeStream::Scope b(m_Environment.get().getStream()); - for(auto &s : compound.getStatements()) { - s->accept(*this); - m_Environment.get().getStream() << std::endl; + virtual void visit(const Expression::Logical &logical) final + { + logical.getLeft()->accept(*this); + m_Environment.get().getStream() << " " << logical.getOperator().lexeme << " "; + logical.getRight()->accept(*this); } - // Restore old environment - m_Environment = oldEnvironment; - } + virtual void visit(const Expression::PostfixIncDec &postfixIncDec) final + { + postfixIncDec.getTarget()->accept(*this); + m_Environment.get().getStream() << postfixIncDec.getOperator().lexeme; + } - virtual void visit(const Statement::Continue&) final - { - m_Environment.get().getStream() << "continue;"; - } + virtual void visit(const Expression::PrefixIncDec &prefixIncDec) final + { + m_Environment.get().getStream() << prefixIncDec.getOperator().lexeme; + prefixIncDec.getTarget()->accept(*this); + } - virtual void visit(const Statement::Do &doStatement) final - { - m_Environment.get().getStream() << "do"; - doStatement.getBody()->accept(*this); - m_Environment.get().getStream() << "while("; - doStatement.getCondition()->accept(*this); - m_Environment.get().getStream() << ");" << std::endl; - } + virtual void visit(const Expression::Identifier &variable) final + { + // Get name of identifier + const auto &type = m_ResolvedTypes.at(&variable); + std::string name = m_Environment.get().getName(variable.getName().lexeme, type); + + // If identifier is function i.e. name is a function template + if (type.isFunction()) + { + // Check that there are call arguments on the stack + assert(!m_CallArguments.empty()); + + // Loop through call arguments on top of stack + size_t i = 0; + for (i = 0; i < m_CallArguments.top().second.size(); i++) + { + // If name contains a $(i) placeholder to replace with this argument, replace with pretty-printed argument + const std::string placeholder = "$(" + std::to_string(i) + ")"; + + // If placeholder isn't found at all, stop looking for arguments + size_t found = name.find(placeholder); + if (found == std::string::npos) + { + break; + } + + // Keep replacing placeholders + do + { + name.replace(found, placeholder.length(), m_CallArguments.top().second.at(i)); + found = name.find(placeholder, found); + } while (found != std::string::npos); + } - virtual void visit(const Statement::Expression &expression) final - { - if(expression.getExpression()) { - expression.getExpression()->accept(*this); + // If function is variadic + if (type.getFunction().hasFlag(Type::FunctionFlags::VARIADIC)) + { + const std::string variadicPlaceholder = "$(@)"; + const size_t found = name.find(variadicPlaceholder); + if (found != std::string::npos) + { + std::ostringstream variadicArgumentsStream; + // Only copy remaining arguments if there are any + if (m_CallArguments.top().second.size() > i) + { + std::copy(m_CallArguments.top().second.cbegin() + i, + m_CallArguments.top().second.cend(), + std::ostream_iterator(variadicArgumentsStream, ", ")); + } + std::string variadicArguments = variadicArgumentsStream.str(); + // If variadicArguments is not empty, remove the trailing comma and space. + if (!variadicArguments.empty()) + { + variadicArguments = variadicArguments.substr(0, variadicArguments.size() - 2); + } + name.replace(found, variadicPlaceholder.length(), variadicArguments); + } + else + { + throw std::runtime_error("Variadic function template for '" + + variable.getName().lexeme + "' (" + name + ") has " + "insufficient placeholders for " + + std::to_string(m_CallArguments.top().second.size()) + + " argument call and no variadic placeholder '$(@)'"); + } + } + } + // Otherwise, if there are array subscript arguments on top of stack + else if (!m_CallArguments.empty() && m_CallArguments.top().first) + { + assert(m_CallArguments.top().second.size() == 1); + + // Add standard indexing to name + name += "[" + m_CallArguments.top().second.front() + "]"; + } + + // Print out name + // **NOTE** this will apply any remaining substitutions + m_Environment.get().print(name); } - m_Environment.get().getStream() << ";"; - } - virtual void visit(const Statement::For &forStatement) final - { - // Cache reference to current reference - std::reference_wrapper oldEnvironment = m_Environment; + virtual void visit(const Expression::Unary &unary) final + { + m_Environment.get().getStream() << unary.getOperator().lexeme; + unary.getRight()->accept(*this); + } - // Create new environment and set to current - EnvironmentInternal environment(m_Environment); - m_Environment = environment; + //--------------------------------------------------------------------------- + // Statement::Visitor virtuals + //--------------------------------------------------------------------------- + virtual void visit(const Statement::Break &) final + { + m_Environment.get().getStream() << "break;"; + } - m_Environment.get().getStream() << "for("; - if(forStatement.getInitialiser()) { - forStatement.getInitialiser()->accept(*this); + virtual void visit(const Statement::Compound &compound) final + { + // Cache reference to current reference + std::reference_wrapper oldEnvironment = m_Environment; + + // Create new environment and set to current + EnvironmentInternal environment(m_Environment); + m_Environment = environment; + + CodeGenerator::CodeStream::Scope b(m_Environment.get().getStream()); + for (auto &s : compound.getStatements()) + { + s->accept(*this); + m_Environment.get().getStream() << std::endl; + } + + // Restore old environment + m_Environment = oldEnvironment; } - else { - m_Environment.get().getStream() << ";"; + + virtual void visit(const Statement::Continue &) final + { + m_Environment.get().getStream() << "continue;"; } - m_Environment.get().getStream() << " "; - if(forStatement.getCondition()) { - forStatement.getCondition()->accept(*this); + virtual void visit(const Statement::Do &doStatement) final + { + m_Environment.get().getStream() << "do"; + doStatement.getBody()->accept(*this); + m_Environment.get().getStream() << "while("; + doStatement.getCondition()->accept(*this); + m_Environment.get().getStream() << ");" << std::endl; } - m_Environment.get().getStream() << "; "; - if(forStatement.getIncrement()) { - forStatement.getIncrement()->accept(*this); + virtual void visit(const Statement::Expression &expression) final + { + if (expression.getExpression()) + { + expression.getExpression()->accept(*this); + } + m_Environment.get().getStream() << ";"; } - m_Environment.get().getStream() << ")"; - forStatement.getBody()->accept(*this); - // Restore old environment - m_Environment = oldEnvironment; - } + virtual void visit(const Statement::For &forStatement) final + { + // Cache reference to current reference + std::reference_wrapper oldEnvironment = m_Environment; - virtual void visit(const Statement::ForEachSynapse &forEachSynapseStatement) final - { - // Cache reference to current reference - std::reference_wrapper oldEnvironment = m_Environment; - - // Create new environment and set to current - EnvironmentInternal environment(m_Environment); - m_Environment = environment; - - m_ForEachSynapseHandler(m_Environment, - [this, &forEachSynapseStatement](EnvironmentBase &env) - { - m_Environment = env; - forEachSynapseStatement.getBody()->accept(*this); - }); - // Restore old environment - m_Environment = oldEnvironment; - } + // Create new environment and set to current + EnvironmentInternal environment(m_Environment); + m_Environment = environment; - virtual void visit(const Statement::If &ifStatement) final - { - m_Environment.get().getStream() << "if("; - ifStatement.getCondition()->accept(*this); - m_Environment.get().getStream() << ")" << std::endl; - ifStatement.getThenBranch()->accept(*this); - if(ifStatement.getElseBranch()) { - m_Environment.get().getStream() << "else" << std::endl; - ifStatement.getElseBranch()->accept(*this); + m_Environment.get().getStream() << "for("; + if (forStatement.getInitialiser()) + { + forStatement.getInitialiser()->accept(*this); + } + else + { + m_Environment.get().getStream() << ";"; + } + m_Environment.get().getStream() << " "; + + if (forStatement.getCondition()) + { + forStatement.getCondition()->accept(*this); + } + + m_Environment.get().getStream() << "; "; + if (forStatement.getIncrement()) + { + forStatement.getIncrement()->accept(*this); + } + m_Environment.get().getStream() << ")"; + forStatement.getBody()->accept(*this); + + // Restore old environment + m_Environment = oldEnvironment; } - } - virtual void visit(const Statement::Labelled &labelled) final - { - m_Environment.get().getStream() << labelled.getKeyword().lexeme << " "; - if(labelled.getValue()) { - labelled.getValue()->accept(*this); + virtual void visit(const Statement::ForEachSynapse &forEachSynapseStatement) final + { + // Cache reference to current reference + std::reference_wrapper oldEnvironment = m_Environment; + + // Create new environment and set to current + EnvironmentInternal environment(m_Environment); + m_Environment = environment; + + m_ForEachSynapseHandler(m_Environment, + [this, &forEachSynapseStatement](EnvironmentBase &env) + { + m_Environment = env; + forEachSynapseStatement.getBody()->accept(*this); + }); + // Restore old environment + m_Environment = oldEnvironment; } - m_Environment.get().getStream() << " : "; - labelled.getBody()->accept(*this); - } - virtual void visit(const Statement::Switch &switchStatement) final - { - m_Environment.get().getStream() << "switch("; - switchStatement.getCondition()->accept(*this); - m_Environment.get().getStream() << ")" << std::endl; - switchStatement.getBody()->accept(*this); - } + virtual void visit(const Statement::If &ifStatement) final + { + m_Environment.get().getStream() << "if("; + ifStatement.getCondition()->accept(*this); + m_Environment.get().getStream() << ")" << std::endl; + ifStatement.getThenBranch()->accept(*this); + if (ifStatement.getElseBranch()) + { + m_Environment.get().getStream() << "else" << std::endl; + ifStatement.getElseBranch()->accept(*this); + } + } - virtual void visit(const Statement::VarDeclaration &varDeclaration) final - { - m_Environment.get().getStream() << varDeclaration.getType().getName() << " "; - - const size_t numDeclarators = varDeclaration.getInitDeclaratorList().size(); - for(size_t i = 0; i < numDeclarators; i++) { - const auto &var = varDeclaration.getInitDeclaratorList()[i]; - m_Environment.get().getStream() << m_Environment.get().define(std::get<0>(var).lexeme); - if(std::get<1>(var)) { - m_Environment.get().getStream() << " = "; - std::get<1>(var)->accept(*this); + virtual void visit(const Statement::Labelled &labelled) final + { + m_Environment.get().getStream() << labelled.getKeyword().lexeme << " "; + if (labelled.getValue()) + { + labelled.getValue()->accept(*this); } - if(i != (numDeclarators - 1)) { - m_Environment.get().getStream() << ", "; + m_Environment.get().getStream() << " : "; + labelled.getBody()->accept(*this); + } + + virtual void visit(const Statement::Switch &switchStatement) final + { + m_Environment.get().getStream() << "switch("; + switchStatement.getCondition()->accept(*this); + m_Environment.get().getStream() << ")" << std::endl; + switchStatement.getBody()->accept(*this); + } + + virtual void visit(const Statement::VarDeclaration &varDeclaration) final + { + m_Environment.get().getStream() << varDeclaration.getType().getName() << " "; + + const size_t numDeclarators = varDeclaration.getInitDeclaratorList().size(); + for (size_t i = 0; i < numDeclarators; i++) + { + const auto &var = varDeclaration.getInitDeclaratorList()[i]; + m_Environment.get().getStream() << m_Environment.get().define(std::get<0>(var).lexeme); + if (std::get<1>(var)) + { + m_Environment.get().getStream() << " = "; + std::get<1>(var)->accept(*this); + } + if (i != (numDeclarators - 1)) + { + m_Environment.get().getStream() << ", "; + } } + m_Environment.get().getStream() << ";"; } - m_Environment.get().getStream() << ";"; - } - virtual void visit(const Statement::While &whileStatement) final - { - m_Environment.get().getStream() << "while("; - whileStatement.getCondition()->accept(*this); - m_Environment.get().getStream() << ")" << std::endl; - whileStatement.getBody()->accept(*this); - } + virtual void visit(const Statement::While &whileStatement) final + { + m_Environment.get().getStream() << "while("; + whileStatement.getCondition()->accept(*this); + m_Environment.get().getStream() << ")" << std::endl; + whileStatement.getBody()->accept(*this); + } -private: - //--------------------------------------------------------------------------- - // Members - //--------------------------------------------------------------------------- - std::reference_wrapper m_Environment; - const Type::TypeContext &m_Context; - const TypeChecker::ResolvedTypeMap &m_ResolvedTypes; - StatementHandler m_ForEachSynapseHandler; - std::stack>> m_CallArguments; -}; -} // Anonymous namespace + private: + //--------------------------------------------------------------------------- + // Members + //--------------------------------------------------------------------------- + std::reference_wrapper m_Environment; + const Type::TypeContext &m_Context; + const TypeChecker::ResolvedTypeMap &m_ResolvedTypes; + StatementHandler m_ForEachSynapseHandler; + std::stack>> m_CallArguments; + }; +} // Anonymous namespace //--------------------------------------------------------------------------- // GeNN::Transpiler::PrettyPrinter::EnvironmentBase //--------------------------------------------------------------------------- + void EnvironmentBase::print(const std::string &format) { getStream() << printSubs(format, *this); } -//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + void EnvironmentBase::printLine(const std::string &format) { getStream() << printSubs(format, *this) << std::endl; @@ -495,21 +532,25 @@ void EnvironmentBase::printLine(const std::string &format) //--------------------------------------------------------------------------- // GeNN::Transpiler::PrettyPrinter::EnvironmentInternal //--------------------------------------------------------------------------- + std::string EnvironmentInternal::define(const std::string &name) { - if(!m_LocalVariables.emplace(name).second) { + if (!m_LocalVariables.emplace(name).second) + { throw std::runtime_error("Redeclaration of variable"); } return "_" + name; } -//--------------------------------------------------------------------------- + std::string EnvironmentInternal::getName(const std::string &name, std::optional type) { - if(m_LocalVariables.find(name) == m_LocalVariables.end()) { + if (m_LocalVariables.find(name) == m_LocalVariables.end()) + { return m_Enclosing.getName(name, type); } - else { + else + { return "_" + name; } } @@ -517,13 +558,14 @@ std::string EnvironmentInternal::getName(const std::string &name, std::optional< //--------------------------------------------------------------------------- // GeNN::Transpiler::PrettyPrinter //--------------------------------------------------------------------------- -void GeNN::Transpiler::PrettyPrinter::print(const Statement::StatementList &statements, EnvironmentInternal &environment, + +void GeNN::Transpiler::PrettyPrinter::print(const Statement::StatementList &statements, EnvironmentInternal &environment, const Type::TypeContext &context, const TypeChecker::ResolvedTypeMap &resolvedTypes, StatementHandler forEachSynapseHandler) { Visitor visitor(statements, environment, context, resolvedTypes, forEachSynapseHandler); } -//--------------------------------------------------------------------------- + void GeNN::Transpiler::PrettyPrinter::print(const Expression::ExpressionPtr &expression, EnvironmentInternal &environment, const Type::TypeContext &context, const TypeChecker::ResolvedTypeMap &resolvedTypes) { From fb9147e54018cbfab6c63cef3a997f3b868907c1 Mon Sep 17 00:00:00 2001 From: eshant742 Date: Wed, 5 Mar 2025 18:19:38 +0530 Subject: [PATCH 2/4] updating --- src/genn/genn/transpiler/prettyPrinter.cc | 132 ++++++++-------------- 1 file changed, 47 insertions(+), 85 deletions(-) diff --git a/src/genn/genn/transpiler/prettyPrinter.cc b/src/genn/genn/transpiler/prettyPrinter.cc index ece7429f6..287839db8 100644 --- a/src/genn/genn/transpiler/prettyPrinter.cc +++ b/src/genn/genn/transpiler/prettyPrinter.cc @@ -1,17 +1,17 @@ #include "transpiler/prettyPrinter.h" -// Standard C++ includes +/* Standard C++ includes */ #include #include #include #include #include -// GeNN code generator includes +/* GeNN code generator includes */ #include "code_generator/codeGenUtils.h" #include "code_generator/codeStream.h" -// Transpiler includes +/* Transpiler includes */ #include "transpiler/typeChecker.h" using namespace GeNN; @@ -19,15 +19,11 @@ using namespace GeNN::CodeGenerator; using namespace GeNN::Transpiler; using namespace GeNN::Transpiler::PrettyPrinter; -//--------------------------------------------------------------------------- -// Anonymous namespace -//--------------------------------------------------------------------------- - +/*--------------------------------------------------------------------------- + Anonymous namespace +---------------------------------------------------------------------------*/ namespace { - //--------------------------------------------------------------------------- - // EnvironmentCallArgument - //--------------------------------------------------------------------------- class EnvironmentCallArgument : public EnvironmentBase { @@ -37,9 +33,7 @@ namespace { } - //--------------------------------------------------------------------------- // EnvironmentBase virtuals - //--------------------------------------------------------------------------- virtual std::string define(const std::string &) final { throw std::runtime_error("Cannot declare variable in call environment"); @@ -55,27 +49,18 @@ namespace return m_CodeStream; } - //--------------------------------------------------------------------------- // Public API - //--------------------------------------------------------------------------- std::string getString() const { return m_Stream.str(); } private: - //--------------------------------------------------------------------------- - // Members - //--------------------------------------------------------------------------- EnvironmentBase &m_Enclosing; std::ostringstream m_Stream; CodeStream m_CodeStream; }; - //--------------------------------------------------------------------------- - // Visitor - //--------------------------------------------------------------------------- - class Visitor : public Expression::Visitor, public Statement::Visitor { public: @@ -98,13 +83,10 @@ namespace expression.get()->accept(*this); } - private: - //--------------------------------------------------------------------------- // Expression::Visitor virtuals - //--------------------------------------------------------------------------- virtual void visit(const Expression::ArraySubscript &arraySubscript) final { - // Cache reference to current reference + // Cache reference to current environment std::reference_wrapper oldEnvironment = m_Environment; // Create new call argument environment and set to current @@ -124,8 +106,7 @@ namespace m_CallArguments.top().second.push_back(environment.getString()); // Pretty print array - // **NOTE** like with Expression::Call, when this reaches an - // Expression::Identifier, the indexing will get created from m_CallArguments + // NOTE: when this reaches an Expression::Identifier, the indexing will be created from m_CallArguments arraySubscript.getArray()->accept(*this); // Pop stack @@ -148,7 +129,7 @@ namespace virtual void visit(const Expression::Call &call) final { - // Cache reference to current reference + // Cache reference to current environment std::reference_wrapper oldEnvironment = m_Environment; // Loop through call arguments @@ -251,7 +232,7 @@ namespace const auto &type = m_ResolvedTypes.at(&variable); std::string name = m_Environment.get().getName(variable.getName().lexeme, type); - // If identifier is function i.e. name is a function template + // If identifier is a function i.e. name is a function template if (type.isFunction()) { // Check that there are call arguments on the stack @@ -263,14 +244,11 @@ namespace { // If name contains a $(i) placeholder to replace with this argument, replace with pretty-printed argument const std::string placeholder = "$(" + std::to_string(i) + ")"; - - // If placeholder isn't found at all, stop looking for arguments size_t found = name.find(placeholder); if (found == std::string::npos) { break; } - // Keep replacing placeholders do { @@ -286,29 +264,36 @@ namespace const size_t found = name.find(variadicPlaceholder); if (found != std::string::npos) { - std::ostringstream variadicArgumentsStream; - // Only copy remaining arguments if there are any - if (m_CallArguments.top().second.size() > i) + // If no extra variadic arguments, remove the placeholder and preceding comma if present + if (m_CallArguments.top().second.size() <= i) { - std::copy(m_CallArguments.top().second.cbegin() + i, - m_CallArguments.top().second.cend(), - std::ostream_iterator(variadicArgumentsStream, ", ")); + if (found > 0 && name[found - 1] == ',') + { + size_t remove_start = found - 1; + size_t remove_len = variadicPlaceholder.length() + 1; + name.erase(remove_start, remove_len); + } + else + { + name.erase(found, variadicPlaceholder.length()); + } } - std::string variadicArguments = variadicArgumentsStream.str(); - // If variadicArguments is not empty, remove the trailing comma and space. - if (!variadicArguments.empty()) + else { - variadicArguments = variadicArguments.substr(0, variadicArguments.size() - 2); + std::ostringstream variadicArgumentsStream; + std::copy(m_CallArguments.top().second.cbegin() + i, m_CallArguments.top().second.cend(), + std::ostream_iterator(variadicArgumentsStream, ", ")); + std::string variadicArguments = variadicArgumentsStream.str(); + if (!variadicArguments.empty()) + variadicArguments.resize(variadicArguments.size() - 2); + name.replace(found, variadicPlaceholder.length(), variadicArguments); } - name.replace(found, variadicPlaceholder.length(), variadicArguments); } else { - throw std::runtime_error("Variadic function template for '" + - variable.getName().lexeme + "' (" + name + ") has " - "insufficient placeholders for " + - std::to_string(m_CallArguments.top().second.size()) + - " argument call and no variadic placeholder '$(@)'"); + throw std::runtime_error("Variadic function template for '" + variable.getName().lexeme + "' (" + name + ") has " + "insufficient placeholders for " + + std::to_string(m_CallArguments.top().second.size()) + " argument call and no variadic placeholder '$(@)'"); } } } @@ -316,13 +301,11 @@ namespace else if (!m_CallArguments.empty() && m_CallArguments.top().first) { assert(m_CallArguments.top().second.size() == 1); - // Add standard indexing to name name += "[" + m_CallArguments.top().second.front() + "]"; } - // Print out name - // **NOTE** this will apply any remaining substitutions + // Print out name (this will apply any remaining substitutions) m_Environment.get().print(name); } @@ -332,9 +315,7 @@ namespace unary.getRight()->accept(*this); } - //--------------------------------------------------------------------------- // Statement::Visitor virtuals - //--------------------------------------------------------------------------- virtual void visit(const Statement::Break &) final { m_Environment.get().getStream() << "break;"; @@ -342,20 +323,17 @@ namespace virtual void visit(const Statement::Compound &compound) final { - // Cache reference to current reference + // Cache reference to current environment std::reference_wrapper oldEnvironment = m_Environment; - // Create new environment and set to current EnvironmentInternal environment(m_Environment); m_Environment = environment; - CodeGenerator::CodeStream::Scope b(m_Environment.get().getStream()); for (auto &s : compound.getStatements()) { s->accept(*this); m_Environment.get().getStream() << std::endl; } - // Restore old environment m_Environment = oldEnvironment; } @@ -385,13 +363,11 @@ namespace virtual void visit(const Statement::For &forStatement) final { - // Cache reference to current reference + // Cache reference to current environment std::reference_wrapper oldEnvironment = m_Environment; - // Create new environment and set to current EnvironmentInternal environment(m_Environment); m_Environment = environment; - m_Environment.get().getStream() << "for("; if (forStatement.getInitialiser()) { @@ -402,12 +378,10 @@ namespace m_Environment.get().getStream() << ";"; } m_Environment.get().getStream() << " "; - if (forStatement.getCondition()) { forStatement.getCondition()->accept(*this); } - m_Environment.get().getStream() << "; "; if (forStatement.getIncrement()) { @@ -415,20 +389,17 @@ namespace } m_Environment.get().getStream() << ")"; forStatement.getBody()->accept(*this); - // Restore old environment m_Environment = oldEnvironment; } virtual void visit(const Statement::ForEachSynapse &forEachSynapseStatement) final { - // Cache reference to current reference + // Cache reference to current environment std::reference_wrapper oldEnvironment = m_Environment; - // Create new environment and set to current EnvironmentInternal environment(m_Environment); m_Environment = environment; - m_ForEachSynapseHandler(m_Environment, [this, &forEachSynapseStatement](EnvironmentBase &env) { @@ -474,7 +445,6 @@ namespace virtual void visit(const Statement::VarDeclaration &varDeclaration) final { m_Environment.get().getStream() << varDeclaration.getType().getName() << " "; - const size_t numDeclarators = varDeclaration.getInitDeclaratorList().size(); for (size_t i = 0; i < numDeclarators; i++) { @@ -502,44 +472,37 @@ namespace } private: - //--------------------------------------------------------------------------- - // Members - //--------------------------------------------------------------------------- std::reference_wrapper m_Environment; const Type::TypeContext &m_Context; const TypeChecker::ResolvedTypeMap &m_ResolvedTypes; StatementHandler m_ForEachSynapseHandler; std::stack>> m_CallArguments; }; -} // Anonymous namespace -//--------------------------------------------------------------------------- -// GeNN::Transpiler::PrettyPrinter::EnvironmentBase -//--------------------------------------------------------------------------- +} // anonymous namespace +/*--------------------------------------------------------------------------- + GeNN::Transpiler::PrettyPrinter::EnvironmentBase +---------------------------------------------------------------------------*/ void EnvironmentBase::print(const std::string &format) { getStream() << printSubs(format, *this); } -//---------------------------------------------------------------------------- - void EnvironmentBase::printLine(const std::string &format) { getStream() << printSubs(format, *this) << std::endl; } -//--------------------------------------------------------------------------- -// GeNN::Transpiler::PrettyPrinter::EnvironmentInternal -//--------------------------------------------------------------------------- - +/*--------------------------------------------------------------------------- + GeNN::Transpiler::PrettyPrinter::EnvironmentInternal +---------------------------------------------------------------------------*/ std::string EnvironmentInternal::define(const std::string &name) { if (!m_LocalVariables.emplace(name).second) { throw std::runtime_error("Redeclaration of variable"); } - return "_" + name; } @@ -555,10 +518,9 @@ std::string EnvironmentInternal::getName(const std::string &name, std::optional< } } -//--------------------------------------------------------------------------- -// GeNN::Transpiler::PrettyPrinter -//--------------------------------------------------------------------------- - +/*--------------------------------------------------------------------------- + GeNN::Transpiler::PrettyPrinter +---------------------------------------------------------------------------*/ void GeNN::Transpiler::PrettyPrinter::print(const Statement::StatementList &statements, EnvironmentInternal &environment, const Type::TypeContext &context, const TypeChecker::ResolvedTypeMap &resolvedTypes, StatementHandler forEachSynapseHandler) From 3f4d9bd50d9db4f0dc1398c464236ac1c45c8037 Mon Sep 17 00:00:00 2001 From: eshant742 Date: Wed, 5 Mar 2025 21:57:49 +0530 Subject: [PATCH 3/4] updatingfinal --- src/genn/genn/transpiler/prettyPrinter.cc | 126 +++++++++++++--------- 1 file changed, 77 insertions(+), 49 deletions(-) diff --git a/src/genn/genn/transpiler/prettyPrinter.cc b/src/genn/genn/transpiler/prettyPrinter.cc index 287839db8..3f232af34 100644 --- a/src/genn/genn/transpiler/prettyPrinter.cc +++ b/src/genn/genn/transpiler/prettyPrinter.cc @@ -1,17 +1,17 @@ #include "transpiler/prettyPrinter.h" -/* Standard C++ includes */ +// Standard C++ includes #include #include #include #include #include -/* GeNN code generator includes */ +// GeNN code generator includes #include "code_generator/codeGenUtils.h" #include "code_generator/codeStream.h" -/* Transpiler includes */ +// Transpiler includes #include "transpiler/typeChecker.h" using namespace GeNN; @@ -19,12 +19,15 @@ using namespace GeNN::CodeGenerator; using namespace GeNN::Transpiler; using namespace GeNN::Transpiler::PrettyPrinter; -/*--------------------------------------------------------------------------- - Anonymous namespace ----------------------------------------------------------------------------*/ +//--------------------------------------------------------------------------- +// Anonymous namespace +//--------------------------------------------------------------------------- namespace { + //--------------------------------------------------------------------------- + // EnvironmentCallArgument + //--------------------------------------------------------------------------- class EnvironmentCallArgument : public EnvironmentBase { public: @@ -33,7 +36,9 @@ namespace { } + //--------------------------------------------------------------------------- // EnvironmentBase virtuals + //--------------------------------------------------------------------------- virtual std::string define(const std::string &) final { throw std::runtime_error("Cannot declare variable in call environment"); @@ -49,18 +54,26 @@ namespace return m_CodeStream; } + //--------------------------------------------------------------------------- // Public API + //--------------------------------------------------------------------------- std::string getString() const { return m_Stream.str(); } private: + //--------------------------------------------------------------------------- + // Members + //--------------------------------------------------------------------------- EnvironmentBase &m_Enclosing; std::ostringstream m_Stream; CodeStream m_CodeStream; }; + //--------------------------------------------------------------------------- + // Visitor + //--------------------------------------------------------------------------- class Visitor : public Expression::Visitor, public Statement::Visitor { public: @@ -83,10 +96,13 @@ namespace expression.get()->accept(*this); } + private: + //--------------------------------------------------------------------------- // Expression::Visitor virtuals + //--------------------------------------------------------------------------- virtual void visit(const Expression::ArraySubscript &arraySubscript) final { - // Cache reference to current environment + // Cache reference to current reference std::reference_wrapper oldEnvironment = m_Environment; // Create new call argument environment and set to current @@ -106,7 +122,8 @@ namespace m_CallArguments.top().second.push_back(environment.getString()); // Pretty print array - // NOTE: when this reaches an Expression::Identifier, the indexing will be created from m_CallArguments + // **NOTE** like with Expression::Call, when this reaches an + // Expression::Identifier, the indexing will get created from m_CallArguments arraySubscript.getArray()->accept(*this); // Pop stack @@ -129,7 +146,7 @@ namespace virtual void visit(const Expression::Call &call) final { - // Cache reference to current environment + // Cache reference to current reference std::reference_wrapper oldEnvironment = m_Environment; // Loop through call arguments @@ -200,7 +217,7 @@ namespace { m_Environment.get().getStream() << "u"; } - // Otherwise, if literal is a scalar, return literal suffix of scalar type from context + // Otherwise, if literal is a scalar, return literal suffix of scalar type fro context else if (literal.getValue().type == Token::Type::SCALAR_NUMBER) { m_Environment.get().getStream() << m_Context.at("scalar").getNumeric().literalSuffix; @@ -232,7 +249,7 @@ namespace const auto &type = m_ResolvedTypes.at(&variable); std::string name = m_Environment.get().getName(variable.getName().lexeme, type); - // If identifier is a function i.e. name is a function template + // If identifier is function i.e. name is a function template if (type.isFunction()) { // Check that there are call arguments on the stack @@ -244,11 +261,14 @@ namespace { // If name contains a $(i) placeholder to replace with this argument, replace with pretty-printed argument const std::string placeholder = "$(" + std::to_string(i) + ")"; + + // If placeholder isn't found at all, stop looking for arguments size_t found = name.find(placeholder); if (found == std::string::npos) { break; } + // Keep replacing placeholders do { @@ -260,34 +280,25 @@ namespace // If function is variadic if (type.getFunction().hasFlag(Type::FunctionFlags::VARIADIC)) { + // If variadic placeholder is found const std::string variadicPlaceholder = "$(@)"; const size_t found = name.find(variadicPlaceholder); if (found != std::string::npos) { - // If no extra variadic arguments, remove the placeholder and preceding comma if present - if (m_CallArguments.top().second.size() <= i) + // Concatenate together all remaining arguments + std::ostringstream variadicArgumentsStream; + bool first = true; + for (auto it = m_CallArguments.top().second.cbegin() + i; it != m_CallArguments.top().second.cend(); ++it) { - if (found > 0 && name[found - 1] == ',') + if (!first) { - size_t remove_start = found - 1; - size_t remove_len = variadicPlaceholder.length() + 1; - name.erase(remove_start, remove_len); + variadicArgumentsStream << ", "; } - else - { - name.erase(found, variadicPlaceholder.length()); - } - } - else - { - std::ostringstream variadicArgumentsStream; - std::copy(m_CallArguments.top().second.cbegin() + i, m_CallArguments.top().second.cend(), - std::ostream_iterator(variadicArgumentsStream, ", ")); - std::string variadicArguments = variadicArgumentsStream.str(); - if (!variadicArguments.empty()) - variadicArguments.resize(variadicArguments.size() - 2); - name.replace(found, variadicPlaceholder.length(), variadicArguments); + variadicArgumentsStream << *it; + first = false; } + std::string variadicArguments = variadicArgumentsStream.str(); + name.replace(found, variadicPlaceholder.length(), variadicArguments); } else { @@ -301,11 +312,13 @@ namespace else if (!m_CallArguments.empty() && m_CallArguments.top().first) { assert(m_CallArguments.top().second.size() == 1); + // Add standard indexing to name name += "[" + m_CallArguments.top().second.front() + "]"; } - // Print out name (this will apply any remaining substitutions) + // Print out name + // **NOTE** this will apply any remaining substitutions m_Environment.get().print(name); } @@ -315,7 +328,9 @@ namespace unary.getRight()->accept(*this); } + //--------------------------------------------------------------------------- // Statement::Visitor virtuals + //--------------------------------------------------------------------------- virtual void visit(const Statement::Break &) final { m_Environment.get().getStream() << "break;"; @@ -323,17 +338,20 @@ namespace virtual void visit(const Statement::Compound &compound) final { - // Cache reference to current environment + // Cache reference to current reference std::reference_wrapper oldEnvironment = m_Environment; + // Create new environment and set to current EnvironmentInternal environment(m_Environment); m_Environment = environment; + CodeGenerator::CodeStream::Scope b(m_Environment.get().getStream()); for (auto &s : compound.getStatements()) { s->accept(*this); m_Environment.get().getStream() << std::endl; } + // Restore old environment m_Environment = oldEnvironment; } @@ -363,11 +381,13 @@ namespace virtual void visit(const Statement::For &forStatement) final { - // Cache reference to current environment + // Cache reference to current reference std::reference_wrapper oldEnvironment = m_Environment; + // Create new environment and set to current EnvironmentInternal environment(m_Environment); m_Environment = environment; + m_Environment.get().getStream() << "for("; if (forStatement.getInitialiser()) { @@ -378,10 +398,12 @@ namespace m_Environment.get().getStream() << ";"; } m_Environment.get().getStream() << " "; + if (forStatement.getCondition()) { forStatement.getCondition()->accept(*this); } + m_Environment.get().getStream() << "; "; if (forStatement.getIncrement()) { @@ -389,17 +411,20 @@ namespace } m_Environment.get().getStream() << ")"; forStatement.getBody()->accept(*this); + // Restore old environment m_Environment = oldEnvironment; } virtual void visit(const Statement::ForEachSynapse &forEachSynapseStatement) final { - // Cache reference to current environment + // Cache reference to current reference std::reference_wrapper oldEnvironment = m_Environment; + // Create new environment and set to current EnvironmentInternal environment(m_Environment); m_Environment = environment; + m_ForEachSynapseHandler(m_Environment, [this, &forEachSynapseStatement](EnvironmentBase &env) { @@ -445,6 +470,7 @@ namespace virtual void visit(const Statement::VarDeclaration &varDeclaration) final { m_Environment.get().getStream() << varDeclaration.getType().getName() << " "; + const size_t numDeclarators = varDeclaration.getInitDeclaratorList().size(); for (size_t i = 0; i < numDeclarators; i++) { @@ -472,31 +498,33 @@ namespace } private: + //--------------------------------------------------------------------------- + // Members + //--------------------------------------------------------------------------- std::reference_wrapper m_Environment; const Type::TypeContext &m_Context; const TypeChecker::ResolvedTypeMap &m_ResolvedTypes; StatementHandler m_ForEachSynapseHandler; std::stack>> m_CallArguments; }; +} // Anonymous namespace -} // anonymous namespace - -/*--------------------------------------------------------------------------- - GeNN::Transpiler::PrettyPrinter::EnvironmentBase ----------------------------------------------------------------------------*/ +//--------------------------------------------------------------------------- +// GeNN::Transpiler::PrettyPrinter::EnvironmentBase +//--------------------------------------------------------------------------- void EnvironmentBase::print(const std::string &format) { getStream() << printSubs(format, *this); } - +//---------------------------------------------------------------------------- void EnvironmentBase::printLine(const std::string &format) { getStream() << printSubs(format, *this) << std::endl; } -/*--------------------------------------------------------------------------- - GeNN::Transpiler::PrettyPrinter::EnvironmentInternal ----------------------------------------------------------------------------*/ +//--------------------------------------------------------------------------- +// GeNN::Transpiler::PrettyPrinter::EnvironmentInternal +//--------------------------------------------------------------------------- std::string EnvironmentInternal::define(const std::string &name) { if (!m_LocalVariables.emplace(name).second) @@ -505,7 +533,7 @@ std::string EnvironmentInternal::define(const std::string &name) } return "_" + name; } - +//--------------------------------------------------------------------------- std::string EnvironmentInternal::getName(const std::string &name, std::optional type) { if (m_LocalVariables.find(name) == m_LocalVariables.end()) @@ -518,16 +546,16 @@ std::string EnvironmentInternal::getName(const std::string &name, std::optional< } } -/*--------------------------------------------------------------------------- - GeNN::Transpiler::PrettyPrinter ----------------------------------------------------------------------------*/ +//--------------------------------------------------------------------------- +// GeNN::Transpiler::PrettyPrinter +//--------------------------------------------------------------------------- void GeNN::Transpiler::PrettyPrinter::print(const Statement::StatementList &statements, EnvironmentInternal &environment, const Type::TypeContext &context, const TypeChecker::ResolvedTypeMap &resolvedTypes, StatementHandler forEachSynapseHandler) { Visitor visitor(statements, environment, context, resolvedTypes, forEachSynapseHandler); } - +//--------------------------------------------------------------------------- void GeNN::Transpiler::PrettyPrinter::print(const Expression::ExpressionPtr &expression, EnvironmentInternal &environment, const Type::TypeContext &context, const TypeChecker::ResolvedTypeMap &resolvedTypes) { From bad3ebbb06c060d309759527180ffc3eb5d7e2a9 Mon Sep 17 00:00:00 2001 From: eshant742 Date: Thu, 6 Mar 2025 18:48:18 +0530 Subject: [PATCH 4/4] updatingfinal2 --- src/genn/genn/transpiler/prettyPrinter.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/genn/genn/transpiler/prettyPrinter.cc b/src/genn/genn/transpiler/prettyPrinter.cc index 3f232af34..9a92ccb16 100644 --- a/src/genn/genn/transpiler/prettyPrinter.cc +++ b/src/genn/genn/transpiler/prettyPrinter.cc @@ -24,7 +24,6 @@ using namespace GeNN::Transpiler::PrettyPrinter; //--------------------------------------------------------------------------- namespace { - //--------------------------------------------------------------------------- // EnvironmentCallArgument //---------------------------------------------------------------------------