Add chibicc

This program popped up on Hacker News recently. It's the only modern
compiler I've ever seen that doesn't have dependencies and is easily
modified. So I added all of the missing GNU extensions I like to use
which means it might be possible soon to build on non-Linux and have
third party not vendor gcc binaries.
This commit is contained in:
Justine Tunney 2020-12-05 12:20:41 -08:00
parent e44a0cf6f8
commit 8da931a7f6
298 changed files with 19493 additions and 11950 deletions

View file

@ -20,7 +20,7 @@ static void rehash(HashMap *map) {
int nkeys = 0;
for (int i = 0; i < map->capacity; i++)
if (map->buckets[i].key && map->buckets[i].key != TOMBSTONE) nkeys++;
int cap = map->capacity;
size_t cap = map->capacity;
while ((nkeys * 100) / cap >= 50) cap = cap * 2;
// Create a new hashmap and copy all key-values.
HashMap map2 = {};
@ -44,7 +44,7 @@ static HashEntry *get_entry(HashMap *map, char *key, int keylen) {
if (!map->buckets) return NULL;
uint64_t hash = fnv_hash(key, keylen);
for (int i = 0; i < map->capacity; i++) {
HashEntry *ent = &map->buckets[(hash + i) % map->capacity];
HashEntry *ent = &map->buckets[(hash + i) & (map->capacity - 1)];
if (match(ent, key, keylen)) return ent;
if (ent->key == NULL) return NULL;
}
@ -58,7 +58,7 @@ static HashEntry *get_or_insert_entry(HashMap *map, char *key, int keylen) {
if ((map->used * 100) / map->capacity >= 70) rehash(map);
uint64_t hash = fnv_hash(key, keylen);
for (int i = 0; i < map->capacity; i++) {
HashEntry *ent = &map->buckets[(hash + i) % map->capacity];
HashEntry *ent = &map->buckets[(hash + i) & (map->capacity - 1)];
if (match(ent, key, keylen)) return ent;
if (ent->key == TOMBSTONE) {
ent->key = key;
@ -102,29 +102,31 @@ void hashmap_delete2(HashMap *map, char *key, int keylen) {
if (ent) ent->key = TOMBSTONE;
}
#if 0
void hashmap_test(void) {
HashMap *map = calloc(1, sizeof(HashMap));
for (int i = 0; i < 5000; i++)
hashmap_put(map, format("key %d", i), (void *)(size_t)i);
for (int i = 1000; i < 2000; i++) hashmap_delete(map, format("key %d", i));
hashmap_put(map, xasprintf("key %d", i), (void *)(size_t)i);
for (int i = 1000; i < 2000; i++) hashmap_delete(map, xasprintf("key %d", i));
for (int i = 1500; i < 1600; i++)
hashmap_put(map, format("key %d", i), (void *)(size_t)i);
hashmap_put(map, xasprintf("key %d", i), (void *)(size_t)i);
for (int i = 6000; i < 7000; i++)
hashmap_put(map, format("key %d", i), (void *)(size_t)i);
hashmap_put(map, xasprintf("key %d", i), (void *)(size_t)i);
for (int i = 0; i < 1000; i++)
assert((size_t)hashmap_get(map, format("key %d", i)) == i);
assert((size_t)hashmap_get(map, xasprintf("key %d", i)) == i);
for (int i = 1000; i < 1500; i++)
assert(hashmap_get(map, "no such key") == NULL);
for (int i = 1500; i < 1600; i++)
assert((size_t)hashmap_get(map, format("key %d", i)) == i);
assert((size_t)hashmap_get(map, xasprintf("key %d", i)) == i);
for (int i = 1600; i < 2000; i++)
assert(hashmap_get(map, "no such key") == NULL);
for (int i = 2000; i < 5000; i++)
assert((size_t)hashmap_get(map, format("key %d", i)) == i);
assert((size_t)hashmap_get(map, xasprintf("key %d", i)) == i);
for (int i = 5000; i < 6000; i++)
assert(hashmap_get(map, "no such key") == NULL);
for (int i = 6000; i < 7000; i++)
hashmap_put(map, format("key %d", i), (void *)(size_t)i);
hashmap_put(map, xasprintf("key %d", i), (void *)(size_t)i);
assert(hashmap_get(map, "no such key") == NULL);
printf("OK\n");
}
#endif