forked from AbleOS/holey-bytes
properly type checking, null checks are fixed
Signed-off-by: Jakub Doka <jakub.doka2@gmail.com>
This commit is contained in:
parent
1ca9529302
commit
e65c72e19f
|
@ -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}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue