conlang: Add array and slice type syntax

This commit is contained in:
2024-07-20 18:22:50 -05:00
parent b3d62c09aa
commit 3511575669
9 changed files with 135 additions and 3 deletions

View File

@@ -253,12 +253,27 @@ pub enum TyKind {
Never,
Empty,
Path(Path),
Array(TyArray),
Slice(TySlice),
Tuple(TyTuple),
Ref(TyRef),
Fn(TyFn),
// TODO: slice, array types
}
/// An array of [`T`](Ty)
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct TyArray {
pub ty: Box<TyKind>,
pub count: usize,
}
/// A [Ty]pe slice expression: `[T]`
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct TySlice {
pub ty: Box<TyKind>,
}
/// A tuple of [Ty]pes
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct TyTuple {

View File

@@ -307,6 +307,8 @@ mod display {
TyKind::Never => "!".fmt(f),
TyKind::Empty => "()".fmt(f),
TyKind::Path(v) => v.fmt(f),
TyKind::Array(v) => v.fmt(f),
TyKind::Slice(v) => v.fmt(f),
TyKind::Tuple(v) => v.fmt(f),
TyKind::Ref(v) => v.fmt(f),
TyKind::Fn(v) => v.fmt(f),
@@ -314,6 +316,20 @@ mod display {
}
}
impl Display for TyArray {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { ty, count } = self;
write!(f, "[{ty}; {count}]")
}
}
impl Display for TySlice {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { ty } = self;
write!(f, "[{ty}]")
}
}
impl Display for TyTuple {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
separate(&self.types, ", ")(f.delimit(INLINE_PARENS))

View File

@@ -172,6 +172,14 @@ pub trait Fold {
fn fold_ty_kind(&mut self, kind: TyKind) -> TyKind {
or_fold_ty_kind(self, kind)
}
fn fold_ty_array(&mut self, a: TyArray) -> TyArray {
let TyArray { ty, count } = a;
TyArray { ty: Box::new(self.fold_ty_kind(*ty)), count }
}
fn fold_ty_slice(&mut self, s: TySlice) -> TySlice {
let TySlice { ty } = s;
TySlice { ty: Box::new(self.fold_ty_kind(*ty)) }
}
fn fold_ty_tuple(&mut self, t: TyTuple) -> TyTuple {
let TyTuple { types } = t;
TyTuple {
@@ -500,6 +508,8 @@ pub fn or_fold_ty_kind<F: Fold + ?Sized>(folder: &mut F, kind: TyKind) -> TyKind
TyKind::Never => TyKind::Never,
TyKind::Empty => TyKind::Empty,
TyKind::Path(p) => TyKind::Path(folder.fold_path(p)),
TyKind::Array(a) => TyKind::Array(folder.fold_ty_array(a)),
TyKind::Slice(s) => TyKind::Slice(folder.fold_ty_slice(s)),
TyKind::Tuple(t) => TyKind::Tuple(folder.fold_ty_tuple(t)),
TyKind::Ref(t) => TyKind::Ref(folder.fold_ty_ref(t)),
TyKind::Fn(t) => TyKind::Fn(folder.fold_ty_fn(t)),

View File

@@ -145,6 +145,14 @@ pub trait Visit<'a>: Sized {
fn visit_ty_kind(&mut self, kind: &'a TyKind) {
or_visit_ty_kind(self, kind)
}
fn visit_ty_array(&mut self, a: &'a TyArray) {
let TyArray { ty, count: _ } = a;
self.visit_ty_kind(ty);
}
fn visit_ty_slice(&mut self, s: &'a TySlice) {
let TySlice { ty } = s;
self.visit_ty_kind(ty)
}
fn visit_ty_tuple(&mut self, t: &'a TyTuple) {
let TyTuple { types } = t;
types.iter().for_each(|kind| self.visit_ty_kind(kind))
@@ -424,6 +432,8 @@ pub fn or_visit_ty_kind<'a, V: Visit<'a>>(visitor: &mut V, kind: &'a TyKind) {
TyKind::Never => {}
TyKind::Empty => {}
TyKind::Path(p) => visitor.visit_path(p),
TyKind::Array(t) => visitor.visit_ty_array(t),
TyKind::Slice(t) => visitor.visit_ty_slice(t),
TyKind::Tuple(t) => visitor.visit_ty_tuple(t),
TyKind::Ref(t) => visitor.visit_ty_ref(t),
TyKind::Fn(t) => visitor.visit_ty_fn(t),