From d4c768a481b923d407201c25d3d750040b6ccd44 Mon Sep 17 00:00:00 2001 From: WormHeamer Date: Sun, 10 Aug 2025 02:46:50 -0400 Subject: add type-specifiers to let, N_UNINIT for uninitialized values --- main.c | 73 ++++++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 44 insertions(+), 29 deletions(-) (limited to 'main.c') diff --git a/main.c b/main.c index 9fba001..ae19e7a 100644 --- a/main.c +++ b/main.c @@ -75,14 +75,50 @@ void parse_return(Lexer *l, Proc *p) { ctrl(p, NULL); } +Type parse_type(Lexer *l, Proc *proc) { + (void)proc; + Type t = { .lvl = T_BOT }; + if (l->tok == TOK_DEREF) { + lex_next(l); + t.t = T_PTR; + t.next = new(&proc->arena, Type); + *t.next = parse_type(l, proc); + return t; + } + lex_expected(l, TM_IDENT); + if (l->tok == TOK_IDENT) { + if (str_eql(l->ident, S("i64"))) { + t.t = T_INT; + } else if (str_eql(l->ident, S("bool"))) { + t.t = T_BOOL; + } else { + lex_error(l, LE_ERROR, S("unknown type")); + } + } + lex_next(l); + return t; +} + void parse_let(Lexer *l, Proc *p) { recurse: lex_expect(l, TM_IDENT); Str name = l->ident; LexSpan pos = l->pos; - lex_expect(l, TM_EQL); lex_next(l); - Node *rhs = parse_expr(l, p); + Node *rhs = NULL; + Type t = { .t = T_NONE }; + if (l->tok != TOK_EQL) { + t = parse_type(l, p); + if (l->tok != TOK_EQL) { + rhs = node_new(p, N_UNINIT, p->start); + rhs->type = t; + } + } + if (l->tok == TOK_EQL) { + lex_next(l); + rhs = parse_expr(l, p); + if (t.t != T_NONE) type_expected(&t, rhs, l); + } NameBinding *b = scope_bind(&p->scope, name, rhs, pos, p); if (b) { lex_error_at(l, pos, LE_WARN, S("shadowing previous declaration")); @@ -125,6 +161,11 @@ void parse_assign(Lexer *l, Proc *p) { type_desc(&e->type, &p->arena), type_desc(&b->node->type, &p->arena))); } + if (e->op == N_UNINIT) { + lex_error_at(l, e->src_pos, LE_ERROR, + str_fmt(&p->arena, "assigning from uninitialized %S value", + type_desc(&e->type, &p->arena))); + } scope_update(b, e, p); } @@ -317,29 +358,6 @@ void parse_stmt(Lexer *l, Proc *p) { } } -Type parse_type(Lexer *l, Proc *proc) { - (void)proc; - Type t = { .lvl = T_BOT }; - if (l->tok == TOK_DEREF) { - lex_next(l); - t.t = T_PTR; - t.next = new(&proc->arena, Type); - *t.next = parse_type(l, proc); - return t; - } - if (l->tok == TOK_IDENT) { - if (str_eql(l->ident, S("i64"))) { - t.t = T_INT; - } else if (str_eql(l->ident, S("bool"))) { - t.t = T_BOOL; - } - } else { - lex_error(l, LE_ERROR, S("unknown type")); - } - lex_next(l); - return t; -} - void parse_args_list(Lexer *l, Proc *proc) { Node *start = proc->start; int i = 0; @@ -390,10 +408,7 @@ void proc_opt_fwd(Proc *p, Lexer *l, Node *n) { switch (n->op) { case N_START: for (int i = 0; i < n->out.len; i++) { - if (!(NMASK(n->out.data[i]->op) & (NM_LIT | NM_PROJ))) { - proc_opt_fwd(p, l, n->out.data[i]); - break; - } + proc_opt_fwd(p, l, n->out.data[i]); } break; case N_IF_ELSE: -- cgit v1.2.3