From f05c61a99e87f312992419dc10c8ce62a3469449 Mon Sep 17 00:00:00 2001 From: Jakub Doka Date: Wed, 18 Dec 2024 00:06:57 +0100 Subject: [PATCH] adding @ChildOf directive Signed-off-by: Jakub Doka --- lang/README.md | 3 ++- lang/src/son.rs | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/lang/README.md b/lang/README.md index c3be9401f..4b04266ba 100644 --- a/lang/README.md +++ b/lang/README.md @@ -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()`: 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 +- `@ChildOf()`: returns the child type of the ``, works for pointers and optionals (`@ChildOf(?u8) == u8`) #### c_strings ```hb diff --git a/lang/src/son.rs b/lang/src/son.rs index 60b3543a5..5ed56bc45 100644 --- a/lang/src/son.rs +++ b/lang/src/son.rs @@ -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)