/// This function assumes that we have just consumed the apostrophe `'`
/// before the base indication.
This function assumes that we have just consumed the apostrophe `'`
before the base indication.
This function assumes that we have just consumed the apostrophe ` ' ` before the base indication .
fn match_based_number(
        &mut self,
        size: Option<Name>,
        mut span: Span,
    ) -> DiagResult2<TokenAndSpan> {
        match self.peek[0] {
            (CatTokenKind::Text, sp) => {
                self.bump()?;
                let text = sp.extract();
                span.expand(sp);
                let mut chars = text.chars();
                let mut c = chars.next();
                // Consume the optional sign indicator or emit an unbased and
                // unsized literal if the apostrophe is immediately followed by
                // [zZxX].
                let signed = match c {
                    Some('s') | Some('S') => {
                        c = chars.next();
                        true
                    }
                    Some('z') | Some('Z') if text.len() == 1 => {
                        return Ok((Literal(UnbasedUnsized('z')), span))
                    }
                    Some('x') | Some('X') if text.len() == 1 => {
                        return Ok((Literal(UnbasedUnsized('x')), span))
                    }
                    _ => false,
                };
                // Consume the base of the number.
                let base = match c {
                    Some('d') | Some('D') => 'd',
                    Some('b') | Some('B') => 'b',
                    Some('o') | Some('O') => 'o',
                    Some('h') | Some('H') => 'h',
                    Some(x) => {
                        return Err(DiagBuilder2::fatal(format!(
                            "`{}` is not a valid number base",
                            x
                        ))
                        .span(span))
                    }
                    None => return Err(DiagBuilder2::fatal("Missing number base").span(span)),
                };
                c = chars.next();
                // If no more characters remain, a whitespace and subsequent
                // digits may follow. Otherwise, the remaining characters are to
                // be treated as part of the number body and no whitespace
                // follows.
                let mut body = String::new();
                if let Some(c) = c {
                    body.push(c);
                    body.push_str(chars.as_str());
                } else {
                    self.skip_noise()?;
                }
                self.eat_number_body_into(&mut body, &mut span, true)?;
                return Ok((
                    Literal(BasedInteger(
                        size,
                        signed,
                        base,
                        get_name_table().intern(&body, true),
                    )),
                    span,
                ));
            }
            (CatTokenKind::Digits, sp) if size.is_none() => {
                self.bump()?;
                let value = sp.extract();
                span.expand(sp);
                match value.chars().next() {
                    Some('0') if value.len() == 1 => {
                        return Ok((Literal(UnbasedUnsized('0')), span))
                    }
                    Some('1') if value.len() == 1 => {
                        return Ok((Literal(UnbasedUnsized('1')), span))
                    }
                    _ => {
                        return Err(DiagBuilder2::fatal(
                            "Unbased unsized literal may only be '0, '1, 'x, or 'z",
                        )
                        .span(span))
                    }
                }
            }
            (CatTokenKind::Symbol('?'), sp) => {
                self.bump()?;
                span.expand(sp);
                return Ok((Literal(UnbasedUnsized('z')), span));
            }
            // (_, sp) => return Err(DiagBuilder2::fatal("Invalid number base").span(sp))
            _ => return Ok((Apostrophe, span)),
        }
    }
fn match_based_number ( & mut self , size : Option < Name > , mut span : Span , ) -> DiagResult2 < TokenAndSpan > { match self . peek [ 0 ] { ( CatTokenKind :: Text , sp ) => { self . bump ( ) ? ; let text = sp . extract ( ) ; span . expand ( sp ) ; let mut chars = text . chars ( ) ; let mut c = chars . next ( ) ; // Consume the optional sign indicator or emit an unbased and // unsized literal if the apostrophe is immediately followed by // [zZxX]. let signed = match c { Some ( 's' ) | Some ( 'S' ) => { c = chars . next ( ) ; true } Some ( 'z' ) | Some ( 'Z' ) if text . len ( ) == 1 => { return Ok ( ( Literal ( UnbasedUnsized ( 'z' ) ) , span ) ) } Some ( 'x' ) | Some ( 'X' ) if text . len ( ) == 1 => { return Ok ( ( Literal ( UnbasedUnsized ( 'x' ) ) , span ) ) } _ => false , } ; // Consume the base of the number. let base = match c { Some ( 'd' ) | Some ( 'D' ) => 'd' , Some ( 'b' ) | Some ( 'B' ) => 'b' , Some ( 'o' ) | Some ( 'O' ) => 'o' , Some ( 'h' ) | Some ( 'H' ) => 'h' , Some ( x ) => { return Err ( DiagBuilder2 :: fatal ( format ! ( " " x ) ) . span ( span ) ) } None => return Err ( DiagBuilder2 :: fatal ( " " ) . span ( span ) ) , } ; c = chars . next ( ) ; // If no more characters remain, a whitespace and subsequent // digits may follow. Otherwise, the remaining characters are to // be treated as part of the number body and no whitespace // follows. let mut body = String :: new ( ) ; if let Some ( c ) = c { body . push ( c ) ; body . push_str ( chars . as_str ( ) ) ; } else { self . skip_noise ( ) ? ; } self . eat_number_body_into ( & mut body , & mut span , true ) ? ; return Ok ( ( Literal ( BasedInteger ( size , signed , base , get_name_table ( ) . intern ( & body , true ) , ) ) , span , ) ) ; } ( CatTokenKind :: Digits , sp ) if size . is_none ( ) => { self . bump ( ) ? ; let value = sp . extract ( ) ; span . expand ( sp ) ; match value . chars ( ) . next ( ) { Some ( '0' ) if value . len ( ) == 1 => { return Ok ( ( Literal ( UnbasedUnsized ( '0' ) ) , span ) ) } Some ( '1' ) if value . len ( ) == 1 => { return Ok ( ( Literal ( UnbasedUnsized ( '1' ) ) , span ) ) } _ => { return Err ( DiagBuilder2 :: fatal ( " " , ) . span ( span ) ) } } } ( CatTokenKind :: Symbol ( '?' ) , sp ) => { self . bump ( ) ? ; span . expand ( sp ) ; return Ok ( ( Literal ( UnbasedUnsized ( 'z' ) ) , span ) ) ; } // (_, sp) => return Err(DiagBuilder2::fatal("Invalid number base").span(sp)) _ => return Ok ( ( Apostrophe , span ) ) , } }
This function assumes that we have just consumed the apostrophe `'`
before the base indication.
This function assumes that we have just consumed the apostrophe ` ' ` before the base indication .
&mut self
size
Option<Name>
span
Span