scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit 65d95b778688f40febd8e94c03bd2616c7dc0bd5
parent d24706caaba60e213fc19fa32155d944095db824
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Mon, 14 May 2018 07:08:02 +0100

[ld] Implement lookup()

Diffstat:
Mld/ld.h | 1+
Mld/obj.c | 32+++++++++++++++++++++++++++++++-
2 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/ld/ld.h b/ld/ld.h @@ -15,6 +15,7 @@ struct obj { struct symbol { char *name; + struct symbol *hash; }; struct objfile { diff --git a/ld/obj.c b/ld/obj.c @@ -7,9 +7,13 @@ static char sccsid[] = "@(#) ./ld/obj.c"; #include "../inc/scc.h" #include "ld.h" +#define NR_SYM_HASH 64 + Obj *objlst; static Obj *tail; +static Symbol *symtbl[NR_SYM_HASH]; + Obj * newobj(char *fname, char *member) { @@ -45,5 +49,31 @@ newobj(char *fname, char *member) Symbol * lookup(char *name) { - return NULL; + unsigned h, c; + char *s; + size_t len; + Symbol *sym; + + for (h = 0; c = *name; ++s) + h = h*33 ^ c; + h &= NR_SYM_HASH-1; + + for (sym = symtbl[h]; sym; sym = sym->hash) { + s = sym->name; + if (*name == *s && !strcmp(name, s)) + return sym; + } + + len = strlen(name) + 1; + sym = malloc(sizeof(*sym)); + s = malloc(len); + if (!sym || !s) + outmem(); + sym->hash = symtbl[h]; + symtbl[h] = sym; + sym->name = s; + memset(sym, 0, sizeof(*sym)); + memcpy(sym->name, name, len); + + return sym; }