Skip to main content

dada_ir_sym/ir/
primitive.rs

1use dada_ir_ast::ast::Identifier;
2use dada_util::SalsaSerialize;
3use salsa::Update;
4use serde::Serialize;
5
6/// Returns the standard primitives available in Dada.
7#[salsa::tracked(return_ref)]
8pub fn primitives<'db>(db: &'db dyn crate::Db) -> Vec<SymPrimitive<'db>> {
9    vec![
10        SymPrimitive::new(db, SymPrimitiveKind::Bool),
11        SymPrimitive::new(db, SymPrimitiveKind::Char),
12        SymPrimitive::new(db, SymPrimitiveKind::Isize),
13        SymPrimitive::new(db, SymPrimitiveKind::Usize),
14        SymPrimitive::new(db, SymPrimitiveKind::Float { bits: 32 }),
15        SymPrimitive::new(db, SymPrimitiveKind::Float { bits: 64 }),
16        SymPrimitive::new(db, SymPrimitiveKind::Int { bits: 8 }),
17        SymPrimitive::new(db, SymPrimitiveKind::Int { bits: 16 }),
18        SymPrimitive::new(db, SymPrimitiveKind::Int { bits: 32 }),
19        SymPrimitive::new(db, SymPrimitiveKind::Int { bits: 64 }),
20        SymPrimitive::new(db, SymPrimitiveKind::Uint { bits: 8 }),
21        SymPrimitive::new(db, SymPrimitiveKind::Uint { bits: 16 }),
22        SymPrimitive::new(db, SymPrimitiveKind::Uint { bits: 32 }),
23        SymPrimitive::new(db, SymPrimitiveKind::Uint { bits: 64 }),
24    ]
25}
26
27/// A "primitive" is a scalar type that is built-in to Dada and cannot be defined as an aggregate
28/// type like a struct, enum, or class.
29#[derive(SalsaSerialize)]
30#[salsa::interned(debug)]
31pub struct SymPrimitive<'db> {
32    pub kind: SymPrimitiveKind,
33}
34
35impl std::fmt::Display for SymPrimitive<'_> {
36    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37        salsa::with_attached_database(|db| {
38            let db: &dyn crate::Db = db.as_view();
39            write!(f, "{}", self.name(db))
40        })
41        .unwrap_or_else(|| std::fmt::Debug::fmt(self, f))
42    }
43}
44
45/// A "primitive" is a scalar type that is built-in to Dada and cannot be defined as a struct.
46#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Update, Debug, Serialize)]
47pub enum SymPrimitiveKind {
48    Bool,
49    Char,
50    Int { bits: u32 },
51    Isize,
52    Uint { bits: u32 },
53    Usize,
54    Float { bits: u32 },
55}
56
57impl<'db> SymPrimitive<'db> {
58    /// Gets the name of the scalar type.
59    /// We give them the same names as Rust.
60    pub fn name(self, db: &'db dyn crate::Db) -> Identifier<'db> {
61        match self.kind(db) {
62            SymPrimitiveKind::Bool => Identifier::new(db, "bool".to_string()),
63            SymPrimitiveKind::Char => Identifier::new(db, "char".to_string()),
64            SymPrimitiveKind::Int { bits } => Identifier::new(db, format!("i{bits}")),
65            SymPrimitiveKind::Isize => Identifier::new(db, "isize".to_string()),
66            SymPrimitiveKind::Uint { bits } => Identifier::new(db, format!("u{bits}")),
67            SymPrimitiveKind::Usize => Identifier::new(db, "usize".to_string()),
68            SymPrimitiveKind::Float { bits } => Identifier::new(db, format!("f{bits}")),
69        }
70    }
71}
72
73impl SymPrimitiveKind {
74    /// Intern `SymPrimitive<'db>`
75    pub fn intern(self, db: &dyn crate::Db) -> SymPrimitive<'_> {
76        SymPrimitive::new(db, self)
77    }
78}