adding @error directive

Signed-off-by: Jakub Doka <jakub.doka2@gmail.com>
This commit is contained in:
Jakub Doka 2024-12-17 21:35:47 +01:00
parent 1584ec7563
commit b3f858f64b
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
2 changed files with 33 additions and 0 deletions

View file

@ -427,6 +427,9 @@ $SOME_CONST := 34
foo := @use("foo.hb") foo := @use("foo.hb")
main := fn(): uint { main := fn(): uint {
if false {
@error("unexpected '\0", u8, "', wah now?\0")
}
byte := @as(u8, 10) byte := @as(u8, 10)
_ = sum(byte, byte) _ = sum(byte, byte)
same_type_as_byte := @as(@TypeOf(byte), 30) same_type_as_byte := @as(@TypeOf(byte), 30)
@ -474,6 +477,7 @@ arbitrary text
- `@len(<ty>)`: reports a length of the type of indexing purposes or length ot a string constant - `@len(<ty>)`: reports a length of the type of indexing purposes or length ot a string constant
- `@kindof(<ty>)`: 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]` - `@kindof(<ty>)`: 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 - `@Any()`: generic parameter based on inference, TBD: this will ake arguments in the future that restrict what is accepted
- `@error(...<expr>)`: emit compiler error, if reachable, and use arguments to construct a message, can display strings and types
#### c_strings #### c_strings
```hb ```hb

View file

@ -1482,6 +1482,35 @@ impl<'a> Codegen<'a> {
self.assert_ty(expr.pos(), &mut val, ty, "hinted expr"); self.assert_ty(expr.pos(), &mut val, ty, "hinted expr");
Some(val) 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 } => { Expr::Directive { pos, name: "eca", args } => {
inference!(ty, ctx, self, pos, "return type", "@as(<return_ty>, @eca(<expr>...))"); inference!(ty, ctx, self, pos, "return type", "@as(<return_ty>, @eca(<expr>...))");