Remove degrees keyword

This commit is contained in:
Kasper 2024-01-13 08:42:46 +01:00
parent 0dcd13f775
commit be51ec4ff0
No known key found for this signature in database
GPG Key ID: 3E47D7CD99820B85
4 changed files with 15 additions and 17 deletions

View File

@ -1,5 +1,9 @@
# Changelog # Changelog
## Next
- Remove the `degrees` keyword which referred to `celcius` by default
- Remove the `default_degrees` argument from `eval()` and `lex()`. Not necessary now that the `degrees` keyword is removed
## 1.9.3 - 2023 sep 20 ## 1.9.3 - 2023 sep 20
- Fix negative unary `-` always having higher precedence than `^`. This resulted in `-3^2` returning `9` instead of `-9` - Fix negative unary `-` always having higher precedence than `^`. This resulted in `-3^2` returning `9` instead of `-9`

View File

@ -9,7 +9,6 @@ use crate::NamedNumber::*;
use crate::Constant::{E, Pi}; use crate::Constant::{E, Pi};
use crate::LexerKeyword::{In, PercentChar, Per, Mercury, Hg, PoundForce, Force, DoubleQuotes, Revolution}; use crate::LexerKeyword::{In, PercentChar, Per, Mercury, Hg, PoundForce, Force, DoubleQuotes, Revolution};
use crate::FunctionIdentifier::{Cbrt, Ceil, Cos, Exp, Abs, Floor, Ln, Log, Round, Sin, Sqrt, Tan}; use crate::FunctionIdentifier::{Cbrt, Ceil, Cos, Exp, Abs, Floor, Ln, Log, Round, Sin, Sqrt, Tan};
use crate::units::Unit;
use crate::units::Unit::*; use crate::units::Unit::*;
use unicode_segmentation::{Graphemes, UnicodeSegmentation}; use unicode_segmentation::{Graphemes, UnicodeSegmentation};
@ -595,7 +594,6 @@ fn parse_word(word: &str, lexer: &mut Lexer) -> Result<(), String> {
"k" | "kelvin" | "kelvins" => Token::Unit(Kelvin), "k" | "kelvin" | "kelvins" => Token::Unit(Kelvin),
"c" | "celsius" => Token::Unit(Celsius), "c" | "celsius" => Token::Unit(Celsius),
"f" | "fahrenheit" | "fahrenheits" => Token::Unit(Fahrenheit), "f" | "fahrenheit" | "fahrenheits" => Token::Unit(Fahrenheit),
"deg" | "degree" | "degrees" => Token::Unit(lexer.default_degree),
string => { string => {
return Err(format!("Invalid string: {}", string)); return Err(format!("Invalid string: {}", string));
@ -610,11 +608,10 @@ struct Lexer<'a> {
right_paren_count: u16, right_paren_count: u16,
chars: Peekable<Graphemes<'a>>, chars: Peekable<Graphemes<'a>>,
tokens: Vec<Token>, tokens: Vec<Token>,
default_degree: Unit,
} }
/// Lex an input string and returns [`Token`]s /// Lex an input string and returns [`Token`]s
pub fn lex(input: &str, remove_trailing_operator: bool, default_degree: Unit) -> Result<Vec<Token>, String> { pub fn lex(input: &str, remove_trailing_operator: bool) -> Result<Vec<Token>, String> {
let mut input = input.replace(',', "").to_ascii_lowercase(); let mut input = input.replace(',', "").to_ascii_lowercase();
if remove_trailing_operator { if remove_trailing_operator {
@ -631,7 +628,6 @@ pub fn lex(input: &str, remove_trailing_operator: bool, default_degree: Unit) ->
right_paren_count: 0, right_paren_count: 0,
chars: UnicodeSegmentation::graphemes(input.as_str(), true).peekable(), chars: UnicodeSegmentation::graphemes(input.as_str(), true).peekable(),
tokens: Vec::new(), tokens: Vec::new(),
default_degree,
}; };
while let Some(c) = lexer.chars.next() { while let Some(c) = lexer.chars.next() {
@ -945,7 +941,7 @@ mod tests {
let nonplural_data_units = Regex::new(r"(bit|byte)s").unwrap(); let nonplural_data_units = Regex::new(r"(bit|byte)s").unwrap();
let run_lex = |input: &str, expected_tokens: Vec<Token>| { let run_lex = |input: &str, expected_tokens: Vec<Token>| {
let tokens = match lex(input, false, Unit::Celsius) { let tokens = match lex(input, false) {
Ok(tokens) => tokens, Ok(tokens) => tokens,
Err(e) => { Err(e) => {
panic!("lex error: {}\nrun_lex input: {}", e, input); panic!("lex error: {}\nrun_lex input: {}", e, input);
@ -956,17 +952,17 @@ mod tests {
// Prove we can handle multiple spaces wherever we handle a single space // Prove we can handle multiple spaces wherever we handle a single space
let input_extra_spaces = input.replace(" ", " "); let input_extra_spaces = input.replace(" ", " ");
let tokens_extra_spaces = lex(&input_extra_spaces, false, Unit::Celsius).unwrap(); let tokens_extra_spaces = lex(&input_extra_spaces, false).unwrap();
assert!(tokens_extra_spaces == expected_tokens, "{info_msg}"); assert!(tokens_extra_spaces == expected_tokens, "{info_msg}");
// Prove we don't need spaces around operators // Prove we don't need spaces around operators
let input_stripped_spaces = strip_operator_spacing.replace_all(input, "$1"); let input_stripped_spaces = strip_operator_spacing.replace_all(input, "$1");
let tokens_stripped_spaces = lex(&input_stripped_spaces, false, Unit::Celsius).unwrap(); let tokens_stripped_spaces = lex(&input_stripped_spaces, false).unwrap();
assert!(tokens_stripped_spaces == expected_tokens, "{info_msg}"); assert!(tokens_stripped_spaces == expected_tokens, "{info_msg}");
// Prove we don't need a space after a digit // Prove we don't need a space after a digit
let input_afterdigit_stripped_spaces = strip_afterdigit_spacing.replace_all(input, "$1"); let input_afterdigit_stripped_spaces = strip_afterdigit_spacing.replace_all(input, "$1");
let tokens_afterdigit_stripped_spaces = lex(&input_afterdigit_stripped_spaces, false, Unit::Celsius).unwrap(); let tokens_afterdigit_stripped_spaces = lex(&input_afterdigit_stripped_spaces, false).unwrap();
assert!(tokens_afterdigit_stripped_spaces == expected_tokens, "{info_msg}"); assert!(tokens_afterdigit_stripped_spaces == expected_tokens, "{info_msg}");
}; };
@ -975,7 +971,7 @@ mod tests {
// Prove plural and non-plural data units behave identically // Prove plural and non-plural data units behave identically
let input_nonplural_units = nonplural_data_units.replace_all(input, "$1"); let input_nonplural_units = nonplural_data_units.replace_all(input, "$1");
let tokens_nonplural_units = lex(&input_nonplural_units, false, Unit::Celsius).unwrap(); let tokens_nonplural_units = lex(&input_nonplural_units, false).unwrap();
let info_msg = format!("run_datarate_lex input: {}\nexpected: {:?}\nreceived: {:?}", input, expected_tokens, tokens_nonplural_units); let info_msg = format!("run_datarate_lex input: {}\nexpected: {:?}\nreceived: {:?}", input, expected_tokens, tokens_nonplural_units);
assert!(tokens_nonplural_units == expected_tokens, "{info_msg}"); assert!(tokens_nonplural_units == expected_tokens, "{info_msg}");
}; };

View File

@ -19,7 +19,7 @@
//! use cpc::eval; //! use cpc::eval;
//! use cpc::units::Unit; //! use cpc::units::Unit;
//! //!
//! match eval("3m + 1cm", true, Unit::Celsius, false) { //! match eval("3m + 1cm", true, false) {
//! Ok(answer) => { //! Ok(answer) => {
//! // answer: Number { value: 301, unit: Unit::Centimeter } //! // answer: Number { value: 301, unit: Unit::Centimeter }
//! println!("Evaluated value: {} {:?}", answer.value, answer.unit) //! println!("Evaluated value: {} {:?}", answer.value, answer.unit)
@ -230,7 +230,7 @@ macro_rules! numtok {
/// use cpc::eval; /// use cpc::eval;
/// use cpc::units::Unit; /// use cpc::units::Unit;
/// ///
/// match eval("3m + 1cm", true, Unit::Celsius, false) { /// match eval("3m + 1cm", true, false) {
/// Ok(answer) => { /// Ok(answer) => {
/// // answer: Number { value: 301, unit: Unit::Centimeter } /// // answer: Number { value: 301, unit: Unit::Centimeter }
/// println!("Evaluated value: {} {:?}", answer.value, answer.unit) /// println!("Evaluated value: {} {:?}", answer.value, answer.unit)
@ -243,12 +243,11 @@ macro_rules! numtok {
pub fn eval( pub fn eval(
input: &str, input: &str,
allow_trailing_operators: bool, allow_trailing_operators: bool,
default_degree: Unit,
verbose: bool, verbose: bool,
) -> Result<Number, String> { ) -> Result<Number, String> {
let lex_start = Instant::now(); let lex_start = Instant::now();
match lexer::lex(input, allow_trailing_operators, default_degree) { match lexer::lex(input, allow_trailing_operators) {
Ok(tokens) => { Ok(tokens) => {
let lex_time = Instant::now().duration_since(lex_start).as_nanos() as f32; let lex_time = Instant::now().duration_since(lex_start).as_nanos() as f32;
if verbose { if verbose {
@ -296,7 +295,7 @@ mod tests {
use super::*; use super::*;
fn default_eval(input: &str) -> Number { fn default_eval(input: &str) -> Number {
eval(input, true, units::Unit::Celsius, false).unwrap() eval(input, true, false).unwrap()
} }
#[test] #[test]

View File

@ -1,5 +1,4 @@
use cpc::eval; use cpc::eval;
use cpc::units::Unit;
use std::env; use std::env;
use std::process::exit; use std::process::exit;
@ -61,7 +60,7 @@ fn main() {
} }
}; };
match eval(&expression, true, Unit::Celsius, verbose) { match eval(&expression, true, verbose) {
Ok(answer) => { Ok(answer) => {
if !verbose { if !verbose {
println!("{answer}"); println!("{answer}");