diff --git a/lang/README.md b/lang/README.md index e451902..dfe7bf9 100644 --- a/lang/README.md +++ b/lang/README.md @@ -527,6 +527,14 @@ main := fn(): uint { ### Purely Testing Examples +#### reading_idk +```hb +main := fn(): int { + a := @as(int, idk) + return a +} +``` + #### nonexistent_ident_import ```hb main := @use("foo.hb").main diff --git a/lang/src/son.rs b/lang/src/son.rs index cb174f1..d6a08f1 100644 --- a/lang/src/son.rs +++ b/lang/src/son.rs @@ -692,7 +692,6 @@ impl Nodes { Kind::Load => write!(out, "load: "), Kind::Stre => write!(out, "stre: "), Kind::Mem => write!(out, " mem: "), - Kind::Idk => write!(out, " idk: "), Kind::Extend => write!(out, " ext: "), }?; @@ -1062,8 +1061,6 @@ pub enum Kind { args: ty::Tuple, }, // [ctrl] - Idk, - // [ctrl] Stck, // [ctrl, memory] Load, @@ -1661,7 +1658,6 @@ impl ItemCtx { let offset = fuc.nodes[nid].offset; self.emit(instrs::addi64(atr(allocs[0]), base, offset as _)); } - Kind::Idk => {} Kind::Load => { let mut region = node.inputs[1]; let mut offset = 0; @@ -2168,7 +2164,15 @@ impl<'a> Codegen<'a> { let stck = self.ci.nodes.new_node(ty, Kind::Stck, [VOID, MEM]); Some(Value::ptr(stck).ty(ty)) } else { - Some(self.ci.nodes.new_node_lit(ty, Kind::Idk, [VOID])) + self.report( + pos, + fa!( + "type '{}' cannot be uninitialized, use a zero \ + value instead ('@bitcast(0)' in case of pointers)", + self.ty_display(ty) + ), + ); + Value::NEVER } } Expr::Bool { value, .. } => Some(self.ci.nodes.new_node_lit( @@ -2376,6 +2380,7 @@ impl<'a> Codegen<'a> { } Expr::BinOp { left, op: TokenKind::Decl, right, .. } => { let mut right = self.expr(right)?; + if right.ty.loc(self.tys) == Loc::Stack { let stck = self.ci.nodes.new_node_nop(right.ty, Kind::Stck, [VOID, MEM]); self.store_mem(stck, right.ty, right.id); @@ -2417,9 +2422,7 @@ impl<'a> Codegen<'a> { match lhs.ty.expand() { _ if lhs.ty.is_pointer() || lhs.ty.is_integer() || lhs.ty == ty::Id::BOOL => { - if mem::take(&mut lhs.ptr) { - lhs.id = self.load_mem(lhs.id, lhs.ty); - } + self.strip_ptr(&mut lhs); self.ci.nodes.lock(lhs.id); let rhs = self.expr_ctx(right, Ctx::default().with_ty(lhs.ty)); self.ci.nodes.unlock(lhs.id); @@ -3400,12 +3403,20 @@ impl<'a> Codegen<'a> { fn expr_ctx(&mut self, expr: &Expr, ctx: Ctx) -> Option { let mut n = self.raw_expr_ctx(expr, ctx)?; self.strip_var(&mut n); - if mem::take(&mut n.ptr) { - n.id = self.load_mem(n.id, n.ty); - } + self.strip_ptr(&mut n); Some(n) } + fn expr(&mut self, expr: &Expr) -> Option { + self.expr_ctx(expr, Default::default()) + } + + fn strip_ptr(&mut self, target: &mut Value) { + if mem::take(&mut target.ptr) { + target.id = self.load_mem(target.id, target.ty); + } + } + fn offset(&mut self, val: Nid, off: Offset) -> Nid { if off == 0 { return val; @@ -3424,10 +3435,6 @@ impl<'a> Codegen<'a> { } } - fn expr(&mut self, expr: &Expr) -> Option { - self.expr_ctx(expr, Default::default()) - } - fn jump_to(&mut self, pos: Pos, id: usize) -> Option { let Some(mut loob) = self.ci.loops.last_mut() else { self.report(pos, "break outside a loop"); @@ -3574,9 +3581,7 @@ impl<'a> Codegen<'a> { }; if let Some(oper) = to_correct { - if mem::take(&mut oper.ptr) { - oper.id = self.load_mem(oper.id, oper.ty); - } + self.strip_ptr(oper); oper.ty = upcasted; oper.id = self.ci.nodes.new_node(upcasted, Kind::Extend, [VOID, oper.id]); if matches!(op, TokenKind::Add | TokenKind::Sub) @@ -3625,9 +3630,7 @@ impl<'a> Codegen<'a> { self.ty_display(src.ty), self.ty_display(upcasted) ); - if mem::take(&mut src.ptr) { - src.id = self.load_mem(src.id, src.ty); - } + self.strip_ptr(src); src.ty = upcasted; src.id = self.ci.nodes.new_node(upcasted, Kind::Extend, [VOID, src.id]); } @@ -4133,10 +4136,6 @@ impl<'a> Function<'a> { let ops = vec![self.drg(nid)]; self.add_instr(nid, ops); } - Kind::Idk => { - let ops = vec![self.drg(nid)]; - self.add_instr(nid, ops); - } Kind::Phi | Kind::Arg | Kind::Mem => {} Kind::Load { .. } if node.ty.loc(self.tys) == Loc::Stack => { self.nodes.lock(nid) @@ -4764,6 +4763,7 @@ mod tests { fb_driver; // Purely Testing Examples; + reading_idk; nonexistent_ident_import; big_array_crash; returning_global_struct; diff --git a/lang/tests/son_tests_reading_idk.txt b/lang/tests/son_tests_reading_idk.txt new file mode 100644 index 0000000..66b3f42 --- /dev/null +++ b/lang/tests/son_tests_reading_idk.txt @@ -0,0 +1,3 @@ +test.hb:3:16: type 'int' cannot be uninitialized, use a zero value instead ('@bitcast(0)' in case of pointers) + a := @as(int, idk) + ^