Skip to content

Instantly share code, notes, and snippets.

@RealNeGate
Last active November 28, 2021 01:57
Show Gist options
  • Save RealNeGate/2071e851899065f628124360e6d09bae to your computer and use it in GitHub Desktop.
Save RealNeGate/2071e851899065f628124360e6d09bae to your computer and use it in GitHub Desktop.
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <x86intrin.h>
const char keywords[][16] = {
"alignof",
"auto",
"break",
"case",
"char",
"const",
"continue",
"default",
"do",
"double",
"else",
"enum",
"extern",
"float",
"for",
"goto",
"if",
"inline",
"int",
"long",
"register",
"restrict",
"return",
"short",
"signed",
"sizeof",
"static",
"struct",
"switch",
"typedef",
"union",
"unsigned",
"void",
"volatile",
"while",
"_Alignas",
"_Atomic",
"_Bool",
"_Complex",
"_Generic",
"_Imaginary",
"_Noreturn",
"_Static_assert",
"_Thread_local"
};
static uint32_t fnv1a(const void* data) {
const unsigned char* ptr = (const unsigned char*)data;
uint32_t hash = 0x811C9DC5;
while (*ptr) {
hash = ((*ptr++) ^ hash) * 0x01000193;
}
return hash;
}
// This thing just prints to the console some source code you copy into the code
enum { num_keywords = sizeof(keywords) / sizeof(*keywords) };
inline static uint64_t next_pow2(uint64_t x) {
return x == 1 ? 1 : 1 << (64 - __builtin_clzl(x - 1));
}
int compare_ints(const void* a, const void* b) {
uint32_t arg1 = *(const uint32_t*)a;
uint32_t arg2 = *(const uint32_t*)b;
if (arg1 < arg2) return -1;
if (arg1 > arg2) return 1;
return 0;
}
int main() {
uint32_t hashes[2 * num_keywords];
for (uint64_t i = 0; i < num_keywords; i++) {
hashes[(2 * i)] = fnv1a(keywords[i]);
hashes[(2 * i) + 1] = i;
}
qsort(hashes, num_keywords, 2 * sizeof(uint32_t), compare_ints);
size_t padded_len = next_pow2(num_keywords);
printf("// BINARY SEARCH ARRAYS\n");
printf("const static uint32_t keys[%d] = {\n\n\t", padded_len);
for (uint64_t i = 0; i < padded_len; i++) {
if (i < num_keywords) printf("0x%08X,", hashes[2 * i]);
else printf("0xFFFFFFFF,");
if (i % 8 == 7) printf("\n\t");
}
printf("\n};\n");
printf("const static uint32_t values[%d] = {\n\t", padded_len);
for (uint64_t i = 0; i < num_keywords; i++) {
printf("%d,", hashes[2 * i + 1]);
}
printf("\n};\n\n");
return 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment