properly type checking, null checks are fixed

Signed-off-by: Jakub Doka <jakub.doka2@gmail.com>
This commit is contained in:
Jakub Doka 2024-12-16 23:32:08 +01:00
parent 1ca9529302
commit e65c72e19f
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
2 changed files with 29 additions and 26 deletions

View file

@ -937,8 +937,14 @@ StructB := struct {g: ^uint, c: StructC}
StructC := struct {c: uint}
some_index := fn(): ?uint return 0
heap := [u8].(0, 1, 2)
optionala := fn(): ?StructA {
return .(.(&0, .(1)), &0, 0)
i := some_index()
if i == null die
return .(.(&0, .(1)), &0, heap[i])
}
Struct := struct {inner: uint}

View file

@ -28,11 +28,9 @@ use {
fmt::{self, Debug, Display, Write},
format_args as fa, mem,
ops::{self, Range},
usize,
},
hashbrown::hash_map,
hbbytecode::DisasmError,
std::panic,
};
pub const VOID: Nid = 0;
@ -515,10 +513,6 @@ impl Nodes {
}
cursor = self.idom(cursor, Some(scheds));
}
//if out == 110 && load == 108 {
// panic!("{min} {cursor} {}", antideps[cursor as usize] == load)
//}
break;
}
Kind::Phi => {
@ -3293,9 +3287,7 @@ impl<'a> Codegen<'a> {
}
Expr::BinOp { left, pos, op: TokenKind::Assign, right } => {
let dest = self.raw_expr(left)?;
let mut value = self.expr_ctx(right, Ctx::default().with_ty(dest.ty))?;
self.assert_ty(pos, &mut value, dest.ty, "assignment source");
let value = self.checked_expr(right, dest.ty, "assignment source")?;
if dest.var {
let var = &mut self.ci.scope.vars[(u16::MAX - dest.id) as usize];
@ -3425,13 +3417,12 @@ impl<'a> Codegen<'a> {
bs.ty = base;
}
let mut idx = self.expr_ctx(index, Ctx::default().with_ty(ty::Id::DINT))?;
let idx = self.checked_expr(index, ty::Id::DINT, "subscript")?;
match bs.ty.expand() {
ty::Kind::Slice(s) => {
let elem = self.tys.ins.slices[s].elem;
let size = self.ci.nodes.new_const(ty::Id::INT, self.tys.size_of(elem));
self.assert_ty(index.pos(), &mut idx, ty::Id::DINT, "subscript");
let inps = [VOID, idx.id, size];
let offset = self.ci.nodes.new_node(
ty::Id::INT,
@ -3747,10 +3738,8 @@ impl<'a> Codegen<'a> {
break;
};
let mut value = self.expr_ctx(field, Ctx::default().with_ty(ty))?;
_ = self.assert_ty(field.pos(), &mut value, ty, "tuple field");
let value = self.checked_expr(field, ty, "tuple field")?;
let mem = self.offset(mem, offset);
self.store_mem(mem, ty, value.id);
}
@ -3794,8 +3783,7 @@ impl<'a> Codegen<'a> {
for (field, offset) in
fields.iter().zip((0u32..).step_by(elem_size as usize))
{
let mut value = self.expr_ctx(field, Ctx::default().with_ty(elem))?;
_ = self.assert_ty(field.pos(), &mut value, elem, "array value");
let value = self.checked_expr(field, elem, "array value")?;
let mem = self.offset(mem, offset);
self.store_mem(mem, elem, value.id);
}
@ -3843,8 +3831,7 @@ impl<'a> Codegen<'a> {
let (ty, offset) = (field.ty, 0);
let mut value = self.expr_ctx(&value, Ctx::default().with_ty(ty))?;
self.assert_ty(fpos, &mut value, ty, fa!("field {}", name));
let value = self.checked_expr(&value, ty, fa!("field {}", name))?;
let mem = self.offset(mem, offset);
self.store_mem(mem, ty, value.id);
@ -3877,9 +3864,8 @@ impl<'a> Codegen<'a> {
continue;
}
let mut value =
self.expr_ctx(&field.value, Ctx::default().with_ty(ty))?;
self.assert_ty(field.pos, &mut value, ty, fa!("field {}", field.name));
let value =
self.checked_expr(&field.value, ty, fa!("field {}", field.name))?;
let mem = self.offset(mem, offset);
self.store_mem(mem, ty, value.id);
}
@ -3919,7 +3905,7 @@ impl<'a> Codegen<'a> {
let mut ret = Some(Value::VOID);
for stmt in stmts {
ret = ret.and(self.expr_ctx(stmt, Ctx::default().with_ty(ty::Id::VOID)));
if let Some(mut id) = ret {
if let Some(id) = ret {
if id.ty != ty::Id::VOID {
self.warn(
stmt.pos(),
@ -3931,7 +3917,6 @@ impl<'a> Codegen<'a> {
),
);
}
self.assert_ty(stmt.pos(), &mut id, ty::Id::VOID, "statement");
} else {
break;
}
@ -4235,8 +4220,7 @@ impl<'a> Codegen<'a> {
Expr::Break { pos } => self.jump_to(pos, 1),
Expr::Continue { pos } => self.jump_to(pos, 0),
Expr::If { cond, then, else_, .. } => {
let mut cnd = self.expr_ctx(cond, Ctx::default().with_ty(ty::Id::BOOL))?;
self.assert_ty(cond.pos(), &mut cnd, ty::Id::BOOL, "condition");
let cnd = self.checked_expr(cond, ty::Id::BOOL, "condition")?;
let if_node = self.ci.nodes.new_node(
ty::Id::VOID,
@ -4391,6 +4375,19 @@ impl<'a> Codegen<'a> {
}
}
fn checked_expr(
&mut self,
expr: &Expr,
expected_ty: ty::Id,
hint: impl Display,
) -> Option<Value> {
let mut value = self.raw_expr_ctx(expr, Ctx::default().with_ty(expected_ty))?;
self.strip_var(&mut value);
self.assert_ty(expr.pos(), &mut value, expected_ty, hint);
self.strip_ptr(&mut value);
Some(value)
}
fn gen_field(
&mut self,
ctx: Ctx,