ast: add gens for ty and impl, raw ptr types, make fn return value non-optional

This commit is contained in:
2025-07-18 05:25:35 -04:00
parent 6ba62ac1c4
commit 148ef34a01
19 changed files with 242 additions and 147 deletions

View File

@@ -191,6 +191,17 @@ macro path_like() {
TokenKind::Super | TokenKind::SelfTy | TokenKind::Identifier | TokenKind::ColonColon
}
type Spanned<T> = (T, Span);
impl<'t, T: Parse<'t>> Parse<'t> for Spanned<T> {
fn parse(p: &mut Parser<'t>) -> PResult<Self> {
let head = p.loc();
let body = p.parse()?;
let tail = p.loc();
Ok((body, Span(head, tail)))
}
}
pub trait Parse<'t>: Sized {
/// Parses a Self from the provided [Parser]
fn parse(p: &mut Parser<'t>) -> PResult<Self>;
@@ -343,8 +354,8 @@ impl Parse<'_> for ItemKind {
impl Parse<'_> for Generics {
fn parse(p: &mut Parser<'_>) -> PResult<Self> {
const P: Parsing = Parsing::Generics;
let vars = match p.peek_kind(P)? {
TokenKind::Lt => delim(
let vars = match p.peek_kind(P) {
Ok(TokenKind::Lt) => delim(
sep(Sym::parse, TokenKind::Comma, TokenKind::Gt, P),
(TokenKind::Lt, TokenKind::Gt),
P,
@@ -451,17 +462,16 @@ impl Parse<'_> for Function {
let name = Sym::parse(p)?;
let gens = Generics::parse(p)?;
let (bind, types) = delim(FnSig::parse, PARENS, P)(p)?;
let ((bind, types), span) = delim(Spanned::<FnSig>::parse, PARENS, P)(p)?;
let sign = TyFn {
args: Box::new(match types.len() {
0 => TyKind::Empty,
_ => TyKind::Tuple(TyTuple { types }),
0 => Ty { span, kind: TyKind::Empty, gens: Default::default() },
_ => Ty { span, kind: TyKind::Tuple(TyTuple { types }), gens: Default::default() },
}),
rety: Box::new(match p.match_type(TokenKind::Arrow, Parsing::TyFn) {
Ok(_) => Ty::parse(p)?,
Err(_) => Ty { span, kind: TyKind::Empty, gens: Generics { vars: vec![] } },
}),
rety: Ok(match p.match_type(TokenKind::Arrow, Parsing::TyFn) {
Ok(_) => Some(Ty::parse(p)?),
Err(_) => None,
})?
.map(Box::new),
};
Ok(Function {
name,
@@ -479,7 +489,7 @@ impl Parse<'_> for Function {
}
}
type FnSig = (Pattern, Vec<TyKind>);
type FnSig = (Pattern, Vec<Ty>);
impl Parse<'_> for FnSig {
/// Parses the parameter list of a Function
@@ -498,17 +508,17 @@ impl Parse<'_> for FnSig {
}
}
type TypedParam = (Pattern, TyKind);
type TypedParam = (Pattern, Ty);
impl Parse<'_> for TypedParam {
/// Parses a single function parameter
fn parse(p: &mut Parser) -> PResult<(Pattern, TyKind)> {
fn parse(p: &mut Parser) -> PResult<(Pattern, Ty)> {
Ok((
Pattern::parse(p)?,
if p.match_type(TokenKind::Colon, Parsing::Param).is_ok() {
TyKind::parse(p)?
Ty::parse(p)?
} else {
TyKind::Infer
Ty { span: Span::dummy(), kind: TyKind::Infer, gens: Default::default() }
},
))
}
@@ -604,7 +614,11 @@ impl Parse<'_> for Impl {
const P: Parsing = Parsing::Impl;
p.match_type(TokenKind::Impl, P)?;
Ok(Impl { target: ImplKind::parse(p)?, body: delim(File::parse, CURLIES, P)(p)? })
Ok(Impl {
gens: Generics::parse(p)?,
target: ImplKind::parse(p)?,
body: delim(File::parse, CURLIES, P)(p)?,
})
}
}
@@ -682,8 +696,9 @@ impl Parse<'_> for Ty {
///
/// See also: [TyKind::parse]
fn parse(p: &mut Parser<'_>) -> PResult<Self> {
let start = p.loc();
Ok(Ty { kind: TyKind::parse(p)?, span: Span(start, p.loc()) })
let (kind, span) = p.parse()?;
let gens = p.parse()?;
Ok(Ty { span, kind, gens })
}
}
@@ -699,9 +714,10 @@ impl Parse<'_> for TyKind {
TyKind::Never
}
TokenKind::Amp | TokenKind::AmpAmp => TyRef::parse(p)?.into(),
TokenKind::Star => TyPtr::parse(p)?.into(),
TokenKind::LBrack => {
p.match_type(BRACKETS.0, Parsing::TySlice)?;
let ty = TyKind::parse(p)?;
let ty = p.parse()?;
let (out, kind) = match p.match_type(TokenKind::Semi, Parsing::TyArray).is_ok() {
true => {
let literal = p.match_type(TokenKind::Literal, Parsing::TyArray)?;
@@ -709,14 +725,11 @@ impl Parse<'_> for TyKind {
Err(p.error(Unexpected(TokenKind::Literal), Parsing::TyArray))?
};
(
TyKind::Array(TyArray { ty: Box::new(ty), count: count as _ }),
TyKind::Array(TyArray { ty, count: count as _ }),
Parsing::TyArray,
)
}
false => (
TyKind::Slice(TySlice { ty: Box::new(ty) }),
Parsing::TySlice,
),
false => (TyKind::Slice(TySlice { ty }), Parsing::TySlice),
};
p.match_type(BRACKETS.1, kind)?;
out
@@ -748,9 +761,7 @@ impl Parse<'_> for TyTuple {
/// [TyTuple] = `(` ([Ty] `,`)* [Ty]? `)`
fn parse(p: &mut Parser) -> PResult<TyTuple> {
const P: Parsing = Parsing::TyTuple;
Ok(TyTuple {
types: delim(sep(TyKind::parse, TokenKind::Comma, PARENS.1, P), PARENS, P)(p)?,
})
Ok(TyTuple { types: delim(sep(Ty::parse, TokenKind::Comma, PARENS.1, P), PARENS, P)(p)? })
}
}
@@ -771,24 +782,36 @@ impl Parse<'_> for TyRef {
}
}
impl Parse<'_> for TyPtr {
/// [TyPtr] = `*` [Ty]
fn parse(p: &mut Parser) -> PResult<TyPtr> {
const P: Parsing = Parsing::TyRef;
p.match_type(TokenKind::Star, P)?;
Ok(TyPtr { to: p.parse()? })
}
}
impl Parse<'_> for TyFn {
/// [TyFn] = `fn` [TyTuple] (-> [Ty])?
fn parse(p: &mut Parser) -> PResult<TyFn> {
const P: Parsing = Parsing::TyFn;
p.match_type(TokenKind::Fn, P)?;
let args = delim(sep(TyKind::parse, TokenKind::Comma, PARENS.1, P), PARENS, P)(p)?;
let head = p.loc();
let args = delim(sep(Ty::parse, TokenKind::Comma, PARENS.1, P), PARENS, P)(p)?;
let span = Span(head, p.loc());
Ok(TyFn {
args: Box::new(match args {
t if t.is_empty() => TyKind::Empty,
types => TyKind::Tuple(TyTuple { types }),
t if t.is_empty() => Ty { kind: TyKind::Empty, span, gens: Default::default() },
types => {
Ty { kind: TyKind::Tuple(TyTuple { types }), span, gens: Default::default() }
}
}),
rety: Box::new(match p.match_type(TokenKind::Arrow, Parsing::TyFn) {
Ok(_) => Ty::parse(p)?,
Err(_) => Ty { span, kind: TyKind::Empty, gens: Generics { vars: vec![] } },
}),
rety: match p.match_type(TokenKind::Arrow, Parsing::TyFn) {
Ok(_) => Some(Ty::parse(p)?),
Err(_) => None,
}
.map(Into::into),
})
}
}
@@ -847,15 +870,12 @@ impl Parse<'_> for Stmt {
///
/// See also: [StmtKind::parse]
fn parse(p: &mut Parser) -> PResult<Stmt> {
let start = p.loc();
Ok(Stmt {
kind: StmtKind::parse(p)?,
semi: match p.match_type(TokenKind::Semi, Parsing::Stmt) {
Ok(_) => Semi::Terminated,
_ => Semi::Unterminated,
},
span: Span(start, p.loc()),
})
let (kind, span) = Spanned::<StmtKind>::parse(p)?;
let semi = match p.match_type(TokenKind::Semi, Parsing::Stmt) {
Ok(_) => Semi::Terminated,
_ => Semi::Unterminated,
};
Ok(Stmt { span, kind, semi })
}
}
@@ -1132,7 +1152,7 @@ impl Parse<'_> for Pattern {
// Name, Path, Struct, TupleStruct
TokenKind::Identifier => pathpattern(p)?,
// Literal
TokenKind::Literal => Pattern::Literal(p.parse()?),
TokenKind::True | TokenKind::False | TokenKind::Literal => Pattern::Literal(p.parse()?),
// Rest
TokenKind::DotDot => {
p.consume_peeked();

View File

@@ -204,13 +204,7 @@ fn exprkind_array_rep(p: &mut Parser) -> PResult<ExprKind> {
value: first.into(),
repeat: {
p.consume_peeked();
let value = p.match_type(TokenKind::Literal, Parsing::ArrayRep)?;
match value.data() {
TokenData::Integer(size) => *size as usize,
_ => {
Err(p.error(ErrorKind::Unexpected(TokenKind::Literal), Parsing::ArrayRep))?
}
}
p.parse()?
},
}
.into(),