use crate::ast::expression::Expression; use crate::ast::ir_builder::IrBuilder; use crate::ir::ir_assign::IrAssign; use crate::ir::ir_expression::IrExpression; use crate::ir::ir_operation::IrOperation; use crate::ir::ir_statement::IrStatement; use crate::ir::ir_variable::IrVariable; use crate::symbol_table::SymbolTable; use crate::type_info::TypeInfo; pub fn expression_to_ir_expression( expression: &Expression, builder: &mut IrBuilder, symbol_table: &SymbolTable, ) -> Option { match expression { Expression::Call(call) => { let ir_call = call.to_ir(builder, symbol_table); if matches!(call.type_info(), TypeInfo::Void) { builder .current_block_mut() .add_statement(IrStatement::Call(ir_call)); None } else { let t_var = IrVariable::new(&builder.new_t_var(), call.type_info()); let assign = IrAssign::new(t_var, IrOperation::Call(ir_call)); let destination = assign.destination().clone(); builder .current_block_mut() .add_statement(IrStatement::Assign(assign)); Some(IrExpression::Variable(destination)) } } Expression::IntegerLiteral(integer_literal) => { Some(IrExpression::Int(integer_literal.value())) } Expression::String(string_literal) => { Some(IrExpression::String(string_literal.content().into())) } Expression::Identifier(identifier) => { let expressible_symbol = identifier.expressible_symbol(); Some(expressible_symbol.ir_expression()) } Expression::Additive(additive_expression) => { let ir_add = additive_expression.to_ir(builder, symbol_table); let t_var = IrVariable::new(&builder.new_t_var(), additive_expression.type_info()); let assign = IrAssign::new(t_var, IrOperation::Add(ir_add)); let destination = assign.destination().clone(); builder .current_block_mut() .add_statement(IrStatement::Assign(assign)); Some(IrExpression::Variable(destination)) } } }