Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement i128 and u128. #284

Merged
merged 13 commits into from
Dec 3, 2020
5 changes: 0 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,3 @@ jobs:
- name: Build and Run QEMU tests
working-directory: firmware/qemu
run: ./test.sh
- name: Backward compatibility check against decoder v0.1.0
working-directory: firmware/qemu
run: |
cargo install --debug --git https://github.com/knurling-rs/defmt --tag v0.1.0-without-version-check qemu-run
CARGO_TARGET_THUMBV7M_NONE_EABI_RUNNER=qemu-run ./test.sh
22 changes: 21 additions & 1 deletion decoder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,8 +332,10 @@ enum Arg<'t> {
F32(f32),
/// U8, U16, U24 and U32
Uxx(u64),
U128(u128),
/// I8, I16, I24 and I32
Ixx(i64),
I128(i128),
/// Str
Str(String),
/// Interned string
Expand Down Expand Up @@ -725,6 +727,10 @@ impl<'t, 'b> Decoder<'t, 'b> {
let data = self.bytes.read_i64::<LE>()?;
args.push(Arg::Ixx(data as i64));
}
Type::I128 => {
let data = self.bytes.read_i128::<LE>()?;
args.push(Arg::I128(data));
}
Type::I8 => {
let data = self.bytes.read_i8()?;
args.push(Arg::Ixx(data as i64));
Expand Down Expand Up @@ -752,6 +758,10 @@ impl<'t, 'b> Decoder<'t, 'b> {
let data = self.bytes.read_u64::<LE>()?;
args.push(Arg::Uxx(data as u64));
}
Type::U128 => {
let data = self.bytes.read_u128::<LE>()?;
args.push(Arg::U128(data));
}
Type::Usize => {
let unsigned = read_leb128(&mut self.bytes)?;
args.push(Arg::Uxx(unsigned))
Expand Down Expand Up @@ -884,7 +894,9 @@ fn format_args_real(format: &str, args: &[Arg]) -> Result<String, fmt::Error> {
_ => write!(buf, "{}", x)?,
}
}
Arg::U128(x) => write!(buf, "{}", x)?,
Arg::Ixx(x) => write!(buf, "{}", x)?,
Arg::I128(x) => write!(buf, "{}", x)?,
Arg::Str(x) => write!(buf, "{}", x)?,
Arg::IStr(x) => write!(buf, "{}", x)?,
Arg::Format { format, args } => buf.push_str(&format_args(format, args)),
Expand Down Expand Up @@ -996,7 +1008,7 @@ mod tests {

#[test]
fn all_integers() {
const FMT: &str = "Hello, {:u8} {:u16} {:u24} {:u32} {:i8} {:i16} {:i32}!";
const FMT: &str = "Hello, {:u8} {:u16} {:u24} {:u32} {:u64} {:u128} {:i8} {:i16} {:i32} {:i64} {:i128}!";
let mut entries = BTreeMap::new();
entries.insert(0, TableEntry::new_without_symbol(Tag::Info, FMT.to_owned()));

Expand All @@ -1009,9 +1021,13 @@ mod tests {
0xff, 0xff, // u16
0, 0, 1, // u24
0xff, 0xff, 0xff, 0xff, // u32
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // u64
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // u128
0xff, // i8
0xff, 0xff, // i16
0xff, 0xff, 0xff, 0xff, // i32
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // i64
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // i128
];

assert_eq!(
Expand All @@ -1027,9 +1043,13 @@ mod tests {
Arg::Uxx(u16::max_value().into()), // u16
Arg::Uxx(0x10000), // u24
Arg::Uxx(u32::max_value().into()), // u32
Arg::Uxx(u64::max_value().into()), // u64
Arg::U128(u128::max_value().into()),
Arg::Ixx(-1), // i8
Arg::Ixx(-1), // i16
Arg::Ixx(-1), // i32
Arg::Ixx(-1), // i64
Arg::I128(-1), // i128
],
},
bytes.len(),
Expand Down
6 changes: 5 additions & 1 deletion firmware/qemu/src/bin/log.out
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,8 @@
0.000094 INFO [S { x: -1, y: 2 }, S { x: -1, y: 2 }]
0.000095 INFO [Some(S { x: -1, y: 2 }), None]
0.000096 INFO 127.0.0.1:8888
0.000097 INFO QEMU test finished!
0.000097 INFO i128: 0 = 0, -1 = -1, MAX = 170141183460469231731687303715884105727, MIN = -170141183460469231731687303715884105728
0.000098 INFO u128: 0 = 0, -1 = 1, MAX = 340282366920938463463374607431768211455, MIN = 0
0.000099 INFO 340282366920938
0.000100 INFO -170141183460469
0.000101 INFO QEMU test finished!
6 changes: 5 additions & 1 deletion firmware/qemu/src/bin/log.release.out
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,8 @@
0.000092 INFO [S { x: -1, y: 2 }, S { x: -1, y: 2 }]
0.000093 INFO [Some(S { x: -1, y: 2 }), None]
0.000094 INFO 127.0.0.1:8888
0.000095 INFO QEMU test finished!
0.000095 INFO i128: 0 = 0, -1 = -1, MAX = 170141183460469231731687303715884105727, MIN = -170141183460469231731687303715884105728
0.000096 INFO u128: 0 = 0, -1 = 1, MAX = 340282366920938463463374607431768211455, MIN = 0
0.000097 INFO 340282366920938
0.000098 INFO -170141183460469
0.000099 INFO QEMU test finished!
19 changes: 19 additions & 0 deletions firmware/qemu/src/bin/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,25 @@ fn main() -> ! {
defmt::info!("{:?}", Display2Format::<consts::U32>(&addr));
}

defmt::info!(
"i128: 0 = {:i128}, -1 = {:i128}, MAX = {:i128}, MIN = {:i128}",
0,
-1,
i128::max_value(),
i128::min_value()
);

defmt::info!(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you also test here that we can format u128 and i128 values using the {:?} format specifier?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it ok now?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, looks good; thanks! I'll re-approve the PR but it will need a rebase before it can be merged.

"u128: 0 = {:u128}, -1 = {:u128}, MAX = {:u128}, MIN = {:u128}",
0,
1,
u128::max_value(),
u128::min_value()
);

defmt::info!("{:?}", 340282366920938u128);
defmt::info!("{:?}", -170141183460469i128);

defmt::info!("QEMU test finished!");

loop {
Expand Down
6 changes: 6 additions & 0 deletions macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1069,6 +1069,9 @@ impl Codegen {
defmt_parser::Type::I64 => {
exprs.push(quote!(_fmt_.i64(#arg)));
}
defmt_parser::Type::I128 => {
exprs.push(quote!(_fmt_.i128(#arg)));
}
defmt_parser::Type::I8 => {
exprs.push(quote!(_fmt_.i8(#arg)));
}
Expand All @@ -1093,6 +1096,9 @@ impl Codegen {
defmt_parser::Type::U64 => {
exprs.push(quote!(_fmt_.u64(#arg)));
}
defmt_parser::Type::U128 => {
exprs.push(quote!(_fmt_.u128(#arg)));
}
defmt_parser::Type::U8 => {
exprs.push(quote!(_fmt_.u8(#arg)));
}
Expand Down
36 changes: 36 additions & 0 deletions parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pub enum Type {
I16,
I32,
I64,
I128,
Isize,
/// String slice (i.e. passed directly; not as interned string indices).
Str,
Expand All @@ -64,6 +65,7 @@ pub enum Type {
U24,
U32,
U64,
U128,
Usize,
/// Byte slice `{:[u8]}`.
U8Slice,
Expand Down Expand Up @@ -152,11 +154,13 @@ fn parse_param(mut s: &str) -> Result<Param, Cow<'static, str>> {
"u24" => Type::U24,
"u32" => Type::U32,
"u64" => Type::U64,
"u128"=> Type::U128,
"usize" => Type::Usize,
"i8" => Type::I8,
"i16" => Type::I16,
"i32" => Type::I32,
"i64" => Type::I64,
"i128" => Type::I128,
"isize" => Type::Isize,
"f32" => Type::F32,
"bool" => Type::Bool,
Expand Down Expand Up @@ -414,6 +418,22 @@ mod tests {
})])
);

assert_eq!(
parse("{:i64}"),
Ok(vec![Fragment::Parameter(Parameter {
index: 0,
ty: Type::I64,
})])
);

assert_eq!(
parse("{:i128}"),
Ok(vec![Fragment::Parameter(Parameter {
index: 0,
ty: Type::I128,
})])
);

assert_eq!(
parse("{:i8}"),
Ok(vec![Fragment::Parameter(Parameter {
Expand Down Expand Up @@ -454,6 +474,22 @@ mod tests {
})])
);

assert_eq!(
parse("{:u64}"),
Ok(vec![Fragment::Parameter(Parameter {
index: 0,
ty: Type::U64,
})])
);

assert_eq!(
parse("{:u128}"),
Ok(vec![Fragment::Parameter(Parameter {
index: 0,
ty: Type::U128,
})])
);

assert_eq!(
parse("{:f32}"),
Ok(vec![Fragment::Parameter(Parameter {
Expand Down
20 changes: 20 additions & 0 deletions src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ impl Format for i64 {
}
}

impl Format for i128 {
fn format(&self, fmt: &mut Formatter) {
if fmt.needs_tag() {
let t = internp!("{:i128}");
fmt.u8(&t);
}
fmt.i128(self);
}
}

impl Format for isize {
fn format(&self, fmt: &mut Formatter) {
if fmt.needs_tag() {
Expand Down Expand Up @@ -94,6 +104,16 @@ impl Format for u64 {
}
}

impl Format for u128 {
fn format(&self, fmt: &mut Formatter) {
if fmt.needs_tag() {
let t = internp!("{:u128}");
fmt.u8(&t);
}
fmt.u128(self);
}
}

impl Format for usize {
fn format(&self, fmt: &mut Formatter) {
if fmt.needs_tag() {
Expand Down
10 changes: 10 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,11 @@ impl Formatter {
self.write(&b.to_le_bytes())
}

/// Implementation detail
pub fn i128(&mut self, b: &i128) {
self.write(&b.to_le_bytes())
}

/// Implementation detail
pub fn isize(&mut self, b: &isize) {
// Zig-zag encode the signed value.
Expand Down Expand Up @@ -491,6 +496,11 @@ impl Formatter {
self.write(&b.to_le_bytes())
}

/// Implementation detail
pub fn u128(&mut self, b: &u128) {
self.write(&b.to_le_bytes())
}

/// Implementation detail
pub fn usize(&mut self, b: &usize) {
self.leb64(*b as u64);
Expand Down