Skip to content

Commit

Permalink
Improve parsing of configurations. Issue #372
Browse files Browse the repository at this point in the history
  • Loading branch information
nickg committed Oct 24, 2021
1 parent 4d44b57 commit 69ee308
Show file tree
Hide file tree
Showing 15 changed files with 326 additions and 115 deletions.
11 changes: 11 additions & 0 deletions src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,14 @@ static void dump_generic_map(tree_t t, int indent)
}
}

static void dump_binding(tree_t t, int indent)
{
syntax("#use %s", istr(tree_ident(t)));
if (tree_has_ident2(t))
printf("(%s)", istr(tree_ident2(t)));
printf(";\n");
}

static void dump_stmts(tree_t t, int indent)
{
const int nstmts = tree_stmts(t);
Expand Down Expand Up @@ -1254,6 +1262,9 @@ void dump(tree_t t)
dump_range(t);
printf("\n");
break;
case T_BINDING:
dump_binding(t, 0);
break;
default:
cannot_dump(t, "tree");
}
Expand Down
74 changes: 55 additions & 19 deletions src/names.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ struct scope {
tree_t subprog;
ident_t prefix;
tree_t unit;
bool suppress;
};

struct nametab {
Expand Down Expand Up @@ -338,6 +339,11 @@ void pop_scope(nametab_t *tab)
tab->top_scope = tmp;
}

void suppress_errors(nametab_t *tab)
{
tab->top_scope->suppress = true;
}

static scope_t *chain_scope(nametab_t *tab, ident_t tag)
{
scope_t *s = xcalloc(sizeof(scope_t));
Expand Down Expand Up @@ -732,7 +738,11 @@ tree_t resolve_name(nametab_t *tab, const loc_t *loc, ident_t name)
return NULL;
}
else if (decl == NULL) {
if (name == ident_new("error")) {
if (tab->top_scope->suppress) {
// Suppressing cascading errors
assert(error_count() > 0);
}
else if (name == ident_new("error")) {
// Was a parse error, suppress further errors
}
else if (tab->top_scope->formal_kind != F_NONE) {
Expand Down Expand Up @@ -948,6 +958,22 @@ static tree_t resolve_ref(nametab_t *tab, tree_t ref)
}
}

static void bind_instance(tree_t inst, tree_t spec)
{
if (tree_has_spec(inst)) {
tree_t exist = tree_spec(inst);
if (tree_has_ident(exist)) { // Not an OTHERS specification
error_at(tree_loc(spec), "instance %s is already bound by a "
"specification", istr(tree_ident(inst)));
note_at(tree_loc(exist), "originally bound by specification "
"here");
return;
}
}

tree_set_spec(inst, spec);
}

void resolve_specs(nametab_t *tab, tree_t container)
{
const int ndecls = tree_decls(container);
Expand All @@ -967,13 +993,12 @@ void resolve_specs(nametab_t *tab, tree_t container)
else
kind = NAMED;

ident_t cname = tree_ident2(d);
tree_t comp = resolve_name(tab, tree_loc(d), cname);
if (!tree_has_ref(d))
continue;

if (comp == NULL) {
// Skip it
}
else if (kind == NAMED) {
tree_t comp = tree_ref(d);

if (kind == NAMED) {
// Only look for the instance in the innermost scope
scope_t *inner = tab->top_scope;
tree_t inst = scope_find(inner, iname, inner, NULL, 0);
Expand All @@ -988,7 +1013,7 @@ void resolve_specs(nametab_t *tab, tree_t container)
continue;
}

sem_bind(d, inst, comp);
bind_instance(inst, d);
}
else {
const void *key;
Expand All @@ -999,19 +1024,16 @@ void resolve_specs(nametab_t *tab, tree_t container)

if (obj == (tree_t)-1)
continue; // Error marker

if (tree_kind(obj) != T_INSTANCE)
else if (tree_kind(obj) != T_INSTANCE)
continue;

if (tree_class(obj) != C_COMPONENT)
else if (tree_class(obj) != C_COMPONENT)
continue;

if (tree_ident2(obj) == cname) {
if (kind == ALL || !tree_has_spec(obj)) {
if (!sem_bind(d, obj, comp))
break;
}
}
else if (!tree_has_ref(obj))
continue;
else if (tree_ref(obj) != comp)
continue;
else if (kind == ALL || !tree_has_spec(obj))
bind_instance(obj, d);
}
}
}
Expand Down Expand Up @@ -1224,6 +1246,20 @@ void insert_protected_decls(nametab_t *tab, type_t type)
insert_name(tab, type_decl(type, i), NULL, 0);
}

void insert_names_for_config(nametab_t *tab, tree_t unit)
{
const int ndecls = tree_decls(unit);
for (int i = 0; i < ndecls; i++) {
tree_t d = tree_decl(unit, i);
if (tree_kind(d) == T_COMPONENT)
insert_name(tab, d, NULL, 0);
}

const int nstmts = tree_stmts(unit);
for (int i = 0; i < nstmts; i++)
insert_name(tab, tree_stmt(unit, i), NULL, 0);
}

////////////////////////////////////////////////////////////////////////////////
// Name mangling

Expand Down
2 changes: 2 additions & 0 deletions src/names.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ formal_kind_t scope_formal_kind(nametab_t *tab);
tree_t scope_subprogram(nametab_t *tab);
tree_t scope_unit(nametab_t *tab);
bool name_is_formal(nametab_t *tab, ident_t id);
void suppress_errors(nametab_t *tab);

void mangle_func(nametab_t *tab, tree_t decl);
void mangle_type(nametab_t *tab, type_t type);
Expand All @@ -57,6 +58,7 @@ void insert_decls(nametab_t *tab, tree_t container);
void insert_ports(nametab_t *tab, tree_t container);
void insert_generics(nametab_t *tab, tree_t container);
void insert_protected_decls(nametab_t *tab, type_t type);
void insert_names_for_config(nametab_t *tab, tree_t unit);

tree_t resolve_name(nametab_t *tab, const loc_t *loc, ident_t name);
type_t resolve_type(nametab_t *tab, type_t incomplete);
Expand Down
Loading

0 comments on commit 69ee308

Please sign in to comment.