diff --git a/src/language/PugsParser.cpp b/src/language/PugsParser.cpp
index 352ea84e60ba0ddefb8ea439e8070a255566f5c9..ed0c231071540050b6c216a6e8230487e801e0ba 100644
--- a/src/language/PugsParser.cpp
+++ b/src/language/PugsParser.cpp
@@ -32,6 +32,8 @@
 #include <unordered_map>
 #include <variant>
 
+const std::unique_ptr<ASTNode>* p_root_node = nullptr;
+
 void
 parser(const std::string& filename)
 {
@@ -48,6 +50,7 @@ parser(const std::string& filename)
 
   auto parse_and_execute = [](auto& input) {
     std::unique_ptr<ASTNode> root_node = ASTBuilder::build(input);
+    p_root_node                        = &root_node;
 
     ASTModulesImporter{*root_node};
     ASTNodeTypeCleaner<language::import_instruction>{*root_node};
@@ -68,35 +71,15 @@ parser(const std::string& filename)
     ASTNodeTypeCleaner<language::var_declaration>{*root_node};
     ASTNodeTypeCleaner<language::fct_declaration>{*root_node};
 
-    {
-      std::string dot_filename{"parse_tree.dot"};
-      std::ofstream fout(dot_filename);
-      ASTDotPrinter dot_printer{*root_node};
-      fout << dot_printer;
-      std::cout << "   AST dot file: " << dot_filename << '\n';
-    }
-
     ASTNodeEmptyBlockCleaner{*root_node};
 
     ASTNodeExpressionBuilder{*root_node};
 
-    std::cout << ASTPrinter{*root_node} << '\n';
-
-    auto& function_table = root_node->m_symbol_table->functionTable();
-
-    for (size_t i_function = 0; i_function < function_table.size(); ++i_function) {
-      const auto& function_descriptor = function_table[i_function];
-      std::cout << "function " << rang::fgB::magenta << function_descriptor.name() << rang::style::reset << '\n';
-      std::cout << ASTPrinter(function_descriptor.domainMappingNode());
-      std::cout << ASTPrinter(function_descriptor.definitionNode());
-      std::cout << "--------\n";
-    }
-
     ExecutionPolicy exec_all;
     root_node->execute(exec_all);
-    std::cout << *(root_node->m_symbol_table) << '\n';
 
     root_node->m_symbol_table->clearValues();
+    p_root_node = nullptr;
   };
 
   if (not SignalManager::pauseOnError()) {
diff --git a/src/language/modules/UtilsModule.cpp b/src/language/modules/UtilsModule.cpp
index ff5b2a0df4ae576546d30e2c8a73934a8f443526..8c688e20768b5499549f88334deab4f2ac85a7a9 100644
--- a/src/language/modules/UtilsModule.cpp
+++ b/src/language/modules/UtilsModule.cpp
@@ -1,8 +1,13 @@
 #include <language/modules/UtilsModule.hpp>
 
+#include <language/utils/ASTDotPrinter.hpp>
+#include <language/utils/ASTPrinter.hpp>
 #include <language/utils/BuiltinFunctionEmbedder.hpp>
+#include <language/utils/SymbolTable.hpp>
 #include <utils/PugsUtils.hpp>
 
+extern const std::unique_ptr<ASTNode>* p_root_node;
+
 UtilsModule::UtilsModule()
 {
   this->_addBuiltinFunction("getPugsVersion", std::make_shared<BuiltinFunctionEmbedder<std::string(void)>>(
@@ -16,4 +21,64 @@ UtilsModule::UtilsModule()
                                                   []() -> std::string { return pugsBuildInfo(); }
 
                                                   ));
+
+  this->_addBuiltinFunction("getAST", std::make_shared<BuiltinFunctionEmbedder<std::string(void)>>(
+
+                                        []() -> std::string {
+                                          Assert(p_root_node != nullptr, "unable to find AST's root node");
+
+                                          const auto& root_node = *p_root_node;
+                                          std::ostringstream os;
+                                          os << ASTPrinter{*root_node};
+
+                                          return os.str();
+                                        }
+
+                                        ));
+
+  this->_addBuiltinFunction("saveASTDot", std::make_shared<BuiltinFunctionEmbedder<void(const std::string&)>>(
+
+                                            [](const std::string& dot_filename) -> void {
+                                              Assert(p_root_node != nullptr, "unable to find AST's root node");
+
+                                              const auto& root_node = *p_root_node;
+
+                                              std::ofstream fout(dot_filename);
+
+                                              if (not fout) {
+                                                std::ostringstream os;
+                                                os << "could not create file '" << dot_filename << "'\n";
+                                                throw NormalError(os.str());
+                                              }
+
+                                              ASTDotPrinter dot_printer{*root_node};
+                                              fout << dot_printer;
+
+                                              if (not fout) {
+                                                std::ostringstream os;
+                                                os << "could not write AST to '" << dot_filename << "'\n";
+                                                throw NormalError(os.str());
+                                              }
+                                            }
+
+                                            ));
+
+  this->_addBuiltinFunction("getFunctionAST",
+                            std::make_shared<BuiltinFunctionEmbedder<std::string(const FunctionSymbolId&)>>(
+
+                              [](const FunctionSymbolId& function_symbol_id) -> std::string {
+                                auto& function_table = function_symbol_id.symbolTable().functionTable();
+
+                                const auto& function_descriptor = function_table[function_symbol_id.id()];
+
+                                std::ostringstream os;
+                                os << function_descriptor.name() << ": domain mapping\n";
+                                os << ASTPrinter(function_descriptor.domainMappingNode());
+                                os << function_descriptor.name() << ": definition\n";
+                                os << ASTPrinter(function_descriptor.definitionNode());
+
+                                return os.str();
+                              }
+
+                              ));
 }
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index aaf4bfbad904a6466b4442b0d99f35a41840ddb3..746f5d7b1b820818a6069853a2ea0bc130025321 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -104,11 +104,11 @@ add_library(test_Pugs_MeshDataBase
 
 target_link_libraries (unit_tests
   test_Pugs_MeshDataBase
-  PugsLanguage
   PugsLanguageAST
   PugsLanguageModules
   PugsLanguageAlgorithms
   PugsLanguageUtils
+  PugsLanguage
   PugsMesh
   PugsAlgebra
   PugsUtils