]> Repositorios git - scryer-prolog.git/commitdiff
ENHANCED: Support '_' followed by layout text sequence in integers.
authorMarkus Triska <[email protected]>
Sat, 27 Nov 2021 08:11:41 +0000 (09:11 +0100)
committerMarkus Triska <[email protected]>
Sat, 27 Nov 2021 09:09:39 +0000 (10:09 +0100)
This is handy for writing large integers, for example in cryptographic
applications.

This addresses #994.

Examples:

    ?- X = 1_000_000.
    %@    X = 1000000.

    ?- X = 1_
    000_
    000.
    %@    X = 1000000.

crates/prolog_parser/src/lexer.rs

index 8bd77d5b1ea94061c844cee4ca95ddfa0b848bb7..5c3557059bc13a11d8dc44c1d6d21e6ea9532ba5 100644 (file)
@@ -559,16 +559,37 @@ impl<'a, R: Read> Lexer<'a, R> {
         Token::Constant(Constant::Float(result))
     }
 
+    fn skip_underscore_in_number(&mut self) -> Result<char, ParserError> {
+        let mut c = self.lookahead_char()?;
+
+        if c == '_' {
+            self.skip_char()?;
+            c = self.lookahead_char()?;
+            while layout_char!(c) {
+                self.skip_char()?;
+                c = self.lookahead_char()?;
+            }
+
+            if decimal_digit_char!(c) {
+                Ok(c)
+            } else {
+                Err(ParserError::ParseBigInt(self.line_num, self.col_num))
+            }
+        } else {
+            Ok(c)
+        }
+    }
+
     pub fn number_token(&mut self) -> Result<Token, ParserError> {
         let mut token = String::new();
 
         token.push(self.skip_char()?);
-        let mut c = self.lookahead_char()?;
+        let mut c = self.skip_underscore_in_number()?;
 
         while decimal_digit_char!(c) {
             token.push(c);
             self.skip_char()?;
-            c = self.lookahead_char()?;
+            c = self.skip_underscore_in_number()?;
         }
 
         if decimal_point_char!(c) {