From d3f4fcc046799c683ee26d77834f8169a3ee811f Mon Sep 17 00:00:00 2001 From: Kaz Wesley Date: Thu, 20 Apr 2023 15:02:47 +0000 Subject: [PATCH] Exclude comparison operators from modifier logic --- app/gui/language/parser/src/translation.rs | 22 +++++++++------------- lib/rust/parser/src/lexer.rs | 8 ++++++++ lib/rust/parser/src/syntax/token.rs | 11 +++++++++++ 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/app/gui/language/parser/src/translation.rs b/app/gui/language/parser/src/translation.rs index 9847124501b6..5360ad29e827 100644 --- a/app/gui/language/parser/src/translation.rs +++ b/app/gui/language/parser/src/translation.rs @@ -436,21 +436,17 @@ impl Translate { infix(lhs, opr, rhs).map(|opr_app| self.finish_ast(opr_app, builder)) } - /// Translate an operator or multiple-operator erorr into the [`Ast`] representation. + /// Translate an operator or multiple-operator error into the [`Ast`] representation. fn translate_operators(&mut self, opr: &tree::OperatorOrError) -> WithInitialSpace { match opr { - Ok(name) => match name.code.repr.strip_suffix('=') { - Some(mod_name) if mod_name.contains(|c| c != '=') => { - let opr_builder = self.start_ast(); - let token = self.visit_token(name); - token.map(|_| { - let name = mod_name.to_string(); - let opr = ast::Mod { name }; - self.finish_ast(opr, opr_builder) - }) - } - _ => self.translate_operator(name), - }, + Ok(name) if name.properties.is_modifier() => { + let opr_builder = self.start_ast(); + self.visit_token(name).map(|name| { + let name = name.strip_suffix('=').map(|s| s.to_owned()).unwrap_or(name); + self.finish_ast(ast::Mod { name }, opr_builder) + }) + } + Ok(name) => self.translate_operator(name), Err(names) => { let opr_builder = self.start_ast(); let mut span_info = SpanSeedBuilder::new(); diff --git a/lib/rust/parser/src/lexer.rs b/lib/rust/parser/src/lexer.rs index b53a87d16b5d..46a15aff561a 100644 --- a/lib/rust/parser/src/lexer.rs +++ b/lib/rust/parser/src/lexer.rs @@ -673,6 +673,14 @@ fn analyze_operator(token: &str) -> token::OperatorProperties { if token.ends_with("->") && !token.starts_with("<-") { operator = operator.as_right_associative(); } + if token.ends_with('=') && !token.bytes().all(|c| c == b'=') { + match token { + // Inclusive comparison operators are not modifiers. + ">=" | "<=" => (), + // Any other operator ending with "=" is a modifier. + _ => operator = operator.as_modifier(), + } + } match token { // Operators that can be unary. "\\" => diff --git a/lib/rust/parser/src/syntax/token.rs b/lib/rust/parser/src/syntax/token.rs index ff090d7b5f47..ef23f7420cfb 100644 --- a/lib/rust/parser/src/syntax/token.rs +++ b/lib/rust/parser/src/syntax/token.rs @@ -333,6 +333,7 @@ pub struct OperatorProperties { // Special properties is_compile_time_operation: bool, is_right_associative: bool, + is_modifier: bool, // Unique operators is_decimal: bool, is_type_annotation: bool, @@ -375,6 +376,11 @@ impl OperatorProperties { Self { is_right_associative: true, ..self } } + /// Return a copy of this operator, modified to be flagged as an modified-assignment operator. + pub fn as_modifier(self) -> Self { + Self { is_modifier: true, ..self } + } + /// Return a copy of this operator, modified to be flagged as special. pub fn as_special(self) -> Self { Self { is_special: true, ..self } @@ -467,6 +473,11 @@ impl OperatorProperties { self.is_assignment } + /// Return whether this operator is a modified-assignment operator. + pub fn is_modifier(&self) -> bool { + self.is_modifier + } + /// Return whether this operator is the arrow operator. pub fn is_arrow(&self) -> bool { self.is_arrow