summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorWormHeamer2025-08-10 02:46:50 -0400
committerWormHeamer2025-08-10 02:46:50 -0400
commitd4c768a481b923d407201c25d3d750040b6ccd44 (patch)
tree16dd697288846b8effd1f18a3e23187654710e02 /main.c
parent1c4efc8009292b6f8d6079f87645e8eb65e85f3e (diff)
add type-specifiers to let, N_UNINIT for uninitialized values
Diffstat (limited to 'main.c')
-rw-r--r--main.c73
1 files changed, 44 insertions, 29 deletions
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: