From b3f858f64bfeede0e3d57a79a3a70450a4331e97 Mon Sep 17 00:00:00 2001 From: Jakub Doka Date: Tue, 17 Dec 2024 21:35:47 +0100 Subject: [PATCH] adding @error directive Signed-off-by: Jakub Doka --- lang/README.md | 4 ++++ lang/src/son.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/lang/README.md b/lang/README.md index f3f0cea0..c3be9401 100644 --- a/lang/README.md +++ b/lang/README.md @@ -427,6 +427,9 @@ $SOME_CONST := 34 foo := @use("foo.hb") main := fn(): uint { + if false { + @error("unexpected '\0", u8, "', wah now?\0") + } byte := @as(u8, 10) _ = sum(byte, byte) same_type_as_byte := @as(@TypeOf(byte), 30) @@ -474,6 +477,7 @@ arbitrary text - `@len()`: reports a length of the type of indexing purposes or length ot a string constant - `@kindof()`: gives an u8 integer describing the kind of type as an index to array `[Builtin, Struct, Enum, Union, Ptr, Slice, Opt, Func, Template, Global, Const, Module]` - `@Any()`: generic parameter based on inference, TBD: this will ake arguments in the future that restrict what is accepted +- `@error(...)`: emit compiler error, if reachable, and use arguments to construct a message, can display strings and types #### c_strings ```hb diff --git a/lang/src/son.rs b/lang/src/son.rs index 99542c78..78200b34 100644 --- a/lang/src/son.rs +++ b/lang/src/son.rs @@ -1482,6 +1482,35 @@ impl<'a> Codegen<'a> { self.assert_ty(expr.pos(), &mut val, ty, "hinted expr"); Some(val) } + Expr::Directive { pos, name: "error", args } => { + let mut error_msg = String::new(); + for arg in args { + let Some(val) = self.expr(arg) else { + self.error(arg.pos(), "unreachable argument"); + continue; + }; + match self.ci.nodes[val.id].kind { + Kind::Global { global } + if let Ok(str) = core::str::from_utf8( + &self.tys.ins.globals[global].data + [..self.tys.ins.globals[global].data.len() - 1], + ) => + { + error_msg.push_str(str) + } + Kind::CInt { value } if val.ty == ty::Id::TYPE => { + _ = write!( + error_msg, + "{}", + ty::Display::new(self.tys, self.files, ty::Id::from(value as u64)) + ) + } + _ => _ = self.error(arg.pos(), "expression can not (yet) be displayed"), + } + } + self.error(pos, error_msg); + None + } Expr::Directive { pos, name: "eca", args } => { inference!(ty, ctx, self, pos, "return type", "@as(, @eca(...))");