diff options
-rw-r--r-- | cgen.c | 48 | ||||
-rw-r--r-- | copy.c | 24 | ||||
-rw-r--r-- | decls_cgen.c | 49 | ||||
-rw-r--r-- | eval.c | 21 | ||||
-rw-r--r-- | main.c | 2 | ||||
-rw-r--r-- | parse.c | 49 | ||||
-rw-r--r-- | types.c | 94 | ||||
-rw-r--r-- | types.h | 10 |
8 files changed, 143 insertions, 154 deletions
@@ -2061,27 +2061,30 @@ static void cgen_stmt(CGenerator *g, Statement *s) { case STMT_DECL: cgen_decl(g, s->decl); break; - case STMT_EXPR: - if ((g->block != NULL || s->expr.kind == EXPR_C) && !type_is_compileonly(&s->expr.type)) { - cgen_expr_pre(g, &s->expr); - cgen_expr(g, &s->expr); - if (s->expr.kind != EXPR_C) + case STMT_EXPR: { + Expression *e = s->expr; + if ((g->block != NULL || e->kind == EXPR_C) && !type_is_compileonly(&e->type)) { + cgen_expr_pre(g, e); + cgen_expr(g, e); + if (e->kind != EXPR_C) cgen_writeln(g, ";"); } - break; + } break; case STMT_RET: { - unsigned has_expr = s->ret.flags & RET_HAS_EXPR; - cgen_ret(g, s->ret.referring_to, has_expr ? &s->ret.expr : NULL); + Return *r = s->ret; + unsigned has_expr = r->flags & RET_HAS_EXPR; + cgen_ret(g, r->referring_to, has_expr ? &r->expr : NULL); } break; - case STMT_INCLUDE: - if (s->inc.inc_file && (s->inc.inc_file->flags & INC_FILE_CGEND)){ + case STMT_INCLUDE: { + Include *i = s->inc; + if (i->inc_file && (i->inc_file->flags & INC_FILE_CGEND)){ /* already generated */ } else { - if (s->inc.inc_file) s->inc.inc_file->flags |= INC_FILE_CGEND; - arr_foreach(s->inc.stmts, Statement, sub) + if (i->inc_file) i->inc_file->flags |= INC_FILE_CGEND; + arr_foreach(i->stmts, Statement, sub) cgen_stmt(g, sub); } - break; + } break; case STMT_BREAK: { Block *b = s->referring_to; cgen_deferred_up_to(g, b); @@ -2141,21 +2144,22 @@ static void cgen_defs_stmt(CGenerator *g, Statement *s) { cgen_defs_decl(g, s->decl); break; case STMT_EXPR: - cgen_defs_expr(g, &s->expr); + cgen_defs_expr(g, s->expr); break; case STMT_RET: - if (s->ret.flags & RET_HAS_EXPR) - cgen_defs_expr(g, &s->ret.expr); + if (s->ret->flags & RET_HAS_EXPR) + cgen_defs_expr(g, &s->ret->expr); break; - case STMT_INCLUDE: - if (s->inc.inc_file && (s->inc.inc_file->flags & INC_FILE_CGEND_DEFS)) { + case STMT_INCLUDE: { + Include *i = s->inc; + if (i->inc_file && (i->inc_file->flags & INC_FILE_CGEND_DEFS)) { /* already generated */ } else { - if (s->inc.inc_file) s->inc.inc_file->flags |= INC_FILE_CGEND_DEFS; - arr_foreach(s->inc.stmts, Statement, sub) + if (i->inc_file) i->inc_file->flags |= INC_FILE_CGEND_DEFS; + arr_foreach(i->stmts, Statement, sub) cgen_defs_stmt(g, sub); } - break; + } break; case STMT_BREAK: case STMT_CONT: case STMT_MESSAGE: @@ -2164,7 +2168,7 @@ static void cgen_defs_stmt(CGenerator *g, Statement *s) { cgen_defs_stmt(g, s->defer); break; case STMT_USE: - cgen_defs_expr(g, &s->use); + cgen_defs_expr(g, s->use); break; } } @@ -405,28 +405,34 @@ static void copy_stmt(Copier *c, Statement *out, Statement *in) { *out = *in; switch (in->kind) { case STMT_RET: - if (in->ret.flags & RET_HAS_EXPR) - copy_expr(c, &out->ret.expr, &in->ret.expr); + out->ret = copier_malloc(c, sizeof *out->ret); + *out->ret = *in->ret; + if (in->ret->flags & RET_HAS_EXPR) + copy_expr(c, &out->ret->expr, &in->ret->expr); break; case STMT_INCLUDE: + out->inc = copier_malloc(c, sizeof *out->inc); + *out->inc = *in->inc; if (in->flags & STMT_TYPED) { - size_t nstmts = arr_len(in->inc.stmts); - arr_set_lena(&out->inc.stmts, nstmts, c->allocr); + size_t nstmts = arr_len(in->inc->stmts); + arr_set_lena(&out->inc->stmts, nstmts, c->allocr); for (size_t i = 0; i < nstmts; ++i) { - copy_stmt(c, &out->inc.stmts[i], &in->inc.stmts[i]); + copy_stmt(c, &out->inc->stmts[i], &in->inc->stmts[i]); } } else { - copy_expr(c, &out->inc.filename, &in->inc.filename); + copy_expr(c, &out->inc->filename, &in->inc->filename); } break; case STMT_EXPR: - copy_expr(c, &out->expr, &in->expr); + out->expr = copy_expr_(c, in->expr); break; case STMT_DECL: copy_decl(c, out->decl = allocr_malloc(c->allocr, sizeof *out->decl), in->decl); break; case STMT_MESSAGE: - copy_expr(c, &out->message.text, &in->message.text); + out->message = copier_malloc(c, sizeof *out->message); + *out->message = *in->message; + copy_expr(c, &out->message->text, &in->message->text); break; case STMT_DEFER: copy_stmt(c, out->defer = allocr_malloc(c->allocr, sizeof *out->defer), in->defer); @@ -435,7 +441,7 @@ static void copy_stmt(Copier *c, Statement *out, Statement *in) { case STMT_CONT: break; case STMT_USE: - copy_expr(c, &out->use, &in->use); + out->use = copy_expr_(c, in->use); break; } } diff --git a/decls_cgen.c b/decls_cgen.c index 46db767..1cb5393 100644 --- a/decls_cgen.c +++ b/decls_cgen.c @@ -131,22 +131,23 @@ static void cgen_sdecls_stmt(CGenerator *g, Statement *s) { cgen_sdecls_decl(g, s->decl); break; case STMT_EXPR: - cgen_sdecls_expr(g, &s->expr); + cgen_sdecls_expr(g, s->expr); break; - case STMT_RET: - if (s->ret.flags & RET_HAS_EXPR) - cgen_sdecls_expr(g, &s->ret.expr); - break; - case STMT_INCLUDE: - - if (s->inc.inc_file && (s->inc.inc_file->flags & INC_FILE_CGEND_SDECLS)) { + case STMT_RET: { + Return *r = s->ret; + if (r->flags & RET_HAS_EXPR) + cgen_sdecls_expr(g, &r->expr); + } break; + case STMT_INCLUDE: { + Include *i = s->inc; + if (i->inc_file && (i->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) + if (i->inc_file) i->inc_file->flags |= INC_FILE_CGEND_SDECLS; + arr_foreach(i->stmts, Statement, sub) cgen_sdecls_stmt(g, sub); } - break; + } break; case STMT_BREAK: if (!s->referring_to->c.break_lbl) { s->referring_to->c.break_lbl = ++g->lbl_counter; @@ -163,7 +164,7 @@ static void cgen_sdecls_stmt(CGenerator *g, Statement *s) { cgen_sdecls_stmt(g, s->defer); break; case STMT_USE: - cgen_sdecls_expr(g, &s->use); + cgen_sdecls_expr(g, s->use); break; } } @@ -372,21 +373,23 @@ static void cgen_decls_stmt(CGenerator *g, Statement *s) { cgen_decls_decl(g, s->decl); break; case STMT_EXPR: - cgen_decls_expr(g, &s->expr); + cgen_decls_expr(g, s->expr); break; - case STMT_RET: - if (s->ret.flags & RET_HAS_EXPR) - cgen_decls_expr(g, &s->ret.expr); - break; - case STMT_INCLUDE: - if (s->inc.inc_file && (s->inc.inc_file->flags & INC_FILE_CGEND_DECLS)) { + case STMT_RET: { + Return *r = s->ret; + if (r->flags & RET_HAS_EXPR) + cgen_decls_expr(g, &r->expr); + } break; + case STMT_INCLUDE: { + Include *i = s->inc; + if (i->inc_file && (i->inc_file->flags & INC_FILE_CGEND_DECLS)) { /* already generated */ } else { - if (s->inc.inc_file) s->inc.inc_file->flags |= INC_FILE_CGEND_DECLS; - arr_foreach(s->inc.stmts, Statement, sub) + if (i->inc_file) i->inc_file->flags |= INC_FILE_CGEND_DECLS; + arr_foreach(i->stmts, Statement, sub) cgen_decls_stmt(g, sub); } - break; + } break; case STMT_BREAK: case STMT_CONT: case STMT_MESSAGE: @@ -395,7 +398,7 @@ static void cgen_decls_stmt(CGenerator *g, Statement *s) { cgen_decls_stmt(g, s->defer); break; case STMT_USE: - cgen_sdecls_expr(g, &s->use); + cgen_sdecls_expr(g, s->use); break; } } @@ -1673,17 +1673,19 @@ static Status eval_stmt(Evaluator *ev, Statement *stmt) { break; case STMT_EXPR: { Value unused; - if (!eval_expr(ev, &stmt->expr, &unused)) + if (!eval_expr(ev, stmt->expr, &unused)) return false; } break; case STMT_RET: { - if (stmt->ret.flags & RET_HAS_EXPR) { - Value r; - if (!eval_expr(ev, &stmt->ret.expr, &r)) + Return *r = stmt->ret; + + if (r->flags & RET_HAS_EXPR) { + Value v; + if (!eval_expr(ev, &r->expr, &v)) return false; - copy_val(NULL, &ev->ret_val, r, &stmt->ret.expr.type); + copy_val(NULL, &ev->ret_val, v, &r->expr.type); } - ev->returning = stmt->ret.referring_to; + ev->returning = r->referring_to; } break; case STMT_BREAK: ev->returning = stmt->referring_to; @@ -1694,8 +1696,9 @@ static Status eval_stmt(Evaluator *ev, Statement *stmt) { ev->is_break = false; break; case STMT_INCLUDE: { - Statement *last_reached = arr_last(stmt->inc.stmts); - arr_foreach(stmt->inc.stmts, Statement, sub) { + Include *i = stmt->inc; + Statement *last_reached = arr_last(i->stmts); + arr_foreach(i->stmts, Statement, sub) { if (!eval_stmt(ev, sub)) return false; if (ev->returning) { @@ -1703,7 +1706,7 @@ static Status eval_stmt(Evaluator *ev, Statement *stmt) { break; } } - eval_exit_stmts(stmt->inc.stmts, last_reached); + eval_exit_stmts(i->stmts, last_reached); } break; case STMT_MESSAGE: break; @@ -8,8 +8,8 @@ /* TODO: -all big Statement members should be pointers use + - note: just keep an array of useds on the block - use with a decl, e.g. use p : Point; local structs should not be named in C simplify eval macros with val_to_u/i64 @@ -2343,13 +2343,14 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { case KW_RETURN: { s->kind = STMT_RET; ++t->token; - s->ret.flags = 0; + Return *r = s->ret = parser_malloc(p, sizeof *r); + r->flags = 0; if (token_is_kw(t->token, KW_SEMICOLON)) { /* return with no expr */ ++t->token; goto success; } - s->ret.flags |= RET_HAS_EXPR; + r->flags |= RET_HAS_EXPR; Token *end = expr_find_end(p, 0); if (!end) { while (t->token->kind != TOKEN_EOF) ++t->token; /* move to end of file */ @@ -2360,7 +2361,7 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { t->token = end->kind == TOKEN_EOF ? end : end + 1; return false; } - bool parsed = parse_expr(p, &s->ret.expr, end); + bool parsed = parse_expr(p, &r->expr, end); t->token = end + 1; if (!parsed) return false; goto success; @@ -2403,7 +2404,7 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { case KW_USE: { ++t->token; s->kind = STMT_USE; - if (!parse_expr(p, &s->use, expr_find_end(p, 0))) + if (!parse_expr(p, s->use = parser_malloc(p, sizeof *s->use), expr_find_end(p, 0))) return false; goto success; } @@ -2412,17 +2413,18 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { } else if (t->token->kind == TOKEN_DIRECT) { switch (t->token->direct) { case DIRECT_INCLUDE: { + Include *i = s->inc = parser_malloc(p, sizeof *i); ++t->token; s->kind = STMT_INCLUDE; - s->inc.flags = 0; + i->flags = 0; if (token_is_direct(t->token, DIRECT_FORCE)) { - s->inc.flags |= INC_FORCED; + i->flags |= INC_FORCED; ++t->token; } - if (!parse_expr(p, &s->inc.filename, expr_find_end(p, EXPR_CAN_END_WITH_COMMA))) + if (!parse_expr(p, &i->filename, expr_find_end(p, EXPR_CAN_END_WITH_COMMA))) return false; if (token_is_kw(t->token, KW_COMMA)) { - Expression filename = s->inc.filename; + Expression filename = i->filename; ++t->token; if (t->token->kind != TOKEN_IDENT) { tokr_err(t, "Expected identifier for #include name (after comma)."); @@ -2461,7 +2463,8 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { inc_stmt->kind = STMT_INCLUDE; inc_stmt->flags = STMT_INC_TO_NMS; inc_stmt->where = s->where; - inc_stmt->inc.filename = filename; + inc_stmt->inc = parser_calloc(p, 1, sizeof *inc_stmt->inc); + inc_stmt->inc->filename = filename; } if (!token_is_kw(t->token, KW_SEMICOLON)) { tokr_err(t, "Expected ; after #include directive"); @@ -2484,7 +2487,7 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { } ++t->token; s->kind = STMT_MESSAGE; - Message *m = &s->message; + Message *m = s->message = parser_malloc(p, sizeof *m); m->kind = kind; if (!parse_expr(p, &m->text, expr_find_end(p, 0))) { tokr_skip_semicolon(t); @@ -2514,7 +2517,7 @@ static Status parse_stmt(Parser *p, Statement *s, bool *was_a_statement) { tokr_skip_to_eof(t); return false; } - bool valid = parse_expr(p, &s->expr, end); + bool valid = parse_expr(p, s->expr = parser_malloc(p, sizeof *s->expr), end); /* go past end of expr regardless of whether successful or not */ if (token_is_kw(end, KW_SEMICOLON)) { @@ -2852,27 +2855,29 @@ static void fprint_stmt(FILE *out, Statement *s) { fprintf(out, ";\n"); break; case STMT_EXPR: - fprint_expr(out, &s->expr); + fprint_expr(out, s->expr); fprintf(out, ";\n"); break; - case STMT_RET: + case STMT_RET: { + Return *r = s->ret; fprintf(out, "return "); - if (s->ret.flags & RET_HAS_EXPR) - fprint_expr(out, &s->ret.expr); + if (r->flags & RET_HAS_EXPR) + fprint_expr(out, &r->expr); fprintf(out, ";\n"); - break; - case STMT_INCLUDE: + } break; + case STMT_INCLUDE: { + Include *i = s->inc; if (s->flags & STMT_TYPED) { - arr_foreach(s->inc.stmts, Statement, sub) + arr_foreach(i->stmts, Statement, sub) fprint_stmt(out, sub); } else { fprintf(out, "#include "); - fprint_expr(out, &s->inc.filename); + fprint_expr(out, &i->filename); fprintf(out, ";\n"); } - break; + } break; case STMT_MESSAGE: { - Message *m = &s->message; + Message *m = s->message; switch (m->kind) { case MESSAGE_ERROR: fprintf(out, "#error "); @@ -2897,7 +2902,7 @@ static void fprint_stmt(FILE *out, Statement *s) { break; case STMT_USE: fprintf(out, "use "); - fprint_expr(out, &s->use); + fprint_expr(out, s->use); break; } } @@ -581,48 +581,12 @@ static Status type_of_ident(Typer *tr, Location where, Identifier *ident, Type * Identifier i = *ident; Block *b = tr->block; bool undeclared = false; - UsedExpr *used = arr_last(tr->used); while (1) { /* for each block we are inside... */ /* OPTIM: only hash once */ Identifier translated = ident_translate(i, b ? &b->idents : tr->globals); if (translated && translated->decl_kind == IDECL_NONE) translated = NULL; - Statement *translated_is_from_use_stmt = NULL; - while (used && used->scope == b) { - /* look up identifier in this used thing. */ - Statement *stmt = used->stmt; - Expression *expr = &stmt->use; - Type *type = &expr->type; - if (type->kind == TYPE_STRUCT) { - /* TODO */ - } else { - assert(type_is_builtin(type, BUILTIN_NMS)); - assert(expr->kind == EXPR_VAL); - Identifier nms_ident = ident_translate(i, &expr->val.nms->body.idents); - if (nms_ident && nms_ident->decl_kind != IDECL_NONE) { - if (translated) { - /* ambiguous ident reference */ - char *s = ident_to_str(nms_ident); - err_print(where, "Ambiguous reference to identifier %s.", s); - info_print(stmt->where, "%s was imported from this use statement.", s); - info_print(ident_decl_location(tr->file, nms_ident), "Specifically, it was declared here."); - /* - we should have given an error about the use statement if it conflicted with a non-used ident, - so translated must be from another use stmt. - */ - assert(translated_is_from_use_stmt); - info_print(translated_is_from_use_stmt->where, "...and also imported from *this* use statement."); - info_print(ident_decl_location(tr->file, translated), "Specifically, it was also declared here."); - } - translated = nms_ident; - translated_is_from_use_stmt = stmt; - } - } - if (used > tr->used) - --used; - else - used = NULL; - } + /* TODO: use */ if (translated) { #if 0 printf("translated %s from\n", ident_to_str(i)); @@ -759,8 +723,8 @@ static Status type_of_ident(Typer *tr, Location where, Identifier *ident, Type * static Status add_block_to_struct(Typer *tr, Block *b, StructDef *s, Statement **new_stmts) { arr_foreach(b->stmts, Statement, stmt) { if (stmt->kind == STMT_EXPR) { - if (stmt->expr.kind == EXPR_BLOCK) { - if (!add_block_to_struct(tr, stmt->expr.block, s, new_stmts)) + if (stmt->expr->kind == EXPR_BLOCK) { + if (!add_block_to_struct(tr, stmt->expr->block, s, new_stmts)) return false; continue; } @@ -1719,8 +1683,9 @@ static Status types_expr(Typer *tr, Expression *e) { /* create sub-block #i */ memset(stmt, 0, sizeof *stmt); stmt->kind = STMT_EXPR; - stmt->expr.kind = EXPR_BLOCK; - Block *sub = stmt->expr.block = typer_calloc(tr, 1, sizeof *sub); + stmt->expr = typer_calloc(tr, 1, sizeof *stmt->expr); + stmt->expr->kind = EXPR_BLOCK; + Block *sub = stmt->expr->block = typer_calloc(tr, 1, sizeof *sub); sub->parent = b; idents_create(&sub->idents, tr->allocr, sub); sub->stmts = NULL; @@ -3175,7 +3140,7 @@ static Status types_block(Typer *tr, Block *b) { } if (s->kind == STMT_EXPR && (s->flags & STMT_EXPR_NO_SEMICOLON)) { /* not voided */ - Expression *e = &s->expr; + Expression *e = s->expr; if (e->type.kind == TYPE_VOID) { if (!(e->kind == EXPR_BLOCK || e->kind == EXPR_IF @@ -3374,17 +3339,18 @@ static bool expr_is_usable(Expression *e) { static Status types_stmt(Typer *tr, Statement *s) { if (s->flags & STMT_TYPED) return true; switch (s->kind) { - case STMT_EXPR: - if (!types_expr(tr, &s->expr)) { + case STMT_EXPR: { + Expression *e = s->expr; + if (!types_expr(tr, e)) { return false; } if (!(s->flags & STMT_EXPR_NO_SEMICOLON)) { - if (s->expr.kind == EXPR_TUPLE) { + if (e->kind == EXPR_TUPLE) { err_print(s->where, "Statement of a tuple is not allowed. Use a semicolon instead of a comma here."); return false; } - Type *t = &s->expr.type; + Type *t = &e->type; if (type_is_compileonly(t)) { char *str = type_to_str(t); warn_print(s->where, "This expression has a compile-only type (%s), so this statement will not actually be outputted in C code.", str); @@ -3393,24 +3359,25 @@ static Status types_stmt(Typer *tr, Statement *s) { } if (tr->block == NULL) { /* evaluate expression statements at global scope */ - if (s->expr.kind != EXPR_C) { + if (e->kind != EXPR_C) { if (!eval_stmt(tr->evalr, s)) return false; } } - break; + } break; case STMT_DECL: if (!types_decl(tr, s->decl)) { return false; } break; - case STMT_RET: + case STMT_RET: { + Return *r = s->ret; if (!tr->fn) { err_print(s->where, "return outside of a function."); return false; } - s->ret.referring_to = &tr->fn->body; - if (s->ret.flags & RET_HAS_EXPR) { + r->referring_to = &tr->fn->body; + if (r->flags & RET_HAS_EXPR) { if (tr->fn->ret_type.kind == TYPE_VOID) { err_print(s->where, "Return value in a void function."); return false; @@ -3419,10 +3386,10 @@ static Status types_stmt(Typer *tr, Statement *s) { err_print(s->where, "Return expression in a function with named return values."); return false; } - if (!types_expr(tr, &s->ret.expr)) + if (!types_expr(tr, &r->expr)) return false; - if (!type_eq(&tr->fn->ret_type, &s->ret.expr.type)) { - char *got = type_to_str(&s->ret.expr.type); + if (!type_eq(&tr->fn->ret_type, &r->expr.type)) { + char *got = type_to_str(&r->expr.type); char *expected = type_to_str(&tr->fn->ret_type); err_print(s->where, "Returning type %s in function which returns %s.", got, expected); return false; @@ -3434,26 +3401,27 @@ static Status types_stmt(Typer *tr, Statement *s) { return false; } } - break; + } break; case STMT_INCLUDE: { - char *filename = eval_expr_as_cstr(tr, &s->inc.filename, "import filename"); + Include *inc = s->inc; + char *filename = eval_expr_as_cstr(tr, &inc->filename, "import filename"); if (!filename) return false; size_t filename_len = strlen(filename); IncludedFile *inc_f = NULL; if (s->flags & STMT_INC_TO_NMS) { - if (!(s->inc.flags & INC_FORCED)) { + if (!(inc->flags & INC_FORCED)) { inc_f = str_hash_table_get(&tr->included_files, filename, filename_len); if (inc_f) { tr->nms->body.idents = inc_f->main_nms->body.idents; tr->nms->body.idents.scope = &tr->nms->body; tr->nms->points_to = inc_f->main_nms; - s->inc.inc_file = inc_f; - s->inc.stmts = inc_f->stmts; + inc->inc_file = inc_f; + inc->stmts = inc_f->stmts; break; } } - s->inc.inc_file = inc_f = str_hash_table_insert(&tr->included_files, filename, filename_len); + inc->inc_file = inc_f = str_hash_table_insert(&tr->included_files, filename, filename_len); inc_f->main_nms = tr->nms; } char *contents = read_file_contents(tr->allocr, filename, s->where); @@ -3479,7 +3447,7 @@ static Status types_stmt(Typer *tr, Statement *s) { if (inc_f) { inc_f->stmts = stmts_inc; } - s->inc.stmts = stmts_inc; + inc->stmts = stmts_inc; arr_foreach(stmts_inc, Statement, s_incd) { if (!types_stmt(tr, s_incd)) return false; @@ -3487,7 +3455,7 @@ static Status types_stmt(Typer *tr, Statement *s) { } break; case STMT_MESSAGE: { - Message *m = &s->message; + Message *m = s->message; char *text = eval_expr_as_cstr(tr, &m->text, "message"); if (!text) return false; @@ -3531,7 +3499,7 @@ static Status types_stmt(Typer *tr, Statement *s) { } break; case STMT_USE: { - Expression *e = &s->use; + Expression *e = s->use; if (!types_expr(tr, e)) return false; if (e->type.kind != TYPE_STRUCT && !type_is_builtin(&e->type, BUILTIN_NMS)) { @@ -983,13 +983,13 @@ typedef struct Statement { U8 flags; union { Declaration *decl; /* we want the pointer to be fixed so that we can refer to it from an identifier */ - Expression expr; - Return ret; - Include inc; - Message message; /* #error, #warn, #info */ + Expression *expr; + Return *ret; + Include *inc; + Message *message; /* #error, #warn, #info */ Block *referring_to; /* for break/continue; set during typing */ struct Statement *defer; - Expression use; + Expression *use; }; } Statement; |