aboutsummaryrefslogtreecommitdiff
path: root/source/20-codegen-compiler
diff options
context:
space:
mode:
authorrtk0c <[email protected]>2022-05-30 23:42:02 -0700
committerrtk0c <[email protected]>2022-05-30 23:42:02 -0700
commit8a0f2cd0b398ee0b7740e44a0e5fb2f75d090ccb (patch)
tree2838fd73313948f4db156b60c079468314eb1564 /source/20-codegen-compiler
parent3571627772b245e3e1a45b66e9a8fe4d50d06c8c (diff)
Changeset: 59 Integrate enum codegen into the actual project
Diffstat (limited to 'source/20-codegen-compiler')
-rw-r--r--source/20-codegen-compiler/CodegenMacros.hpp10
-rw-r--r--source/20-codegen-compiler/CodegenUtils.inl48
-rw-r--r--source/20-codegen-compiler/main.cpp58
3 files changed, 46 insertions, 70 deletions
diff --git a/source/20-codegen-compiler/CodegenMacros.hpp b/source/20-codegen-compiler/CodegenMacros.hpp
index 84c9d09..e56aed0 100644
--- a/source/20-codegen-compiler/CodegenMacros.hpp
+++ b/source/20-codegen-compiler/CodegenMacros.hpp
@@ -5,7 +5,12 @@
// I give up, hopefully nothing overflows this buffer
// TODO handle buffer sizing properly
-#define APPEND_LIT(out, str) out += str
+#define INPLACE_FMT(varName, format, ...) \
+ char varName[2048]; \
+ snprintf(varName, sizeof(varName), format, __VA_ARGS__);
+
+#define APPEND_LIT(out, str) \
+ out += str
#define APPEND_FMT(out, format, ...) \
{ \
@@ -14,7 +19,8 @@
out += buffer; \
}
-#define WRITE_LIT(file, str) fwrite(str, sizeof(char), sizeof(str) - 1, file)
+#define WRITE_LIT(file, str) \
+ fwrite(str, sizeof(char), sizeof(str) - 1, file)
// NOTE: snprintf() returns the size written (given an infinite buffer) not including \0
#define WRITE_FMT(file, format, ...) \
diff --git a/source/20-codegen-compiler/CodegenUtils.inl b/source/20-codegen-compiler/CodegenUtils.inl
index 6feb654..dddfe61 100644
--- a/source/20-codegen-compiler/CodegenUtils.inl
+++ b/source/20-codegen-compiler/CodegenUtils.inl
@@ -14,25 +14,7 @@
namespace Utils {
-std::string ReadFileAsString(const std::filesystem::path& path) {
- auto file = Utils::OpenCstdioFile(path, Utils::Read);
- if (!file) throw std::runtime_error("Failed to open source file.");
- DEFER { fclose(file); };
-
- fseek(file, 0, SEEK_END);
- auto fileSize = ftell(file);
- rewind(file);
-
- std::string result(fileSize, '\0');
- fread(result.data(), fileSize, 1, file);
-
- return result;
-}
-
-bool WriteOutputFile(const CodegenOutput& output, std::string_view dir, std::string_view filename, std::string_view additionalSuffix = {}) {
- char path[2048];
- snprintf(path, sizeof(path), "%.*s/%.*s%.*s", PRINTF_STRING_VIEW(dir), PRINTF_STRING_VIEW(filename), PRINTF_STRING_VIEW(additionalSuffix));
-
+bool WriteOutputFile(const CodegenOutput& output, const char* path) {
auto outputFile = Utils::OpenCstdioFile(path, Utils::WriteTruncate);
if (!outputFile) {
printf("[ERROR] unable to open output file %s\n", path);
@@ -74,9 +56,9 @@ std::string MakeFullName(std::string_view name, DeclNamespace* ns = nullptr) {
return fullname;
}
-void ProduceGeneratedHeaderFileHeader(CodegenOutput& output) {
- output.AddOutputThing(CodegenOutputThing{
- .text = &R"""(
+void ProduceGeneratedHeader(const char* headerFilename, CodegenOutput& header, const char* sourceFilename, CodegenOutput& source) {
+ CodegenOutputThing headerOut;
+ headerOut.text += &R"""(
// This file is generated. Any changes will be overidden when building.
#pragma once
@@ -84,23 +66,19 @@ void ProduceGeneratedHeaderFileHeader(CodegenOutput& output) {
#include <cstddef>
#include <cstdint>
-)"""[1],
- });
-}
-
-void ProduceGeneratedSourceFileHeader(CodegenOutput& output) {
- output.AddOutputThing(CodegenOutputThing{
- // TODO we need to get the header name
- .text = &R"""(
-// This file is generated. Any changes will be overidden when building.
+)"""[1];
-#include <cstddef>
-#include <cstdint>
+ CodegenOutputThing sourceOut;
+ APPEND_LIT_LN(sourceOut.text, "// This file is generated. Any changes will be overidden when building.");
+ APPEND_FMT_LN(sourceOut.text, "#include \"%s\"", headerFilename);
+ sourceOut.text += &R"""(
#include <frozen/string.h>
#include <frozen/unordered_map.h>
using namespace std::literals;
- )"""[1],
- });
+)"""[1];
+
+ header.AddOutputThing(std::move(headerOut));
+ source.AddOutputThing(std::move(sourceOut));
}
} // namespace Utils
diff --git a/source/20-codegen-compiler/main.cpp b/source/20-codegen-compiler/main.cpp
index b139515..874cacb 100644
--- a/source/20-codegen-compiler/main.cpp
+++ b/source/20-codegen-compiler/main.cpp
@@ -27,13 +27,10 @@
using namespace std::literals;
namespace fs = std::filesystem;
-// TODO handle namespace
// TODO support codegen target in .cpp files
struct AppState {
std::string_view outputDir;
- CodegenOutput mainHeaderOutput;
- CodegenOutput mainSourceOutput;
};
enum {
@@ -252,30 +249,28 @@ BSTR_LUT_DECL(EnumMetaGenOptions, 0, EMGO_COUNT) {
BSTR_LUT_MAP(EMGO_ExcludeUseHeuristics, "ExcludeHeuristics");
}
-std::string GenerateEnumStringArray(CodegenOutput& out, const DeclEnum& decl, bool useHeruistics) {
- std::string arrayName;
- APPEND_FMT(arrayName, "gCG_%s_Val2Str", decl.name.c_str());
+std::string GenerateEnumStringArray(CodegenOutput& out, const DeclEnum& decl, const std::vector<DeclEnumElement>& filteredElements, bool useHeruistics) {
+ INPLACE_FMT(arrayName, "gCG_%s_Val2Str", decl.name.c_str());
CodegenOutputThing thing;
- APPEND_FMT_LN(thing.text, "const char* %s[] = {", arrayName.c_str());
- for (auto& elm : decl.elements) {
- if (useHeruistics && elm.name.ends_with("COUNT")) {
- continue;
- }
-
+ APPEND_FMT_LN(thing.text, "const char* %s[] = {", arrayName);
+ for (auto& elm : filteredElements) {
APPEND_FMT_LN(thing.text, "\"%s\",", elm.name.c_str());
}
APPEND_LIT_LN(thing.text, "};");
out.AddOutputThing(std::move(thing));
- return arrayName;
+ return std::string(arrayName);
}
std::string GenerateEnumStringMap(CodegenOutput& out, const DeclEnum& decl, bool useHeruistics) {
- std::string mapName;
+ INPLACE_FMT(mapName, "gCG_%s_Val2Str", decl.name.c_str());
+
+ CodegenOutputThing thing;
// TODO
+ out.AddOutputThing(std::move(thing));
- return mapName;
+ return std::string(mapName);
}
void GenerateForEnum(CodegenOutput& headerOut, CodegenOutput& sourceOut, const DeclEnum& decl, EnumFlags<EnumMetaGenOptions> options) {
@@ -306,7 +301,7 @@ void GenerateForEnum(CodegenOutput& headerOut, CodegenOutput& sourceOut, const D
switch (decl.GetPattern()) {
case EVP_Continuous: {
- auto arrayName = GenerateEnumStringArray(sourceOut, decl, useExcludeHeuristics);
+ auto arrayName = GenerateEnumStringArray(sourceOut, decl, filteredElements, useExcludeHeuristics);
int minVal = filteredElements.empty() ? 0 : filteredElements.front().value;
int maxVal = filteredElements.empty() ? 0 : filteredElements.back().value;
@@ -324,7 +319,7 @@ void GenerateForEnum(CodegenOutput& headerOut, CodegenOutput& sourceOut, const D
} break;
case EVP_Bits: {
- auto arrayName = GenerateEnumStringArray(sourceOut, decl, useExcludeHeuristics);
+ auto arrayName = GenerateEnumStringArray(sourceOut, decl, filteredElements, useExcludeHeuristics);
// TODO
} break;
@@ -339,9 +334,8 @@ void GenerateForEnum(CodegenOutput& headerOut, CodegenOutput& sourceOut, const D
if (options.IsSet(EMGO_FromString)) {
// Generate string -> value lookup table
- char mapName[1024];
// TODO mangle to prevent name conflicts of enum in different namespaces
- snprintf(mapName, sizeof(mapName), "gCG_%s_Str2Val", decl.name.c_str());
+ INPLACE_FMT(mapName, "gCG_%s_Str2Val", decl.name.c_str());
CodegenOutputThing lookupTable;
{
@@ -388,9 +382,13 @@ void HandleInputFile(AppState& state, std::string_view filenameStem, std::string
CodegenInput cgInput;
CodegenOutput cgHeaderOutput;
- Utils::ProduceGeneratedHeaderFileHeader(cgHeaderOutput);
CodegenOutput cgSourceOutput;
- Utils::ProduceGeneratedSourceFileHeader(cgSourceOutput);
+ {
+ INPLACE_FMT(hpp, "%.*s.gh.inl", PRINTF_STRING_VIEW(filenameStem));
+ INPLACE_FMT(cpp, "%.*s.gs.inl", PRINTF_STRING_VIEW(filenameStem));
+ Utils::ProduceGeneratedHeader(hpp, cgHeaderOutput, cpp, cgSourceOutput);
+ }
+ CodegenOutput cgStandaloneSourceOutput;
int currentBraceDepth = 0;
// The current effective namespace, see example
@@ -640,11 +638,12 @@ void HandleInputFile(AppState& state, std::string_view filenameStem, std::string
printf("[WARNING] unbalanced brace at end of file.");
}
- Utils::WriteOutputFile(cgHeaderOutput, state.outputDir, filenameStem, ".gh.inl"sv);
- Utils::WriteOutputFile(cgSourceOutput, state.outputDir, filenameStem, ".gs.inl"sv);
-
- // TODO see CMakeLists.txt for rationale, clean this up to be a proper citizen
- Utils::WriteOutputFile(CodegenOutput{}, state.outputDir, filenameStem, ".gs.cpp"sv);
+ INPLACE_FMT(generatedHeaderInlName, "%.*s/%.*s.gh.inl", PRINTF_STRING_VIEW(state.outputDir), PRINTF_STRING_VIEW(filenameStem));
+ Utils::WriteOutputFile(cgHeaderOutput, generatedHeaderInlName);
+ INPLACE_FMT(generatedSourceInlName, "%.*s/%.*s.gs.inl", PRINTF_STRING_VIEW(state.outputDir), PRINTF_STRING_VIEW(filenameStem));
+ Utils::WriteOutputFile(cgSourceOutput, generatedSourceInlName);
+ INPLACE_FMT(generatedCppName, "%.*s/%.*s.g.cpp", PRINTF_STRING_VIEW(state.outputDir), PRINTF_STRING_VIEW(filenameStem));
+ Utils::WriteOutputFile(cgStandaloneSourceOutput, generatedCppName);
}
enum InputOpcode {
@@ -718,9 +717,6 @@ int main(int argc, char* argv[]) {
AppState state;
- Utils::ProduceGeneratedHeaderFileHeader(state.mainHeaderOutput);
- Utils::ProduceGeneratedSourceFileHeader(state.mainSourceOutput);
-
// If no cli is provided (argv[0] conventionally but not mandatorily the cli), this will do thing
// Otherwise, start with the 2nd element in the array, which is the 1st actual argument
if (argc < 2) {
@@ -753,9 +749,5 @@ where <output path>: the directory to write generated contents to. This will N
}
}
- // TODO do we even need these?
- // Utils::WriteOutputFile(state.mainHeaderOutput, state.outputDir, "GeneratedCode.hpp"sv);
- // Utils::WriteOutputFile(state.mainSourceOutput, state.outputDir, "GeneratedCode.cpp"sv);
-
return 0;
}