Created
December 12, 2019 18:23
-
-
Save sploiselle/a11bc1e4cc277e8bcd6e8277b5ab15fb to your computer and use it in GitHub Desktop.
Parsing a string as a decimal in a single pass with a lot of if statements
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
for c in s.chars() { | |
if c == '.' { | |
if seen_decimal { | |
bail!("multiple decimal points in numeric literal: {}", s) | |
} | |
seen_decimal = true; | |
continue; | |
} | |
if c == '-' { | |
if seen_e_notation { | |
if e_negative { | |
bail!("multiple negative signs in e-notation: {}", s); | |
} | |
e_negative = true; | |
continue; | |
} | |
if negative { | |
bail!("multiple negative signs in numeric literal: {}", s); | |
} | |
negative = true; | |
continue; | |
} | |
if c == 'e' || c == 'E' { | |
if seen_e_notation { | |
bail!("more than one E for e-notation in numeric literal: {}", s) | |
} | |
seen_e_notation = true; | |
continue; | |
} | |
let digit = c | |
.to_digit(10) | |
.ok_or_else(|| format_err!("invalid digit in numeric literal: {}", s))?; | |
if seen_e_notation { | |
e_exponent = e_exponent | |
.checked_mul(10) | |
.ok_or_else(|| format_err!("exponent in e-notation overflows u8: {}", s))?; | |
e_exponent = e_exponent | |
.checked_add(digit as u8) | |
.ok_or_else(|| format_err!("exponent in e-notation overflows u8: {}", s))?; | |
} else { | |
precision += 1; | |
if seen_decimal { | |
scale += 1; | |
} | |
significand = significand | |
.checked_mul(10) | |
.ok_or_else(|| format_err!("numeric literal overflows i128: {}", s))?; | |
significand = significand | |
.checked_add(i128::from(digit)) | |
.ok_or_else(|| format_err!("numeric literal overflows i128: {}", s))?; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment