/// Scans the next bunch of tokens.
Scans the next bunch of tokens.
Scans the next bunch of tokens .
fn scan_token(&mut self) {
        let st = self.advance();
        self.line = st.line;
        match st.kind {
            SubTokenKind::BlankLine => {
                if self.stage == Stage::Method {
                    if let Some(SubToken {
                        kind: SubTokenKind::Word("Serves"),
                        ..
                    }) = self.peek()
                    {
                        self.stage = Stage::Serves;
                    } else {
                        self.stage = Stage::Title;
                    }
                } else if self.stage == Stage::Serves {
                    self.stage = Stage::Title;
                }
                self.add_token(TokenKind::BlankLine)
            }
            SubTokenKind::NewLine => self.add_token(TokenKind::NewLine),
            SubTokenKind::Eof => self.add_token(TokenKind::Eof),
            SubTokenKind::InvalidChar(c) => self.invalid_char(c),
            SubTokenKind::Word(w) => {
                if self.stage == Stage::Title {
                    self.title();
                } else if let Some(x) = matches_single_keyword(&st) {
                    if x == TokenKind::Method {
                        self.stage = Stage::Method;
                    }
                    self.add_token(x);
                } else {
                    use ParseNumIdentError::*;
                    match parse_numeric(w) {
                        Err(InvalidFormat) => {}
                        Err(AlmostValidFormat) => {
                            crate::report_error(self.line, "numeric ", "invalid number literal");
                            self.errored = true;
                            return;
                        }
                        Err(OutOfRange) => {
                            crate::report_error(
                                self.line,
                                "numeric ",
                                "number literal out of range",
                            );
                            self.errored = true;
                            return;
                        }
                        Ok(n) => {
                            self.add_token(TokenKind::Number(n));
                            return;
                        }
                    }
                    match parse_ordinal(w) {
                        Err(InvalidFormat) => {}
                        Err(AlmostValidFormat) => {
                            crate::report_error(
                                self.line,
                                "numeric ",
                                "invalid ordinal identifier",
                            );
                            self.errored = true;
                            return;
                        }
                        Err(OutOfRange) => {
                            crate::report_error(
                                self.line,
                                "numeric ",
                                "ordinal identifier out of range",
                            );
                            self.errored = true;
                            return;
                        }
                        Ok(n) => {
                            self.add_token(TokenKind::Ordinal(n));
                            return;
                        }
                    }
                    if_chain! {
                        if let Some(next) = self.peek();
                        if let Some(x) = matches_double_keyword(&st, &next);
                        then {
                            let serve_with = x == TokenKind::ServeWith;
                            self.advance(); // consume the second subtoken
                            self.add_token(x);
                            if serve_with {
                                // the split is because rust won't let me perform the
                                // equality after using x
                                self.serve_with();
                            }
                        } else {
                            self.identifier();
                        }
                    }
                }
            }
            SubTokenKind::FullStop => {
                if self.stage == Stage::Title {
                    // the full stop should not be at the beginning!
                    // if there was already a title, this case wouldn't happen.
                    self.invalid_char('.');
                } else {
                    self.add_token(TokenKind::FullStop);
                }
            }
        }
    }
fn scan_token ( & mut self ) { let st = self . advance ( ) ; self . line = st . line ; match st . kind { SubTokenKind :: BlankLine => { if self . stage == Stage :: Method { if let Some ( SubToken { kind : SubTokenKind :: Word ( " " ) , .. } ) = self . peek ( ) { self . stage = Stage :: Serves ; } else { self . stage = Stage :: Title ; } } else if self . stage == Stage :: Serves { self . stage = Stage :: Title ; } self . add_token ( TokenKind :: BlankLine ) } SubTokenKind :: NewLine => self . add_token ( TokenKind :: NewLine ) , SubTokenKind :: Eof => self . add_token ( TokenKind :: Eof ) , SubTokenKind :: InvalidChar ( c ) => self . invalid_char ( c ) , SubTokenKind :: Word ( w ) => { if self . stage == Stage :: Title { self . title ( ) ; } else if let Some ( x ) = matches_single_keyword ( & st ) { if x == TokenKind :: Method { self . stage = Stage :: Method ; } self . add_token ( x ) ; } else { use ParseNumIdentError :: * ; match parse_numeric ( w ) { Err ( InvalidFormat ) => { } Err ( AlmostValidFormat ) => { crate :: report_error ( self . line , " " , " " ) ; self . errored = true ; return ; } Err ( OutOfRange ) => { crate :: report_error ( self . line , " " , " " , ) ; self . errored = true ; return ; } Ok ( n ) => { self . add_token ( TokenKind :: Number ( n ) ) ; return ; } } match parse_ordinal ( w ) { Err ( InvalidFormat ) => { } Err ( AlmostValidFormat ) => { crate :: report_error ( self . line , " " , " " , ) ; self . errored = true ; return ; } Err ( OutOfRange ) => { crate :: report_error ( self . line , " " , " " , ) ; self . errored = true ; return ; } Ok ( n ) => { self . add_token ( TokenKind :: Ordinal ( n ) ) ; return ; } } if_chain ! { if let Some ( next ) self peek ( ) if let Some ( x ) matches_double_keyword ( st next ) then { let serve_with x TokenKind ServeWith self advance ( ) // consume the second subtoken self add_token ( x ) if serve_with { // the split is because rust won't let me perform the // equality after using x self serve_with ( ) } } else { self identifier ( ) } } } } SubTokenKind :: FullStop => { if self . stage == Stage :: Title { // the full stop should not be at the beginning! // if there was already a title, this case wouldn't happen. self . invalid_char ( '.' ) ; } else { self . add_token ( TokenKind :: FullStop ) ; } } } }
Scans the next bunch of tokens.
Scans the next bunch of tokens .
&mut self