diff --git a/lang/README.md b/lang/README.md index f57453a5..50c0c55a 100644 --- a/lang/README.md +++ b/lang/README.md @@ -212,7 +212,7 @@ use_foo := fn(foo: Foo, str: ^u8): void { Bar := struct {a: ?^uint, b: uint} new_bar := fn(a: ?^uint): ?Bar return .(a, 1) -decide := fn(): bool return true +decide := fn(): bool return !false ``` #### structs diff --git a/lang/src/lexer.rs b/lang/src/lexer.rs index c4bd805d..2cacd5a8 100644 --- a/lang/src/lexer.rs +++ b/lang/src/lexer.rs @@ -263,6 +263,7 @@ impl TokenKind { match self { Self::Sub if float => (-f64::from_bits(value as _)).to_bits() as _, Self::Sub => value.wrapping_neg(), + Self::Not => (value == 0) as _, Self::Float if float => value, Self::Float => (value as f64).to_bits() as _, Self::Number => { diff --git a/lang/src/parser.rs b/lang/src/parser.rs index f65ad9fd..7d8ef97a 100644 --- a/lang/src/parser.rs +++ b/lang/src/parser.rs @@ -459,7 +459,7 @@ impl<'a, 'b> Parser<'a, 'b> { pos }, }, - T::Band | T::Mul | T::Xor | T::Sub | T::Que => E::UnOp { + T::Band | T::Mul | T::Xor | T::Sub | T::Que | T::Not => E::UnOp { pos, op: token.kind, val: { diff --git a/lang/src/son.rs b/lang/src/son.rs index 13f538f6..52ba57a5 100644 --- a/lang/src/son.rs +++ b/lang/src/son.rs @@ -2029,12 +2029,6 @@ struct Variable { impl Variable { fn new(id: Ident, ty: ty::Id, ptr: bool, value: Nid, nodes: &mut Nodes) -> Self { - if value == NEVER { - if ty == ty::Id::NEVER { - panic!(); - } - } - Self { id, ty, ptr, value: StrongRef::new(value, nodes) } } @@ -2813,6 +2807,21 @@ impl<'a> Codegen<'a> { Value::NEVER } } + Expr::UnOp { pos, op: op @ TokenKind::Not, val } => { + let val = + self.expr_ctx(val, Ctx::default().with_ty(ctx.ty.unwrap_or(ty::Id::INT)))?; + if val.ty == ty::Id::BOOL { + Some(self.ci.nodes.new_node_lit( + val.ty, + Kind::UnOp { op }, + [VOID, val.id], + self.tys, + )) + } else { + self.report(pos, fa!("cant logically negate '{}'", self.ty_display(val.ty))); + Value::NEVER + } + } Expr::BinOp { left, op: TokenKind::Decl, right, pos } => { let mut right = self.expr(right)?; diff --git a/lang/src/son/hbvm.rs b/lang/src/son/hbvm.rs index 4eef68be..5ab76e1d 100644 --- a/lang/src/son/hbvm.rs +++ b/lang/src/son/hbvm.rs @@ -568,7 +568,10 @@ impl TokenKind { Some(match self { Self::Sub => instrs::neg, Self::Float if dst.is_float() && src.is_integer() => { - debug_assert_eq!(dst.simple_size(), src.simple_size()); + debug_assert_matches!( + (dst.simple_size(), src.simple_size()), + (Some(4 | 8), Some(8)) + ); [instrs::itf32, instrs::itf64][src_idx] } Self::Number if src.is_float() && dst.is_integer() => {