fn parse_record_intro(
        &mut self,
        start_token: Token<'file>,
    ) -> Result<Term<'file>, Diagnostic<FileSpan>> {
        let mut fields = Vec::new();

        self.expect_match(TokenKind::Open(DelimKind::Brace))?;

        while let Some(label) = self.try_identifier() {
            let params = self.parse_intro_params()?;

            // TODO: implement punned fields

            let body_ty = match self.try_match(TokenKind::Colon) {
                None => None,
                Some(_) => Some(self.parse_term(Prec(0))?),
            };

            self.expect_match(TokenKind::Equals)?;
            let body = self.parse_term(Prec(0))?;

            fields.push(RecordIntroField::Explicit {
                label,
                params,
                body_ty,
                body,
            });

            if self.try_match(TokenKind::Semicolon).is_some() {
                continue;
            } else {
                let end_token = self.expect_match(TokenKind::Close(DelimKind::Brace))?;
                let span = FileSpan::merge(start_token.span(), end_token.span());

                return Ok(Term::RecordIntro(span, fields));
            }
        }

        let end_token = self.expect_match(TokenKind::Close(DelimKind::Brace))?;
        let span = FileSpan::merge(start_token.span(), end_token.span());

        Ok(Term::RecordIntro(span, fields))
    }
/// Parse the trailing part of a record introduction.
///
/// ```text
/// record-intro        ::= "{" (record-intro-field ";")* record-intro-field? "}"
/// record-intro-field  ::= IDENTIFIER
///                       | IDENTIFIER intro-param* (":" term(0))? "=" term(0)
/// ```
Parse the trailing part of a record introduction.
Parse the trailing part of a record introduction .
fn parse_record_intro(
        &mut self,
        start_token: Token<'file>,
    ) -> Result<Term<'file>, Diagnostic<FileSpan>> {
        let mut fields = Vec::new();
        self.expect_match(TokenKind::Open(DelimKind::Brace))?;
        while let Some(label) = self.try_identifier() {
            let params = self.parse_intro_params()?;
            // TODO: implement punned fields
            let body_ty = match self.try_match(TokenKind::Colon) {
                None => None,
                Some(_) => Some(self.parse_term(Prec(0))?),
            };
            self.expect_match(TokenKind::Equals)?;
            let body = self.parse_term(Prec(0))?;
            fields.push(RecordIntroField::Explicit {
                label,
                params,
                body_ty,
                body,
            });
            if self.try_match(TokenKind::Semicolon).is_some() {
                continue;
            } else {
                let end_token = self.expect_match(TokenKind::Close(DelimKind::Brace))?;
                let span = FileSpan::merge(start_token.span(), end_token.span());
                return Ok(Term::RecordIntro(span, fields));
            }
        }
        let end_token = self.expect_match(TokenKind::Close(DelimKind::Brace))?;
        let span = FileSpan::merge(start_token.span(), end_token.span());
        Ok(Term::RecordIntro(span, fields))
    }
fn parse_record_intro ( & mut self , start_token : Token < ' file > , ) -> Result < Term < ' file > , Diagnostic < FileSpan > > { let mut fields = Vec :: new ( ) ; self . expect_match ( TokenKind :: Open ( DelimKind :: Brace ) ) ? ; while let Some ( label ) = self . try_identifier ( ) { let params = self . parse_intro_params ( ) ? ; // TODO: implement punned fields let body_ty = match self . try_match ( TokenKind :: Colon ) { None => None , Some ( _ ) => Some ( self . parse_term ( Prec ( 0 ) ) ? ) , } ; self . expect_match ( TokenKind :: Equals ) ? ; let body = self . parse_term ( Prec ( 0 ) ) ? ; fields . push ( RecordIntroField :: Explicit { label , params , body_ty , body , } ) ; if self . try_match ( TokenKind :: Semicolon ) . is_some ( ) { continue ; } else { let end_token = self . expect_match ( TokenKind :: Close ( DelimKind :: Brace ) ) ? ; let span = FileSpan :: merge ( start_token . span ( ) , end_token . span ( ) ) ; return Ok ( Term :: RecordIntro ( span , fields ) ) ; } } let end_token = self . expect_match ( TokenKind :: Close ( DelimKind :: Brace ) ) ? ; let span = FileSpan :: merge ( start_token . span ( ) , end_token . span ( ) ) ; Ok ( Term :: RecordIntro ( span , fields ) ) }
Parse the trailing part of a record introduction.
Parse the trailing part of a record introduction .
&mut self
start_token
Token<'file>
&mut self
start_token
Token<'file>