ENHANCED: Support '_' followed by layout text sequence in integers.

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.
This commit is contained in:
Markus Triska
2021-11-27 09:11:41 +01:00
parent ca28f24e42
commit 1647e67dd4

View File

@@ -559,16 +559,37 @@ impl<'a, R: Read> Lexer<'a, R> {
Token::Constant(Constant::Float(result)) 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> { pub fn number_token(&mut self) -> Result<Token, ParserError> {
let mut token = String::new(); let mut token = String::new();
token.push(self.skip_char()?); token.push(self.skip_char()?);
let mut c = self.lookahead_char()?; let mut c = self.skip_underscore_in_number()?;
while decimal_digit_char!(c) { while decimal_digit_char!(c) {
token.push(c); token.push(c);
self.skip_char()?; self.skip_char()?;
c = self.lookahead_char()?; c = self.skip_underscore_in_number()?;
} }
if decimal_point_char!(c) { if decimal_point_char!(c) {