Skip to content

Commit

Permalink
check variable redeclaration
Browse files Browse the repository at this point in the history
  • Loading branch information
Luís Möllmann committed Jun 5, 2017
1 parent 52b3486 commit 4aedfa0
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 12 deletions.
41 changes: 33 additions & 8 deletions astree.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,9 +349,16 @@ void print_identation(FILE* stream, int level){
fprintf(stream, " ");
}

static void ast_annotate(struct astree* tree, struct hashmap *declared_variables);

/* `yes` is a dummy variable. Our hashmap implementation is being used here as
* a hashset. I.e., we only care about the keys. So `yes` is just a constant
* with no meaning to be put in the value field. */
static char yes = 1;

/* Annotate symbol table when tree is a declaration (i.e., of type AST_VAR,
* AST_VEC or AST_FHEADER). */
static void annotate_identifier(struct astree *tree) {
static void annotate_declaration(struct astree *tree, struct hashmap *declared_variables) {
struct astree *id_node;
struct astree *type_node;
switch (tree->type) {
Expand All @@ -362,8 +369,8 @@ static void annotate_identifier(struct astree *tree) {
case AST_VEC:
id_node = tree->children[0];
type_node = tree->children[1];
ast_annotate(tree->children[2]);
ast_annotate(tree->children[3]);
ast_annotate(tree->children[2], declared_variables);
ast_annotate(tree->children[3], declared_variables);
break;
case AST_FHEADER:
id_node = tree->children[1];
Expand All @@ -374,10 +381,17 @@ static void annotate_identifier(struct astree *tree) {
* Right now, this accomplishes nothing, since this node is of type
* AST_IDENTIFIER. Test program with the argument of `tests/fun_dec.txt`
* to see. */
ast_annotate(tree->children[2]);
ast_annotate(tree->children[2], declared_variables);
break;
}

/* check redeclarations */
if (hm_getref(declared_variables, id_node->symbol->key) != NULL) {
fprintf(stderr, "Redeclaration: %s\n", id_node->symbol->key);
exit(4);
}
hm_put(declared_variables, id_node->symbol->key, &yes);

struct symtab_item *item = id_node->symbol->value;
switch (tree->type) {
case AST_VAR:
Expand Down Expand Up @@ -431,15 +445,27 @@ static void annotate_symbol(struct astree *tree) {
}
}

void ast_annotate(struct astree* tree) {
void ast_semantic_check(struct astree *tree) {
struct hashmap declared_variables;
hm_initialize(20, 0.6, sizeof(char), &declared_variables);

ast_annotate(tree, &declared_variables);
hm_fprint(stderr, &declared_variables, 0);

hm_terminate(&declared_variables);
}

/* Traverses the tree annotating the type of the symbols in the symbol table.
* Annotates `data_type` for all symbols and `id_type` for identifiers. */
static void ast_annotate(struct astree* tree, struct hashmap *declared_variables) {
if (tree == NULL) {
return;
}

/* Annotating children before the root seems more intuitive, but I don't think
* it makes any difference. */
for (int i = 0; i < AST_MAXCHILDREN; i++) {
ast_annotate(tree->children[i]);
ast_annotate(tree->children[i], declared_variables);
}

int node_type = tree->type;
Expand All @@ -451,7 +477,6 @@ void ast_annotate(struct astree* tree) {
if (sym) {
annotate_symbol(tree);
} else if (decl) {
annotate_identifier(tree);
annotate_declaration(tree, declared_variables);
}

}
5 changes: 2 additions & 3 deletions astree.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ void ast_make_source(FILE* stream, struct astree* tree, int level);
/* Internal function to help make source*/
void print_identation(FILE* stream, int level);

/* Traverses the tree annotating the type of the symbols in the symbol table.
* Annotates `data_type` for all symbols and `id_type` for identifiers. */
void ast_annotate(struct astree* tree);
/* Does a semantic check on `tree`. */
void ast_semantic_check(struct astree* tree);
#endif /* ifndef AST_H */
2 changes: 1 addition & 1 deletion main.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ void main(int argc, char* argv[]){
}
yyparse();
printf("SUCESS:\n\t Program was accepted.\n");
ast_annotate(program);
ast_semantic_check(program);
symtab_print();
printf("SOURCE:\n");
ast_make_source(out, program, 0);
Expand Down
2 changes: 2 additions & 0 deletions tests/duplicated_var_dec.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
a: short 0;
a: short 1;
2 changes: 2 additions & 0 deletions tests/fun_dec.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
long incn (long x, long n)
return x+n;
2 changes: 2 additions & 0 deletions tests/var_dec.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
a: short 0;
b: short 1;
1 change: 1 addition & 0 deletions tests/vec_dec.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v: long[10] 0 0 0 0 0 0 0 0 0 0;

0 comments on commit 4aedfa0

Please sign in to comment.