use crate::*;
use py_ir::types::TypeDefine;
use std::collections::HashMap;
use terl::Span;
#[derive(Default)]
pub struct Defs {
pub(crate) fn_signs: FnSigns,
}
impl Defs {
pub fn new() -> Self {
Self::default()
}
pub fn new_fn(&mut self, unmangled: &str, mangled: &str, sign: defs::FnSign) -> Type {
self.fn_signs.new_fn(unmangled, mangled, sign)
}
pub fn get_mangled(&self, name: &str) -> &Overload {
self.fn_signs.get_mangled(name)
}
pub fn try_get_mangled(&self, name: &str) -> Option<&Overload> {
self.fn_signs.try_get_mangled(name)
}
pub fn get_unmangled(&self, name: &str) -> Option<&[Overload]> {
self.fn_signs.get_unmangled(name)
}
}
#[derive(Default)]
pub struct FnSigns {
fn_signs: Vec<Overload>,
unmangled: HashMap<String, Vec<Overload>>,
mangled: HashMap<String, Overload>,
}
impl FnSigns {
pub fn new() -> Self {
Self::default()
}
pub fn new_fn(&mut self, unmangled: &str, mangled: &str, sign: defs::FnSign) -> Type {
let value = defs::FnSignWithName {
sign,
name: mangled.to_owned(),
};
let overload: Overload = value.into();
self.fn_signs.push(overload.clone());
self.unmangled
.entry(unmangled.to_owned())
.or_default()
.push(overload.clone());
self.mangled.insert(mangled.to_owned(), overload.clone());
Type::Overload(overload)
}
pub fn get_unmangled(&self, name: &str) -> Option<&[Overload]> {
self.unmangled.get(name).map(|v| &**v)
}
pub fn get_mangled(&self, name: &str) -> &Overload {
self.mangled.get(name).unwrap()
}
pub fn try_get_mangled(&self, name: &str) -> Option<&Overload> {
self.mangled.get(name)
}
}
#[derive(Debug, Clone)]
pub struct FnSignWithName {
pub sign: FnSign,
pub name: String,
}
impl std::ops::Deref for FnSignWithName {
type Target = FnSign;
fn deref(&self) -> &Self::Target {
&self.sign
}
}
impl std::ops::DerefMut for FnSignWithName {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.sign
}
}
#[derive(Debug, Clone)]
pub struct FnSign {
pub ty: TypeDefine,
pub params: Vec<Parameter>,
pub retty_span: Span,
pub sign_span: Span,
}
impl FnSign {
pub fn new(ty: TypeDefine, params: Vec<Parameter>, retty_span: Span, sign_span: Span) -> Self {
Self {
ty,
params,
retty_span,
sign_span,
}
}
}
impl std::fmt::Display for FnSignWithName {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let unmangled = self.name.split_ascii_whitespace().next().unwrap();
f.write_str(unmangled)?;
f.write_str("(")?;
match self.params.len() {
0 => f.write_str(")")?,
1 => f.write_fmt(format_args!("{})", self.params[0].ty))?,
_ => {
f.write_fmt(format_args!("{}", self.params[0].ty))?;
for param in &self.params[1..] {
f.write_fmt(format_args!(", {}", param.name))?;
}
f.write_str(")")?
}
}
f.write_fmt(format_args!(" -> {}", self.ty))
}
}
pub type Parameter = py_ir::Parameter<TypeDefine>;
#[derive(Debug, Clone)]
pub struct VarDef {
pub ty: GroupIdx,
pub mutable: bool,
}