deimos-lang/dmc-lib/src/ast/negative_expression.rs
2026-03-09 16:35:32 -05:00

65 lines
1.7 KiB
Rust

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<Expression>,
source_range: SourceRange,
type_info: Option<TypeInfo>,
}
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<Diagnostic>> {
self.operand.gather_declared_names(symbol_table)
}
pub fn check_name_usages(&mut self, symbol_table: &SymbolTable) -> Result<(), Vec<Diagnostic>> {
self.operand.check_name_usages(symbol_table)
}
pub fn type_check(&mut self, symbol_table: &SymbolTable) -> Result<(), Vec<Diagnostic>> {
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()
}
}