adding @ChildOf directive

Signed-off-by: Jakub Doka <jakub.doka2@gmail.com>
This commit is contained in:
Jakub Doka 2024-12-18 00:06:57 +01:00
parent e769fa8dba
commit f05c61a99e
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
2 changed files with 20 additions and 1 deletions

View file

@ -430,7 +430,7 @@ main := fn(): uint {
if false {
@error("unexpected '\0", u8, "', wah now?\0")
}
byte := @as(u8, 10)
byte := @as(@ChildOf(^u8), 10)
_ = sum(byte, byte)
same_type_as_byte := @as(@TypeOf(byte), 30)
wide_uint := @as(u32, 40)
@ -478,6 +478,7 @@ arbitrary text
- `@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
- `@error(...<expr>)`: emit compiler error, if reachable, and use arguments to construct a message, can display strings and types
- `@ChildOf(<ty>)`: returns the child type of the `<ty>`, works for pointers and optionals (`@ChildOf(?u8) == u8`)
#### c_strings
```hb

View file

@ -491,6 +491,13 @@ impl Pool {
ctrl_scope.map(|mut s| s.clear(&mut dst.nodes));
}
});
if let Some((_, ctrl, mut scope, acl)) = dst.inline_ret.take() {
ctrl.remove(&mut dst.nodes);
if let Some(acl) = acl {
acl.remove(&mut dst.nodes)
};
scope.clear(&mut dst.nodes);
}
mem::take(&mut dst.ctrl).remove(&mut dst.nodes);
*dst = mem::take(&mut self.cis[self.used_cis]);
}
@ -3827,6 +3834,17 @@ impl<'a> Codegen<'a> {
}
Expr::Directive { name: "Any", args: [], .. } => ty::Id::ANY_TYPE,
Expr::Directive { name: "TypeOf", args: [expr], .. } => self.infer_type(expr),
Expr::Directive { name: "ChildOf", args: [aty], .. } => {
let ty = self.parse_ty(sc.anon(), aty);
let Some(ty) = self.tys.base_of(ty).or(self.tys.inner_of(ty)) else {
return self.error_low(
sc.file,
aty.pos(),
fa!("only work for pointers and optionals, not '{}'", self.ty_display(ty)),
);
};
ty
}
Expr::Slice { size: None, item, .. } => {
let ty = self.parse_ty(sc.anon(), item);
self.tys.make_array(ty, ArrayLen::MAX)