diff options
Diffstat (limited to 'source/compiler-core/slang-perfect-hash-codegen.cpp')
| -rw-r--r-- | source/compiler-core/slang-perfect-hash-codegen.cpp | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/source/compiler-core/slang-perfect-hash-codegen.cpp b/source/compiler-core/slang-perfect-hash-codegen.cpp new file mode 100644 index 000000000..611b34c54 --- /dev/null +++ b/source/compiler-core/slang-perfect-hash-codegen.cpp @@ -0,0 +1,81 @@ +#include "slang-perfect-hash-codegen.h" +#include "../core/slang-io.h" + +namespace Slang +{ + SlangResult writeHashFile( + String outCppPath, + String valueType, + const List<String> includes, + const HashParams& hashParams, + const List<String> values) + { + StringBuilder sb; + StringWriter writer(&sb, WriterFlags(0)); + WriterHelper w(&writer); + + w.print("// Hash function for %s\n", valueType.getBuffer()); + w.print("//\n"); + w.print("// This file was thoughtfully generated by a machine,\n"); + w.print("// don't even think about modifying it yourself!\n"); + w.print("//\n"); + w.print("\n"); + for (const auto& i : includes) + { + if (i.getLength()) + w.print("#include \"%s\"\n", i.getBuffer()); + } + w.print("\n"); + w.print("\n"); + w.print("namespace Slang\n"); + w.print("{\n"); + w.print("\n"); + + w.put(perfectHashToEmbeddableCpp( + hashParams, + valueType.getUnownedSlice(), + (String("lookup") + valueType).getUnownedSlice(), + values + ).getBuffer()); + + w.print("}\n"); + + return File::writeAllTextIfChanged(outCppPath, sb.getUnownedSlice()); + } + + SlangResult writePerfectHashLookupCppFile(String fileName, List<String> opnames, String enumName, String enumerantPrefix, String enumHeaderFile, DiagnosticSink* sink) + { + HashParams hashParams; + auto r = minimalPerfectHash(opnames, hashParams); + switch (r) + { + case HashFindResult::UnavoidableHashCollision: + { + sink->diagnoseRaw( + Severity::Error, + "Unable to find a non-overlapping hash function.\n" + "The hash function probably has a unavoidable " + "collision for some input words\n"); + return SLANG_FAIL; + } + case HashFindResult::NonUniqueKeys: + { + sink->diagnoseRaw(Severity::Error, "Input word list has duplicates\n"); + return SLANG_FAIL; + } + case HashFindResult::Success:; + } + + List<String> values; + values.reserve(hashParams.destTable.getCount()); + for (const auto& v : hashParams.destTable) + values.add(enumerantPrefix + v); + return writeHashFile( + fileName, + enumName, + { "../core/slang-common.h", "../core/slang-string.h", enumHeaderFile }, + hashParams, + values); + } + +} |
