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

@@ -78,6 +78,8 @@ pub enum Parsing {
Ty,
TyKind,
TySlice,
TyArray,
TyTuple,
TyRef,
TyFn,
@@ -181,13 +183,15 @@ impl Display for Parsing {
Parsing::Ty => "a type",
Parsing::TyKind => "a type",
Parsing::TySlice => "a slice type",
Parsing::TyArray => "an array type",
Parsing::TyTuple => "a tuple of types",
Parsing::TyRef => "a reference type",
Parsing::TyFn => "a function pointer type",
Parsing::Path => "a path",
Parsing::PathPart => "a path component",
Parsing::Stmt => "a statement",
Parsing::StmtKind => "a statement",
Parsing::Let => "a local variable declaration",

View File

@@ -673,6 +673,7 @@ impl<'t> Parser<'t> {
TyKind::Never
}
TokenKind::Punct(Punct::Amp) | TokenKind::Punct(Punct::AmpAmp) => self.tyref()?.into(),
TokenKind::Punct(Punct::LBrack) => self.tyslice_or_array()?,
TokenKind::Punct(Punct::LParen) => {
let out = self.tytuple()?;
match out.types.is_empty() {
@@ -687,6 +688,32 @@ impl<'t> Parser<'t> {
Ok(out)
}
/// [`TySlice`] = `[` [Ty] `]` \
/// [`TyArray`] = `[` [Ty] `;` [usize] `]`
pub fn tyslice_or_array(&mut self) -> PResult<TyKind> {
self.match_op(BRACKETS.0, Parsing::TySlice)?;
let ty = self.tykind()?;
let (out, kind) = match self.match_op(Punct::Semi, Parsing::TyArray).is_ok() {
true => {
let literal = self.match_type(TokenKind::Literal, Parsing::TyArray)?;
let &TokenData::Integer(count) = literal.data() else {
Err(self.error(Unexpected(TokenKind::Literal), Parsing::TyArray))?
};
(
TyKind::Array(TyArray { ty: Box::new(ty), count: count as _ }),
Parsing::TyArray,
)
}
false => (
TyKind::Slice(TySlice { ty: Box::new(ty) }),
Parsing::TySlice,
),
};
self.match_op(BRACKETS.1, kind)?;
Ok(out)
}
/// [TyTuple] = `(` ([Ty] `,`)* [Ty]? `)`
pub fn tytuple(&mut self) -> PResult<TyTuple> {
const PARSING: Parsing = Parsing::TyTuple;