diff --git a/src/language/ASTSymbolTableBuilder.cpp b/src/language/ASTSymbolTableBuilder.cpp
index e078f079f699dd65d4a075d05e78ab31a6dba76e..aaab7c1413d3f59c63533e589942b5ce38f64a3b 100644
--- a/src/language/ASTSymbolTableBuilder.cpp
+++ b/src/language/ASTSymbolTableBuilder.cpp
@@ -29,6 +29,10 @@ ASTSymbolTableBuilder::buildSymbolTable(ASTNode& n, std::shared_ptr<SymbolTable>
     for (auto& child : n.children) {
       this->buildSymbolTable(*child, local_symbol_table);
     }
+
+    size_t function_id             = symbol_table->functionTable()->add(FunctionDescriptor{});
+    i_symbol->attributes().value() = function_id;
+
   } else {
     n.m_symbol_table = symbol_table;
     if (n.has_content()) {
diff --git a/src/language/FunctionTable.hpp b/src/language/FunctionTable.hpp
index 0471969b4b79784d7eafb98beed886124ed05cc1..a5dae9c85d841e73d098da0529785de4cac23473 100644
--- a/src/language/FunctionTable.hpp
+++ b/src/language/FunctionTable.hpp
@@ -12,22 +12,25 @@
 
 #include <iostream>
 
-class FunctionTable
+class FunctionDescriptor
 {
-  class FunctionDescriptor
-  {
-    std::unique_ptr<ASTNode> m_domain_mapping_node;
-    std::unique_ptr<ASTNode> m_expression_node;
+  std::unique_ptr<ASTNode> m_domain_mapping_node;
+  std::unique_ptr<ASTNode> m_expression_node;
 
-   public:
-    FunctionDescriptor& operator=(const FunctionDescriptor&) = default;
-    FunctionDescriptor& operator=(FunctionDescriptor&&) = default;
+ public:
+  FunctionDescriptor& operator=(FunctionDescriptor&&) = default;
 
-    FunctionDescriptor(FunctionDescriptor&&) = default;
-    FunctionDescriptor()                     = default;
-    ~FunctionDescriptor()                    = default;
-  };
+  FunctionDescriptor(std::unique_ptr<ASTNode>&& domain_mapping_node, std::unique_ptr<ASTNode>&& expression_node)
+    : m_domain_mapping_node(std::move(domain_mapping_node)), m_expression_node(std::move(expression_node))
+  {}
 
+  FunctionDescriptor(FunctionDescriptor&&) = default;
+  FunctionDescriptor()                     = default;
+  ~FunctionDescriptor()                    = default;
+};
+
+class FunctionTable
+{
  private:
   std::vector<FunctionDescriptor> m_function_descriptor_list;
 
diff --git a/src/language/SymbolTable.hpp b/src/language/SymbolTable.hpp
index 193dac31fb71dd5b5172af6fdf6fdbff907fe2c4..af700706fe3955520da4117ff453685b7a24edcd 100644
--- a/src/language/SymbolTable.hpp
+++ b/src/language/SymbolTable.hpp
@@ -70,6 +70,9 @@ class SymbolTable
     friend std::ostream&
     operator<<(std::ostream& os, const Attributes& attributes)
     {
+      if (attributes.m_data_type == ASTNodeDataType::function_t) {
+        os << "function_id:";
+      }
       std::visit(
         [&](const auto& value) {
           using T = std::decay_t<decltype(value)>;
@@ -124,7 +127,6 @@ class SymbolTable
 
     Symbol(const Symbol&) = default;
     Symbol(Symbol&&)      = default;
-    Symbol()              = default;
     ~Symbol()             = default;
   };
 
@@ -134,6 +136,12 @@ class SymbolTable
   std::shared_ptr<FunctionTable> m_function_table;
 
  public:
+  auto
+  functionTable() const
+  {
+    return m_function_table;
+  }
+
   friend std::ostream&
   operator<<(std::ostream& os, const SymbolTable& symbol_table)
   {