summaryrefslogtreecommitdiffstats
path: root/source/compiler-core/slang-perfect-hash-codegen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/compiler-core/slang-perfect-hash-codegen.cpp')
-rw-r--r--source/compiler-core/slang-perfect-hash-codegen.cpp81
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);
+ }
+
+}