datex_core/decompiler/
ast_from_value_container.rs1use crate::ast::expressions::{CreateRef, DatexExpressionData, List, Map};
2use crate::ast::spanned::Spanned;
3use crate::ast::type_expressions::{
4 Intersection, TypeExpression, TypeExpressionData, Union,
5};
6use crate::types::definition::TypeDefinition;
7use crate::types::structural_type_definition::StructuralTypeDefinition;
8use crate::values::core_value::CoreValue;
9use crate::values::core_values::r#type::Type;
10use crate::values::value::Value;
11use crate::values::value_container::ValueContainer;
12use datex_core::ast::expressions::CallableDeclaration;
13use datex_core::libs::core::CoreLibPointerId;
14
15impl From<&ValueContainer> for DatexExpressionData {
16 fn from(value: &ValueContainer) -> Self {
19 match value {
20 ValueContainer::Value(value) => value_to_datex_expression(value),
21 ValueContainer::Reference(reference) => {
22 DatexExpressionData::CreateRef(CreateRef {
23 mutability: reference.mutability(),
24 expression: Box::new(
25 DatexExpressionData::from(&reference.value_container())
26 .with_default_span(),
27 ),
28 })
29 }
30 }
31 }
32}
33
34fn value_to_datex_expression(value: &Value) -> DatexExpressionData {
35 match &value.inner {
36 CoreValue::Integer(integer) => {
37 DatexExpressionData::Integer(integer.clone())
38 }
39 CoreValue::TypedInteger(typed_integer) => {
40 DatexExpressionData::TypedInteger(typed_integer.clone())
41 }
42 CoreValue::Decimal(decimal) => {
43 DatexExpressionData::Decimal(decimal.clone())
44 }
45 CoreValue::TypedDecimal(typed_decimal) => {
46 DatexExpressionData::TypedDecimal(typed_decimal.clone())
47 }
48 CoreValue::Boolean(boolean) => DatexExpressionData::Boolean(boolean.0),
49 CoreValue::Text(text) => DatexExpressionData::Text(text.0.clone()),
50 CoreValue::Endpoint(endpoint) => {
51 DatexExpressionData::Endpoint(endpoint.clone())
52 }
53 CoreValue::Null => DatexExpressionData::Null,
54 CoreValue::List(list) => DatexExpressionData::List(List::new(
55 list.into_iter()
56 .map(DatexExpressionData::from)
57 .map(|data| data.with_default_span())
58 .collect(),
59 )),
60 CoreValue::Map(map) => DatexExpressionData::Map(Map::new(
61 map.into_iter()
62 .map(|(key, value)| {
63 (
64 DatexExpressionData::from(&ValueContainer::from(key))
65 .with_default_span(),
66 DatexExpressionData::from(value).with_default_span(),
67 )
68 })
69 .collect(),
70 )),
71 CoreValue::Type(type_value) => DatexExpressionData::TypeExpression(
72 type_to_type_expression(type_value),
73 ),
74 CoreValue::Callable(callable) => {
75 DatexExpressionData::CallableDeclaration(CallableDeclaration {
76 name: callable.name.clone(),
77 kind: callable.signature.kind.clone(),
78 parameters: callable
79 .signature
80 .parameter_types
81 .iter()
82 .map(|(maybe_name, ty)| {
83 (
84 maybe_name.clone().unwrap_or("_".to_string()),
85 type_to_type_expression(ty),
86 )
87 })
88 .collect(),
89 rest_parameter: callable
90 .signature
91 .rest_parameter_type
92 .as_ref()
93 .map(|(maybe_name, ty)| {
94 (
95 maybe_name.clone().unwrap_or("_".to_string()),
96 type_to_type_expression(ty),
97 )
98 }),
99 return_type: callable
100 .signature
101 .return_type
102 .as_ref()
103 .map(|ty| type_to_type_expression(ty)),
104 yeet_type: callable
105 .signature
106 .yeet_type
107 .as_ref()
108 .map(|ty| type_to_type_expression(ty)),
109 body: Box::new(
110 DatexExpressionData::NativeImplementationIndicator
111 .with_default_span(),
112 ),
113 })
114 }
115 }
116}
117
118fn type_to_type_expression(type_value: &Type) -> TypeExpression {
119 match &type_value.type_definition {
120 TypeDefinition::Structural(struct_type) => match struct_type {
121 StructuralTypeDefinition::Integer(integer) => {
122 TypeExpressionData::Integer(integer.clone()).with_default_span()
123 }
124 StructuralTypeDefinition::Text(text) => {
125 TypeExpressionData::Text(text.0.clone()).with_default_span()
126 }
127 StructuralTypeDefinition::Boolean(boolean) => {
128 TypeExpressionData::Boolean(boolean.0).with_default_span()
129 }
130 StructuralTypeDefinition::Decimal(decimal) => {
131 TypeExpressionData::Decimal(decimal.clone()).with_default_span()
132 }
133 StructuralTypeDefinition::TypedInteger(typed_integer) => {
134 TypeExpressionData::TypedInteger(typed_integer.clone())
135 .with_default_span()
136 }
137 StructuralTypeDefinition::TypedDecimal(typed_decimal) => {
138 TypeExpressionData::TypedDecimal(typed_decimal.clone())
139 .with_default_span()
140 }
141 StructuralTypeDefinition::Endpoint(endpoint) => {
142 TypeExpressionData::Endpoint(endpoint.clone())
143 .with_default_span()
144 }
145 StructuralTypeDefinition::Null => {
146 TypeExpressionData::Null.with_default_span()
147 }
148 _ => TypeExpressionData::Text(format!(
149 "[[STRUCTURAL TYPE {:?}]]",
150 struct_type
151 ))
152 .with_default_span(),
153 },
154 TypeDefinition::Union(union_types) => TypeExpressionData::Union(Union(
155 union_types
156 .iter()
157 .map(|t| type_to_type_expression(t))
158 .collect::<Vec<TypeExpression>>(),
159 ))
160 .with_default_span(),
161 TypeDefinition::Intersection(intersection_types) => {
162 TypeExpressionData::Intersection(Intersection(
163 intersection_types
164 .iter()
165 .map(|t| type_to_type_expression(t))
166 .collect::<Vec<TypeExpression>>(),
167 ))
168 .with_default_span()
169 }
170 TypeDefinition::Unit => TypeExpressionData::Unit.with_default_span(),
171 TypeDefinition::Reference(type_reference) => {
172 if let Some(address) = &type_reference.borrow().pointer_address {
174 if let Ok(core_lib_type) = CoreLibPointerId::try_from(address) {
175 TypeExpressionData::Identifier(core_lib_type.to_string())
176 .with_default_span()
177 } else {
178 todo!(
179 "#651 Handle non-core-lib type references in decompiler"
180 );
181 }
182 } else {
183 panic!("Unresolved type reference in decompiler"); }
185 }
186 _ => TypeExpressionData::Text(format!(
187 "[[TYPE {:?}]]",
188 type_value.type_definition
189 ))
190 .with_default_span(),
191 }
192}
193
194#[cfg(test)]
195mod tests {
196 use crate::ast::expressions::{DatexExpressionData, List};
197 use crate::ast::spanned::Spanned;
198 use crate::values::core_values::decimal::Decimal;
199 use crate::values::core_values::decimal::typed_decimal::TypedDecimal;
200 use crate::values::core_values::integer::Integer;
201 use crate::values::core_values::integer::typed_integer::TypedInteger;
202 use crate::values::value::Value;
203 use crate::values::value_container::ValueContainer;
204
205 #[test]
206 fn test_integer_to_ast() {
207 let value = ValueContainer::from(Integer::from(42));
208 let ast = DatexExpressionData::from(&value);
209 assert_eq!(ast, DatexExpressionData::Integer(Integer::from(42)));
210 }
211
212 #[test]
213 fn test_typed_integer_to_ast() {
214 let value = ValueContainer::from(TypedInteger::from(42i8));
215 let ast = DatexExpressionData::from(&value);
216 assert_eq!(
217 ast,
218 DatexExpressionData::TypedInteger(TypedInteger::from(42i8))
219 );
220 }
221
222 #[test]
223 fn test_decimal_to_ast() {
224 let value = ValueContainer::from(Decimal::from(1.23));
225 let ast = DatexExpressionData::from(&value);
226 assert_eq!(ast, DatexExpressionData::Decimal(Decimal::from(1.23)));
227 }
228
229 #[test]
230 fn test_typed_decimal_to_ast() {
231 let value = ValueContainer::from(TypedDecimal::from(2.71f32));
232 let ast = DatexExpressionData::from(&value);
233 assert_eq!(
234 ast,
235 DatexExpressionData::TypedDecimal(TypedDecimal::from(2.71f32))
236 );
237 }
238
239 #[test]
240 fn test_boolean_to_ast() {
241 let value = ValueContainer::from(true);
242 let ast = DatexExpressionData::from(&value);
243 assert_eq!(ast, DatexExpressionData::Boolean(true));
244 }
245
246 #[test]
247 fn test_text_to_ast() {
248 let value = ValueContainer::from("Hello, World!".to_string());
249 let ast = DatexExpressionData::from(&value);
250 assert_eq!(ast, DatexExpressionData::Text("Hello, World!".to_string()));
251 }
252
253 #[test]
254 fn test_null_to_ast() {
255 let value = ValueContainer::Value(Value::null());
256 let ast = DatexExpressionData::from(&value);
257 assert_eq!(ast, DatexExpressionData::Null);
258 }
259
260 #[test]
261 fn test_list_to_ast() {
262 let value = ValueContainer::from(vec![
263 Integer::from(1),
264 Integer::from(2),
265 Integer::from(3),
266 ]);
267 let ast = DatexExpressionData::from(&value);
268 assert_eq!(
269 ast,
270 DatexExpressionData::List(List::new(vec![
271 DatexExpressionData::Integer(Integer::from(1))
272 .with_default_span(),
273 DatexExpressionData::Integer(Integer::from(2))
274 .with_default_span(),
275 DatexExpressionData::Integer(Integer::from(3))
276 .with_default_span(),
277 ]))
278 );
279 }
280}