deimos-lang/dmc-lib/src/ast/ast_to_ir_util.rs

56 lines
2.2 KiB
Rust

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<IrExpression> {
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))
}
}
}