1mod literals;
8mod binary_ops;
9mod calls;
10mod misc;
11
12use super::{escape_rust_keyword, CodeGenerator, TypeContext};
13use decy_hir::{HirExpression, HirType};
14
15impl CodeGenerator {
16 #[allow(clippy::only_used_in_recursion)]
18 pub fn generate_expression(&self, expr: &HirExpression) -> String {
19 self.generate_expression_with_context(expr, &TypeContext::new())
20 }
21
22 #[allow(clippy::only_used_in_recursion)]
24 pub(crate) fn generate_expression_with_context(&self, expr: &HirExpression, ctx: &TypeContext) -> String {
25 self.generate_expression_with_target_type(expr, ctx, None)
26 }
27
28 #[allow(clippy::only_used_in_recursion)]
31 pub(crate) fn generate_expression_with_target_type(
32 &self,
33 expr: &HirExpression,
34 ctx: &TypeContext,
35 target_type: Option<&HirType>,
36 ) -> String {
37 match expr {
38 HirExpression::IntLiteral(val) => self.gen_expr_int_literal(*val, target_type),
39 HirExpression::FloatLiteral(val) => self.gen_expr_float_literal(val, target_type),
40 HirExpression::AddressOf(inner) => {
41 self.gen_expr_address_of(inner, ctx, target_type)
42 }
43 HirExpression::UnaryOp { op: decy_hir::UnaryOperator::AddressOf, operand } => {
44 self.gen_expr_unary_address_of(operand, ctx, target_type)
45 }
46 HirExpression::UnaryOp { op: decy_hir::UnaryOperator::LogicalNot, operand } => {
47 self.gen_expr_unary_logical_not(operand, ctx, target_type)
48 }
49 HirExpression::StringLiteral(s) => {
50 self.gen_expr_string_literal(s, target_type)
51 }
52 HirExpression::CharLiteral(c) => Self::gen_expr_char_literal(*c),
53 HirExpression::Variable(name) => {
54 self.gen_expr_variable(name, ctx, target_type)
55 }
56 HirExpression::BinaryOp { op, left, right } => {
57 self.gen_expr_binary_op(op, left, right, ctx, target_type)
58 }
59 HirExpression::Dereference(inner) => {
60 self.gen_expr_dereference(inner, ctx)
61 }
62 HirExpression::UnaryOp { op, operand } => {
63 self.gen_expr_unary_op(op, operand, ctx)
64 }
65 HirExpression::FunctionCall { function, arguments } => {
66 self.gen_expr_function_call(function, arguments, ctx, target_type)
67 }
68 HirExpression::FieldAccess { object, field } => {
69 format!(
70 "{}.{}",
71 self.generate_expression_with_context(object, ctx),
72 escape_rust_keyword(field)
73 )
74 }
75 HirExpression::PointerFieldAccess { pointer, field } => {
76 self.gen_expr_pointer_field_access(pointer, field, ctx)
77 }
78 HirExpression::ArrayIndex { array, index } => {
79 self.gen_expr_array_index(array, index, ctx)
80 }
81 HirExpression::SliceIndex { slice, index, .. } => {
82 let slice_code = self.generate_expression_with_context(slice, ctx);
83 let index_code = self.generate_expression_with_context(index, ctx);
84 format!("{}[({}) as usize]", slice_code, index_code)
85 }
86 HirExpression::Sizeof { type_name } => {
87 self.gen_expr_sizeof(type_name, ctx)
88 }
89 HirExpression::NullLiteral => "None".to_string(),
90 HirExpression::IsNotNull(inner) => {
91 let inner_code = self.generate_expression_with_context(inner, ctx);
92 format!("if let Some(_) = {}", inner_code)
93 }
94 HirExpression::Calloc { count, element_type } => {
95 self.gen_expr_calloc(count, element_type, ctx)
96 }
97 HirExpression::Malloc { size } => self.gen_expr_malloc(size, ctx),
98 HirExpression::Realloc { pointer, new_size } => {
99 self.gen_expr_realloc(pointer, new_size, ctx)
100 }
101 HirExpression::StringMethodCall { receiver, method, arguments } => {
102 self.gen_expr_string_method_call(receiver, method, arguments, ctx)
103 }
104 HirExpression::Cast { target_type: cast_target, expr } => {
105 self.gen_expr_cast(cast_target, expr, ctx, target_type)
106 }
107 HirExpression::CompoundLiteral { literal_type, initializers } => {
108 self.gen_expr_compound_literal(literal_type, initializers, ctx)
109 }
110 HirExpression::PostIncrement { operand } => {
111 self.gen_expr_post_increment(operand, ctx)
112 }
113 HirExpression::PreIncrement { operand } => {
114 self.gen_expr_pre_increment(operand, ctx)
115 }
116 HirExpression::PostDecrement { operand } => {
117 self.gen_expr_post_decrement(operand, ctx)
118 }
119 HirExpression::PreDecrement { operand } => {
120 self.gen_expr_pre_decrement(operand, ctx)
121 }
122 HirExpression::Ternary { condition, then_expr, else_expr } => {
123 self.gen_expr_ternary(condition, then_expr, else_expr, ctx, target_type)
124 }
125 HirExpression::CxxNew { allocated_type, arguments } => {
127 let type_name = Self::map_type(allocated_type);
128 if arguments.is_empty() {
129 format!("Box::new({}::default())", type_name)
130 } else {
131 let args: Vec<String> = arguments
132 .iter()
133 .map(|a| self.generate_expression_with_context(a, ctx))
134 .collect();
135 format!("Box::new({}::new({}))", type_name, args.join(", "))
136 }
137 }
138 HirExpression::CxxDelete { operand } => {
140 let operand_code = self.generate_expression_with_context(operand, ctx);
141 format!("drop({})", operand_code)
142 }
143 }
144 }
145}