From 655954e301621737988a4fa0a2c72ffc24285c8d Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Wed, 7 Oct 2020 11:13:22 +0900 Subject: [PATCH] Use hashmap for block-scope lookup --- parse.c | 62 +++++++++++++++++++++------------------------------------ 1 file changed, 23 insertions(+), 39 deletions(-) diff --git a/parse.c b/parse.c index 25a9d48..947b823 100644 --- a/parse.c +++ b/parse.c @@ -20,23 +20,12 @@ // Scope for local variables, global variables, typedefs // or enum constants -typedef struct VarScope VarScope; -struct VarScope { - VarScope *next; - char *name; +typedef struct { Obj *var; Type *type_def; Type *enum_ty; int enum_val; -}; - -// Scope for struct, union or enum tags -typedef struct TagScope TagScope; -struct TagScope { - TagScope *next; - char *name; - Type *ty; -}; +} VarScope; // Represents a block scope. typedef struct Scope Scope; @@ -45,8 +34,8 @@ struct Scope { // C has two block scopes; one is for variables/typedefs and // the other is for struct/union/enum tags. - VarScope *vars; - TagScope *tags; + HashMap vars; + HashMap tags; }; // Variable attributes such as typedef or extern. @@ -183,18 +172,20 @@ static void leave_scope(void) { // Find a variable by name. static VarScope *find_var(Token *tok) { - for (Scope *sc = scope; sc; sc = sc->next) - for (VarScope *sc2 = sc->vars; sc2; sc2 = sc2->next) - if (equal(tok, sc2->name)) - return sc2; + for (Scope *sc = scope; sc; sc = sc->next) { + VarScope *sc2 = hashmap_get2(&sc->vars, tok->loc, tok->len); + if (sc2) + return sc2; + } return NULL; } static Type *find_tag(Token *tok) { - for (Scope *sc = scope; sc; sc = sc->next) - for (TagScope *sc2 = sc->tags; sc2; sc2 = sc2->next) - if (equal(tok, sc2->name)) - return sc2->ty; + for (Scope *sc = scope; sc; sc = sc->next) { + Type *ty = hashmap_get2(&sc->tags, tok->loc, tok->len); + if (ty) + return ty; + } return NULL; } @@ -263,9 +254,7 @@ Node *new_cast(Node *expr, Type *ty) { static VarScope *push_scope(char *name) { VarScope *sc = calloc(1, sizeof(VarScope)); - sc->name = name; - sc->next = scope->vars; - scope->vars = sc; + hashmap_put(&scope->vars, name, sc); return sc; } @@ -366,11 +355,7 @@ static Type *find_typedef(Token *tok) { } static void push_tag_scope(Token *tok, Type *ty) { - TagScope *sc = calloc(1, sizeof(TagScope)); - sc->name = strndup(tok->loc, tok->len); - sc->ty = ty; - sc->next = scope->tags; - scope->tags = sc; + hashmap_put2(&scope->tags, tok->loc, tok->len, ty); } // declspec = ("void" | "_Bool" | "char" | "short" | "int" | "long" @@ -2559,11 +2544,10 @@ static Type *struct_union_decl(Token **rest, Token *tok) { if (tag) { // If this is a redefinition, overwrite a previous type. // Otherwise, register the struct type. - for (TagScope *sc = scope->tags; sc; sc = sc->next) { - if (equal(tag, sc->name)) { - *sc->ty = *ty; - return sc->ty; - } + Type *ty2 = hashmap_get2(&scope->tags, tag->loc, tag->len); + if (ty2) { + *ty2 = *ty; + return ty2; } push_tag_scope(tag, ty); @@ -3053,9 +3037,9 @@ static Obj *find_func(char *name) { while (sc->next) sc = sc->next; - for (VarScope *sc2 = sc->vars; sc2; sc2 = sc2->next) - if (!strcmp(sc2->name, name) && sc2->var && sc2->var->is_function) - return sc2->var; + VarScope *sc2 = hashmap_get(&sc->vars, name); + if (sc2 && sc2->var && sc2->var->is_function) + return sc2->var; return NULL; }