G

G Programming Language
git clone http://git.omkov.net/G
Log | Tree | Refs | README | Download

AuthorJakob Wakeling <[email protected]>
Date2021-09-04 02:59:38
Commit341eca0bbbcb15ac36b4f524afd91a0da7930b7c
Parent382d4166479634b66a754f1050d20edd66e4b553

lexer: Fix incorrect identifier hashing

Diffstat

M src/lexer.c | 10 +++++-----
M src/map.c | 23 +++++------------------
M src/map.h | 4 ----

3 files changed, 10 insertions, 27 deletions

diff --git a/src/lexer.c b/src/lexer.c
index 2fa1bbf..9a76a19 100644
--- a/src/lexer.c
+++ b/src/lexer.c
@@ -6,10 +6,10 @@
 

 #include "lexer.h"
-#include "map.h"
 #include "type.h"
 
 #include "cll/error.h"
+#include "cll/fnv.h"
 
 #include <ctype.h>
 #include <stddef.h>
@@ -62,10 +62,9 @@ skip:;
 
 			// printf("%s[%zu]: %lx\n", ss, sl, hashl(ss, sl));
 
-			switch (hashl(ss, sl)) {
-			/* FIXME the hashes are not what I expect them to be */
-			case 0x97D2D80E3FED2FB5: { n.k = LK_PROC;   } goto end;
-			case 0x2C46B8D34B10A205: { n.k = LK_RETURN; } goto end;
+			switch (fnv1a64((u8 *)ss, sl)) {
+			case 0x85729B0E3537BC61: { n.k = LK_PROC;   } goto end;
+			case 0xC5C7B983377CAD5F: { n.k = LK_RETURN; } goto end;
 			default: { n.k = LK_IDN; goto end; }
 			}
 		}
diff --git a/src/map.c b/src/map.c
index 101fda1..c4e7e25 100644
--- a/src/map.c
+++ b/src/map.c
@@ -8,23 +8,11 @@
 #include "map.h"
 #include "misc.h"
 
+#include "cll/fnv.h"
+
 #include <stdlib.h>
 #include <string.h>
 
-/* Compute the FNV1a-64 hash of a string. */
-inline u64 hash(register char *s) {
-	register u64 h = 0xCBF29CE484222325;
-	for (; *s; ++s) { h ^= *s; h *= 0x00000100000001B3; }
-	return h;
-}
-
-/* Compute the FNV1a-64 hash of a string. */
-inline u64 hashl(str s, UINT l) {
-	register u64 h = 0xCBF29CE484222325;
-	for (; l; --l) { h ^= *s; h *= 0x00000100000001B3; }
-	return h;
-}
-
 /* Initialise a new map entry. */
 static inline ent *ent_init(str k, sym v) {
 	ent *e = calloc(1, sizeof (*e)); if (!e) { return NULL; }
@@ -57,7 +45,7 @@ extern void map_free(map *m) {
 
 /* Get the element associated with a key. */
 extern sym *map_get(map *m, str k) {
-	register ent *e = m->a[hash(k) % m->ac];
+	register ent *e = m->a[fnv1a64((u8 *)k, strlen(k)) % m->ac];
 
 	/* Check if the key is present in the bucket */
 	for (; e; e = e->n) { if (!strcmp(k, e->k)) { return &e->v; }} return NULL;
@@ -67,7 +55,7 @@ extern sym *map_get(map *m, str k) {
 extern void map_set(map *m, str k, sym v) {
 	if ((f64)m->al / m->ac >= 0.75) { map_grow(m); }
 
-	u64 i = hash(k) % m->ac; register ent *e = m->a[i];
+	u64 i = fnv1a64((u8 *)k, strlen(k)) % m->ac; register ent *e = m->a[i];
 
 	/* Check if the bucket is completely empty */
 	if (!e) {
diff --git a/src/map.h b/src/map.h
index af29d33..14baf10 100644
--- a/src/map.h
+++ b/src/map.h
@@ -18,9 +18,6 @@ typedef struct sym { ent_k k; ent_f f; type t; } sym;
 typedef struct ent { str k; sym v; struct ent *n, *c; } ent;
 typedef struct { ent **a, *c; UINT al, ac; } map;
 
-extern u64 hash(register char *s);
-extern u64 hashl(str s, UINT l);
-
 extern void map_init(map *m);
 extern void map_free(map *m);