use std::fmt;
use hir_expand::name::{AsName, Name};
use intern::{sym, Symbol};
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum BuiltinInt {
Isize,
I8,
I16,
I32,
I64,
I128,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum BuiltinUint {
Usize,
U8,
U16,
U32,
U64,
U128,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum BuiltinFloat {
F16,
F32,
F64,
F128,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum BuiltinType {
Char,
Bool,
Str,
Int(BuiltinInt),
Uint(BuiltinUint),
Float(BuiltinFloat),
}
impl BuiltinType {
#[rustfmt::skip]
pub fn all_builtin_types() -> [(Name, BuiltinType); 19] {
[
(Name::new_symbol_root(sym::char.clone()), BuiltinType::Char),
(Name::new_symbol_root(sym::bool.clone()), BuiltinType::Bool),
(Name::new_symbol_root(sym::str.clone()), BuiltinType::Str),
(Name::new_symbol_root(sym::isize.clone()), BuiltinType::Int(BuiltinInt::Isize)),
(Name::new_symbol_root(sym::i8.clone()), BuiltinType::Int(BuiltinInt::I8)),
(Name::new_symbol_root(sym::i16.clone()), BuiltinType::Int(BuiltinInt::I16)),
(Name::new_symbol_root(sym::i32.clone()), BuiltinType::Int(BuiltinInt::I32)),
(Name::new_symbol_root(sym::i64.clone()), BuiltinType::Int(BuiltinInt::I64)),
(Name::new_symbol_root(sym::i128.clone()), BuiltinType::Int(BuiltinInt::I128)),
(Name::new_symbol_root(sym::usize.clone()), BuiltinType::Uint(BuiltinUint::Usize)),
(Name::new_symbol_root(sym::u8.clone()), BuiltinType::Uint(BuiltinUint::U8)),
(Name::new_symbol_root(sym::u16.clone()), BuiltinType::Uint(BuiltinUint::U16)),
(Name::new_symbol_root(sym::u32.clone()), BuiltinType::Uint(BuiltinUint::U32)),
(Name::new_symbol_root(sym::u64.clone()), BuiltinType::Uint(BuiltinUint::U64)),
(Name::new_symbol_root(sym::u128.clone()), BuiltinType::Uint(BuiltinUint::U128)),
(Name::new_symbol_root(sym::f16.clone()), BuiltinType::Float(BuiltinFloat::F16)),
(Name::new_symbol_root(sym::f32.clone()), BuiltinType::Float(BuiltinFloat::F32)),
(Name::new_symbol_root(sym::f64.clone()), BuiltinType::Float(BuiltinFloat::F64)),
(Name::new_symbol_root(sym::f128.clone()), BuiltinType::Float(BuiltinFloat::F128)),
]
}
pub fn by_name(name: &Name) -> Option<Self> {
Self::all_builtin_types()
.iter()
.find_map(|(n, ty)| if n == name { Some(*ty) } else { None })
}
}
impl AsName for BuiltinType {
fn as_name(&self) -> Name {
match self {
BuiltinType::Char => Name::new_symbol_root(sym::char.clone()),
BuiltinType::Bool => Name::new_symbol_root(sym::bool.clone()),
BuiltinType::Str => Name::new_symbol_root(sym::str.clone()),
BuiltinType::Int(it) => match it {
BuiltinInt::Isize => Name::new_symbol_root(sym::isize.clone()),
BuiltinInt::I8 => Name::new_symbol_root(sym::i8.clone()),
BuiltinInt::I16 => Name::new_symbol_root(sym::i16.clone()),
BuiltinInt::I32 => Name::new_symbol_root(sym::i32.clone()),
BuiltinInt::I64 => Name::new_symbol_root(sym::i64.clone()),
BuiltinInt::I128 => Name::new_symbol_root(sym::i128.clone()),
},
BuiltinType::Uint(it) => match it {
BuiltinUint::Usize => Name::new_symbol_root(sym::usize.clone()),
BuiltinUint::U8 => Name::new_symbol_root(sym::u8.clone()),
BuiltinUint::U16 => Name::new_symbol_root(sym::u16.clone()),
BuiltinUint::U32 => Name::new_symbol_root(sym::u32.clone()),
BuiltinUint::U64 => Name::new_symbol_root(sym::u64.clone()),
BuiltinUint::U128 => Name::new_symbol_root(sym::u128.clone()),
},
BuiltinType::Float(it) => match it {
BuiltinFloat::F16 => Name::new_symbol_root(sym::f16.clone()),
BuiltinFloat::F32 => Name::new_symbol_root(sym::f32.clone()),
BuiltinFloat::F64 => Name::new_symbol_root(sym::f64.clone()),
BuiltinFloat::F128 => Name::new_symbol_root(sym::f128.clone()),
},
}
}
}
impl fmt::Display for BuiltinType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
BuiltinType::Char => f.write_str("char"),
BuiltinType::Bool => f.write_str("bool"),
BuiltinType::Str => f.write_str("str"),
BuiltinType::Int(it) => it.fmt(f),
BuiltinType::Uint(it) => it.fmt(f),
BuiltinType::Float(it) => it.fmt(f),
}
}
}
#[rustfmt::skip]
impl BuiltinInt {
pub fn from_suffix(suffix: &str) -> Option<BuiltinInt> {
let res = match suffix {
"isize" => Self::Isize,
"i8" => Self::I8,
"i16" => Self::I16,
"i32" => Self::I32,
"i64" => Self::I64,
"i128" => Self::I128,
_ => return None,
};
Some(res)
}
pub fn from_suffix_sym(suffix: &Symbol) -> Option<BuiltinInt> {
let res = match suffix {
s if *s == sym::isize => Self::Isize,
s if *s == sym::i8 => Self::I8,
s if *s == sym::i16 => Self::I16,
s if *s == sym::i32 => Self::I32,
s if *s == sym::i64 => Self::I64,
s if *s == sym::i128 => Self::I128,
_ => return None,
};
Some(res)
}
}
#[rustfmt::skip]
impl BuiltinUint {
pub fn from_suffix(suffix: &str) -> Option<BuiltinUint> {
let res = match suffix {
"usize" => Self::Usize,
"u8" => Self::U8,
"u16" => Self::U16,
"u32" => Self::U32,
"u64" => Self::U64,
"u128" => Self::U128,
_ => return None,
};
Some(res)
}
pub fn from_suffix_sym(suffix: &Symbol) -> Option<BuiltinUint> {
let res = match suffix {
s if *s == sym::usize => Self::Usize,
s if *s == sym::u8 => Self::U8,
s if *s == sym::u16 => Self::U16,
s if *s == sym::u32 => Self::U32,
s if *s == sym::u64 => Self::U64,
s if *s == sym::u128 => Self::U128,
_ => return None,
};
Some(res)
}
}
#[rustfmt::skip]
impl BuiltinFloat {
pub fn from_suffix(suffix: &str) -> Option<BuiltinFloat> {
let res = match suffix {
"f16" => BuiltinFloat::F16,
"f32" => BuiltinFloat::F32,
"f64" => BuiltinFloat::F64,
"f128" => BuiltinFloat::F128,
_ => return None,
};
Some(res)
}
}
impl fmt::Display for BuiltinInt {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
BuiltinInt::Isize => "isize",
BuiltinInt::I8 => "i8",
BuiltinInt::I16 => "i16",
BuiltinInt::I32 => "i32",
BuiltinInt::I64 => "i64",
BuiltinInt::I128 => "i128",
})
}
}
impl fmt::Display for BuiltinUint {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
BuiltinUint::Usize => "usize",
BuiltinUint::U8 => "u8",
BuiltinUint::U16 => "u16",
BuiltinUint::U32 => "u32",
BuiltinUint::U64 => "u64",
BuiltinUint::U128 => "u128",
})
}
}
impl fmt::Display for BuiltinFloat {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
BuiltinFloat::F16 => "f16",
BuiltinFloat::F32 => "f32",
BuiltinFloat::F64 => "f64",
BuiltinFloat::F128 => "f128",
})
}
}