use crate::registry::time_scale::TimeScale;
use crate::syntax::ast::{GenericConstraint, MulDivOp};
use crate::syntax::dimension::Rational;
use crate::syntax::names::{GenericParamName, ResolvedName, TimeScaleName, namespace};
use crate::syntax::span::{Span, Spanned};
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct GenericParamId {
pub owner: GenericParamOwner,
pub name: GenericParamName,
}
impl GenericParamId {
#[must_use]
pub const fn new(owner: GenericParamOwner, name: GenericParamName) -> Self {
Self { owner, name }
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum GenericParamOwner {
Type(ResolvedName<namespace::StructType>),
Function(ResolvedName<namespace::Fn>),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct GenericParamDef {
pub id: Spanned<GenericParamId>,
pub constraint: GenericConstraint,
pub default: Option<TypeExpr>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum BuiltinType {
Dimensionless,
Bool,
Int,
Datetime(TimeScaleName),
}
impl BuiltinType {
#[must_use]
pub const fn datetime_utc() -> Self {
Self::Datetime(TimeScaleName::new(TimeScale::UTC))
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TypeExpr {
pub kind: TypeExprKind,
pub span: Span,
}
impl TypeExpr {
#[must_use]
pub const fn new(kind: TypeExprKind, span: Span) -> Self {
Self { kind, span }
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TypeExprKind {
Builtin(BuiltinType),
DimExpr(DimExpr),
Index(IndexRef),
Struct(Spanned<ResolvedName<namespace::StructType>>),
GenericTypeParam(Spanned<GenericParamId>),
TypeApplication {
name: Spanned<ResolvedName<namespace::StructType>>,
type_args: Vec<TypeExpr>,
},
Indexed {
base: Box<TypeExpr>,
indexes: Vec<IndexRef>,
},
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DimExpr {
pub terms: Vec<DimExprItem>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DimExprItem {
pub op: MulDivOp,
pub term: DimTermRef,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DimTermRef {
pub target: DimTermTarget,
pub power: Option<Rational>,
pub span: Span,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum DimTermTarget {
Dimension(Spanned<ResolvedName<namespace::Dim>>),
GenericParam(Spanned<GenericParamId>),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum IndexRef {
Concrete(Spanned<ResolvedName<namespace::Index>>),
GenericParam(Spanned<GenericParamId>),
NatExpr(NatExpr),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum NatExpr {
Literal(u64, Span),
Param(Spanned<GenericParamId>),
Add(Box<Self>, Box<Self>, Span),
Mul(Box<Self>, Box<Self>, Span),
}
impl NatExpr {
#[must_use]
pub const fn span(&self) -> Span {
match self {
Self::Literal(_, span) | Self::Add(_, _, span) | Self::Mul(_, _, span) => *span,
Self::Param(param) => param.span,
}
}
}