use crate::ast::additive_expression::AdditiveExpression; use crate::ast::call::Call; use crate::ast::identifier::Identifier; use crate::ast::integer_literal::IntegerLiteral; use crate::ast::string_literal::StringLiteral; use crate::diagnostic::Diagnostic; use crate::source_range::SourceRange; use crate::symbol_table::SymbolTable; use crate::type_info::TypeInfo; pub enum Expression { Call(Call), IntegerLiteral(IntegerLiteral), String(StringLiteral), Identifier(Identifier), Additive(AdditiveExpression), } impl Expression { pub fn gather_declared_names(&mut self, symbol_table: &mut SymbolTable) -> Vec { match self { Expression::Call(call) => call.gather_declared_names(symbol_table), Expression::Identifier(identifier) => identifier.gather_declared_names(symbol_table), Expression::Additive(additive_expression) => { match additive_expression.gather_declared_names(symbol_table) { Ok(_) => { vec![] } Err(diagnostics) => diagnostics, } } _ => vec![], } } pub fn check_name_usages(&mut self, symbol_table: &SymbolTable) -> Vec { match self { Expression::Call(call) => call.check_name_usages(symbol_table), Expression::Identifier(identifier) => identifier.check_name_usages(symbol_table), Expression::Additive(additive_expression) => { match additive_expression.check_name_usages(symbol_table) { Ok(_) => { vec![] } Err(diagnostics) => diagnostics, } } _ => vec![], } } pub fn type_check(&mut self, symbol_table: &SymbolTable) -> Vec { match self { Expression::Call(call) => call.type_check(symbol_table), Expression::Additive(additive_expression) => { match additive_expression.type_check(symbol_table) { Ok(_) => { vec![] } Err(diagnostics) => diagnostics, } } _ => vec![], } } pub fn type_info(&self) -> TypeInfo { match self { Expression::Call(call) => call.type_info(), Expression::IntegerLiteral(_) => TypeInfo::Integer, Expression::String(_) => TypeInfo::String, Expression::Identifier(identifier) => identifier.type_info(), Expression::Additive(additive_expression) => additive_expression.type_info(), } } pub fn source_range(&self) -> &SourceRange { match self { Expression::Call(call) => call.source_range(), Expression::IntegerLiteral(integer_literal) => integer_literal.source_range(), Expression::String(string_literal) => string_literal.source_range(), Expression::Identifier(identifier) => identifier.source_range(), Expression::Additive(additive_expression) => additive_expression.source_range(), } } }