Skip to content

Commit

Permalink
Merge pull request #77 from rigetti/update-use-lexical-for-float-to-s…
Browse files Browse the repository at this point in the history
…tring

Breaking: Update nom to v7. Use lexical for writing floating point values (changing formatting output)
  • Loading branch information
genos authored Jun 15, 2022
2 parents 618aa5e + 6b37e04 commit d13c292
Show file tree
Hide file tree
Showing 17 changed files with 152 additions and 119 deletions.
144 changes: 74 additions & 70 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@ categories = ["parser-implementations", "science", "compilers", "emulators"]
[dependencies]
dot-writer = { version = "0.1.2", optional = true }
indexmap = "1.6.1"
lexical = "5.2.0"
nom = "6.1.0"
lexical = "6.1.1"
nom = "7.1.1"
num-complex = "0.4.0"
petgraph = "0.5.1"
ryu = "1.0.10"
serde = { version = "1.0.125", features = ["derive"] }
thiserror = "1.0.30"

Expand Down
40 changes: 35 additions & 5 deletions src/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use lexical::{format, to_string_with_options, WriteFloatOptions};
use num_complex::Complex64;
use std::collections::{hash_map::DefaultHasher, HashMap};
use std::f64::consts::PI;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::num::NonZeroI32;
use std::str::FromStr;

#[cfg(test)]
Expand Down Expand Up @@ -435,16 +437,44 @@ impl<'a> FromStr for Expression {
/// - When both are non-zero, show with the correct operator in between
#[inline(always)]
fn format_complex(value: &Complex64) -> String {
const FORMAT: u128 = format::STANDARD;
// Safety:
// This uses `build_unchecked`, which is safe as long as `is_valid` is true, and
// `is_valid` must be true because we don't change the default values for:
// - the exponent string,
// - the decimal point,
// - the NaN string,
// - the ∞ string,
// - or the minimum or maximum significant digits.
// Of what we _do_ change:
// - negative_exponent_break is < 0,
// - positive_exponent_break is > 0,
// - and trim floats can only take a bool and both branches are safe.
// As of version 6.1.1 of lexical, this means `OPTIONS.is_valid()` must be true. However, we
// still `assert!` it just to be "safe."
const OPTIONS: WriteFloatOptions = unsafe {
let options = WriteFloatOptions::builder()
.negative_exponent_break(NonZeroI32::new(-5))
.positive_exponent_break(NonZeroI32::new(15))
.trim_floats(true)
.build_unchecked();
assert!(options.is_valid());
options
};
if value.re == 0f64 && value.im == 0f64 {
"0".to_owned()
} else if value.im == 0f64 {
ryu::Buffer::new().format(value.re).to_owned()
to_string_with_options::<_, FORMAT>(value.re, &OPTIONS)
} else if value.re == 0f64 {
ryu::Buffer::new().format(value.im).to_owned() + "i"
to_string_with_options::<_, FORMAT>(value.im, &OPTIONS) + "i"
} else {
let mut buf = ryu::Buffer::new();
let op = if value.im > 0f64 { "+" } else { "" };
buf.format(value.re).to_owned() + op + buf.format(value.im) + "i"
let mut out = to_string_with_options::<_, FORMAT>(value.re, &OPTIONS);
if value.im > 0f64 {
out.push('+')
}
out.push_str(&to_string_with_options::<_, FORMAT>(value.im, &OPTIONS));
out.push('i');
out
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,7 @@ impl Instruction {
/// let mut instructions = program.to_instructions(true);
/// instructions.iter_mut().for_each(|inst| inst.apply_to_expressions(Expression::simplify));
///
/// assert_eq!(instructions[0].to_string(), String::from("SHIFT-PHASE 0 \"rf\" 4.0"))
/// assert_eq!(instructions[0].to_string(), String::from("SHIFT-PHASE 0 \"rf\" 4"))
///
/// ```
pub fn apply_to_expressions(&mut self, mut closure: impl FnMut(&mut Expression)) {
Expand Down
4 changes: 2 additions & 2 deletions src/parser/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,8 @@ mod tests {
let cases = vec![
"pi",
"sin(pi)",
"(1.0+(2.0*3.0))",
"((1.0+2.0)*3.0)",
"(1+(2*3))",
"((1+2)*3)",
"%theta",
"cis(%theta)",
"(%a+%b)",
Expand Down
10 changes: 5 additions & 5 deletions src/program/calibration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,9 +353,9 @@ mod tests {
"RX(pi/2) 0\n"
),
expected: concat!(
"PULSE 1 \"xy\" gaussian(duration: 1.0, fwhm: 2.0, t0: 3.0)\n",
"PULSE 2 \"xy\" gaussian(duration: 1.0, fwhm: 2.0, t0: 3.0)\n",
"PULSE 3 \"xy\" gaussian(duration: 1.0, fwhm: 2.0, t0: 3.0)\n"
"PULSE 1 \"xy\" gaussian(duration: 1, fwhm: 2, t0: 3)\n",
"PULSE 2 \"xy\" gaussian(duration: 1, fwhm: 2, t0: 3)\n",
"PULSE 3 \"xy\" gaussian(duration: 1, fwhm: 2, t0: 3)\n"
),
},
TestCase {
Expand All @@ -364,7 +364,7 @@ mod tests {
" PULSE 0 \"xy\" gaussian(duration: 1, fwhm: 2, t0: 3)\n",
"X 0\n"
),
expected: "PULSE 0 \"xy\" gaussian(duration: 1.0, fwhm: 2.0, t0: 3.0)\n",
expected: "PULSE 0 \"xy\" gaussian(duration: 1, fwhm: 2, t0: 3)\n",
},
TestCase {
input: concat!(
Expand All @@ -374,7 +374,7 @@ mod tests {
" PULSE 0 \"xy\" gaussian(duration: 1, fwhm: 2, t0: 3)\n",
"X 0\n"
),
expected: "PULSE 0 \"xy\" gaussian(duration: 1.0, fwhm: 2.0, t0: 3.0)\n",
expected: "PULSE 0 \"xy\" gaussian(duration: 1, fwhm: 2, t0: 3)\n",
},
TestCase {
input: concat!(
Expand Down
6 changes: 3 additions & 3 deletions src/program/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ DEFCAL I 0:
DEFFRAME 0 \"rx\":
HARDWARE-OBJECT: \"hardware\"
DEFWAVEFORM custom:
1.0, 2.0
1, 2
I 0
";
let program = Program::from_str(input).unwrap();
Expand All @@ -304,9 +304,9 @@ I 0
DEFFRAME 0 \"rx\":
\tHARDWARE-OBJECT: \"hardware\"
DEFWAVEFORM custom:
\t1.0, 2.0
\t1, 2
DEFCAL I 0:
\tDELAY 0 1.0
\tDELAY 0 1
I 0
"
);
Expand Down
Loading

0 comments on commit d13c292

Please sign in to comment.