conlang: Add array and slice type syntax
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user