Utils: Extract expression evaluation loop to Expression.cpp

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Change-Id: I22e7577f47cabb3fce68e90bbd71331d78b09590
diff --git a/include/Expression.hpp b/include/Expression.hpp
index b832e72..e2ecb52 100644
--- a/include/Expression.hpp
+++ b/include/Expression.hpp
@@ -19,6 +19,7 @@
 
 #include <optional>
 #include <string>
+#include <vector>
 
 namespace expression
 {
@@ -33,4 +34,6 @@
 
 std::optional<Operation> parseOperation(std::string& op);
 int evaluate(int a, Operation op, int b);
+int evaluate(int substitute, std::vector<std::string>::iterator& curr,
+             std::vector<std::string>::iterator&& end);
 } // namespace expression
diff --git a/src/Expression.cpp b/src/Expression.cpp
index 43fcaf7..b3f21d9 100644
--- a/src/Expression.cpp
+++ b/src/Expression.cpp
@@ -17,6 +17,7 @@
 
 #include "Expression.hpp"
 
+#include <iostream>
 #include <stdexcept>
 
 namespace expression
@@ -76,4 +77,40 @@
             throw std::invalid_argument("Unrecognised operation");
     }
 }
+
+int evaluate(int substitute, std::vector<std::string>::iterator& curr,
+             std::vector<std::string>::iterator&& end)
+{
+    bool isOperator = true;
+    std::optional<Operation> next = Operation::addition;
+
+    for (; curr != end; curr++)
+    {
+        if (isOperator)
+        {
+            next = expression::parseOperation(*curr);
+            if (!next)
+            {
+                break;
+            }
+        }
+        else
+        {
+            try
+            {
+                int constant = std::stoi(*curr);
+                substitute = evaluate(substitute, *next, constant);
+            }
+            catch (const std::invalid_argument&)
+            {
+                std::cerr << "Parameter not supported for templates " << *curr
+                          << "\n";
+                continue;
+            }
+        }
+        isOperator = !isOperator;
+    }
+
+    return substitute;
+}
 } // namespace expression
diff --git a/src/Utils.cpp b/src/Utils.cpp
index b73e469..221a438 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -292,43 +292,14 @@
             continue;
         }
 
+        auto it = split.begin();
+
         // we assume that the replacement is a number, because we can
         // only do math on numbers.. we might concatenate strings in the
         // future, but thats later
         int number = std::visit(VariantToIntVisitor(), propValue);
 
-        bool isOperator = true;
-        std::optional<expression::Operation> next =
-            expression::Operation::addition;
-
-        auto it = split.begin();
-
-        for (; it != split.end(); it++)
-        {
-            if (isOperator)
-            {
-                next = expression::parseOperation(*it);
-                if (!next)
-                {
-                    break;
-                }
-            }
-            else
-            {
-                try
-                {
-                    int constant = std::stoi(*it);
-                    number = expression::evaluate(number, *next, constant);
-                }
-                catch (const std::invalid_argument&)
-                {
-                    std::cerr << "Parameter not supported for templates " << *it
-                              << "\n";
-                    continue;
-                }
-            }
-            isOperator = !isOperator;
-        }
+        number = expression::evaluate(number, it, split.end());
 
         std::string result = prefix + std::to_string(number);