diff --git a/src/language/ASTNodeCFunctionExpressionBuilder.cpp b/src/language/ASTNodeCFunctionExpressionBuilder.cpp
index ca9f36e6a6db1e71e395889c57ef94162a247272..6fc40f2f9415bf2632384491e90abc5ea949ca41 100644
--- a/src/language/ASTNodeCFunctionExpressionBuilder.cpp
+++ b/src/language/ASTNodeCFunctionExpressionBuilder.cpp
@@ -6,18 +6,22 @@
 #include <node_processor/CFunctionProcessor.hpp>
 
 PUGS_INLINE std::unique_ptr<INodeProcessor>
-ASTNodeCFunctionExpressionBuilder::_getArgumentProcessor(ASTNode& argument_node)
+ASTNodeCFunctionExpressionBuilder::_getArgumentProcessor(ASTNode& argument_node, ASTNodeDataVariant& argument_value)
 {
 #warning use correct types
-  return std::make_unique<CFunctionArgumentProcessor<double, double>>(argument_node);
+  return std::make_unique<CFunctionArgumentProcessor<double, double>>(argument_node, argument_value);
 }
 
 PUGS_INLINE
 void
-ASTNodeCFunctionExpressionBuilder::_storeArgumentProcessor(ASTNode& argument_node,
+ASTNodeCFunctionExpressionBuilder::_storeArgumentProcessor(const size_t argument_number,
+                                                           ASTNode& argument_node,
                                                            CFunctionProcessor& c_function_processor)
 {
-  c_function_processor.addArgumentProcessor(this->_getArgumentProcessor(argument_node));
+  auto& argument_values = c_function_processor.argumentValues();
+
+  c_function_processor.addArgumentProcessor(
+    this->_getArgumentProcessor(argument_node, argument_values[argument_number]));
 }
 
 PUGS_INLINE
@@ -28,6 +32,8 @@ ASTNodeCFunctionExpressionBuilder::_buildArgumentProcessors(ASTNode& node, CFunc
 
   const size_t arguments_number = argument_nodes.is<language::expression_list>() ? argument_nodes.children.size() : 1;
 
+  c_function_processor.setNumberOfArguments(arguments_number);
+
 #warning use the correct number of parameters_domain_node
   const size_t parameters_number = 1;
 
@@ -41,10 +47,10 @@ ASTNodeCFunctionExpressionBuilder::_buildArgumentProcessors(ASTNode& node, CFunc
   if (arguments_number > 1) {
     for (size_t i = 0; i < arguments_number; ++i) {
       ASTNode& argument_node = *argument_nodes.children[i];
-      this->_storeArgumentProcessor(argument_node, c_function_processor);
+      this->_storeArgumentProcessor(i, argument_node, c_function_processor);
     }
   } else {
-    this->_storeArgumentProcessor(argument_nodes, c_function_processor);
+    this->_storeArgumentProcessor(0, argument_nodes, c_function_processor);
   }
 }
 
@@ -61,6 +67,9 @@ ASTNodeCFunctionExpressionBuilder::ASTNodeCFunctionExpressionBuilder(ASTNode& no
 
   this->_buildArgumentProcessors(node, *c_function_processor);
 
+  c_function_processor->setFunctionExpressionProcessor(
+    std::make_unique<CFunctionExpressionProcessor<double, double>>(node, c_function_processor->argumentValues()));
+
   ASTNodeDataType c_function_return_type = ASTNodeDataType::double_t;
 
   node.m_node_processor = std::move(c_function_processor);
diff --git a/src/language/ASTNodeCFunctionExpressionBuilder.hpp b/src/language/ASTNodeCFunctionExpressionBuilder.hpp
index f8d1951001bfe6e5912ceb3179680de0d33dbb73..f3b78a8edadf4ea56845120ff59eb72fda2fb1ea 100644
--- a/src/language/ASTNodeCFunctionExpressionBuilder.hpp
+++ b/src/language/ASTNodeCFunctionExpressionBuilder.hpp
@@ -8,10 +8,13 @@ class CFunctionProcessor;
 
 class ASTNodeCFunctionExpressionBuilder
 {
-  PUGS_INLINE std::unique_ptr<INodeProcessor> _getArgumentProcessor(ASTNode& argument_node);
+  PUGS_INLINE std::unique_ptr<INodeProcessor> _getArgumentProcessor(ASTNode& argument_node,
+                                                                    ASTNodeDataVariant& argument_value);
 
   PUGS_INLINE
-  void _storeArgumentProcessor(ASTNode& argument_node, CFunctionProcessor& c_function_processor);
+  void _storeArgumentProcessor(const size_t argument_number,
+                               ASTNode& argument_node,
+                               CFunctionProcessor& c_function_processor);
 
   PUGS_INLINE
   void _buildArgumentProcessors(ASTNode& node, CFunctionProcessor& c_function_processor);
diff --git a/src/language/node_processor/CFunctionProcessor.hpp b/src/language/node_processor/CFunctionProcessor.hpp
index 241196bf45e75dc0a484d364a482fe206ce0b8c5..ca2fb3b338dd6f68af4feaa75ba099a5694f81d6 100644
--- a/src/language/node_processor/CFunctionProcessor.hpp
+++ b/src/language/node_processor/CFunctionProcessor.hpp
@@ -5,11 +5,14 @@
 
 #include <node_processor/INodeProcessor.hpp>
 
+#include <cmath>
+
 template <typename ProvidedValueType, typename ExpectedValueType>
 class CFunctionArgumentProcessor final : public INodeProcessor
 {
  private:
   ASTNode& m_provided_value_node;
+  ASTNodeDataVariant& m_argument_value;
 
  public:
   void
@@ -17,14 +20,16 @@ class CFunctionArgumentProcessor final : public INodeProcessor
   {
     m_provided_value_node.execute(exec_policy);
 
-    // if constexpr (std::is_same_v<ExpectedValueType, ProvidedValueType>) {
-    //   m_symbol_value = m_provided_value_node.m_value;
-    // } else {
-    //   m_symbol_value = static_cast<ExpectedValueType>(std::get<ProvidedValueType>(m_provided_value_node.m_value));
-    // }
+    if constexpr (std::is_same_v<ExpectedValueType, ProvidedValueType>) {
+      m_argument_value = m_provided_value_node.m_value;
+    } else {
+      m_argument_value = static_cast<ExpectedValueType>(std::get<ProvidedValueType>(m_provided_value_node.m_value));
+    }
   }
 
-  CFunctionArgumentProcessor(ASTNode& provided_value_node) : m_provided_value_node{provided_value_node} {}
+  CFunctionArgumentProcessor(ASTNode& provided_value_node, ASTNodeDataVariant& argument_value)
+    : m_provided_value_node{provided_value_node}, m_argument_value{argument_value}
+  {}
 };
 
 template <typename ReturnType, typename ExpressionValueType>
@@ -33,42 +38,83 @@ class CFunctionExpressionProcessor final : public INodeProcessor
  private:
   ASTNode& m_node;
 
+  std::vector<ASTNodeDataVariant>& m_argument_values;
+
  public:
   void
   execute(ExecUntilBreakOrContinue& exec_policy)
   {
-    // if constexpr (std::is_same_v<ReturnType, ExpressionValueType>) {
-    //   m_node.m_value = m_function_expression.m_value;
-    // } else {
-    //   m_node.m_value = static_cast<ReturnType>(std::get<ExpressionValueType>(m_function_expression.m_value));
-    // }
+    if constexpr (std::is_same_v<ReturnType, ExpressionValueType>) {
+      std::visit(
+        [&](auto v) {
+          if constexpr (std::is_arithmetic_v<decltype(v)>) {
+            m_node.m_value = std::sin(v);
+          } else {
+            throw parse_error("invalid C function evaluation", m_node.begin());
+          }
+        },
+        m_argument_values[0]);
+    } else {
+      std::visit(
+        [&](auto v) {
+          if constexpr (std::is_arithmetic_v<decltype(v)>) {
+            m_node.m_value = static_cast<ReturnType>(std::sin(v));
+          } else {
+            throw parse_error("invalid C function evaluation", m_node.begin());
+          }
+        },
+        m_argument_values[0]);
+    }
   }
 
-  CFunctionExpressionProcessor(ASTNode& node) : m_node{node} {}
+  CFunctionExpressionProcessor(ASTNode& node, std::vector<ASTNodeDataVariant>& argument_values)
+    : m_node{node}, m_argument_values{argument_values}
+  {}
 };
 
 class CFunctionProcessor : public INodeProcessor
 {
  private:
+  std::unique_ptr<INodeProcessor> m_function_expression_processor;
+
   std::vector<std::unique_ptr<INodeProcessor>> m_argument_processors;
+  std::vector<ASTNodeDataVariant> m_argument_values;
 
  public:
+  void
+  setNumberOfArguments(const size_t& number_of_arguments)
+  {
+    Assert(m_argument_values.size() == 0, "argument number has already been provided");
+    m_argument_values.resize(number_of_arguments);
+  }
+
+  std::vector<ASTNodeDataVariant>&
+  argumentValues()
+  {
+    return m_argument_values;
+  }
+
   void
   addArgumentProcessor(std::unique_ptr<INodeProcessor>&& argument_processor)
   {
     m_argument_processors.emplace_back(std::move(argument_processor));
   }
 
+  void
+  setFunctionExpressionProcessor(std::unique_ptr<INodeProcessor>&& function_processor)
+  {
+    m_function_expression_processor = std::move(function_processor);
+  }
+
   void
   execute(ExecUntilBreakOrContinue& exec_policy)
   {
+    Assert(m_argument_processors.size() == m_argument_values.size());
     for (auto& argument_processor : m_argument_processors) {
       argument_processor->execute(exec_policy);
     }
 
-    std::cerr << __FILE__ << ':' << __LINE__ << ": " << rang::fgB::red
-              << "execution of CFunctionProcessor not finished!" << rang::style::reset << '\n';
-    std::exit(1);
+    m_function_expression_processor->execute(exec_policy);
   }
 
   CFunctionProcessor() = default;