summaryrefslogtreecommitdiff
path: root/ir.c
diff options
context:
space:
mode:
authorWormHeamer2025-08-10 02:46:50 -0400
committerWormHeamer2025-08-10 02:46:50 -0400
commitd4c768a481b923d407201c25d3d750040b6ccd44 (patch)
tree16dd697288846b8effd1f18a3e23187654710e02 /ir.c
parent1c4efc8009292b6f8d6079f87645e8eb65e85f3e (diff)
add type-specifiers to let, N_UNINIT for uninitialized values
Diffstat (limited to 'ir.c')
-rw-r--r--ir.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/ir.c b/ir.c
index 6e91faa..125e882 100644
--- a/ir.c
+++ b/ir.c
@@ -122,7 +122,6 @@ Node *node_new_empty(Proc *p, NodeType t) {
return n;
}
-int type_check(Node *);
Node *node_newv(Proc *p, NodeType t, Node *ctrl, ...) {
Node *node = node_new_empty(p, t);
va_list ap;
@@ -317,7 +316,13 @@ void type_err(Node *n, Lexer *l) {
lex_error_at(l, n->src_pos, LE_ERROR, str_fmt(&l->arena, "type error %s (%S)", node_type_name(n->op), s));
}
-int type_check(Node *n) {
+void type_expected(Type *want, Node *n, Lexer *l) {
+ if (type_base_eql(want, &n->type)) return;
+ lex_error_at(l, n->src_pos, LE_ERROR, str_fmt(&l->arena, "type error: expected %S, but got %S",
+ type_desc(want, &l->arena), type_desc(&n->type, &l->arena)));
+}
+
+static int type_ok(Node *n) {
switch (n->op) {
case N_PHI:
n->type = (Type) { .lvl = T_TOP, .t = IN(n, 1)->type.t };
@@ -355,3 +360,14 @@ int type_check(Node *n) {
return 1;
}
}
+
+void type_check(Node *n, Lexer *l) {
+ for (int i = 0; i < n->in.len; i++) {
+ if (IN(n,i) && IN(n,i)->op == N_UNINIT) {
+ lex_error_at(l, n->src_pos, LE_ERROR,
+ str_fmt(&l->arena, "attempt to use uninitialized %S value",
+ type_desc(&IN(n,i)->type, &l->arena)));
+ }
+ }
+ if (!type_ok(n)) type_err(n, l);
+}