diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2020-02-27 12:04:19 -0500 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2020-02-27 12:04:19 -0500 |
commit | cb29bbe47fa67b9da183d39f343f7923c2ddaa7b (patch) | |
tree | e25aded7cc41386488c56582fdc01d2aedc4bb1d /sdecls_cgen.c | |
parent | 5ae9274e34a6a33753d453e18072c8de2e7686f8 (diff) |
only #include stuff once
Diffstat (limited to 'sdecls_cgen.c')
-rw-r--r-- | sdecls_cgen.c | 53 |
1 files changed, 48 insertions, 5 deletions
diff --git a/sdecls_cgen.c b/sdecls_cgen.c index eb388c3..7eec064 100644 --- a/sdecls_cgen.c +++ b/sdecls_cgen.c @@ -42,6 +42,29 @@ static void cgen_sdecls_block(CGenerator *g, Block *b) { g->block = prev_block; } +static char *cgen_nms_prefix_part(CGenerator *g, Namespace *n) { + char *s; + while (n->points_to) { + n = n->points_to; + } + if (n->associated_ident) { + size_t ident_len = n->associated_ident->len; + s = malloc(ident_len + 3); + memcpy(s, n->associated_ident->str, ident_len); + s[ident_len] = '_'; + s[ident_len+1] = '_'; + s[ident_len+2] = '\0'; + } else { + s = calloc(CGEN_IDENT_ID_STR_SIZE + 3, 1); + cgen_ident_id_to_str(s, ++g->ident_counter); + size_t len = strlen(s); + s[len] = '_'; + s[len+1] = '_'; + s[len+2] = '\0'; + } + return s; +} + static void cgen_sdecls_expr(CGenerator *g, Expression *e) { switch (e->kind) { case EXPR_CAST: @@ -54,12 +77,26 @@ static void cgen_sdecls_expr(CGenerator *g, Expression *e) { case EXPR_TYPE: cgen_sdecls_type(g, &e->typeval); break; - case EXPR_NMS: - e->nms.c.id = 0; - break; + case EXPR_NMS: { + char *prefix_part = cgen_nms_prefix_part(g, &e->nms); + size_t prefix_part_len = strlen(prefix_part); + char const *prev_prefix = g->nms_prefixes ? *(char const **)arr_last(g->nms_prefixes) + : ""; + size_t prev_prefix_len = strlen(prev_prefix); + char *new_prefix = cgen_malloc(g, prev_prefix_len + prefix_part_len + 1); + memcpy(new_prefix, prev_prefix, prev_prefix_len); + memcpy(new_prefix + prev_prefix_len, prefix_part, prefix_part_len); + free(prefix_part); + *(char const **)arr_add(&g->nms_prefixes) = new_prefix; + new_prefix[prev_prefix_len + prefix_part_len] = 0; + e->nms.c.prefix = new_prefix; + } break; default: break; } cgen_recurse_subexprs(g, e, cgen_sdecls_expr, cgen_sdecls_block, cgen_sdecls_decl); + if (e->kind == EXPR_NMS) { + arr_remove_last(&g->nms_prefixes); + } } @@ -101,8 +138,14 @@ static void cgen_sdecls_stmt(CGenerator *g, Statement *s) { cgen_sdecls_expr(g, &s->ret.expr); break; case STMT_INCLUDE: - arr_foreach(s->inc.stmts, Statement, sub) - cgen_sdecls_stmt(g, sub); + + if (s->inc.inc_file && (s->inc.inc_file->flags & INC_FILE_CGEND_SDECLS)) { + /* already generated */ + } else { + if (s->inc.inc_file) s->inc.inc_file->flags |= INC_FILE_CGEND_SDECLS; + arr_foreach(s->inc.stmts, Statement, sub) + cgen_sdecls_stmt(g, sub); + } break; } } |