use crate::ast::expression::Expression; use crate::diagnostic::Diagnostic; use crate::source_range::SourceRange; use crate::symbol_table::SymbolTable; use crate::type_info::TypeInfo; pub struct NegativeExpression { operand: Box, source_range: SourceRange, type_info: Option, } impl NegativeExpression { pub fn new(operand: Expression, source_range: SourceRange) -> Self { Self { operand: operand.into(), source_range, type_info: None, } } pub fn source_range(&self) -> &SourceRange { &self.source_range } pub fn operand(&self) -> &Expression { &self.operand } pub fn operand_mut(&mut self) -> &mut Expression { &mut self.operand } pub fn gather_declared_names( &mut self, symbol_table: &mut SymbolTable, ) -> Result<(), Vec> { self.operand.gather_declared_names(symbol_table) } pub fn check_name_usages(&mut self, symbol_table: &SymbolTable) -> Result<(), Vec> { self.operand.check_name_usages(symbol_table) } pub fn type_check(&mut self, symbol_table: &SymbolTable) -> Result<(), Vec> { self.operand.type_check(symbol_table)?; let type_info = self.operand.type_info(); if type_info.can_negate() { self.type_info = Some(type_info.negate_result()); Ok(()) } else { Err(vec![Diagnostic::new( &format!("Cannot negate {}", type_info), self.source_range.start(), self.source_range.end(), )]) } } pub fn type_info(&self) -> &TypeInfo { self.type_info.as_ref().unwrap() } }