summaryrefslogtreecommitdiff
path: root/blocks.c
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-08-21 20:42:16 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2019-08-21 20:42:16 -0400
commitd63a28aa4d227544b912b3edc2479de622d18a32 (patch)
tree42aac6845611365d4243dcc7f9b36214da3dcd09 /blocks.c
parent1c214758924bbfcd0cbafb6a4240210f057de007 (diff)
started identification
Diffstat (limited to 'blocks.c')
-rw-r--r--blocks.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/blocks.c b/blocks.c
new file mode 100644
index 0000000..5c06a6e
--- /dev/null
+++ b/blocks.c
@@ -0,0 +1,49 @@
+/* identifies identifiers in this block */
+static bool block_enter(Block *b) {
+ bool ret = true;
+ arr_foreach(&b->stmts, Statement, stmt) {
+ if (stmt->kind == STMT_DECL) {
+ Declaration *decl = &stmt->decl;
+ arr_foreach(&decl->idents, Identifier, ident) {
+ Array *decls = &(*ident)->decls;
+ if (decls->item_sz) {
+ /* check that it hasn't been declared in this block */
+ IdentDecl *prev = decls->last;
+ if (prev->scope == b) {
+ err_print(decl->where, "Re-declaration of identifier in the same block.");
+ info_print(prev->decl->where, "Previous declaration was here.");
+ ret = false;
+ continue;
+ }
+ } else {
+ /* array not initialized yet */
+ arr_create(&(*ident)->decls, sizeof(IdentDecl));
+ }
+ IdentDecl *ident_decl = arr_add(decls);
+ ident_decl->decl = decl;
+ ident_decl->scope = b;
+ }
+ }
+ }
+ return ret;
+}
+
+/* de-identifies identifiers in this block */
+static bool block_exit(Block *b) {
+ /* OPTIM: figure out some way of not re-iterating over everything */
+ bool ret = true;
+ arr_foreach(&b->stmts, Statement, stmt) {
+ if (stmt->kind == STMT_DECL) {
+ Declaration *decl = &stmt->decl;
+ arr_foreach(&decl->idents, Identifier, ident) {
+ Array *decls = &(*ident)->decls;
+ assert(decls->item_sz);
+ IdentDecl *last_decl = decls->last;
+ if (last_decl->scope == b)
+ arr_remove_last(decls); /* remove that declaration */
+
+ }
+ }
+ }
+ return ret;
+}