Preserve numeric underscore and hexadecimal notation through formatting.
This commit is contained in:
parent
0b7682306f
commit
6bd8e94e17
|
@ -1,8 +1,3 @@
|
||||||
use itertools::Itertools;
|
|
||||||
use ordinal::Ordinal;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use vec1::Vec1;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{
|
ast::{
|
||||||
Annotation, Arg, ArgName, AssignmentKind, BinOp, ByteArrayFormatPreference, CallArg,
|
Annotation, Arg, ArgName, AssignmentKind, BinOp, ByteArrayFormatPreference, CallArg,
|
||||||
|
@ -23,6 +18,11 @@ use crate::{
|
||||||
},
|
},
|
||||||
tipo::{self, Type},
|
tipo::{self, Type},
|
||||||
};
|
};
|
||||||
|
use itertools::Itertools;
|
||||||
|
use num_bigint::BigInt;
|
||||||
|
use ordinal::Ordinal;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use vec1::Vec1;
|
||||||
|
|
||||||
const INDENT: isize = 2;
|
const INDENT: isize = 2;
|
||||||
const DOCS_MAX_COLUMNS: isize = 80;
|
const DOCS_MAX_COLUMNS: isize = 80;
|
||||||
|
@ -665,7 +665,7 @@ impl<'comments> Formatter<'comments> {
|
||||||
.append("\"")
|
.append("\"")
|
||||||
.append(Document::String(hex::encode(bytes)))
|
.append(Document::String(hex::encode(bytes)))
|
||||||
.append("\""),
|
.append("\""),
|
||||||
ByteArrayFormatPreference::ArrayOfBytes(base) => "#"
|
ByteArrayFormatPreference::ArrayOfBytes(Base::Decimal { .. }) => "#"
|
||||||
.to_doc()
|
.to_doc()
|
||||||
.append(
|
.append(
|
||||||
flex_break("[", "[")
|
flex_break("[", "[")
|
||||||
|
@ -675,6 +675,25 @@ impl<'comments> Formatter<'comments> {
|
||||||
.append("]"),
|
.append("]"),
|
||||||
)
|
)
|
||||||
.group(),
|
.group(),
|
||||||
|
ByteArrayFormatPreference::ArrayOfBytes(Base::Hexadecimal) => "#"
|
||||||
|
.to_doc()
|
||||||
|
.append(
|
||||||
|
flex_break("[", "[")
|
||||||
|
.append(join(
|
||||||
|
bytes.iter().map(|b| {
|
||||||
|
Document::String(if *b < 16 {
|
||||||
|
format!("0x0{b:x}")
|
||||||
|
} else {
|
||||||
|
format!("{b:#x}")
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
break_(",", ", "),
|
||||||
|
))
|
||||||
|
.nest(INDENT)
|
||||||
|
.append(break_(",", ""))
|
||||||
|
.append("]"),
|
||||||
|
)
|
||||||
|
.group(),
|
||||||
ByteArrayFormatPreference::Utf8String => nil()
|
ByteArrayFormatPreference::Utf8String => nil()
|
||||||
.append("\"")
|
.append("\"")
|
||||||
.append(Document::String(String::from_utf8(bytes.to_vec()).unwrap()))
|
.append(Document::String(String::from_utf8(bytes.to_vec()).unwrap()))
|
||||||
|
@ -682,8 +701,37 @@ impl<'comments> Formatter<'comments> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn int<'a>(&mut self, i: &'a str, base: &Base) -> Document<'a> {
|
pub fn int<'a>(&mut self, s: &'a str, base: &Base) -> Document<'a> {
|
||||||
i.to_doc()
|
match base {
|
||||||
|
Base::Decimal { numeric_underscore } if *numeric_underscore => {
|
||||||
|
let s = s
|
||||||
|
.chars()
|
||||||
|
.rev()
|
||||||
|
.enumerate()
|
||||||
|
.flat_map(|(i, c)| {
|
||||||
|
if i != 0 && i % 3 == 0 {
|
||||||
|
Some('_')
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
.into_iter()
|
||||||
|
.chain(std::iter::once(c))
|
||||||
|
})
|
||||||
|
.collect::<String>()
|
||||||
|
.chars()
|
||||||
|
.rev()
|
||||||
|
.collect::<String>();
|
||||||
|
|
||||||
|
Document::String(s)
|
||||||
|
}
|
||||||
|
Base::Decimal { .. } => s.to_doc(),
|
||||||
|
Base::Hexadecimal => Document::String(format!(
|
||||||
|
"0x{}",
|
||||||
|
BigInt::parse_bytes(s.as_bytes(), 10)
|
||||||
|
.expect("Invalid parsed hexadecimal digits ?!")
|
||||||
|
.to_str_radix(16),
|
||||||
|
)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expr<'a>(&mut self, expr: &'a UntypedExpr) -> Document<'a> {
|
pub fn expr<'a>(&mut self, expr: &'a UntypedExpr) -> Document<'a> {
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub fn lexer() -> impl Parser<char, Vec<(Token, Span)>, Error = ParseError> {
|
||||||
.at_least(1)
|
.at_least(1)
|
||||||
.at_most(3)
|
.at_most(3)
|
||||||
.separated_by(just("_"))
|
.separated_by(just("_"))
|
||||||
.at_least(1)
|
.at_least(2)
|
||||||
.flatten()
|
.flatten()
|
||||||
.collect::<String>()
|
.collect::<String>()
|
||||||
.map(|value| Token::Int {
|
.map(|value| Token::Int {
|
||||||
|
|
|
@ -838,9 +838,10 @@ fn pipes_and_expressions() {
|
||||||
fn hex_and_numeric_underscore() {
|
fn hex_and_numeric_underscore() {
|
||||||
let src = indoc! {r#"
|
let src = indoc! {r#"
|
||||||
fn foo() {
|
fn foo() {
|
||||||
let a = 1_000_000
|
let a = 1_000_000 + 1_423 + 10393841
|
||||||
let b = 0xA4
|
let b = 0xa4 - 0xcd
|
||||||
let c = #[ 0xFD, 0x12, 0x00, 0x1B ]
|
let c = #[0xfd, 0x12, 0x00, 0x1b, 0x0a, 0x90]
|
||||||
|
let d = -100_000
|
||||||
}
|
}
|
||||||
"#};
|
"#};
|
||||||
|
|
||||||
|
|
|
@ -3592,6 +3592,7 @@ fn int_parsing_numeric_underscore() {
|
||||||
fn foo() {
|
fn foo() {
|
||||||
let i = 1_234_567
|
let i = 1_234_567
|
||||||
let j = 1_000_000
|
let j = 1_000_000
|
||||||
|
let k = -10_000
|
||||||
}
|
}
|
||||||
"#};
|
"#};
|
||||||
assert_definitions(
|
assert_definitions(
|
||||||
|
@ -3599,49 +3600,69 @@ fn int_parsing_numeric_underscore() {
|
||||||
vec![ast::Definition::Fn(Function {
|
vec![ast::Definition::Fn(Function {
|
||||||
arguments: vec![],
|
arguments: vec![],
|
||||||
body: expr::UntypedExpr::Sequence {
|
body: expr::UntypedExpr::Sequence {
|
||||||
location: Span::new((), 13..50),
|
location: Span::new((), 17..76),
|
||||||
expressions: vec![
|
expressions: vec![
|
||||||
expr::UntypedExpr::Assignment {
|
expr::UntypedExpr::Assignment {
|
||||||
location: Span::new((), 13..30),
|
location: Span::new((), 17..34),
|
||||||
value: Box::new(expr::UntypedExpr::Int {
|
value: Box::new(expr::UntypedExpr::Int {
|
||||||
location: Span::new((), 21..30),
|
location: Span::new((), 25..34),
|
||||||
value: "1234567".to_string(),
|
value: "1234567".to_string(),
|
||||||
base: Base::Decimal {
|
base: Base::Decimal {
|
||||||
numeric_underscore: true,
|
numeric_underscore: true,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
pattern: ast::Pattern::Var {
|
pattern: ast::Pattern::Var {
|
||||||
location: Span::new((), 17..18),
|
location: Span::new((), 21..22),
|
||||||
name: "i".to_string(),
|
name: "i".to_string(),
|
||||||
},
|
},
|
||||||
kind: ast::AssignmentKind::Let,
|
kind: ast::AssignmentKind::Let,
|
||||||
annotation: None,
|
annotation: None,
|
||||||
},
|
},
|
||||||
expr::UntypedExpr::Assignment {
|
expr::UntypedExpr::Assignment {
|
||||||
location: Span::new((), 33..50),
|
location: Span::new((), 39..56),
|
||||||
value: Box::new(expr::UntypedExpr::Int {
|
value: Box::new(expr::UntypedExpr::Int {
|
||||||
location: Span::new((), 41..50),
|
location: Span::new((), 47..56),
|
||||||
value: "1000000".to_string(),
|
value: "1000000".to_string(),
|
||||||
base: Base::Decimal {
|
base: Base::Decimal {
|
||||||
numeric_underscore: true,
|
numeric_underscore: true,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
pattern: ast::Pattern::Var {
|
pattern: ast::Pattern::Var {
|
||||||
location: Span::new((), 37..38),
|
location: Span::new((), 43..44),
|
||||||
name: "j".to_string(),
|
name: "j".to_string(),
|
||||||
},
|
},
|
||||||
kind: ast::AssignmentKind::Let,
|
kind: ast::AssignmentKind::Let,
|
||||||
annotation: None,
|
annotation: None,
|
||||||
},
|
},
|
||||||
|
expr::UntypedExpr::Assignment {
|
||||||
|
location: Span::new((), 61..76),
|
||||||
|
value: Box::new(expr::UntypedExpr::UnOp {
|
||||||
|
op: ast::UnOp::Negate,
|
||||||
|
location: Span::new((), 69..76),
|
||||||
|
value: Box::new(expr::UntypedExpr::Int {
|
||||||
|
location: Span::new((), 70..76),
|
||||||
|
value: "10000".to_string(),
|
||||||
|
base: Base::Decimal {
|
||||||
|
numeric_underscore: true,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
pattern: ast::Pattern::Var {
|
||||||
|
location: Span::new((), 65..66),
|
||||||
|
name: "k".to_string(),
|
||||||
|
},
|
||||||
|
kind: ast::AssignmentKind::Let,
|
||||||
|
annotation: None,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
doc: None,
|
doc: None,
|
||||||
location: Span::new((), 0..8),
|
location: Span::new((), 2..10),
|
||||||
name: "foo".to_string(),
|
name: "foo".to_string(),
|
||||||
public: false,
|
public: false,
|
||||||
return_annotation: None,
|
return_annotation: None,
|
||||||
return_type: (),
|
return_type: (),
|
||||||
end_position: 51,
|
end_position: 77,
|
||||||
can_error: true,
|
can_error: true,
|
||||||
})],
|
})],
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue