aboutsummaryrefslogtreecommitdiff
path: root/source/20-codegen-compiler/CodegenModel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/20-codegen-compiler/CodegenModel.cpp')
-rw-r--r--source/20-codegen-compiler/CodegenModel.cpp177
1 files changed, 170 insertions, 7 deletions
diff --git a/source/20-codegen-compiler/CodegenModel.cpp b/source/20-codegen-compiler/CodegenModel.cpp
index 0017b62..88439e8 100644
--- a/source/20-codegen-compiler/CodegenModel.cpp
+++ b/source/20-codegen-compiler/CodegenModel.cpp
@@ -16,6 +16,8 @@
using namespace std::literals;
+// TODO only delete unused records from model instead of regenerating all records every time
+
struct SomeDecl {
std::variant<DeclStruct, DeclFunction, DeclEnum> v;
};
@@ -55,6 +57,10 @@ struct SQLiteStatement {
SQLiteStatement() = default;
+ SQLiteStatement(sqlite3* database, std::string_view sql) {
+ Initialize(database, sql);
+ }
+
~SQLiteStatement() {
// NOTE: calling with NULL is a harmless no-op
// NOTE: we don't care about the error code, because they are returned if the statement has errored in the most recent execution
@@ -98,9 +104,10 @@ public:
SQLiteStatement beginTransactionStmt;
SQLiteStatement commitTransactionStmt;
SQLiteStatement rollbackTransactionStmt;
- SQLiteStatement storeFileStmt;
SQLiteStatement findFileStmt;
+ SQLiteStatement storeFileStmt;
SQLiteStatement findNamespaceStmt;
+ SQLiteStatement getNamespaceStmt;
SQLiteStatement storeNamespaceStmt;
/* Component Statements, initalized on demand */
SQLiteStatement storeStructStmt;
@@ -112,6 +119,8 @@ public:
SQLiteStatement deleteFunctionDeclByFilenameStmt;
SQLiteStatement deleteStructDeclByFilenameStmt;
SQLiteStatement deleteEnumDeclByFilenameStmt;
+ // TODO
+ // SQLiteStatement getRootClassStmt;
void InitializeDatabase() {
char* errMsg = nullptr;
@@ -120,7 +129,6 @@ public:
PrintErrMsgIfPresent(errMsg);
assert(result == SQLITE_OK);
- // TODO create a table of file names
// TODO unique with overloading, and container structs
result = sqlite3_exec(database, R"""(
BEGIN TRANSACTION;
@@ -140,7 +148,7 @@ CREATE TABLE Namespaces(
CREATE TABLE DeclFunctions(
Id INTEGER PRIMARY KEY,
- FileId INTEGER REFERENCES Files(Id),
+ FileId INTEGER REFERENCES Files(Id) ON DELETE CASCADE,
NamespaceId INTEGER REFERENCES Namespaces(Id),
Name TEXT
);
@@ -153,7 +161,7 @@ CREATE TABLE DeclFunctionParameters(
CREATE TABLE DeclStructs(
Id INTEGER PRIMARY KEY,
- FileId INTEGER REFERENCES Files(Id),
+ FileId INTEGER REFERENCES Files(Id) ON DELETE CASCADE,
NamespaceId INTEGER REFERENCES Namespaces(Id),
Name TEXT,
IsMetadataMarked INTEGER
@@ -193,7 +201,7 @@ CREATE TABLE DeclStructMethodParameters(
CREATE TABLE DeclEnums(
Id INTEGER PRIMARY KEY,
- FileId INTEGER REFERENCES Files(Id),
+FileId INTEGER REFERENCES Files(Id) ON DELETE CASCADE,
NamespaceId INTEGER REFERENCES Namespaces(Id),
Name TEXT,
UnderlyingType TEXT
@@ -286,6 +294,55 @@ COMMIT TRANSACTION;
return nsId;
}
+ // TODO maybe merge with Utils::MakeFullName?
+ std::string GetNamespaceFullName(int64_t nsId) {
+ std::vector<std::string> namespaceNames;
+ size_t fullnameLength = 0;
+
+ sqlite3_stmt* stmt = getNamespaceStmt;
+ int64_t currentNsId = nsId;
+ while (true) {
+ sqlite3_bind_int64(stmt, 1, currentNsId);
+
+ int result = sqlite3_step(stmt);
+ DEFER {
+ sqlite3_reset(stmt);
+ sqlite3_clear_bindings(stmt);
+ };
+ assert(result == SQLITE_ROW);
+
+ /* 0th column Id */
+ int64_t parentNamespaceId = sqlite3_column_int64(stmt, 1);
+ auto nameCstr = (const char*)sqlite3_column_text(stmt, 2);
+
+ currentNsId = parentNamespaceId;
+ std::string name(nameCstr);
+ fullnameLength += name.size() + 2;
+ namespaceNames.push_back(std::move(name));
+
+ if (parentNamespaceId == kGlobalNamespaceId) {
+ break;
+ }
+ }
+ fullnameLength -= 2;
+
+ std::string fullname;
+ fullname.reserve(fullnameLength);
+
+ for (auto it = namespaceNames.rbegin(); it != namespaceNames.rend(); ++it) {
+ fullname.append(*it);
+ if (std::next(it) != namespaceNames.rend()) {
+ fullname.append("::");
+ }
+ }
+
+ return fullname;
+ }
+
+ std::string GetDeclFullName(int64_t nsId, std::string_view declName) {
+ return GetNamespaceFullName(nsId).append(declName);
+ }
+
/// \return Row ID of the file, or 0 if it currently doesn't exist.
int64_t FindFile(std::string_view filename) {
sqlite3_stmt* stmt = findFileStmt;
@@ -498,6 +555,7 @@ CodegenModelArchive::CodegenModelArchive(std::string_view dbPath)
m->findFileStmt.Initialize(m->database, "SELECT Id FROM Files WHERE FileName = ?1");
m->storeFileStmt.Initialize(m->database, "INSERT INTO Files(FileName) VALUES (?1) RETURNING Id");
m->findNamespaceStmt.Initialize(m->database, "SELECT Id FROM Namespaces WHERE ParentNamespaceId = ?1 AND Name = ?2");
+ m->getNamespaceStmt.Initialize(m->database, "SELECT * FROM Namespaces WHERE Id = ?1"sv);
m->storeNamespaceStmt.Initialize(m->database, "INSERT INTO Namespaces(ParentNamespaceId, Name) VALUES (?1, ?2) RETURNING Id");
}
@@ -528,8 +586,8 @@ void CodegenModelArchive::DeleteDeclsRelatedToFile(std::string_view filename) {
m->CommitTransaction();
}
-void CodegenModelArchive::Store(const CodegenModel& cgInput) {
- auto& cgm = cgInput.GetPimpl();
+void CodegenModelArchive::Store(const CodegenModel& cgModel) {
+ auto& cgm = cgModel.GetPimpl();
struct Visiter {
CodegenModelArchive* self;
@@ -551,6 +609,7 @@ void CodegenModelArchive::Store(const CodegenModel& cgInput) {
// TODO why are some namepsaces not found in StoreStruct or StoreEnum calls, if we don't use FindOrStoreNamespace there?
// since we store all currently scanned namespaces into the model here, does that mean the parser is not correctly picking some of those up?
// but if the parser is failing, than the DeclThing objects should have a null `container` field?
+ // [2022-07-15] I think this bug is fixed, it was caused by FindOrStoreNamespace() not calling sqlite3_reset(), causing a stmt execution state mixup between different namespaces
for (auto&& [DISCARD, ns] : cgm.namespaces) {
// This will insert the namespace if it doesn't exist, or no-op (fetches data) if it already exists
m->FindOrStoreNamespace(&ns);
@@ -562,6 +621,110 @@ void CodegenModelArchive::Store(const CodegenModel& cgInput) {
m->CommitTransaction();
}
+void CodegenModelArchive::LoadInto(CodegenModel& model) const {
+ // TODO
+}
+
+CodegenModel CodegenModelArchive::Load() const {
+ CodegenModel cgModel;
+
+ // TODO files
+ // TODO namespaces
+
+ robin_hood::unordered_map<int64_t, DeclStruct*> structsById;
+ robin_hood::unordered_map<int64_t, DeclMemberVariable*> propertiesById;
+ robin_hood::unordered_map<int64_t, DeclMemberFunction*> methodsById;
+
+ // NOTE: this is basically { initializer; while(true) { body; } } in a short form
+ // Load structs
+ for (SQLiteStatement stmt(m->database, "SELECT * FROM DeclStructs"sv);;) {
+ int result = sqlite3_step(stmt);
+ if (result == SQLITE_DONE) {
+ break;
+ }
+
+ if (result == SQLITE_ROW) {
+ int64_t id = sqlite3_column_int64(stmt, 9);
+ int64_t fileId = sqlite3_column_int64(stmt, 1);
+ int64_t nsId = sqlite3_column_int64(stmt, 2);
+ std::string_view name((const char*)sqlite3_column_text(stmt, 3));
+
+ auto decl = cgModel.AddStruct(m->GetDeclFullName(nsId, name), DeclStruct{});
+ structsById.try_emplace(id, decl);
+
+ continue;
+ }
+
+ // Executing the statement resulted in an error
+ assert(false);
+ }
+ // Load struct's base classes
+ for (SQLiteStatement stmt(m->database, "SELECT * FROM DeclStructBaseClassRelations");;) {
+ int result = sqlite3_step(stmt);
+ if (result == SQLITE_DONE) {
+ break;
+ }
+
+ if (result == SQLITE_ROW) {
+ int64_t structId = sqlite3_column_int64(stmt, 0);
+ int64_t parentStructNsId = sqlite3_column_int64(stmt, 1);
+ std::string_view parentStructName((const char*)sqlite3_column_text(stmt, 2));
+
+ auto declThis = structsById.at(structId);
+ auto declParent = cgModel.FindStruct(parentStructName); // TODO namespace
+ declThis->baseClasses.push_back(declParent);
+
+ continue;
+ }
+
+ assert(false);
+ }
+ // Load struct properties
+ for (SQLiteStatement stmt(m->database, "SELECT * FROM DeclStructProperties"sv);;) {
+ int result = sqlite3_step(stmt);
+ if (result == SQLITE_DONE) {
+ break;
+ }
+
+ if (result == SQLITE_ROW) {
+ // TODO
+ continue;
+ }
+
+ assert(false);
+ }
+ // Load struct methods
+ for (SQLiteStatement stmt(m->database, "SELECT * FROM DeclStructMethods"sv);;) {
+ int result = sqlite3_step(stmt);
+ if (result == SQLITE_DONE) {
+ break;
+ }
+
+ if (result == SQLITE_ROW) {
+ // TODO
+ continue;
+ }
+
+ assert(false);
+ }
+ // Load method params
+ for (SQLiteStatement stmt(m->database, "SELECT * FROM DeclStructMethodParameters"sv);;) {
+ int result = sqlite3_step(stmt);
+ if (result == SQLITE_DONE) {
+ break;
+ }
+
+ if (result == SQLITE_ROW) {
+ // TODO
+ continue;
+ }
+
+ assert(false);
+ }
+
+ return cgModel;
+}
+
void CodegenModelArchive::StoreStruct(const DeclStruct& decl) {
// -Argument- -Description-
// ?1 Namespace ID