From 0516ce68f409522bec9874dfbc743495216cd276 Mon Sep 17 00:00:00 2001 From: Jakub Doka Date: Tue, 17 Dec 2024 16:46:43 +0100 Subject: [PATCH] adding @nameof Signed-off-by: Jakub Doka --- lang/src/son.rs | 46 ++++++++++++++++++++++++++++++++-------------- lang/src/ty.rs | 6 ++++++ 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/lang/src/son.rs b/lang/src/son.rs index 56eb0a6..1ab088a 100644 --- a/lang/src/son.rs +++ b/lang/src/son.rs @@ -869,20 +869,7 @@ impl<'a> Codegen<'a> { self.error(pos, "string literal must end with null byte (for now)"); } - let ty = self.tys.make_ptr(ty::Id::U8); - let global = self - .tys - .strings - .get_or_insert(&data, &mut self.tys.ins.globals, |globals| { - StringRef(globals.push(GlobalData { - data: data.clone(), - ty, - ..Default::default() - })) - }) - .0; - let global = self.ci.nodes.new_node_nop(ty, Kind::Global { global }, [VOID]); - self.ci.nodes[global].aclass = GLOBAL_ACLASS as _; + let (global, ty) = self.create_string_global(&data); data.clear(); self.pool.lit_buf = data; @@ -1294,6 +1281,19 @@ impl<'a> Codegen<'a> { self.ci.nodes.new_node(glob.ty, Kind::Global { global: id }, [VOID], self.tys); Some(Value::ptr(g).ty(glob.ty)) } + Expr::Directive { name: "nameof", args: [ty], .. } => { + let ty = self.ty(ty); + let mut data = core::mem::take(&mut self.pool.lit_buf); + self.tys.name_of(ty, self.files, &mut data); + data.push(0); + + let (global, ty) = self.create_string_global(&data); + + data.clear(); + self.pool.lit_buf = data; + + Some(Value::new(global).ty(ty)) + } Expr::Directive { name: "sizeof", args: [ty], .. } => { let ty = self.ty(ty); self.gen_inferred_const(ctx, ty::Id::DINT, self.tys.size_of(ty)) @@ -3877,6 +3877,24 @@ impl<'a> Codegen<'a> { ty } + + fn create_string_global(&mut self, data: &[u8]) -> (Nid, ty::Id) { + let ty = self.tys.make_ptr(ty::Id::U8); + let global = self + .tys + .strings + .get_or_insert(data, &mut self.tys.ins.globals, |globals| { + StringRef(globals.push(GlobalData { + data: data.to_vec(), + ty, + ..Default::default() + })) + }) + .0; + let global = self.ci.nodes.new_node_nop(ty, Kind::Global { global }, [VOID]); + self.ci.nodes[global].aclass = GLOBAL_ACLASS as _; + (global, ty) + } } #[derive(Clone, Copy, Default)] diff --git a/lang/src/ty.rs b/lang/src/ty.rs index 107d4ab..81e5c87 100644 --- a/lang/src/ty.rs +++ b/lang/src/ty.rs @@ -1185,6 +1185,12 @@ impl Types { _ => return None, }) } + + pub fn name_of(&self, ty: Id, files: &EntSlice, data: &mut Vec) { + use core::fmt::Write; + let str = unsafe { core::mem::transmute::<&mut Vec, &mut String>(data) }; + write!(str, "{}", Display::new(self, files, ty)).unwrap(); + } } pub struct OptLayout {