From 96cd5eba956756e93af7a7f8445fe91a866ecd1f Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Thu, 21 Jan 2021 15:57:52 +0100 Subject: [PATCH 1/2] f64 support --- book/src/primitives.md | 1 + decoder/src/lib.rs | 6 + firmware/qemu/src/bin/log.out | 207 +++++++++++++------------- firmware/qemu/src/bin/log.release.out | 203 ++++++++++++------------- firmware/qemu/src/bin/log.rs | 7 +- macros/src/lib.rs | 5 +- parser/src/lib.rs | 4 +- src/impls.rs | 10 ++ src/lib.rs | 5 + 9 files changed, 241 insertions(+), 207 deletions(-) diff --git a/book/src/primitives.md b/book/src/primitives.md index c81e51252..14b6225c7 100644 --- a/book/src/primitives.md +++ b/book/src/primitives.md @@ -27,6 +27,7 @@ The available types are: - `={i,u}{8,16,32,64}`, standard integer types - `={i,u}24`, 32-bit integer truncated to 24 bits - `=f32`, 32-bit floating point type +- `=f64`, 64-bit floating point type - `=[u8; N]`, byte array - `=[u8]`, byte slice - `=str`, string slice diff --git a/decoder/src/lib.rs b/decoder/src/lib.rs index e4988cd3d..3314833af 100644 --- a/decoder/src/lib.rs +++ b/decoder/src/lib.rs @@ -350,6 +350,7 @@ enum Arg<'t> { /// Bool Bool(Arc), F32(f32), + F64(f64), /// U8, U16, U24 and U32 Uxx(u128), /// I8, I16, I24 and I32 @@ -818,6 +819,10 @@ impl<'t, 'b> Decoder<'t, 'b> { let data = self.bytes.read_u32::()?; args.push(Arg::F32(f32::from_bits(data))); } + Type::F64 => { + let data = self.bytes.read_u64::()?; + args.push(Arg::F64(f64::from_bits(data))); + } Type::BitField(range) => { let mut data: u128; let lowest_byte = range.start / 8; @@ -1057,6 +1062,7 @@ fn format_args_real( match &args[param.index] { Arg::Bool(x) => write!(buf, "{}", x)?, Arg::F32(x) => write!(buf, "{}", ryu::Buffer::new().format(*x))?, + Arg::F64(x) => write!(buf, "{}", ryu::Buffer::new().format(*x))?, Arg::Uxx(x) => { match param.ty { Type::BitField(range) => { diff --git a/firmware/qemu/src/bin/log.out b/firmware/qemu/src/bin/log.out index 62ebcc12c..59b2ffaf1 100644 --- a/firmware/qemu/src/bin/log.out +++ b/firmware/qemu/src/bin/log.out @@ -5,111 +5,112 @@ 0.000004 INFO Hello 256 42 false 0.000005 INFO 🍕 slice [3, 14] 0.000006 INFO 🍕 array [3, 14, 1] -0.000007 INFO float like a butterfly 5.67 -0.000008 INFO Hello 42 -0.000009 INFO u64: 0 = 0, 1 = 1, MAX = 18446744073709551615, MIN = 0 -0.000010 INFO i64: 0 = 0, -1 = -1, MAX = 9223372036854775807, MIN = -9223372036854775808 -0.000011 INFO isize: 0 = 0, -1 = -1, MAX = 2147483647, MIN = -2147483648 +0.000007 INFO float like a butterfly 5.67 5.67 +0.000008 INFO double like a butterfly 5.000000000000067 5.000000000000067 +0.000009 INFO Hello 42 +0.000010 INFO u64: 0 = 0, 1 = 1, MAX = 18446744073709551615, MIN = 0 +0.000011 INFO i64: 0 = 0, -1 = -1, MAX = 9223372036854775807, MIN = -9223372036854775808 0.000012 INFO isize: 0 = 0, -1 = -1, MAX = 2147483647, MIN = -2147483648 -0.000013 INFO usize: 0 = 0, MAX = 4294967295 -0.000014 INFO bitfields 6 2 -0.000015 TRACE log trace -0.000016 DEBUG log debug -0.000017 INFO log info -0.000018 WARN log warn -0.000019 ERROR log error -0.000020 INFO S { x: 1, y: 256 } -0.000021 INFO X { y: Y { z: 42 } } -0.000022 INFO &str = string slice +0.000013 INFO isize: 0 = 0, -1 = -1, MAX = 2147483647, MIN = -2147483648 +0.000014 INFO usize: 0 = 0, MAX = 4294967295 +0.000015 INFO bitfields 6 2 +0.000016 TRACE log trace +0.000017 DEBUG log debug +0.000018 INFO log info +0.000019 WARN log warn +0.000020 ERROR log error +0.000021 INFO S { x: 1, y: 256 } +0.000022 INFO X { y: Y { z: 42 } } 0.000023 INFO &str = string slice -0.000024 INFO &Str = interned string +0.000024 INFO &str = string slice 0.000025 INFO &Str = interned string -0.000026 INFO Arr { arr1: [31], arr0: [], arr32: [85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85] } -0.000027 INFO [256, 257, 258] -0.000028 INFO [S { x: 128, y: 256 }, S { x: 129, y: 257 }] -0.000029 INFO [X { y: Y { z: 128 } }, X { y: Y { z: 129 } }] -0.000030 INFO [[256, 257, 258], [259, 260]] -0.000031 INFO e1=A -0.000032 INFO e2=B -0.000033 INFO e3=Some(42) -0.000034 INFO e4=None -0.000035 INFO e5=Ok(42) -0.000036 INFO e6=Err(256) -0.000037 INFO e7=Some(X { y: Y { z: 42 } }) -0.000038 INFO true Flags { a: true, b: false, c: true } -0.000039 INFO [true, true, false] -0.000040 INFO usize slice: [1, 2, 3] -0.000041 INFO isize slice: [-1, -2, -3] -0.000042 INFO S { x: 42, y: 43 } -0.000043 INFO S { x: 44, y: 45 } -0.000044 INFO S { x: 46, y: Some(47) } -0.000045 INFO S { x: Some(48), y: 49 } -0.000046 INFO A -0.000047 INFO B(42) -0.000048 INFO C { y: 43 } -0.000049 INFO A -0.000050 INFO B(44) -0.000051 INFO C { y: 45 } -0.000052 INFO A -0.000053 INFO B(Some(46)) -0.000054 INFO C { y: Ok(47) } -0.000055 INFO A -0.000056 INFO B(Some(48)) -0.000057 INFO C { y: 49 } -0.000058 INFO [None, Some(42)] -0.000059 INFO [Ok(42), Err(43)] -0.000060 INFO [A, B(42)] -0.000061 INFO [S { x: 42, y: None }, S { x: 43, y: Some(44) }] -0.000062 INFO [None, Some(S { x: 42, y: 256 })] -0.000063 INFO [None, Some([42, 43])] -0.000064 INFO in nested 123 -0.000065 INFO after nested log: NestedStruct { a: 170, b: 305419896 } -0.000066 INFO I can now print the @ symbol! -0.000067 INFO @nd @lso vi@ interned strings: this is @n interned string -0.000068 INFO empty tuple: () -0.000069 INFO tuple of ints: (1, 2, 3) -0.000070 INFO nested tuple of ints: (1, 2, (3, 4, 5), (6, 7, 8)) -0.000071 INFO super nested tuples: (((((((())))))), (((((((), ()))))))) -0.000072 INFO slice of tuples: [(1, 2), (3, 4), (5, 6)] -0.000073 INFO tuple of slices: ([1, 2, 3], [4, 5, 6]) -0.000074 INFO tuple of [u8;4]: ([1, 2, 3, 4], [5, 6, 7, 8]) -0.000075 INFO [u8;0]: [] -0.000076 INFO [u8;4]: [1, 2, 3, 4] -0.000077 INFO [i8;4]: [-1, 2, 3, -4] -0.000078 INFO [(u32,u32);4]: [(1, 2), (3, 4), (5, 6), (7, 8)] -0.000079 INFO [u8;0]: [] -0.000080 INFO [u8;4]: [1, 2, 3, 4] -0.000081 INFO [i8;4]: [-1, 2, 3, -4] -0.000082 INFO [u32;4]: [1, 2, 3, 4] -0.000083 INFO [i32;4]: [-1, 2, 3, -4] -0.000084 INFO [[u32;4];4]: [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7]] -0.000085 INFO [Option;4]: [Some(1), None, Some(3), None] -0.000086 INFO [(u32,u32);4]: [(1, 2), (3, 4), (5, 6), (7, 8)] -0.000087 INFO 1-variant enum: A { fld: 123 } -0.000088 INFO wrapped: A(A { fld: 200 }) -0.000089 INFO (A(true), B(true)), (A(false), B(true)), (A(true), B(false)) -0.000090 INFO true, [1, 2]: DhcpReprMin { broadcast: true, a: [1, 2] } -0.000091 INFO nested `Format` impls using `write!`: outer value (inner value (42)) -0.000092 INFO S { x: -1, y: 2 } -0.000093 INFO Some(S { x: -1, y: 2 }) -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 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 Hello 💜 -0.000102 INFO Hello 💜 & 🍕 -0.000103 INFO EnumLarge::A051 -0.000104 INFO EnumLarge::A269 -0.000105 INFO S { x: "hi" } -0.000106 INFO S { x: PhantomData, y: 42 } -0.000107 INFO bitfields 0x97 0b10000100 12 b"42" b"hello" -0.000108 INFO b"Hi" +0.000026 INFO &Str = interned string +0.000027 INFO Arr { arr1: [31], arr0: [], arr32: [85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85] } +0.000028 INFO [256, 257, 258] +0.000029 INFO [S { x: 128, y: 256 }, S { x: 129, y: 257 }] +0.000030 INFO [X { y: Y { z: 128 } }, X { y: Y { z: 129 } }] +0.000031 INFO [[256, 257, 258], [259, 260]] +0.000032 INFO e1=A +0.000033 INFO e2=B +0.000034 INFO e3=Some(42) +0.000035 INFO e4=None +0.000036 INFO e5=Ok(42) +0.000037 INFO e6=Err(256) +0.000038 INFO e7=Some(X { y: Y { z: 42 } }) +0.000039 INFO true Flags { a: true, b: false, c: true } +0.000040 INFO [true, true, false] +0.000041 INFO usize slice: [1, 2, 3] +0.000042 INFO isize slice: [-1, -2, -3] +0.000043 INFO S { x: 42, y: 43 } +0.000044 INFO S { x: 44, y: 45 } +0.000045 INFO S { x: 46, y: Some(47) } +0.000046 INFO S { x: Some(48), y: 49 } +0.000047 INFO A +0.000048 INFO B(42) +0.000049 INFO C { y: 43 } +0.000050 INFO A +0.000051 INFO B(44) +0.000052 INFO C { y: 45 } +0.000053 INFO A +0.000054 INFO B(Some(46)) +0.000055 INFO C { y: Ok(47) } +0.000056 INFO A +0.000057 INFO B(Some(48)) +0.000058 INFO C { y: 49 } +0.000059 INFO [None, Some(42)] +0.000060 INFO [Ok(42), Err(43)] +0.000061 INFO [A, B(42)] +0.000062 INFO [S { x: 42, y: None }, S { x: 43, y: Some(44) }] +0.000063 INFO [None, Some(S { x: 42, y: 256 })] +0.000064 INFO [None, Some([42, 43])] +0.000065 INFO in nested 123 +0.000066 INFO after nested log: NestedStruct { a: 170, b: 305419896 } +0.000067 INFO I can now print the @ symbol! +0.000068 INFO @nd @lso vi@ interned strings: this is @n interned string +0.000069 INFO empty tuple: () +0.000070 INFO tuple of ints: (1, 2, 3) +0.000071 INFO nested tuple of ints: (1, 2, (3, 4, 5), (6, 7, 8)) +0.000072 INFO super nested tuples: (((((((())))))), (((((((), ()))))))) +0.000073 INFO slice of tuples: [(1, 2), (3, 4), (5, 6)] +0.000074 INFO tuple of slices: ([1, 2, 3], [4, 5, 6]) +0.000075 INFO tuple of [u8;4]: ([1, 2, 3, 4], [5, 6, 7, 8]) +0.000076 INFO [u8;0]: [] +0.000077 INFO [u8;4]: [1, 2, 3, 4] +0.000078 INFO [i8;4]: [-1, 2, 3, -4] +0.000079 INFO [(u32,u32);4]: [(1, 2), (3, 4), (5, 6), (7, 8)] +0.000080 INFO [u8;0]: [] +0.000081 INFO [u8;4]: [1, 2, 3, 4] +0.000082 INFO [i8;4]: [-1, 2, 3, -4] +0.000083 INFO [u32;4]: [1, 2, 3, 4] +0.000084 INFO [i32;4]: [-1, 2, 3, -4] +0.000085 INFO [[u32;4];4]: [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7]] +0.000086 INFO [Option;4]: [Some(1), None, Some(3), None] +0.000087 INFO [(u32,u32);4]: [(1, 2), (3, 4), (5, 6), (7, 8)] +0.000088 INFO 1-variant enum: A { fld: 123 } +0.000089 INFO wrapped: A(A { fld: 200 }) +0.000090 INFO (A(true), B(true)), (A(false), B(true)), (A(true), B(false)) +0.000091 INFO true, [1, 2]: DhcpReprMin { broadcast: true, a: [1, 2] } +0.000092 INFO nested `Format` impls using `write!`: outer value (inner value (42)) +0.000093 INFO S { x: -1, y: 2 } +0.000094 INFO Some(S { x: -1, y: 2 }) +0.000095 INFO [S { x: -1, y: 2 }, S { x: -1, y: 2 }] +0.000096 INFO [Some(S { x: -1, y: 2 }), None] +0.000097 INFO 127.0.0.1:8888 +0.000098 INFO i128: 0 = 0, -1 = -1, MAX = 170141183460469231731687303715884105727, MIN = -170141183460469231731687303715884105728 +0.000099 INFO u128: 0 = 0, -1 = 1, MAX = 340282366920938463463374607431768211455, MIN = 0 +0.000100 INFO 340282366920938 +0.000101 INFO -170141183460469 +0.000102 INFO Hello 💜 +0.000103 INFO Hello 💜 & 🍕 +0.000104 INFO EnumLarge::A051 +0.000105 INFO EnumLarge::A269 +0.000106 INFO S { x: "hi" } +0.000107 INFO S { x: PhantomData, y: 42 } +0.000108 INFO bitfields 0x97 0b10000100 12 b"42" b"hello" 0.000109 INFO b"Hi" 0.000110 INFO b"Hi" -0.000111 INFO [45054, 49406] -0.000112 INFO [Data { name: b"Hi", value: true }] -0.000113 INFO true true -0.000114 INFO QEMU test finished! +0.000111 INFO b"Hi" +0.000112 INFO [45054, 49406] +0.000113 INFO [Data { name: b"Hi", value: true }] +0.000114 INFO true true +0.000115 INFO QEMU test finished! diff --git a/firmware/qemu/src/bin/log.release.out b/firmware/qemu/src/bin/log.release.out index ac8ebb138..3c352bc4f 100644 --- a/firmware/qemu/src/bin/log.release.out +++ b/firmware/qemu/src/bin/log.release.out @@ -5,109 +5,110 @@ 0.000004 INFO Hello 256 42 false 0.000005 INFO 🍕 slice [3, 14] 0.000006 INFO 🍕 array [3, 14, 1] -0.000007 INFO float like a butterfly 5.67 -0.000008 INFO Hello 42 -0.000009 INFO u64: 0 = 0, 1 = 1, MAX = 18446744073709551615, MIN = 0 -0.000010 INFO i64: 0 = 0, -1 = -1, MAX = 9223372036854775807, MIN = -9223372036854775808 -0.000011 INFO isize: 0 = 0, -1 = -1, MAX = 2147483647, MIN = -2147483648 +0.000007 INFO float like a butterfly 5.67 5.67 +0.000008 INFO double like a butterfly 5.000000000000067 5.000000000000067 +0.000009 INFO Hello 42 +0.000010 INFO u64: 0 = 0, 1 = 1, MAX = 18446744073709551615, MIN = 0 +0.000011 INFO i64: 0 = 0, -1 = -1, MAX = 9223372036854775807, MIN = -9223372036854775808 0.000012 INFO isize: 0 = 0, -1 = -1, MAX = 2147483647, MIN = -2147483648 -0.000013 INFO usize: 0 = 0, MAX = 4294967295 -0.000014 INFO bitfields 6 2 -0.000015 INFO log info -0.000016 WARN log warn -0.000017 ERROR log error -0.000018 INFO S { x: 1, y: 256 } -0.000019 INFO X { y: Y { z: 42 } } -0.000020 INFO &str = string slice +0.000013 INFO isize: 0 = 0, -1 = -1, MAX = 2147483647, MIN = -2147483648 +0.000014 INFO usize: 0 = 0, MAX = 4294967295 +0.000015 INFO bitfields 6 2 +0.000016 INFO log info +0.000017 WARN log warn +0.000018 ERROR log error +0.000019 INFO S { x: 1, y: 256 } +0.000020 INFO X { y: Y { z: 42 } } 0.000021 INFO &str = string slice -0.000022 INFO &Str = interned string +0.000022 INFO &str = string slice 0.000023 INFO &Str = interned string -0.000024 INFO Arr { arr1: [31], arr0: [], arr32: [85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85] } -0.000025 INFO [256, 257, 258] -0.000026 INFO [S { x: 128, y: 256 }, S { x: 129, y: 257 }] -0.000027 INFO [X { y: Y { z: 128 } }, X { y: Y { z: 129 } }] -0.000028 INFO [[256, 257, 258], [259, 260]] -0.000029 INFO e1=A -0.000030 INFO e2=B -0.000031 INFO e3=Some(42) -0.000032 INFO e4=None -0.000033 INFO e5=Ok(42) -0.000034 INFO e6=Err(256) -0.000035 INFO e7=Some(X { y: Y { z: 42 } }) -0.000036 INFO true Flags { a: true, b: false, c: true } -0.000037 INFO [true, true, false] -0.000038 INFO usize slice: [1, 2, 3] -0.000039 INFO isize slice: [-1, -2, -3] -0.000040 INFO S { x: 42, y: 43 } -0.000041 INFO S { x: 44, y: 45 } -0.000042 INFO S { x: 46, y: Some(47) } -0.000043 INFO S { x: Some(48), y: 49 } -0.000044 INFO A -0.000045 INFO B(42) -0.000046 INFO C { y: 43 } -0.000047 INFO A -0.000048 INFO B(44) -0.000049 INFO C { y: 45 } -0.000050 INFO A -0.000051 INFO B(Some(46)) -0.000052 INFO C { y: Ok(47) } -0.000053 INFO A -0.000054 INFO B(Some(48)) -0.000055 INFO C { y: 49 } -0.000056 INFO [None, Some(42)] -0.000057 INFO [Ok(42), Err(43)] -0.000058 INFO [A, B(42)] -0.000059 INFO [S { x: 42, y: None }, S { x: 43, y: Some(44) }] -0.000060 INFO [None, Some(S { x: 42, y: 256 })] -0.000061 INFO [None, Some([42, 43])] -0.000062 INFO in nested 123 -0.000063 INFO after nested log: NestedStruct { a: 170, b: 305419896 } -0.000064 INFO I can now print the @ symbol! -0.000065 INFO @nd @lso vi@ interned strings: this is @n interned string -0.000066 INFO empty tuple: () -0.000067 INFO tuple of ints: (1, 2, 3) -0.000068 INFO nested tuple of ints: (1, 2, (3, 4, 5), (6, 7, 8)) -0.000069 INFO super nested tuples: (((((((())))))), (((((((), ()))))))) -0.000070 INFO slice of tuples: [(1, 2), (3, 4), (5, 6)] -0.000071 INFO tuple of slices: ([1, 2, 3], [4, 5, 6]) -0.000072 INFO tuple of [u8;4]: ([1, 2, 3, 4], [5, 6, 7, 8]) -0.000073 INFO [u8;0]: [] -0.000074 INFO [u8;4]: [1, 2, 3, 4] -0.000075 INFO [i8;4]: [-1, 2, 3, -4] -0.000076 INFO [(u32,u32);4]: [(1, 2), (3, 4), (5, 6), (7, 8)] -0.000077 INFO [u8;0]: [] -0.000078 INFO [u8;4]: [1, 2, 3, 4] -0.000079 INFO [i8;4]: [-1, 2, 3, -4] -0.000080 INFO [u32;4]: [1, 2, 3, 4] -0.000081 INFO [i32;4]: [-1, 2, 3, -4] -0.000082 INFO [[u32;4];4]: [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7]] -0.000083 INFO [Option;4]: [Some(1), None, Some(3), None] -0.000084 INFO [(u32,u32);4]: [(1, 2), (3, 4), (5, 6), (7, 8)] -0.000085 INFO 1-variant enum: A { fld: 123 } -0.000086 INFO wrapped: A(A { fld: 200 }) -0.000087 INFO (A(true), B(true)), (A(false), B(true)), (A(true), B(false)) -0.000088 INFO true, [1, 2]: DhcpReprMin { broadcast: true, a: [1, 2] } -0.000089 INFO nested `Format` impls using `write!`: outer value (inner value (42)) -0.000090 INFO S { x: -1, y: 2 } -0.000091 INFO Some(S { x: -1, y: 2 }) -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 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 Hello 💜 -0.000100 INFO Hello 💜 & 🍕 -0.000101 INFO EnumLarge::A051 -0.000102 INFO EnumLarge::A269 -0.000103 INFO S { x: "hi" } -0.000104 INFO S { x: PhantomData, y: 42 } -0.000105 INFO bitfields 0x97 0b10000100 12 b"42" b"hello" -0.000106 INFO b"Hi" +0.000024 INFO &Str = interned string +0.000025 INFO Arr { arr1: [31], arr0: [], arr32: [85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85] } +0.000026 INFO [256, 257, 258] +0.000027 INFO [S { x: 128, y: 256 }, S { x: 129, y: 257 }] +0.000028 INFO [X { y: Y { z: 128 } }, X { y: Y { z: 129 } }] +0.000029 INFO [[256, 257, 258], [259, 260]] +0.000030 INFO e1=A +0.000031 INFO e2=B +0.000032 INFO e3=Some(42) +0.000033 INFO e4=None +0.000034 INFO e5=Ok(42) +0.000035 INFO e6=Err(256) +0.000036 INFO e7=Some(X { y: Y { z: 42 } }) +0.000037 INFO true Flags { a: true, b: false, c: true } +0.000038 INFO [true, true, false] +0.000039 INFO usize slice: [1, 2, 3] +0.000040 INFO isize slice: [-1, -2, -3] +0.000041 INFO S { x: 42, y: 43 } +0.000042 INFO S { x: 44, y: 45 } +0.000043 INFO S { x: 46, y: Some(47) } +0.000044 INFO S { x: Some(48), y: 49 } +0.000045 INFO A +0.000046 INFO B(42) +0.000047 INFO C { y: 43 } +0.000048 INFO A +0.000049 INFO B(44) +0.000050 INFO C { y: 45 } +0.000051 INFO A +0.000052 INFO B(Some(46)) +0.000053 INFO C { y: Ok(47) } +0.000054 INFO A +0.000055 INFO B(Some(48)) +0.000056 INFO C { y: 49 } +0.000057 INFO [None, Some(42)] +0.000058 INFO [Ok(42), Err(43)] +0.000059 INFO [A, B(42)] +0.000060 INFO [S { x: 42, y: None }, S { x: 43, y: Some(44) }] +0.000061 INFO [None, Some(S { x: 42, y: 256 })] +0.000062 INFO [None, Some([42, 43])] +0.000063 INFO in nested 123 +0.000064 INFO after nested log: NestedStruct { a: 170, b: 305419896 } +0.000065 INFO I can now print the @ symbol! +0.000066 INFO @nd @lso vi@ interned strings: this is @n interned string +0.000067 INFO empty tuple: () +0.000068 INFO tuple of ints: (1, 2, 3) +0.000069 INFO nested tuple of ints: (1, 2, (3, 4, 5), (6, 7, 8)) +0.000070 INFO super nested tuples: (((((((())))))), (((((((), ()))))))) +0.000071 INFO slice of tuples: [(1, 2), (3, 4), (5, 6)] +0.000072 INFO tuple of slices: ([1, 2, 3], [4, 5, 6]) +0.000073 INFO tuple of [u8;4]: ([1, 2, 3, 4], [5, 6, 7, 8]) +0.000074 INFO [u8;0]: [] +0.000075 INFO [u8;4]: [1, 2, 3, 4] +0.000076 INFO [i8;4]: [-1, 2, 3, -4] +0.000077 INFO [(u32,u32);4]: [(1, 2), (3, 4), (5, 6), (7, 8)] +0.000078 INFO [u8;0]: [] +0.000079 INFO [u8;4]: [1, 2, 3, 4] +0.000080 INFO [i8;4]: [-1, 2, 3, -4] +0.000081 INFO [u32;4]: [1, 2, 3, 4] +0.000082 INFO [i32;4]: [-1, 2, 3, -4] +0.000083 INFO [[u32;4];4]: [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7]] +0.000084 INFO [Option;4]: [Some(1), None, Some(3), None] +0.000085 INFO [(u32,u32);4]: [(1, 2), (3, 4), (5, 6), (7, 8)] +0.000086 INFO 1-variant enum: A { fld: 123 } +0.000087 INFO wrapped: A(A { fld: 200 }) +0.000088 INFO (A(true), B(true)), (A(false), B(true)), (A(true), B(false)) +0.000089 INFO true, [1, 2]: DhcpReprMin { broadcast: true, a: [1, 2] } +0.000090 INFO nested `Format` impls using `write!`: outer value (inner value (42)) +0.000091 INFO S { x: -1, y: 2 } +0.000092 INFO Some(S { x: -1, y: 2 }) +0.000093 INFO [S { x: -1, y: 2 }, S { x: -1, y: 2 }] +0.000094 INFO [Some(S { x: -1, y: 2 }), None] +0.000095 INFO 127.0.0.1:8888 +0.000096 INFO i128: 0 = 0, -1 = -1, MAX = 170141183460469231731687303715884105727, MIN = -170141183460469231731687303715884105728 +0.000097 INFO u128: 0 = 0, -1 = 1, MAX = 340282366920938463463374607431768211455, MIN = 0 +0.000098 INFO 340282366920938 +0.000099 INFO -170141183460469 +0.000100 INFO Hello 💜 +0.000101 INFO Hello 💜 & 🍕 +0.000102 INFO EnumLarge::A051 +0.000103 INFO EnumLarge::A269 +0.000104 INFO S { x: "hi" } +0.000105 INFO S { x: PhantomData, y: 42 } +0.000106 INFO bitfields 0x97 0b10000100 12 b"42" b"hello" 0.000107 INFO b"Hi" 0.000108 INFO b"Hi" -0.000109 INFO [45054, 49406] -0.000110 INFO [Data { name: b"Hi", value: true }] -0.000111 INFO true true -0.000112 INFO QEMU test finished! +0.000109 INFO b"Hi" +0.000110 INFO [45054, 49406] +0.000111 INFO [Data { name: b"Hi", value: true }] +0.000112 INFO true true +0.000113 INFO QEMU test finished! diff --git a/firmware/qemu/src/bin/log.rs b/firmware/qemu/src/bin/log.rs index d6393e43e..4fc58dc1f 100644 --- a/firmware/qemu/src/bin/log.rs +++ b/firmware/qemu/src/bin/log.rs @@ -20,7 +20,12 @@ fn main() -> ! { defmt::info!("Hello {1=u16} {0=u8} {2=bool}", 42u8, 256u16, false); defmt::info!("🍕 slice {=[u8]}", [3, 14]); defmt::info!("🍕 array {=[u8; 3]}", [3, 14, 1]); - defmt::info!("float like a butterfly {=f32}", 5.67f32); + defmt::info!("float like a butterfly {=f32} {}", 5.67f32, 5.67f32); + defmt::info!( + "double like a butterfly {=f64} {}", + 5.000000000000067f64, + 5.000000000000067f64 + ); defmt::info!("Hello {=u8}", 42u16 as u8); defmt::info!( diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 0df753117..d08c2a3b5 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -479,7 +479,7 @@ fn as_native_type(ty: &Type) -> Option { let s = ident.to_string(); match &*s { "u8" | "u16" | "u32" | "usize" | "i8" | "i16" | "i32" | "isize" | "f32" - | "bool" | "str" => Some(s), + | "f64" | "bool" | "str" => Some(s), _ => None, } } @@ -1246,6 +1246,9 @@ impl Codegen { defmt_parser::Type::F32 => { exprs.push(quote!(_fmt_.f32(#arg))); } + defmt_parser::Type::F64 => { + exprs.push(quote!(_fmt_.f64(#arg))); + } defmt_parser::Type::Char => { exprs.push(quote!(_fmt_.u32(&(*#arg as u32)))); } diff --git a/parser/src/lib.rs b/parser/src/lib.rs index 49cf0b22e..28a2faca0 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -60,7 +60,7 @@ pub enum Fragment<'f> { /// /// argtype := bitfield | '?' | format-array | '[?]' | byte-array | '[u8]' | 'istr' | 'str' | /// 'bool' | 'char' | 'u8' | 'u16' | 'u32' | 'u64' | 'u128' | 'usize' | 'i8' | 'i16' | 'i32' | -/// 'i64' | 'i128 | 'isize' | 'f32' +/// 'i64' | 'i128 | 'isize' | 'f32' | 'f64' /// bitfield := integer '..' integer /// format-array := '[?;' spaces integer ']' /// byte-array := '[u8;' spaces integer ']' @@ -115,6 +115,7 @@ pub enum Type { U8Slice, U8Array(usize), // FIXME: This `usize` is not the target's `usize`; use `u64` instead? F32, + F64, /// A single Unicode character Char, } @@ -237,6 +238,7 @@ fn parse_param(mut input: &str, mode: ParserMode) -> Result Type::I128, "isize" => Type::Isize, "f32" => Type::F32, + "f64" => Type::F64, "bool" => Type::Bool, "str" => Type::Str, "istr" => Type::IStr, diff --git a/src/impls.rs b/src/impls.rs index 373e3790e..14b1977c7 100644 --- a/src/impls.rs +++ b/src/impls.rs @@ -134,6 +134,16 @@ impl Format for f32 { } } +impl Format for f64 { + fn format(&self, fmt: Formatter) { + if fmt.inner.needs_tag() { + let t = internp!("{=f64}"); + fmt.inner.u8(&t); + } + fmt.inner.f64(self); + } +} + impl Format for str { fn format(&self, fmt: Formatter) { if fmt.inner.needs_tag() { diff --git a/src/lib.rs b/src/lib.rs index ec3aefbdf..b0329a59d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -511,6 +511,11 @@ impl InternalFormatter { self.write(&f32::to_bits(*b).to_le_bytes()) } + /// Implementation detail + pub fn f64(&mut self, b: &f64) { + self.write(&f64::to_bits(*b).to_le_bytes()) + } + pub fn str(&mut self, s: &str) { self.leb64(s.len()); self.write(s.as_bytes()); From 023156777c5afb8127c95c7167892794d4fce55d Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Thu, 21 Jan 2021 16:00:50 +0100 Subject: [PATCH 2/2] Clarify docs on `Write::write` --- src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index ec3aefbdf..637c4d39b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -633,6 +633,9 @@ pub trait Write { /// /// This will be called by the defmt logging macros to transmit encoded data. The write /// operation must not fail. + /// + /// Note that a call to `write` does *not* correspond to a defmt logging macro invocation. A + /// single `defmt::info!` call can result in an arbitrary number of `write` calls. fn write(&mut self, bytes: &[u8]); }