adding @nameof

Signed-off-by: Jakub Doka <jakub.doka2@gmail.com>
This commit is contained in:
Jakub Doka 2024-12-17 16:46:43 +01:00
parent 945e5c70f6
commit 0516ce68f4
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
2 changed files with 38 additions and 14 deletions

View file

@ -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)]

View file

@ -1185,6 +1185,12 @@ impl Types {
_ => return None,
})
}
pub fn name_of(&self, ty: Id, files: &EntSlice<Module, parser::Ast>, data: &mut Vec<u8>) {
use core::fmt::Write;
let str = unsafe { core::mem::transmute::<&mut Vec<u8>, &mut String>(data) };
write!(str, "{}", Display::new(self, files, ty)).unwrap();
}
}
pub struct OptLayout {