Skip to main content

dada_parser/
generics.rs

1use dada_ir_ast::ast::{
2    AstGenericDecl, AstGenericKind, AstGenericTerm, AstWhereClause, AstWhereClauseKind,
3    AstWhereClauses, SpanVec,
4};
5
6use crate::tokenizer::operator;
7
8use super::{Expected, Parse, ParseFail, Parser, tokenizer::Keyword};
9
10impl<'db> Parse<'db> for AstGenericDecl<'db> {
11    type Output = Self;
12
13    fn opt_parse(
14        db: &'db dyn crate::Db,
15        parser: &mut Parser<'_, 'db>,
16    ) -> Result<Option<Self>, super::ParseFail<'db>> {
17        let Some(kind) = AstGenericKind::opt_parse(db, parser)? else {
18            return Ok(None);
19        };
20
21        let decl = parser.eat_id().ok();
22        Ok(Some(AstGenericDecl::new(db, kind, decl)))
23    }
24
25    fn expected() -> Expected {
26        Expected::Nonterminal("generic declaration")
27    }
28}
29
30impl<'db> Parse<'db> for AstGenericKind<'db> {
31    type Output = AstGenericKind<'db>;
32
33    fn opt_parse(
34        _db: &'db dyn crate::Db,
35        parser: &mut Parser<'_, 'db>,
36    ) -> Result<Option<Self::Output>, ParseFail<'db>> {
37        if let Ok(span) = parser.eat_keyword(Keyword::Type) {
38            Ok(Some(AstGenericKind::Type(span)))
39        } else if let Ok(span) = parser.eat_keyword(Keyword::Perm) {
40            Ok(Some(AstGenericKind::Perm(span)))
41        } else {
42            Ok(None)
43        }
44    }
45
46    fn expected() -> Expected {
47        Expected::Nonterminal("`type` or `perm`")
48    }
49}
50
51impl<'db> Parse<'db> for AstWhereClauses<'db> {
52    type Output = AstWhereClauses<'db>;
53
54    fn opt_parse(
55        db: &'db dyn crate::Db,
56        parser: &mut Parser<'_, 'db>,
57    ) -> Result<Option<Self::Output>, ParseFail<'db>> {
58        let Ok(where_span) = parser.eat_keyword(Keyword::Where) else {
59            return Ok(None);
60        };
61        let clauses = match AstWhereClause::opt_parse_comma(db, parser)? {
62            Some(v) => v,
63            None => SpanVec {
64                span: where_span.to(db, parser.last_span()),
65                values: vec![],
66            },
67        };
68        Ok(Some(AstWhereClauses::new(db, where_span, clauses)))
69    }
70
71    fn expected() -> Expected {
72        Expected::Nonterminal("`where`")
73    }
74}
75
76impl<'db> Parse<'db> for AstWhereClause<'db> {
77    type Output = AstWhereClause<'db>;
78
79    fn opt_parse(
80        db: &'db dyn crate::Db,
81        parser: &mut Parser<'_, 'db>,
82    ) -> Result<Option<Self::Output>, ParseFail<'db>> {
83        let Some(subject) = AstGenericTerm::opt_parse(db, parser)? else {
84            return Ok(None);
85        };
86        let Ok(is_span) = parser.eat_keyword(Keyword::Is) else {
87            return Err(parser.illformed(Expected::Keyword(Keyword::Is)));
88        };
89        // Question: `where A is (shared, copy)` or `where A is shared + copy` or `where A is shared & copy`?
90        let kinds = match AstWhereClauseKind::opt_parse_separated(db, parser, operator::PLUS)? {
91            Some(v) => v,
92            None => SpanVec {
93                span: is_span.to(db, parser.last_span()),
94                values: vec![],
95            },
96        };
97        Ok(Some(AstWhereClause::new(db, subject, kinds)))
98    }
99
100    fn expected() -> Expected {
101        Expected::Nonterminal("where clause")
102    }
103}
104
105impl<'db> Parse<'db> for AstWhereClauseKind<'db> {
106    type Output = AstWhereClauseKind<'db>;
107
108    fn opt_parse(
109        _db: &'db dyn crate::Db,
110        parser: &mut Parser<'_, 'db>,
111    ) -> Result<Option<Self::Output>, ParseFail<'db>> {
112        if let Ok(span) = parser.eat_keyword(Keyword::Ref) {
113            Ok(Some(AstWhereClauseKind::Reference(span)))
114        } else if let Ok(span) = parser.eat_keyword(Keyword::Mut) {
115            Ok(Some(AstWhereClauseKind::Mutable(span)))
116        } else if let Ok(span) = parser.eat_keyword(Keyword::Shared) {
117            Ok(Some(AstWhereClauseKind::Shared(span)))
118        } else if let Ok(span) = parser.eat_keyword(Keyword::Owned) {
119            Ok(Some(AstWhereClauseKind::Owned(span)))
120        } else if let Ok(span) = parser.eat_keyword(Keyword::Unique) {
121            Ok(Some(AstWhereClauseKind::Unique(span)))
122        } else if let Ok(span) = parser.eat_keyword(Keyword::Lent) {
123            Ok(Some(AstWhereClauseKind::Lent(span)))
124        } else {
125            Ok(None)
126        }
127    }
128
129    fn expected() -> Expected {
130        Expected::Nonterminal("`where`")
131    }
132}