From ad25efc5f0f89ab73229b387af73b8c29ecb74e2 Mon Sep 17 00:00:00 2001 From: Lucas Villa Real Date: Wed, 19 Aug 2026 19:37:12 -0300 Subject: [PATCH] Support parsing -style float literals MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extend the grammar to support floating point numbers. The new rule handles '-?digits.digits' with an optional 'e+/-N' exponent. The numbers are encoded as IEEE 754 — binary32 by default, or as binary64 with `/bits/ 64`. --- src/dts.pest | 6 +++++- src/eval.rs | 19 +++++++++++++++++++ src/testdata/float.dts | 14 ++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 src/testdata/float.dts diff --git a/src/dts.pest b/src/dts.pest index e2b8cce..57cc916 100644 --- a/src/dts.pest +++ b/src/dts.pest @@ -129,7 +129,7 @@ LabelOrCell = { Label | Cell } OpenCells = { "<" } CloseCells = { ">" } -Cell = { NodeReference | PropertyReference | ParenExpr | IntLiteral } +Cell = { NodeReference | PropertyReference | ParenExpr | FloatLiteral | IntLiteral } ParenExpr = { OpenParen ~ Expr ~ CloseParen } Expr = { TernaryPrec } @@ -185,6 +185,10 @@ GreaterThan = { ">" } Equal = { "==" } NotEqual = { "!=" } +// DIFF: dtc has no floating-point support. Cells accept -style literals, +// encoded as IEEE 754 (binary32 by default, binary64 with /bits/ 64). +FloatLiteral = @{ "-"? ~ ('0'..'9')+ ~ "." ~ ('0'..'9')+ ~ (^"e" ~ ("+" | "-")? ~ ('0'..'9')+)? } + IntLiteral = ${ CharLiteral | NumericLiteral } // To improve error messages, escape sequences are not fully parsed here. diff --git a/src/eval.rs b/src/eval.rs index 701479c..7665776 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -395,6 +395,24 @@ fn evaluate_propvalue( } } } + Cell::FloatLiteral(lit) => { + let v: f64 = lit + .str() + .parse() + .map_err(|_| lit.err("bad float literal"))?; + // IEEE 754 bit patterns must not go through the + // sign-extension check below. + match bits { + 32 => r.extend((v as f32).to_be_bytes()), + 64 => r.extend(v.to_be_bytes()), + _ => { + return Err( + lit.err("float literals need /bits/ == 32 or 64") + ); + } + } + continue; + } Cell::ParenExpr(expr) => expr.eval(lookup_property)?, Cell::IntLiteral(lit) => lit.eval(lookup_property)?, }; @@ -762,6 +780,7 @@ fn test_eval() { for source in [ include_str!("testdata/charlit.dts"), include_str!("testdata/expr.dts"), + include_str!("testdata/float.dts"), include_str!("testdata/phandle.dts"), #[cfg(feature = "wrapping-arithmetic")] include_str!("testdata/random_expressions.dts"), diff --git a/src/testdata/float.dts b/src/testdata/float.dts new file mode 100644 index 0000000..ca5a8de --- /dev/null +++ b/src/testdata/float.dts @@ -0,0 +1,14 @@ +/dts-v1/; + +/ { + check { + f32_simple = <1.23 0x3f9d70a4>; + f32_zero = <0.0 0x00000000>; + f32_negative = <-0.5 0xbf000000>; + f32_exponent = <2.5e3 0x451c4000>; + f32_exp_neg = <1.5E-1 0x3e19999a>; + f32_mixed = <1 2.0 1 0x40000000>; + f64_simple = /bits/ 64 <1.23 0x3ff3ae147ae147ae>; + f64_negative = /bits/ 64 <-0.5 0xbfe0000000000000>; + }; +};