Skip to content

Commit

Permalink
Implement i128 and u128. (#284)
Browse files Browse the repository at this point in the history
Implement i128 and u128.

Adds tests for `i64` and `u64` where missing.
Adds impls for i128 and u128.
Tests {:?} format specifier.
  • Loading branch information
BriocheBerlin authored Dec 3, 2020
1 parent ccc05b0 commit 497cc50
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 8 deletions.
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!(
"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 @@ -149,11 +151,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 @@ -411,6 +415,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 @@ -451,6 +471,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

0 comments on commit 497cc50

Please sign in to comment.