From 157ffb0e7c17c61d05462e5ffdce19620485b0b1 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Wed, 1 Apr 2020 17:39:47 -0400 Subject: block cleanup --- cgen.c | 2 +- decls_cgen.c | 3 ++- main.c | 2 ++ parse.c | 9 +++++---- types.c | 22 ++++++++++------------ types.h | 28 ++++++++++++---------------- 6 files changed, 32 insertions(+), 34 deletions(-) diff --git a/cgen.c b/cgen.c index 6d03947..f84474a 100644 --- a/cgen.c +++ b/cgen.c @@ -256,7 +256,7 @@ static inline void cgen_writeln(CGenerator *g, const char *fmt, ...) { /* should this declaration be a direct function declaration C? (as opposed to using a function pointer or not being a function) */ static bool cgen_fn_is_direct(CGenerator *g, Declaration *d) { - return (g->block == NULL || (g->block->flags & BLOCK_IS_NMS)) && (d->flags & DECL_HAS_EXPR) && d->expr.kind == EXPR_FN && arr_len(d->idents) == 1; + return g->fn == NULL && (d->flags & DECL_HAS_EXPR) && d->expr.kind == EXPR_FN && arr_len(d->idents) == 1; } static bool fn_has_instances(FnExpr *f) { diff --git a/decls_cgen.c b/decls_cgen.c index 1cb5393..08d0727 100644 --- a/decls_cgen.c +++ b/decls_cgen.c @@ -340,7 +340,8 @@ static void cgen_decls_decl(CGenerator *g, Declaration *d) { if (d->flags & DECL_HAS_EXPR) { cgen_decls_expr(g, &d->expr); } - if ((g->block == NULL || (g->block->flags & BLOCK_IS_NMS)) && g->fn == NULL) { + if (g->fn == NULL) { + /* global variables */ for (int i = 0, n_idents = (int)arr_len(d->idents); i < n_idents; ++i) { Identifier ident = d->idents[i]; Type *type = decl_type_at_index(d, i); diff --git a/main.c b/main.c index d7f5063..1d49ea6 100644 --- a/main.c +++ b/main.c @@ -8,9 +8,11 @@ /* TODO: +figure out why we're not getting redecl errors use - note: just keep an array of useds on the block - use with a decl, e.g. use p : Point; + - make sure use works with functions and for, e.g. for use p := points local structs should not be named in C for some reason forgetting a ; after #include causes a misleading unrecognized expression simplify eval macros with val_to_u/i64 diff --git a/parse.c b/parse.c index f0e93b6..f269ea9 100644 --- a/parse.c +++ b/parse.c @@ -797,6 +797,7 @@ static Status parse_block(Parser *p, Block *b, U8 flags) { Tokenizer *t = p->tokr; Block *prev_block = p->block; b->flags = 0; + b->kind = BLOCK_OTHER; b->ret_expr = NULL; assert(p->block != b); b->parent = p->block; @@ -947,7 +948,7 @@ static Status parse_fn_expr(Parser *p, FnExpr *f) { if (!parse_block(p, &f->body, PARSE_BLOCK_DONT_CREATE_IDENTS)) success = false; ret: - f->body.flags |= BLOCK_IS_FN; + f->body.kind = BLOCK_FN; p->block = prev_block; return success; } @@ -1378,7 +1379,7 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { return false; } if (!parse_block(p, &w->body, 0)) return false; - w->body.flags |= BLOCK_IS_LOOP; + w->body.kind = BLOCK_WHILE; goto success; } case KW_FOR: { @@ -1492,7 +1493,7 @@ static Status parse_expr(Parser *p, Expression *e, Token *end) { p->block = prev_block; if (!parse_block(p, &fo->body, PARSE_BLOCK_DONT_CREATE_IDENTS)) goto for_fail; - fo->body.flags |= BLOCK_IS_LOOP; + fo->body.kind = BLOCK_FOR; goto success; for_fail: p->block = prev_block; @@ -2453,7 +2454,7 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { e->where = s->where; e->nms->associated_ident = ident; Block *body = &e->nms->body; - body->flags |= BLOCK_IS_NMS; + body->kind = BLOCK_NMS; body->where = s->where; body->parent = p->block; idents_create(&body->idents, p->allocr, body); diff --git a/types.c b/types.c index 5e1092f..93e0c24 100644 --- a/types.c +++ b/types.c @@ -613,13 +613,14 @@ static Status type_of_ident(Typer *tr, Location where, Identifier *ident, Type * switch (i->decl_kind) { case IDECL_DECL: { Declaration *d = i->decl; + /* check for trying to capture a variable into a function */ bool captured = false; - if (ident_scope(i) != NULL && !(ident_scope(i)->flags & BLOCK_IS_NMS)) { + if (ident_scope(i) != NULL && ident_scope(i)->kind != BLOCK_NMS) { Block *decl_scope = ident_scope(i); - if (!(decl_scope->flags & BLOCK_IS_NMS)) { + if (decl_scope->kind != BLOCK_NMS) { /* go back through scopes */ for (Block **block = arr_last(tr->blocks); *block && *block != decl_scope; --block) { - if ((*block)->flags & BLOCK_IS_FN) { + if ((*block)->kind == BLOCK_FN) { captured = true; break; } @@ -3100,11 +3101,11 @@ static Status types_expr(Typer *tr, Expression *e) { Namespace *prev_nms = tr->nms; Namespace *n = tr->nms = e->nms; n->points_to = NULL; - n->body.flags |= BLOCK_IS_NMS; if (!types_block(tr, &n->body)) { tr->nms = prev_nms; return false; } + n->body.kind = BLOCK_NMS; tr->nms = prev_nms; n->associated_ident = NULL; /* set when we type the declaration which contains this namespace */ t->kind = TYPE_BUILTIN; @@ -3218,8 +3219,7 @@ static Status types_decl(Typer *tr, Declaration *d) { d->type = d->expr.type; d->type.flags &= (TypeFlags)~(TypeFlags)TYPE_IS_FLEXIBLE; /* x := 5; => x is not flexible */ } - bool need_value = (d->flags & DECL_IS_CONST) || - ((tr->block == NULL || (tr->block->flags & BLOCK_IS_NMS)) && tr->fn == NULL); + bool need_value = (d->flags & DECL_IS_CONST) || tr->fn == NULL; if (need_value) { if (!(d->flags & DECL_FOUND_VAL)) { @@ -3299,7 +3299,7 @@ static Status types_decl(Typer *tr, Declaration *d) { bool is_at_top_level = true; typedef Block *BlockPtr; arr_foreach(tr->blocks, BlockPtr, b) { - if (*b && !((*b)->flags & BLOCK_IS_NMS)) { + if (*b && (*b)->kind != BLOCK_NMS) { is_at_top_level = false; break; } @@ -3476,7 +3476,7 @@ static Status types_stmt(Typer *tr, Statement *s) { /* make sure we are actually in a loop */ Block *block; for (block = tr->block; block; block = block->parent) { - if (block->flags & BLOCK_IS_LOOP) { + if (block->kind == BLOCK_FOR || block->kind == BLOCK_WHILE) { s->referring_to = block; break; } @@ -3512,9 +3512,8 @@ static Status types_stmt(Typer *tr, Statement *s) { err_print(e->where, "You can't use this value. You should probably assign it to a variable."); return false; } - UsedExpr *u = arr_add(&tr->used); - u->scope = tr->block; - u->stmt = s; + Statement **sp = arr_add(&tr->block->used); + *sp = s; } break; } s->flags |= STMT_TYPED; @@ -3522,7 +3521,6 @@ static Status types_stmt(Typer *tr, Statement *s) { } static void typer_create(Typer *tr, Evaluator *ev, File *file, ErrCtx *err_ctx, Allocator *allocr, Identifiers *idents) { - tr->used = NULL; tr->block = NULL; tr->blocks = NULL; tr->fn = NULL; diff --git a/types.h b/types.h index 9960599..db1534f 100644 --- a/types.h +++ b/types.h @@ -488,15 +488,21 @@ typedef struct Field { enum { - BLOCK_IS_FN = 0x01, - BLOCK_IS_NMS = 0x02, - BLOCK_FINDING_TYPES = 0x04, - BLOCK_FOUND_TYPES = 0x08, - BLOCK_IS_LOOP = 0x10 /* can we break/continue in this block? */ + BLOCK_FINDING_TYPES = 0x01, + BLOCK_FOUND_TYPES = 0x02, }; +typedef enum { + BLOCK_OTHER, + BLOCK_FN, + BLOCK_NMS, + BLOCK_FOR, + BLOCK_WHILE +} BlockKind; + typedef U8 BlockFlags; typedef struct Block { BlockFlags flags; + BlockKind kind; struct { IdentID break_lbl, cont_lbl; /* initially 0, set to non-zero values if needed (++g->lbl_counter); set by sdecls_cgen. */ } c; @@ -506,6 +512,7 @@ typedef struct Block { struct Expression *ret_expr; /* the return expression of this block, e.g. {foo(); 3} => 3 NULL for no expression. */ struct Block *parent; struct Statement **deferred; /* deferred stuff from this block; used by both eval and cgen */ + struct Statement **used; /* use statements (for types.c) */ } Block; enum { @@ -1038,16 +1045,6 @@ typedef struct Evaluator { ForeignFnManager ffmgr; } Evaluator; -/* -Keeps track of use stmts. -We need to keep track of the block so that -it can be removed when we exit the block. -*/ -typedef struct { - Statement *stmt; - Block *scope; -} UsedExpr; - typedef struct Typer { Allocator *allocr; Evaluator *evalr; @@ -1061,7 +1058,6 @@ typedef struct Typer { ParsedFile *parsed_file; Namespace *nms; StrHashTable included_files; /* maps to IncludedFile */ - UsedExpr *used; /* things which are currently being `use`d. dynamic array NOT on the allocator. */ File *file; } Typer; -- cgit v1.2.3