aboutsummaryrefslogtreecommitdiff
path: root/source/20-codegen-compiler/CodegenInput.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/20-codegen-compiler/CodegenInput.cpp')
-rw-r--r--source/20-codegen-compiler/CodegenInput.cpp99
1 files changed, 99 insertions, 0 deletions
diff --git a/source/20-codegen-compiler/CodegenInput.cpp b/source/20-codegen-compiler/CodegenInput.cpp
new file mode 100644
index 0000000..0dced0e
--- /dev/null
+++ b/source/20-codegen-compiler/CodegenInput.cpp
@@ -0,0 +1,99 @@
+#include "CodegenInput.hpp"
+
+#include <Macros.hpp>
+#include <Utils.hpp>
+
+#include <robin_hood.h>
+#include <variant>
+
+struct SomeDecl {
+ std::variant<DeclStruct, DeclFunction, DeclEnum> v;
+};
+
+class CodegenInput::Private {
+public:
+ // We want address stability for everything
+ robin_hood::unordered_node_map<std::string, SomeDecl, StringHash, StringEqual> decls;
+ robin_hood::unordered_node_map<std::string, DeclNamespace, StringHash, StringEqual> namespaces;
+};
+
+CodegenInput::CodegenInput()
+ : m{ new Private() } //
+{
+}
+
+CodegenInput::~CodegenInput() {
+ delete m;
+}
+
+#define STORE_DECL_OF_TYPE(DeclType, fullname, decl) \
+ auto [iter, success] = m->decls.try_emplace(std::move(fullname), SomeDecl{ .v = std::move(decl) }); \
+ auto& key = iter->first; \
+ auto& val = iter->second; \
+ auto& declRef = std::get<DeclType>(val.v); \
+ declRef.fullname = key; \
+ return &declRef
+
+DeclEnum* CodegenInput::AddEnum(std::string fullname, DeclEnum decl) {
+#if CODEGEN_DEBUG_PRINT
+ printf("Committed enum '%s'\n", decl.name.c_str());
+ for (auto& elm : decl.elements) {
+ printf(" - element %s = %" PRId64 "\n", elm.name.c_str(), elm.value);
+ }
+#endif
+
+ STORE_DECL_OF_TYPE(DeclEnum, fullname, decl);
+}
+
+DeclStruct* CodegenInput::AddStruct(std::string fullname, DeclStruct decl) {
+#if CODEGEN_DEBUG_PRINT
+ printf("Committed struct '%s'\n", decl.name.c_str());
+ printf(" Base classes:\n");
+ for (auto& base : decl.baseClasses) {
+ printf(" - %.*s\n", PRINTF_STRING_VIEW(base->name));
+ }
+#endif
+
+ STORE_DECL_OF_TYPE(DeclStruct, fullname, decl);
+}
+
+#define FIND_DECL_OF_TYPE(DeclType) \
+ auto iter = m->decls.find(name); \
+ if (iter != m->decls.end()) { \
+ auto& some = iter->second.v; \
+ if (auto decl = std::get_if<DeclType>(&some)) { \
+ return decl; \
+ } \
+ } \
+ return nullptr
+
+const DeclEnum* CodegenInput::FindEnum(std::string_view name) const {
+ FIND_DECL_OF_TYPE(DeclEnum);
+}
+
+const DeclStruct* CodegenInput::FindStruct(std::string_view name) const {
+ FIND_DECL_OF_TYPE(DeclStruct);
+}
+
+DeclNamespace* CodegenInput::AddNamespace(DeclNamespace ns) {
+ auto path = Utils::MakeFullName(""sv, &ns);
+ auto [iter, success] = m->namespaces.try_emplace(std::move(path), std::move(ns));
+ auto& nsRef = iter->second;
+ if (success) {
+ nsRef.fullname = iter->first;
+ }
+ return &nsRef;
+}
+
+const DeclNamespace* CodegenInput::FindNamespace(std::string_view fullname) const {
+ auto iter = m->namespaces.find(fullname);
+ if (iter != m->namespaces.end()) {
+ return &iter->second;
+ } else {
+ return nullptr;
+ }
+}
+
+DeclNamespace* CodegenInput::FindNamespace(std::string_view name) {
+ return const_cast<DeclNamespace*>(const_cast<const CodegenInput*>(this)->FindNamespace(name));
+}