summaryrefslogtreecommitdiff
path: root/frontend/dependency.cc
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/dependency.cc')
-rw-r--r--frontend/dependency.cc102
1 files changed, 102 insertions, 0 deletions
diff --git a/frontend/dependency.cc b/frontend/dependency.cc
new file mode 100644
index 0000000..25658f8
--- /dev/null
+++ b/frontend/dependency.cc
@@ -0,0 +1,102 @@
+/* Dependency graph analysis.
+ Copyright (C) 2025 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "elna/frontend/dependency.h"
+
+#include <fstream>
+#include <sstream>
+#include <string.h>
+
+#include "elna/frontend/driver.h"
+#include "elna/frontend/semantic.h"
+#include "parser.hh"
+
+namespace elna::frontend
+{
+ dependency::dependency(const char *path)
+ : error_container(path)
+ {
+ }
+
+ dependency read_source(std::istream& entry_point, const char *entry_path)
+ {
+ driver parse_driver{ entry_path };
+ lexer tokenizer(entry_point);
+ yy::parser parser(tokenizer, parse_driver);
+
+ dependency outcome{ entry_path };
+ if (parser())
+ {
+ std::swap(outcome.errors(), parse_driver.errors());
+ return outcome;
+ }
+ else
+ {
+ std::swap(outcome.tree, parse_driver.tree);
+ }
+ declaration_visitor declaration_visitor(entry_path);
+ outcome.tree->accept(&declaration_visitor);
+
+ if (!declaration_visitor.errors().empty())
+ {
+ std::swap(outcome.errors(), declaration_visitor.errors());
+ }
+ outcome.unresolved = declaration_visitor.unresolved;
+
+ return outcome;
+ }
+
+ error_list analyze_semantics(const char *path, std::unique_ptr<unit>& tree, symbol_bag bag)
+ {
+ name_analysis_visitor name_analyser(path, bag);
+ tree->accept(&name_analyser);
+
+ if (name_analyser.has_errors())
+ {
+ return std::move(name_analyser.errors());
+ }
+ type_analysis_visitor type_analyzer(path, bag);
+ tree->accept(&type_analyzer);
+
+ if (type_analyzer.has_errors())
+ {
+ return std::move(type_analyzer.errors());
+ }
+ return error_list{};
+ }
+
+ std::filesystem::path build_path(const std::vector<std::string>& segments)
+ {
+ std::filesystem::path result;
+ std::vector<std::string>::const_iterator segment_iterator = std::cbegin(segments);
+
+ if (segment_iterator == std::cend(segments))
+ {
+ return result;
+ }
+ result = *segment_iterator;
+
+ ++segment_iterator;
+ for (; segment_iterator != std::cend(segments); ++segment_iterator)
+ {
+ result /= *segment_iterator;
+ }
+ result.replace_extension(".elna");
+
+ return result;
+ }
+}