From bce9a557214565ef7c94756debcb26263a3eceba Mon Sep 17 00:00:00 2001 From: Devin Bidwell Date: Sun, 1 Dec 2024 20:55:10 -0700 Subject: [PATCH] Auto convert temp units to kelvin before sending to the AST parser --- src/tokenizer/mod.rs | 20 +++++++------------- src/tokenizer/token.rs | 28 ++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/tokenizer/mod.rs b/src/tokenizer/mod.rs index ee30eaa..0828bdc 100644 --- a/src/tokenizer/mod.rs +++ b/src/tokenizer/mod.rs @@ -339,14 +339,11 @@ impl Tokenizer { 'f' => Temperature::Fahrenheit(number), 'k' => Temperature::Kelvin(number), _ => return Ok(Token::new(TokenType::Number(number), line, column)), - }; + } + .to_kelvin(); self.next_char()?; - Ok(Token::new( - TokenType::Temperature(temperature), - line, - column, - )) + Ok(Token::new(TokenType::Number(temperature), line, column)) } else { Ok(Token::new(TokenType::Number(number), line, column)) } @@ -632,28 +629,25 @@ mod tests { #[test] fn test_temperature_unit() -> Result<()> { - let mut tokenizer = Tokenizer::from(String::from("10c 10f 10k")); + let mut tokenizer = Tokenizer::from(String::from("10c 14f 10k")); let token = tokenizer.next_token()?.unwrap(); assert_eq!( token.token_type, - TokenType::Temperature(Temperature::Celsius(Number::Integer(10))) + TokenType::Number(Number::Decimal(Decimal::new(28315, 2))) ); let token = tokenizer.next_token()?.unwrap(); assert_eq!( token.token_type, - TokenType::Temperature(Temperature::Fahrenheit(Number::Integer(10))) + TokenType::Number(Number::Decimal(Decimal::new(26315, 2))) ); let token = tokenizer.next_token()?.unwrap(); - assert_eq!( - token.token_type, - TokenType::Temperature(Temperature::Kelvin(Number::Integer(10))) - ); + assert_eq!(token.token_type, TokenType::Number(Number::Integer(10))); Ok(()) } diff --git a/src/tokenizer/token.rs b/src/tokenizer/token.rs index cfea770..bbf04bf 100644 --- a/src/tokenizer/token.rs +++ b/src/tokenizer/token.rs @@ -1,3 +1,4 @@ +use rust_decimal::prelude::*; use rust_decimal::Decimal; #[derive(Debug, PartialEq, Eq, Clone)] @@ -37,6 +38,31 @@ impl std::fmt::Display for Temperature { } } +impl Temperature { + pub fn to_kelvin(self) -> Number { + match self { + Temperature::Celsius(n) => { + let n = match n { + Number::Integer(i) => Decimal::new(i as i64, 0), + Number::Decimal(d) => d, + }; + Number::Decimal(n + Decimal::new(27315, 2)) + } + Temperature::Fahrenheit(n) => { + let n = match n { + Number::Integer(i) => Decimal::new(i as i64, 0), + Number::Decimal(d) => d, + }; + + let a = n - Decimal::new(32, 0); + let b = Decimal::new(5, 0) / Decimal::new(9, 0); + Number::Decimal(a * b + Decimal::new(27315, 2)) + } + Temperature::Kelvin(n) => n, + } + } +} + #[derive(Debug, PartialEq, Hash, Eq, Clone)] pub enum TokenType { /// Represents a string token @@ -51,7 +77,6 @@ pub enum TokenType { Identifier(String), /// Represents a symbol token Symbol(Symbol), - Temperature(Temperature), /// Represents an end of file token EOF, } @@ -65,7 +90,6 @@ impl std::fmt::Display for TokenType { TokenType::Keyword(k) => write!(f, "{:?}", k), TokenType::Identifier(i) => write!(f, "{}", i), TokenType::Symbol(s) => write!(f, "{:?}", s), - TokenType::Temperature(t) => write!(f, "{}", t), TokenType::EOF => write!(f, "EOF"), } }