work
authorBen Pfaff <blp@cs.stanford.edu>
Tue, 27 Aug 2024 15:29:08 +0000 (08:29 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Tue, 27 Aug 2024 15:29:08 +0000 (08:29 -0700)
rust/pspp/src/command.rs
rust/pspp/src/lex/lexer.rs
rust/pspp/src/lex/scan/mod.rs
rust/pspp/src/lex/scan/test.rs
rust/pspp/src/lex/token.rs
rust/pspp/src/macros.rs

index 57bb885f1459ccac09f52104ea826de2054e63c5..c749b5f2dc2747cc212ca0df5d58ad8c0139a384 100644 (file)
@@ -7,7 +7,7 @@ use crate::{
     integer::ToInteger,
     lex::{
         command_name::CommandMatcher,
-        lexer::{TokenSlice},
+        lexer::TokenSlice,
         token::{Punct, Token},
     },
     message::Diagnostic,
@@ -104,8 +104,7 @@ fn commands() -> &'static [Command] {
                 testing_only: false,
                 no_abbrev: false,
                 name: "ECHO",
-                run: Box::new(|_context| {
-                    
+                run: Box::new(|context| {
                     println!("hi");
                 }),
             },
@@ -132,7 +131,7 @@ fn parse_command_word(lexer: &mut TokenSlice, s: &mut String, n: usize) -> bool
         _ => "",
     };
 
-    match lexer.get(n) {
+    match lexer.get_token(n) {
         Some(Token::Punct(Punct::Dash)) => {
             s.push('-');
             true
@@ -186,9 +185,13 @@ fn parse_command_name(
         Some(command) => Ok((command, ((word as isize + 1) + missing_words) as usize)),
         None => {
             if word == 0 {
-                error(lexer.error(0..=0, "Syntax error expecting command name"))
+                error(
+                    lexer
+                        .subslice(0..1)
+                        .error("Syntax error expecting command name"),
+                )
             } else {
-                error(lexer.error(0..=word, "Unknown command `{s}`."))
+                error(lexer.subslice(0..word + 1).error("Unknown command `{s}`."))
             };
             Err(())
         }
@@ -202,13 +205,14 @@ pub enum Success {
 }
 
 pub fn end_of_command(context: &Context, range: RangeFrom<usize>) -> Result<Success, ()> {
-    match context.lexer.get(range.start) {
-        None | Some(Token::EndCommand) => Ok(Success::Success),
+    match context.lexer.get_token(range.start) {
+        None | Some(Token::End) => Ok(Success::Success),
         _ => {
             context.error(
                 context
                     .lexer
-                    .error(range, "Syntax error expecting end of command."),
+                    .subslice(range.start..context.lexer.len())
+                    .error("Syntax error expecting end of command."),
             );
             Err(())
         }
@@ -217,13 +221,13 @@ pub fn end_of_command(context: &Context, range: RangeFrom<usize>) -> Result<Succ
 
 fn parse_in_state(mut lexer: TokenSlice, error: &Box<dyn Fn(Diagnostic)>, _state: State) {
     println!("{}:{}", file!(), line!());
-    match lexer.get(0) {
-        None | Some(Token::EndCommand) => (),
+    match lexer.get_token(0) {
+        None | Some(Token::End) => (),
         _ => {
             if let Ok((command, n_tokens)) = parse_command_name(&mut lexer, error) {
                 let mut context = Context {
                     error,
-                    lexer: lexer.subslice(n_tokens..),
+                    lexer: lexer.subslice(n_tokens..lexer.len()),
                     command_name: Some(command.name),
                 };
                 (command.run)(&mut context);
index 3e2b342596f2b8e581a14df45ae8d022cad49b49..47c70d169737c450744c9b54547faff351ede6f5 100644 (file)
@@ -6,9 +6,9 @@ use std::{
     io::Result as IoResult,
     iter::once,
     mem::take,
-    ops::{Range, RangeBounds, RangeInclusive},
+    ops::{Range, RangeInclusive},
     path::Path,
-    ptr,
+    ptr, slice,
     sync::Arc,
 };
 
@@ -185,11 +185,11 @@ fn ellipsize(s: &str) -> Cow<str> {
 }
 
 /// A token in a [`Source`].
-struct LexToken<'a> {
+pub struct LexToken<'a> {
     /// The regular token.
-    token: Token,
+    pub token: Token,
 
-    file: &'a SourceFile,
+    pub file: &'a SourceFile,
 
     /// For a token obtained through the lexer in an ordinary way, this is the
     /// location of the token in the [`Source`]'s buffer.
@@ -206,6 +206,19 @@ struct LexToken<'a> {
     macro_rep: Option<MacroRepresentation>,
 }
 
+impl LexToken<'_> {
+    pub fn force_string(&self) -> Result<&str, Diagnostic> {
+        if let Token::String(s) = &self.token {
+            Ok(s.as_str())
+        } else {
+            let slice = TokenSlice {
+                tokens: slice::from_ref(self),
+            };
+            Err(slice.error("Syntax error expecting string."))
+        }
+    }
+}
+
 struct LexError {
     error: ScanError,
     pos: Range<usize>,
@@ -332,6 +345,13 @@ pub struct Tokens<'a> {
     tokens: Vec<LexToken<'a>>,
 }
 
+impl<'a> Tokens<'a> {
+    fn new(tokens: Vec<LexToken<'a>>) -> Self {
+        assert!(matches!(tokens.last().unwrap().token, Token::End));
+        Self { tokens }
+    }
+}
+
 impl Debug for Tokens<'_> {
     fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
         write!(f, "Tokens {{ ")?;
@@ -356,37 +376,60 @@ impl<'a> TokenSlice<'a> {
         }
     }
 
-    pub fn get(&self, index: usize) -> Option<&Token> {
-        self.tokens.get(index).map(|token| &token.token)
+    pub fn get_token(&self, index: usize) -> Option<&Token> {
+        self.get(index).map(|token| &token.token)
+    }
+
+    pub fn get(&self, index: usize) -> Option<&LexToken> {
+        if index < self.len() {
+            Some(&self.tokens[index])
+        } else {
+            None
+        }
     }
 
-    pub fn error<S, B>(&self, range: B, text: S) -> Diagnostic
+    pub fn error<S>(&self, text: S) -> Diagnostic
     where
         S: ToString,
-        B: RangeBounds<usize>,
     {
-        self.subslice(range)
-            .diagnostic(Severity::Error, text.to_string())
+        self.diagnostic(Severity::Error, text.to_string())
     }
 
-    pub fn subslice<B>(&self, range: B) -> Self
-    where
-        B: RangeBounds<usize>,
-    {
+    pub fn subslice(&self, range: Range<usize>) -> Self {
+        debug_assert!(range.start <= range.end);
+        debug_assert!(range.end <= self.len());
         Self {
-            tokens: &self.tokens[(range.start_bound().cloned(), range.end_bound().cloned())],
+            tokens: &self.tokens[range.start..range.end + 1],
         }
     }
 
+    fn first(&self) -> &LexToken {
+        self.tokens.first().unwrap()
+    }
+    fn last(&self) -> &LexToken {
+        self.tokens.last().unwrap()
+    }
+
     fn file(&self) -> Option<&SourceFile> {
-        if !self.tokens.is_empty() {
-            let first = &self.tokens[0];
-            let last = &self.tokens[self.tokens.len() - 1];
-            if ptr::eq(first.file, last.file) {
-                return Some(first.file);
-            }
+        let first = self.first();
+        let last = self.last();
+        if ptr::eq(first.file, last.file) {
+            Some(first.file)
+        } else {
+            None
         }
-        None
+    }
+
+    pub fn len(&self) -> usize {
+        self.tokens.len() - 1
+    }
+
+    pub fn is_empty(&self) -> bool {
+        self.len() == 0
+    }
+
+    pub fn iter(&self) -> std::slice::Iter<LexToken> {
+        (&self.tokens[..self.len()]).iter()
     }
 
     /// If the tokens contains a macro call, this returns the raw
@@ -397,7 +440,7 @@ impl<'a> TokenSlice<'a> {
     ///
     /// Returns `None` if the token range doesn't include a macro call.
     fn get_macro_call(&self) -> Option<&str> {
-        if self.tokens.iter().any(|token| token.macro_rep.is_some()) {
+        if self.iter().any(|token| token.macro_rep.is_some()) {
             let token0 = &self.tokens[0];
             let token1 = &self.tokens[self.tokens.len() - 1];
             if let Some(file) = self.file() {
@@ -413,9 +456,11 @@ impl<'a> TokenSlice<'a> {
 
     fn location(&self) -> Location {
         if let Some(file) = self.file() {
-            file.token_location(self.tokens.first().unwrap()..=self.tokens.last().unwrap())
+            file.token_location(self.first()..=self.last())
         } else {
-            Location::default()
+            // XXX support non-contiguous locations?
+            let first = self.first();
+            first.file.token_location(self.first()..=self.first())
         }
     }
 
@@ -442,14 +487,15 @@ impl<'a> TokenSlice<'a> {
             end: Point { line: l1, .. },
         }) = location.span
         {
-            let file = self.file().unwrap();
-            let lines = if l1 - l0 > 3 {
-                vec![l0, l0 + 1, l1]
-            } else {
-                (l0..=l1).collect()
-            };
-            for line_number in lines {
-                source.push((line_number, file.get_line(line_number).to_string()));
+            if let Some(file) = self.file() {
+                let lines = if l1 - l0 > 3 {
+                    vec![l0, l0 + 1, l1]
+                } else {
+                    (l0..=l1).collect()
+                };
+                for line_number in lines {
+                    source.push((line_number, file.get_line(line_number).to_string()));
+                }
             }
         }
 
@@ -491,11 +537,9 @@ impl<'a> NewSource<'a> {
             if let Some(end) = self
                 .lookahead
                 .iter()
-                .position(|token| token.token == Token::EndCommand)
+                .position(|token| token.token == Token::End)
             {
-                return Some(Tokens {
-                    tokens: self.lookahead.drain(..=end).collect(),
-                });
+                return Some(Tokens::new(self.lookahead.drain(..=end).collect()));
             }
             if !self.read_lookahead(macros) {
                 return None;
@@ -517,7 +561,7 @@ impl<'a> NewSource<'a> {
             match ScanToken::from_segment(&self.file.buffer[pos.clone()], seg_type) {
                 None => (),
                 Some(ScanToken::Token(token)) => {
-                    let end = token == Token::EndCommand;
+                    let end = token == Token::End;
                     pp.push_back(LexToken {
                         file: self.file,
                         token,
index af23a77053b21e99fb6bc7c35bdac5647f2a9e6f..1de961be7f63157c609b269b9f476d744ccfeef5 100644 (file)
@@ -237,7 +237,7 @@ impl ScanToken {
                 Some(Self::Token(Token::Id(Identifier::new("DOCUMENT").unwrap())))
             }
             Segment::StartCommand | Segment::SeparateCommands | Segment::EndCommand => {
-                Some(Self::Token(Token::EndCommand))
+                Some(Self::Token(Token::End))
             }
             Segment::ExpectedQuote => Some(Self::Error(ScanError::ExpectedQuote)),
             Segment::ExpectedExponent => {
index f9c28905d658bb8971600823356d6f775a58d711..a3c5f18b3729896c88612c0e96d4d65aaca20da3 100644 (file)
@@ -13,7 +13,7 @@ fn print_token(token: &Token) {
         Token::Id(s) => print!("Token::Id(String::from({s:?}))"),
         Token::Number(number) => print!("Token::Number({number:?})"),
         Token::String(s) => print!("Token::String(String::from({s:?}))"),
-        Token::EndCommand => print!("Token::EndCommand"),
+        Token::End => print!("Token::EndCommand"),
         Token::Punct(punct) => print!("Token::Punct(Punct::{punct:?})"),
     }
 }
@@ -75,18 +75,18 @@ WXYZ. /* unterminated end of line comment
             ScanToken::Token(Token::Id(Identifier::new("x").unwrap())),
             ScanToken::Token(Token::Punct(Punct::Underscore)),
             ScanToken::Token(Token::Id(Identifier::new("z").unwrap())),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::Id(Identifier::new("abcd.").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("abcd").unwrap())),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::Id(Identifier::new("QRSTUV").unwrap())),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::Id(Identifier::new("QrStUv").unwrap())),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::Id(Identifier::new("WXYZ").unwrap())),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
             ScanToken::Error(ScanError::UnexpectedChar('�')),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
         ],
     );
 }
@@ -142,7 +142,7 @@ and. with.
             ScanToken::Token(Token::Id(Identifier::new("withx").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("and.").unwrap())),
             ScanToken::Token(Token::Punct(Punct::With)),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
         ],
     );
 }
@@ -227,10 +227,10 @@ fn test_positive_numbers() {
             ScanToken::Token(Token::Number(1.0)),
             ScanToken::Token(Token::Number(1.0)),
             ScanToken::Token(Token::Number(1.0)),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::Number(123.0)),
-            ScanToken::Token(Token::EndCommand),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::Number(1.0)),
             ScanToken::Token(Token::Number(0.1)),
             ScanToken::Token(Token::Number(0.1)),
@@ -240,7 +240,7 @@ fn test_positive_numbers() {
             ScanToken::Token(Token::Number(70.0)),
             ScanToken::Token(Token::Number(60.0)),
             ScanToken::Token(Token::Number(0.006)),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::Number(30.0)),
             ScanToken::Token(Token::Number(0.04)),
             ScanToken::Token(Token::Number(5.0)),
@@ -251,7 +251,7 @@ fn test_positive_numbers() {
             ScanToken::Token(Token::Number(789.0)),
             ScanToken::Token(Token::Number(999.0)),
             ScanToken::Token(Token::Number(0.0112)),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
             ScanToken::Error(ScanError::ExpectedExponent(String::from("1e"))),
             ScanToken::Token(Token::Id(Identifier::new("e1").unwrap())),
             ScanToken::Error(ScanError::ExpectedExponent(String::from("1e+"))),
@@ -279,9 +279,9 @@ fn test_negative_numbers() {
             ScanToken::Token(Token::Number(-1.0)),
             ScanToken::Token(Token::Number(-1.0)),
             ScanToken::Token(Token::Number(-1.0)),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::Number(-123.0)),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::Number(-0.1)),
             ScanToken::Token(Token::Number(-0.1)),
             ScanToken::Token(Token::Number(-0.1)),
@@ -310,7 +310,7 @@ fn test_negative_numbers() {
             ScanToken::Error(ScanError::ExpectedExponent(String::from("-1e+"))),
             ScanToken::Error(ScanError::ExpectedExponent(String::from("-1e-"))),
             ScanToken::Token(Token::Number(-1.0)),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
         ],
     );
 }
@@ -369,9 +369,9 @@ x"4142"
             ScanToken::Token(Token::String(String::from("foobar"))),
             ScanToken::Token(Token::String(String::from("foo"))),
             ScanToken::Token(Token::Punct(Punct::Plus)),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::String(String::from("bar"))),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::Punct(Punct::Plus)),
             ScanToken::Token(Token::String(String::from("AB5152"))),
             ScanToken::Token(Token::String(String::from("4142QR"))),
@@ -424,27 +424,27 @@ next command.
 "#,
         Syntax::Auto,
         &[
-            ScanToken::Token(Token::EndCommand),
-            ScanToken::Token(Token::EndCommand),
-            ScanToken::Token(Token::EndCommand),
-            ScanToken::Token(Token::EndCommand),
-            ScanToken::Token(Token::EndCommand),
-            ScanToken::Token(Token::EndCommand),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
+            ScanToken::Token(Token::End),
+            ScanToken::Token(Token::End),
+            ScanToken::Token(Token::End),
+            ScanToken::Token(Token::End),
+            ScanToken::Token(Token::End),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::Id(Identifier::new("com").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("is").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("ambiguous").unwrap())),
             ScanToken::Token(Token::Punct(Punct::With)),
             ScanToken::Token(Token::Id(Identifier::new("COMPUTE").unwrap())),
-            ScanToken::Token(Token::EndCommand),
-            ScanToken::Token(Token::EndCommand),
-            ScanToken::Token(Token::EndCommand),
-            ScanToken::Token(Token::EndCommand),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
+            ScanToken::Token(Token::End),
+            ScanToken::Token(Token::End),
+            ScanToken::Token(Token::End),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::Id(Identifier::new("next").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("command").unwrap())),
-            ScanToken::Token(Token::EndCommand),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
+            ScanToken::Token(Token::End),
         ],
     );
 }
@@ -467,23 +467,23 @@ second paragraph.
         &[
             ScanToken::Token(Token::Id(Identifier::new("DOCUMENT").unwrap())),
             ScanToken::Token(Token::String(String::from("DOCUMENT one line."))),
-            ScanToken::Token(Token::EndCommand),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::Id(Identifier::new("DOCUMENT").unwrap())),
             ScanToken::Token(Token::String(String::from("DOC more"))),
             ScanToken::Token(Token::String(String::from("    than"))),
             ScanToken::Token(Token::String(String::from("        one"))),
             ScanToken::Token(Token::String(String::from("            line."))),
-            ScanToken::Token(Token::EndCommand),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::Id(Identifier::new("DOCUMENT").unwrap())),
             ScanToken::Token(Token::String(String::from("docu"))),
             ScanToken::Token(Token::String(String::from("first.paragraph"))),
             ScanToken::Token(Token::String(String::from("isn't parsed as tokens"))),
             ScanToken::Token(Token::String(String::from(""))),
             ScanToken::Token(Token::String(String::from("second paragraph."))),
-            ScanToken::Token(Token::EndCommand),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
+            ScanToken::Token(Token::End),
         ],
     );
 }
@@ -503,15 +503,15 @@ FILE /*
             ScanToken::Token(Token::Id(Identifier::new("FIL").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("label").unwrap())),
             ScanToken::Token(Token::String(String::from("isn't quoted"))),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::Id(Identifier::new("FILE").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("lab").unwrap())),
             ScanToken::Token(Token::String(String::from("is quoted"))),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::Id(Identifier::new("FILE").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("lab").unwrap())),
             ScanToken::Token(Token::String(String::from("not quoted here either"))),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
         ],
     );
 }
@@ -535,13 +535,13 @@ end data
         &[
             ScanToken::Token(Token::Id(Identifier::new("begin").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("data").unwrap())),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::String(String::from("123"))),
             ScanToken::Token(Token::String(String::from("xxx"))),
             ScanToken::Token(Token::Id(Identifier::new("end").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("data").unwrap())),
-            ScanToken::Token(Token::EndCommand),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::Id(Identifier::new("BEG").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("DAT").unwrap())),
             ScanToken::Token(Token::String(String::from("5 6 7 /* x"))),
@@ -549,7 +549,7 @@ end data
             ScanToken::Token(Token::String(String::from("end  data"))),
             ScanToken::Token(Token::Id(Identifier::new("end").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("data").unwrap())),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
         ],
     );
 }
@@ -581,7 +581,7 @@ end
             ScanToken::Token(Token::Id(Identifier::new("d").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("e").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("f").unwrap())),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::String(String::from("  do repeat a=1 thru 5."))),
             ScanToken::Token(Token::String(String::from("another command."))),
             ScanToken::Token(Token::String(String::from("second command"))),
@@ -591,7 +591,7 @@ end
             ))),
             ScanToken::Token(Token::Id(Identifier::new("end").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("repeat").unwrap())),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
         ],
     );
 }
@@ -628,7 +628,7 @@ end repeat
             ScanToken::Token(Token::Id(Identifier::new("d").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("e").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("f").unwrap())),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::String(String::from("do repeat a=1 thru 5"))),
             ScanToken::Token(Token::String(String::from("another command"))),
             ScanToken::Token(Token::String(String::from("second command"))),
@@ -638,13 +638,13 @@ end repeat
             ))),
             ScanToken::Token(Token::Id(Identifier::new("end").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("repeat").unwrap())),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::Id(Identifier::new("do").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("repeat").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("#a").unwrap())),
             ScanToken::Token(Token::Punct(Punct::Equals)),
             ScanToken::Token(Token::Number(1.0)),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::String(String::from("  inner command"))),
             ScanToken::Token(Token::Id(Identifier::new("end").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("repeat").unwrap())),
@@ -672,19 +672,19 @@ fourth command.
             ScanToken::Token(Token::Id(Identifier::new("of").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("first").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("command").unwrap())),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::Id(Identifier::new("second").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("command").unwrap())),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::Id(Identifier::new("third").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("command").unwrap())),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::Id(Identifier::new("fourth").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("command").unwrap())),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
             ScanToken::Token(Token::Id(Identifier::new("fifth").unwrap())),
             ScanToken::Token(Token::Id(Identifier::new("command").unwrap())),
-            ScanToken::Token(Token::EndCommand),
+            ScanToken::Token(Token::End),
         ],
     );
 }
@@ -716,7 +716,7 @@ var1 var2 var3
                 ScanToken::Token(Token::Punct(Punct::RParen)),
                 ScanToken::Token(Token::String(String::from("var1 var2 var3"))),
                 ScanToken::Token(Token::Id(Identifier::new("!enddefine").unwrap())),
-                ScanToken::Token(Token::EndCommand),
+                ScanToken::Token(Token::End),
             ],
         );
     }
@@ -735,7 +735,7 @@ var1 var2 var3
                 ScanToken::Token(Token::Punct(Punct::RParen)),
                 ScanToken::Token(Token::String(String::from(" var1 var2 var3"))),
                 ScanToken::Token(Token::Id(Identifier::new("!enddefine").unwrap())),
-                ScanToken::Token(Token::EndCommand),
+                ScanToken::Token(Token::End),
             ],
         );
     }
@@ -754,7 +754,7 @@ var1 var2 var3!enddefine.
                 ScanToken::Token(Token::Punct(Punct::RParen)),
                 ScanToken::Token(Token::String(String::from("var1 var2 var3"))),
                 ScanToken::Token(Token::Id(Identifier::new("!enddefine").unwrap())),
-                ScanToken::Token(Token::EndCommand),
+                ScanToken::Token(Token::End),
             ],
         );
     }
@@ -772,7 +772,7 @@ var1 var2 var3!enddefine.
                 ScanToken::Token(Token::Punct(Punct::RParen)),
                 ScanToken::Token(Token::String(String::from("var1 var2 var3"))),
                 ScanToken::Token(Token::Id(Identifier::new("!enddefine").unwrap())),
-                ScanToken::Token(Token::EndCommand),
+                ScanToken::Token(Token::End),
             ],
         );
     }
@@ -790,7 +790,7 @@ var1 var2 var3!enddefine.
                 ScanToken::Token(Token::Punct(Punct::LParen)),
                 ScanToken::Token(Token::Punct(Punct::RParen)),
                 ScanToken::Token(Token::Id(Identifier::new("!enddefine").unwrap())),
-                ScanToken::Token(Token::EndCommand),
+                ScanToken::Token(Token::End),
             ],
         );
     }
@@ -812,7 +812,7 @@ var1 var2 var3!enddefine.
                 ScanToken::Token(Token::String(String::from(""))),
                 ScanToken::Token(Token::String(String::from(""))),
                 ScanToken::Token(Token::Id(Identifier::new("!enddefine").unwrap())),
-                ScanToken::Token(Token::EndCommand),
+                ScanToken::Token(Token::End),
             ],
         );
     }
@@ -841,7 +841,7 @@ var1 var2 var3!enddefine.
                 ScanToken::Token(Token::Punct(Punct::RParen)),
                 ScanToken::Token(Token::Punct(Punct::RParen)),
                 ScanToken::Token(Token::Id(Identifier::new("!enddefine").unwrap())),
-                ScanToken::Token(Token::EndCommand),
+                ScanToken::Token(Token::End),
             ],
         );
     }
@@ -874,7 +874,7 @@ var1 var2 var3!enddefine.
                 ScanToken::Token(Token::Punct(Punct::RParen)),
                 ScanToken::Token(Token::Punct(Punct::RParen)),
                 ScanToken::Token(Token::Id(Identifier::new("!enddefine").unwrap())),
-                ScanToken::Token(Token::EndCommand),
+                ScanToken::Token(Token::End),
             ],
         );
     }
@@ -903,7 +903,7 @@ content 2
                 ScanToken::Token(Token::String(String::from("content 1"))),
                 ScanToken::Token(Token::String(String::from("content 2"))),
                 ScanToken::Token(Token::Id(Identifier::new("!enddefine").unwrap())),
-                ScanToken::Token(Token::EndCommand),
+                ScanToken::Token(Token::End),
             ],
         );
     }
@@ -918,13 +918,13 @@ data list /x 1.
             &[
                 ScanToken::Token(Token::Id(Identifier::new("define").unwrap())),
                 ScanToken::Token(Token::String(String::from("!macro1"))),
-                ScanToken::Token(Token::EndCommand),
+                ScanToken::Token(Token::End),
                 ScanToken::Token(Token::Id(Identifier::new("data").unwrap())),
                 ScanToken::Token(Token::Id(Identifier::new("list").unwrap())),
                 ScanToken::Token(Token::Punct(Punct::Slash)),
                 ScanToken::Token(Token::Id(Identifier::new("x").unwrap())),
                 ScanToken::Token(Token::Number(1.0)),
-                ScanToken::Token(Token::EndCommand),
+                ScanToken::Token(Token::End),
             ],
         );
     }
@@ -941,13 +941,13 @@ data list /x 1.
                 ScanToken::Token(Token::Id(Identifier::new("define").unwrap())),
                 ScanToken::Token(Token::String(String::from("!macro1"))),
                 ScanToken::Token(Token::Id(Identifier::new("x").unwrap())),
-                ScanToken::Token(Token::EndCommand),
+                ScanToken::Token(Token::End),
                 ScanToken::Token(Token::Id(Identifier::new("data").unwrap())),
                 ScanToken::Token(Token::Id(Identifier::new("list").unwrap())),
                 ScanToken::Token(Token::Punct(Punct::Slash)),
                 ScanToken::Token(Token::Id(Identifier::new("x").unwrap())),
                 ScanToken::Token(Token::Number(1.0)),
-                ScanToken::Token(Token::EndCommand),
+                ScanToken::Token(Token::End),
             ],
         );
     }
@@ -964,15 +964,15 @@ data list /x 1.
                 ScanToken::Token(Token::Id(Identifier::new("define").unwrap())),
                 ScanToken::Token(Token::String(String::from("!macro1"))),
                 ScanToken::Token(Token::Punct(Punct::LParen)),
-                ScanToken::Token(Token::EndCommand),
+                ScanToken::Token(Token::End),
                 ScanToken::Token(Token::Id(Identifier::new("x").unwrap())),
-                ScanToken::Token(Token::EndCommand),
+                ScanToken::Token(Token::End),
                 ScanToken::Token(Token::Id(Identifier::new("data").unwrap())),
                 ScanToken::Token(Token::Id(Identifier::new("list").unwrap())),
                 ScanToken::Token(Token::Punct(Punct::Slash)),
                 ScanToken::Token(Token::Id(Identifier::new("x").unwrap())),
                 ScanToken::Token(Token::Number(1.0)),
-                ScanToken::Token(Token::EndCommand),
+                ScanToken::Token(Token::End),
             ],
         );
     }
@@ -989,13 +989,13 @@ data list /x 1.
             &[
                 ScanToken::Token(Token::Id(Identifier::new("define").unwrap())),
                 ScanToken::Token(Token::String(String::from("!macro1"))),
-                ScanToken::Token(Token::EndCommand),
+                ScanToken::Token(Token::End),
                 ScanToken::Token(Token::Id(Identifier::new("data").unwrap())),
                 ScanToken::Token(Token::Id(Identifier::new("list").unwrap())),
                 ScanToken::Token(Token::Punct(Punct::Slash)),
                 ScanToken::Token(Token::Id(Identifier::new("x").unwrap())),
                 ScanToken::Token(Token::Number(1.0)),
-                ScanToken::Token(Token::EndCommand),
+                ScanToken::Token(Token::End),
             ],
         );
     }
index 847c1eae06de233ef43c887108963211d1da57fa..06feca3ec6a9871e070a2276088b83a2ced7bb5f 100644 (file)
@@ -17,7 +17,7 @@ pub enum Token {
     ///
     /// Usually this is `.`, but a blank line also separates commands, and in
     /// batch mode any line that begins with a non-blank starts a new command.
-    EndCommand,
+    End,
 
     /// Operators, punctuators, and reserved words.
     Punct(Punct),
@@ -81,7 +81,7 @@ impl Display for Token {
                     write!(f, "\"")
                 }
             }
-            Token::EndCommand => write!(f, "."),
+            Token::End => write!(f, "."),
             Token::Punct(punct) => punct.fmt(f),
         }
     }
index a0308996eab7db864f49e8c3d8b478becaa77b5d..debf9c3daf69475dc1f7c99326099d3cc14ba41d 100644 (file)
@@ -381,7 +381,7 @@ impl From<&Token> for TokenClass {
     fn from(source: &Token) -> Self {
         match source {
             Token::Id(_) | Token::Number(_) | Token::String(_) => Self::Id,
-            Token::EndCommand => Self::EndCommand,
+            Token::End => Self::EndCommand,
             Token::Punct(punct) => match punct {
                 Punct::LParen
                 | Punct::RParen
@@ -588,7 +588,7 @@ impl<'a> Parser<'a> {
 
     fn push_arg(&mut self, token: &Token, syntax: &str, error: &impl Fn(MacroError)) {
         let param = &self.macro_.parameters[self.args.len() - 1];
-        if let Token::EndCommand = token {
+        if let Token::End = token {
             if let Some(arg) = &self.args[self.arg_index] {
                 let param = &self.macro_.parameters[self.args.len() - 1];
 
@@ -650,7 +650,7 @@ impl<'a> Parser<'a> {
             self.n_tokens += 1;
             self.args[self.arg_index].get_or_insert(Vec::new());
             self.state = ParserState::Arg;
-        } else if param.is_positional() && matches!(token, Token::EndCommand) {
+        } else if param.is_positional() && matches!(token, Token::End) {
             self.finished();
         } else {
             error(MacroError::UnexpectedToken {
@@ -1617,7 +1617,7 @@ impl<'a> Call<'a> {
     {
         let mut parser = Parser::new(macros, &tokens.get(0)?.token)?;
         for token in tokens[1..].iter().chain(&[MacroToken {
-            token: Token::EndCommand,
+            token: Token::End,
             syntax: String::from(""),
         }]) {
             if parser.push(&token.token, &token.syntax, error) == ParseStatus::Complete {