aboutsummaryrefslogtreecommitdiff
path: root/source/20-codegen-compiler
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2022-07-15 14:54:47 -0700
committerrtk0c <[email protected]>2022-07-15 14:54:47 -0700
commitc6e57dc94e532442ffa0bd57a16206217adbca92 (patch)
tree141a50907172f2b6b5986d55ee12c3910f7563da /source/20-codegen-compiler
parent06ab541057fec82415e612e9ff9a7f4bb11fc420 (diff)
Changeset: 84 Make all input commands use the same CodegenModel object
- A clean build on the main game still works - Generating cross-file references works now (only in a clean build, while the child classses are scanned after the parent classes though). This will still need fixing to support 1. reading from database 2. circular dependencies
Diffstat (limited to 'source/20-codegen-compiler')
-rw-r--r--source/20-codegen-compiler/CodegenModel.cpp106
-rw-r--r--source/20-codegen-compiler/main.cpp17
2 files changed, 66 insertions, 57 deletions
diff --git a/source/20-codegen-compiler/CodegenModel.cpp b/source/20-codegen-compiler/CodegenModel.cpp
index 88439e8..e3fc810 100644
--- a/source/20-codegen-compiler/CodegenModel.cpp
+++ b/source/20-codegen-compiler/CodegenModel.cpp
@@ -294,53 +294,12 @@ 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 GetNamespaceFullName(int64_t nsId) const {
+ return GetNamespaceFullNameImpl(nsId, nullptr, 0);
}
- std::string GetDeclFullName(int64_t nsId, std::string_view declName) {
- return GetNamespaceFullName(nsId).append(declName);
+ std::string GetDeclFullName(int64_t nsId, std::string_view declName) const {
+ return GetNamespaceFullNameImpl(nsId, declName.data(), declName.size());
}
/// \return Row ID of the file, or 0 if it currently doesn't exist.
@@ -391,6 +350,59 @@ COMMIT TRANSACTION;
}
private:
+ // TODO maybe merge with Utils::MakeFullName?
+ std::string GetNamespaceFullNameImpl(int64_t nsId, const char* append, size_t appendLength) const {
+ 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;
+ }
+ }
+ if (append) {
+ // Already has the '::' at the end
+ fullnameLength += appendLength;
+ } else {
+ fullnameLength -= 2;
+ }
+
+ std::string fullname;
+ fullname.reserve(fullnameLength);
+
+ for (auto it = namespaceNames.rbegin(); it != namespaceNames.rend(); ++it) {
+ fullname.append(*it);
+ if (!append && std::next(it) != namespaceNames.rend()) {
+ fullname.append("::");
+ }
+ }
+ if (append) {
+ fullname += std::string_view(append, appendLength);
+ }
+
+ return fullname;
+ }
+
int64_t FindNamespaceImpl(const DeclNamespace& ns) {
int64_t parentNsRowId;
if (ns.container) {
@@ -606,10 +618,6 @@ void CodegenModelArchive::Store(const CodegenModel& cgModel) {
m->BeginTransaction();
- // 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);
diff --git a/source/20-codegen-compiler/main.cpp b/source/20-codegen-compiler/main.cpp
index 81b5d23..5350f8e 100644
--- a/source/20-codegen-compiler/main.cpp
+++ b/source/20-codegen-compiler/main.cpp
@@ -593,7 +593,6 @@ struct ParserState {
};
struct ParserOutput {
- CodegenModel model;
CodegenOutput headerOutput;
CodegenOutput sourceOutput;
CodegenOutput standaloneSourceOutput;
@@ -745,7 +744,7 @@ void ParseInputFileAndGenerate(AppState& as, CodegenLexer& /*lexingState*/ ls, s
break;
}
- po.currentNamespace = po.model.AddNamespace(DeclNamespace{
+ po.currentNamespace = as.model->AddNamespace(DeclNamespace{
.container = po.currentNamespace,
.name = tokens[idx].text,
});
@@ -817,7 +816,7 @@ void ParseInputFileAndGenerate(AppState& as, CodegenLexer& /*lexingState*/ ls, s
// TODO support namespace qualified names
auto baseClassFullname = Utils::MakeFullName(idenTok.text, po.currentNamespace);
- auto baseClassDecl = po.model.FindStruct(baseClassFullname);
+ auto baseClassDecl = as.model->FindStruct(baseClassFullname);
if (baseClassDecl) {
// We silently ignore a non-existent base class, because they may reside in a file that we didn't scan
structDecl.baseClasses.push_back(baseClassDecl);
@@ -844,7 +843,7 @@ void ParseInputFileAndGenerate(AppState& as, CodegenLexer& /*lexingState*/ ls, s
{
// Get a pointer to the decl inside CodegenInput's storage
- auto decl = po.model.AddStruct(std::move(fullname), std::move(structDecl));
+ auto decl = as.model->AddStruct(std::move(fullname), std::move(structDecl));
po.currentStruct = decl;
po.currentStructBraceDepth = po.currentBraceDepth;
}
@@ -946,7 +945,7 @@ void ParseInputFileAndGenerate(AppState& as, CodegenLexer& /*lexingState*/ ls, s
}
{
- auto decl = po.model.AddEnum(std::move(fullname), std::move(enumDecl));
+ auto decl = as.model->AddEnum(std::move(fullname), std::move(enumDecl));
po.currentEnum = decl;
po.currentEnumBraceDepth = po.currentBraceDepth;
}
@@ -1194,7 +1193,7 @@ void ParseInputFileAndGenerate(AppState& as, CodegenLexer& /*lexingState*/ ls, s
Utils::WriteOutputFile(po.standaloneSourceOutput, generatedCppName);
as.modelArchive->DeleteDeclsRelatedToFile(filenameStem);
- as.modelArchive->Store(po.model);
+ // as.modelArchive->Store(po.model);
}
void HandleInputFile(AppState& as, const fs::path& path) {
@@ -1360,10 +1359,10 @@ where --output-dir=<path>: the *directory* to write generated contents to. Thi
// - follow the file links in database, and propagate parsing to those files in the hierarchy
// - pretty much defeats the purpose of using an incremental parser: some classes like GameObject will have links throughout a very large portion of the project code
CodegenModel model;
- CodegenModelArchive archive(as.databaseFilePath);
+ CodegenModelArchive modelArchive(as.databaseFilePath);
as.model = &model;
- as.modelArchive = &archive;
+ as.modelArchive = &modelArchive;
// Positional argument pass
for (int i = 1; i < argc; ++i) {
@@ -1384,6 +1383,8 @@ where --output-dir=<path>: the *directory* to write generated contents to. Thi
}
}
+ modelArchive.Store(model);
+
return 0;
}