From 32bc349b0509189ff63c99efee5d9f246a49df5c Mon Sep 17 00:00:00 2001 From: RobertasJ Date: Sun, 20 Oct 2024 10:40:04 +0200 Subject: [PATCH] added prefixes - and + --- crates/torin/src/values/size.rs | 44 ++++++++++++++++++++++++++------- crates/torin/tests/size.rs | 21 ++++++++++++++-- 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/crates/torin/src/values/size.rs b/crates/torin/src/values/size.rs index 8e25d571f..166fedfc2 100644 --- a/crates/torin/src/values/size.rs +++ b/crates/torin/src/values/size.rs @@ -264,13 +264,11 @@ impl<'a> DynamicCalculationEvaluator<'a> { Some(lhs) } - /// Parse and evaluate the value with the following grammar: - /// ```ebnf - /// value = percentage | pixels ; - /// percentage = number, "%" ; - /// pixels = number ; - /// ``` + /// Parse and evaluate the term, implements implicit multiplication. only parenthesis count as + /// a seperator, so syntax like 50 50 isnt correct, but 50(50) is because the parenthesis act + /// as a seperator fn parse_term(&mut self) -> Option { + let prefix = self.parse_prefix()?; let mut lhs = None; // set to true so that the first value is multiplied and counts as normal syntax let mut last_is_seperator = true; @@ -283,10 +281,22 @@ impl<'a> DynamicCalculationEvaluator<'a> { } last_is_seperator = seperator; } - - lhs + if let Some(prefix) = prefix { + match prefix { + DynamicCalculation::Add => lhs, + DynamicCalculation::Sub => lhs.map(|v| v * -1.0), + _ => unreachable!(), + } + } else { + lhs + } } - + /// parse and evaluate the value with the following grammar: + /// ```ebnf + /// value = percentage | pixels ; + /// percentage = number, "%" ; + /// pixels = number ; + /// ` fn parse_value(&mut self) -> Option<(f32, bool)> { match self.current? { DynamicCalculation::Percentage(value) => { @@ -302,6 +312,8 @@ impl<'a> DynamicCalculationEvaluator<'a> { Some((*value, false)) } DynamicCalculation::OpenParenthesis => { + // function should return on DynamicCalculation::ClosedParenthesis because it does + // not have a precedence, thats how it actually works let val = self.parse_expression(0); self.current = self.calcs.next(); Some((val?, true)) @@ -310,6 +322,20 @@ impl<'a> DynamicCalculationEvaluator<'a> { } } + fn parse_prefix(&mut self) -> Option> { + match self.current? { + DynamicCalculation::Add => { + self.current = self.calcs.next(); + Some(Some(DynamicCalculation::Add)) + } + DynamicCalculation::Sub => { + self.current = self.calcs.next(); + Some(Some(DynamicCalculation::Sub)) + } + _ => Some(None), + } + } + /// Get the precedence of the operator if current token is an operator or None otherwise. fn operator_precedence(&self) -> Option { match self.current? { diff --git a/crates/torin/tests/size.rs b/crates/torin/tests/size.rs index e48054101..96697941d 100644 --- a/crates/torin/tests/size.rs +++ b/crates/torin/tests/size.rs @@ -860,7 +860,8 @@ pub fn test_calc() { PARENT_VALUE, PARENT_VALUE ), - None + // becasue +10 is just 10 + Some(10.0) ); assert_eq!( @@ -868,13 +869,14 @@ pub fn test_calc() { &vec![ DynamicCalculation::Pixels(10.0), DynamicCalculation::Add, + // counts as a prefix DynamicCalculation::Add, DynamicCalculation::Pixels(10.0) ], PARENT_VALUE, PARENT_VALUE ), - None + Some(20.0) ); assert_eq!( @@ -925,4 +927,19 @@ pub fn test_calc() { ), Some((10.0 * (10.0 + 20.0) * 10.0) + (10.0 * (10.0) * 10.0)) ); + + assert_eq!( + run_calculations( + &vec![ + DynamicCalculation::Sub, + DynamicCalculation::OpenParenthesis, + DynamicCalculation::Pixels(10.0), + DynamicCalculation::ClosedParenthesis, + DynamicCalculation::Pixels(20.0) + ], + PARENT_VALUE, + PARENT_VALUE + ), + Some(-1.0 * 10.0 * 20.0) + ); }