Skip to content

Commit

Permalink
Use hashmap for block-scope lookup
Browse files Browse the repository at this point in the history
  • Loading branch information
rui314 committed Dec 7, 2020
1 parent 30520e5 commit 655954e
Showing 1 changed file with 23 additions and 39 deletions.
62 changes: 23 additions & 39 deletions parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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.
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit 655954e

Please sign in to comment.