diff --git a/src/generator.cpp b/src/generator.cpp index 4a4ecc2ec4..0b769cf5c7 100644 --- a/src/generator.cpp +++ b/src/generator.cpp @@ -1286,7 +1286,9 @@ std::string Generator::GeneratorImpl::generateMinusUnaryCode(const AnalyserEquat || isLogicalOperator(astLeftChild) || isPlusOperator(astLeftChild) || isMinusOperator(astLeftChild) - || isPiecewiseStatement(astLeftChild)) { + || isNegativeNumber(astLeftChild) + || isPiecewiseStatement(astLeftChild) + || (code.rfind(mProfile->minusString(), 0) == 0)) { code = "(" + code + ")"; } diff --git a/tests/generator/generatorunaryminus.cpp b/tests/generator/generatorunaryminus.cpp new file mode 100644 index 0000000000..48e198a5b5 --- /dev/null +++ b/tests/generator/generatorunaryminus.cpp @@ -0,0 +1,160 @@ +/* +Copyright libCellML Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include "test_utils.h" + +#include "gtest/gtest.h" + +#include + +TEST(GeneratorUnaryMinus, example01) +{ + // rates[0] = --1.0; + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/unary_minus/example_01.cellml")); + + EXPECT_NE(nullptr, model); + + auto analyser = libcellml::Analyser::create(); + analyser->analyseModel(model); + + EXPECT_EQ(size_t(0), analyser->issueCount()); + + auto generator = libcellml::Generator::create(); + + auto implementationCode = generator->implementationCode(analyser->analyserModel()); + + EXPECT_TRUE(implementationCode.find("rates[0] = -(-1.0);\n") != std::string::npos); +} + +TEST(GeneratorUnaryMinus, example02) +{ + // rates[0] = --2.0*constants[0]; + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/unary_minus/example_02.cellml")); + + EXPECT_NE(nullptr, model); + + auto analyser = libcellml::Analyser::create(); + analyser->analyseModel(model); + + EXPECT_EQ(size_t(0), analyser->issueCount()); + + auto generator = libcellml::Generator::create(); + + auto implementationCode = generator->implementationCode(analyser->analyserModel()); + + EXPECT_TRUE(implementationCode.find("rates[0] = -(-2.0*constants[0]);\n") != std::string::npos); +} + +TEST(GeneratorUnaryMinus, example03) +{ + // rates[0] = --constants[1]/constants[0]; + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/unary_minus/example_03.cellml")); + + EXPECT_NE(nullptr, model); + + auto analyser = libcellml::Analyser::create(); + analyser->analyseModel(model); + + EXPECT_EQ(size_t(0), analyser->issueCount()); + + auto generator = libcellml::Generator::create(); + + auto implementationCode = generator->implementationCode(analyser->analyserModel()); + + EXPECT_TRUE(implementationCode.find("rates[0] = -(-constants[1]/constants[0]);\n") != std::string::npos); +} + +TEST(GeneratorUnaryMinus, example04) +{ + // rates[0] = -(-1.0); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/unary_minus/example_04.cellml")); + + EXPECT_NE(nullptr, model); + + auto analyser = libcellml::Analyser::create(); + analyser->analyseModel(model); + + EXPECT_EQ(size_t(0), analyser->issueCount()); + + auto generator = libcellml::Generator::create(); + + auto implementationCode = generator->implementationCode(analyser->analyserModel()); + + EXPECT_TRUE(implementationCode.find("rates[0] = -(-1.0);\n") != std::string::npos); +} + +TEST(GeneratorUnaryMinus, example05) +{ + // rates[0] = -(-constants[1]+constants[0]); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/unary_minus/example_05.cellml")); + + EXPECT_NE(nullptr, model); + + auto analyser = libcellml::Analyser::create(); + analyser->analyseModel(model); + + EXPECT_EQ(size_t(0), analyser->issueCount()); + + auto generator = libcellml::Generator::create(); + + auto implementationCode = generator->implementationCode(analyser->analyserModel()); + + EXPECT_TRUE(implementationCode.find("rates[0] = -(-constants[1]+constants[0]);\n") != std::string::npos); +} + +TEST(GeneratorUnaryMinus, example06) +{ + // rates[0] = -pow(-constants[1], constants[0]); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/unary_minus/example_06.cellml")); + + EXPECT_NE(nullptr, model); + + auto analyser = libcellml::Analyser::create(); + analyser->analyseModel(model); + + EXPECT_EQ(size_t(0), analyser->issueCount()); + + auto generator = libcellml::Generator::create(); + + auto implementationCode = generator->implementationCode(analyser->analyserModel()); + + EXPECT_TRUE(implementationCode.find("rates[0] = -pow(-constants[1], constants[0]);\n") != std::string::npos); +} + +TEST(GeneratorUnaryMinus, example07) +{ + // rates[0] = constants[1]-(-constants[0]); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/unary_minus/example_07.cellml")); + + EXPECT_NE(nullptr, model); + + auto analyser = libcellml::Analyser::create(); + analyser->analyseModel(model); + + EXPECT_EQ(size_t(0), analyser->issueCount()); + + auto generator = libcellml::Generator::create(); + + auto implementationCode = generator->implementationCode(analyser->analyserModel()); + + EXPECT_TRUE(implementationCode.find("rates[0] = constants[1]-(-constants[0]);\n") != std::string::npos); +} diff --git a/tests/generator/tests.cmake b/tests/generator/tests.cmake index dc7636fb93..38e5dc0b37 100644 --- a/tests/generator/tests.cmake +++ b/tests/generator/tests.cmake @@ -6,5 +6,6 @@ list(APPEND LIBCELLML_TESTS ${CURRENT_TEST}) set(${CURRENT_TEST}_SRCS ${CMAKE_CURRENT_LIST_DIR}/generator.cpp ${CMAKE_CURRENT_LIST_DIR}/generatorprofile.cpp + ${CMAKE_CURRENT_LIST_DIR}/generatorunaryminus.cpp ${CMAKE_CURRENT_LIST_DIR}/generatorvariabletracker.cpp ) diff --git a/tests/resources/generator/unary_minus/example_01.cellml b/tests/resources/generator/unary_minus/example_01.cellml new file mode 100644 index 0000000000..405be168f8 --- /dev/null +++ b/tests/resources/generator/unary_minus/example_01.cellml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + t + + x + + + + -1 + + + + + + diff --git a/tests/resources/generator/unary_minus/example_02.cellml b/tests/resources/generator/unary_minus/example_02.cellml new file mode 100644 index 0000000000..29f1ca37ad --- /dev/null +++ b/tests/resources/generator/unary_minus/example_02.cellml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + t + + x + + + + + + + + 2 + + a + + + + + + + diff --git a/tests/resources/generator/unary_minus/example_03.cellml b/tests/resources/generator/unary_minus/example_03.cellml new file mode 100644 index 0000000000..553b25b953 --- /dev/null +++ b/tests/resources/generator/unary_minus/example_03.cellml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + t + + x + + + + + + + + a + + b + + + + + + + diff --git a/tests/resources/generator/unary_minus/example_04.cellml b/tests/resources/generator/unary_minus/example_04.cellml new file mode 100644 index 0000000000..63ee3020f2 --- /dev/null +++ b/tests/resources/generator/unary_minus/example_04.cellml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + t + + x + + + + + + 1 + + + + + + + diff --git a/tests/resources/generator/unary_minus/example_05.cellml b/tests/resources/generator/unary_minus/example_05.cellml new file mode 100644 index 0000000000..e46c958a2a --- /dev/null +++ b/tests/resources/generator/unary_minus/example_05.cellml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + t + + x + + + + + + + + a + + b + + + + + + + diff --git a/tests/resources/generator/unary_minus/example_06.cellml b/tests/resources/generator/unary_minus/example_06.cellml new file mode 100644 index 0000000000..d95003657b --- /dev/null +++ b/tests/resources/generator/unary_minus/example_06.cellml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + t + + x + + + + + + + + a + + b + + + + + + + diff --git a/tests/resources/generator/unary_minus/example_07.cellml b/tests/resources/generator/unary_minus/example_07.cellml new file mode 100644 index 0000000000..6c9359cfb7 --- /dev/null +++ b/tests/resources/generator/unary_minus/example_07.cellml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + t + + x + + + + b + + + a + + + + + + +