helix/dna/atp/
interpreter.rs

1use crate::atp::ast::{HelixAst, Expression, Statement, Declaration};
2use crate::hel::error::HlxError;
3use crate::ops::engine::OperatorEngine;
4use crate::ops::OperatorParser;
5use std::collections::HashMap;
6pub struct HelixInterpreter {
7    operator_engine: OperatorEngine,
8    ops_parser: OperatorParser,
9    variables: HashMap<String, Value>,
10}
11pub use crate::dna::atp::value::Value;
12pub use crate::atp::ast::{BinaryOperator,LoadDecl};
13impl HelixInterpreter {
14    pub async fn new() -> Result<Self, HlxError> {
15        let operator_engine = OperatorEngine::new().await?;
16        let ops_parser = match OperatorParser::new().await {
17            Ok(parser) => parser,
18            Err(e) => return Err(HlxError::execution_error(
19                format!("Failed to create operator parser: {}", e),
20                "Check operator configuration"
21            )),
22        };
23        Ok(Self {
24            operator_engine,
25            ops_parser,
26            variables: HashMap::new(),
27        })
28    }
29    pub async fn execute_ast(&mut self, ast: &HelixAst) -> Result<Value, HlxError> {
30        let mut result = Value::String("".to_string());
31        for declaration in &ast.declarations {
32            match declaration {
33                Declaration::Section(section) => {
34                    result = self.execute_section(&section).await?;
35                }
36                Declaration::Load(load_decl) => {
37                    result = self.execute_load(&load_decl).await?;
38                }
39                _ => {
40                    result = Value::String(
41                        format!("Declaration processed: {:?}", declaration),
42                    );
43                }
44            }
45        }
46        Ok(result)
47    }
48    async fn execute_section(
49        &mut self,
50        section: &crate::atp::ast::SectionDecl,
51    ) -> Result<Value, HlxError> {
52        let mut result = HashMap::new();
53        for (k, v) in &section.properties {
54            let types_value = v.to_value();
55            let converted_value = self.convert_types_value_to_value(types_value);
56            result.insert(k.clone(), converted_value);
57        }
58        Ok(Value::Object(result))
59    }
60    async fn execute_load(
61        &mut self,
62        load: &LoadDecl,
63    ) -> Result<Value, HlxError> {
64        Ok(
65            Value::Object({
66                let mut map = HashMap::new();
67                map.insert("loaded".to_string(), Value::String(load.file_name.clone()));
68                map.insert("type".to_string(), Value::String("file".to_string()));
69                map
70            }),
71        )
72    }
73    async fn execute_statement(
74        &mut self,
75        statement: &Statement,
76    ) -> Result<Value, HlxError> {
77        match statement {
78            Statement::Expression(expr) => self.evaluate_expression(expr).await,
79            Statement::Assignment(var_name, expr) => {
80                let value = self.evaluate_expression(expr).await?;
81                self.variables.insert(var_name.clone(), value.clone());
82                Ok(value)
83            }
84            Statement::Declaration(_) => {
85                Ok(Value::String("Declaration executed".to_string()))
86            }
87        }
88    }
89    async fn evaluate_expression(
90        &mut self,
91        expr: &Expression,
92    ) -> Result<Value, HlxError> {
93        match expr {
94            Expression::String(s) => {
95                if s.starts_with('@') || s.contains(" + ") || s.contains('?')
96                    || s.contains("$")
97                {
98                    match self.ops_parser.evaluate_expression(expr).await {
99                        Ok(value) => Ok(self.convert_ops_value_to_types_value(value)),
100                        Err(e) => {
101                            Err(
102                                HlxError::execution_error(
103                                    format!("Operator evaluation failed: {}", e),
104                                    "Check operator syntax and parameters",
105                                ),
106                            )
107                        }
108                    }
109                } else {
110                    Ok(Value::String(s.clone()))
111                }
112            }
113            Expression::Number(n) => Ok(Value::Number(*n)),
114            Expression::Bool(b) => Ok(Value::Bool(*b)),
115            Expression::Null => Ok(Value::Null),
116            Expression::Duration(d) => {
117                Ok(Value::String(format!("{} {:?}", d.value, d.unit)))
118            }
119            Expression::Array(arr) => {
120                let mut values = Vec::new();
121                for item in arr {
122                    values.push(Box::pin(self.evaluate_expression(item)).await?);
123                }
124                Ok(Value::Array(values))
125            }
126            Expression::Object(obj) => {
127                let mut result = HashMap::new();
128                for (key, value) in obj {
129                    result
130                        .insert(
131                            key.clone(),
132                            Box::pin(self.evaluate_expression(value)).await?,
133                        );
134                }
135                Ok(Value::Object(result))
136            }
137            Expression::Variable(name) => {
138                self.variables
139                    .get(name)
140                    .cloned()
141                    .ok_or_else(|| HlxError::execution_error(
142                        format!("Variable '{}' not found", name),
143                        "Check variable name and scope",
144                    ))
145            }
146            Expression::OperatorCall(operator, key, sub_key, value) => {
147                let mut params = HashMap::new();
148                params.insert("key".to_string(), Expression::String(key.clone()));
149                if let Some(sk) = sub_key {
150                    params.insert("sub_key".to_string(), Expression::String(sk.clone()));
151                }
152                if let Some(v) = value {
153                    params.insert("value".to_string(), Expression::String(v.clone()));
154                }
155                let json_params = self.params_to_json(&params).await?;
156                let value_result = self
157                    .operator_engine
158                    .execute_operator(&operator, &json_params)
159                    .await?;
160                Ok(self.convert_ops_value_to_types_value(value_result))
161            }
162            Expression::AtOperatorCall(_operator, _params) => {
163                match self.ops_parser.evaluate_expression(&expr).await {
164                    Ok(value) => Ok(self.convert_ops_value_to_types_value(value)),
165                    Err(_) => {
166                        Err(
167                            HlxError::validation_error(
168                                "AtOperatorCall failed",
169                                "Check operator syntax",
170                            ),
171                        )
172                    }
173                }
174            }
175            Expression::Identifier(name) => {
176                if let Some(value) = self.variables.get(name) {
177                    Ok(value.clone())
178                } else {
179                    let params = HashMap::new();
180                    let json_params = self.params_to_json(&params).await?;
181                    let value_result = self
182                        .operator_engine
183                        .execute_operator(&name, &json_params)
184                        .await?;
185                    Ok(self.convert_ops_value_to_types_value(value_result))
186                }
187            }
188            Expression::Reference(name) => self.resolve_reference(name),
189            Expression::IndexedReference(file, key) => {
190                Box::pin(self.resolve_indexed_reference(file, key)).await
191            }
192            Expression::Pipeline(stages) => Box::pin(self.execute_pipeline(stages)).await,
193            Expression::Block(_statements) => {
194                Err(
195                    HlxError::validation_error(
196                        "Block expressions not supported",
197                        "Use statement blocks instead",
198                    ),
199                )
200            }
201            Expression::TextBlock(lines) => Ok(Value::String(lines.join("\n"))),
202            Expression::BinaryOp(left, op, right) => {
203                let left_val = Box::pin(self.evaluate_expression(left)).await?;
204                let right_val = Box::pin(self.evaluate_expression(right)).await?;
205                let op_str = match op {
206                    BinaryOperator::Eq => "==",
207                    BinaryOperator::Ne => "!=",
208                    BinaryOperator::Lt => "<",
209                    BinaryOperator::Le => "<=",
210                    BinaryOperator::Gt => ">",
211                    BinaryOperator::Ge => ">=",
212                    BinaryOperator::And => "&&",
213                    BinaryOperator::Or => "||",
214                    BinaryOperator::Add => "+",
215                    BinaryOperator::Sub => "-",
216                    BinaryOperator::Mul => "*",
217                    BinaryOperator::Div => "/",
218                };
219                Ok(Value::String(format!("{:?} {} {:?}", left_val, op_str, right_val)))
220            }
221        }
222    }
223    async fn params_to_json(
224        &mut self,
225        params: &HashMap<String, Expression>,
226    ) -> Result<String, HlxError> {
227        let mut json_map = serde_json::Map::new();
228        for (key, expr) in params {
229            let value = Box::pin(self.evaluate_expression(expr)).await?;
230            let json_value = self.value_to_json_value(&value);
231            json_map.insert(key.clone(), json_value);
232        }
233        let json_obj = serde_json::Value::Object(json_map);
234        serde_json::to_string(&json_obj)
235            .map_err(|e| HlxError::execution_error(
236                format!("Failed to serialize parameters: {}", e),
237                "Check parameter types",
238            ))
239    }
240    fn value_to_json_value(&self, value: &Value) -> serde_json::Value {
241        match value {
242            Value::String(s) => serde_json::Value::String(s.clone()),
243            Value::Number(n) => {
244                serde_json::Number::from_f64(*n)
245                    .map(serde_json::Value::Number)
246                    .unwrap_or(serde_json::Value::Null)
247            }
248            Value::Bool(b) => serde_json::Value::Bool(*b),
249            Value::Array(arr) => {
250                let values: Vec<serde_json::Value> = arr
251                    .iter()
252                    .map(|v| self.value_to_json_value(v))
253                    .collect();
254                serde_json::Value::Array(values)
255            }
256            Value::Object(obj) => {
257                let mut map = serde_json::Map::new();
258                for (k, v) in obj {
259                    map.insert(k.clone(), self.value_to_json_value(v));
260                }
261                serde_json::Value::Object(map)
262            }
263            Value::Null => serde_json::Value::Null,
264            Value::Duration(d) => serde_json::Value::String(format!("{} {:?}", d.value, d.unit)),
265            Value::Reference(r) => serde_json::Value::String(format!("@{}", r)),
266            Value::Identifier(i) => serde_json::Value::String(i.clone()),
267        }
268    }
269    pub fn operator_engine(&self) -> &OperatorEngine {
270        &self.operator_engine
271    }
272    pub fn operator_engine_mut(&mut self) -> &mut OperatorEngine {
273        &mut self.operator_engine
274    }
275    pub fn set_variable(&mut self, name: String, value: Value) {
276        self.variables.insert(name, value);
277    }
278    pub fn get_variable(&self, name: &str) -> Option<&Value> {
279        self.variables.get(name)
280    }
281    pub fn list_variables(&self) -> Vec<(String, Value)> {
282        self.variables.iter().map(|(k, v)| (k.clone(), v.clone())).collect()
283    }
284    fn resolve_reference(&self, name: &str) -> Result<Value, HlxError> {
285        if let Some(value) = self.variables.get(name) {
286            return Ok(value.clone());
287        }
288        match self.operator_engine.get_variable(name) {
289            Ok(value) => Ok(self.convert_ops_value_to_types_value(value)),
290            Err(_) => Err(HlxError::execution_error(
291                format!("Variable '{}' not found", name),
292                "Check variable name and scope",
293            )),
294        }
295    }
296    async fn resolve_indexed_reference(
297        &mut self,
298        file: &str,
299        key: &str,
300    ) -> Result<Value, HlxError> {
301        let base_value = self.resolve_reference(file)?;
302        let keys: Vec<&str> = key.split('.').collect();
303        let mut current_value = base_value;
304        for key_part in keys {
305            match &current_value {
306                Value::Object(obj) => {
307                    current_value = obj.get(key_part).cloned().unwrap_or(Value::Null);
308                }
309                Value::Array(arr) => {
310                    if let Ok(index) = key_part.parse::<usize>() {
311                        current_value = arr.get(index).cloned().unwrap_or(Value::Null);
312                    } else {
313                        return Err(
314                            HlxError::execution_error(
315                                format!(
316                                    "Invalid array index '{}' in '{}[{}]'", key_part, file, key
317                                ),
318                                "Array indices must be numeric",
319                            ),
320                        );
321                    }
322                }
323                _ => {
324                    return Err(
325                        HlxError::execution_error(
326                            format!(
327                                "Cannot index into non-object/non-array value for '{}[{}]'",
328                                file, key
329                            ),
330                            "Indexed references require object or array base values",
331                        ),
332                    );
333                }
334            }
335        }
336        Ok(current_value)
337    }
338    async fn execute_pipeline(&mut self, stages: &[String]) -> Result<Value, HlxError> {
339        if stages.is_empty() {
340            return Err(
341                HlxError::execution_error(
342                    "Empty pipeline",
343                    "Pipelines must contain at least one stage",
344                ),
345            );
346        }
347        let mut result = Value::Null;
348        for (i, stage) in stages.iter().enumerate() {
349            match self.operator_engine.execute_operator(stage, "{}").await {
350                Ok(stage_result) => {
351                    result = self.convert_ops_value_to_types_value(stage_result);
352                }
353                Err(e) => {
354                    return Err(
355                        HlxError::execution_error(
356                            format!("Pipeline stage {} failed: {}", i + 1, e),
357                            "Check pipeline stage syntax and parameters",
358                        ),
359                    );
360                }
361            }
362        }
363        Ok(result)
364    }
365    fn convert_types_value_to_value(&self, types_value: crate::atp::types::Value) -> Value {
366        match types_value {
367            crate::atp::types::Value::String(s) => Value::String(s),
368            crate::atp::types::Value::Number(n) => Value::Number(n),
369            crate::atp::types::Value::Bool(b) => Value::Bool(b),
370            crate::atp::types::Value::Array(arr) => {
371                Value::Array(arr.into_iter().map(|v| self.convert_types_value_to_value(v)).collect())
372            }
373            crate::atp::types::Value::Object(obj) => {
374                Value::Object(obj.into_iter().map(|(k, v)| (k, self.convert_types_value_to_value(v))).collect())
375            }
376            crate::atp::types::Value::Null => Value::Null,
377            crate::atp::types::Value::Duration(d) => Value::Duration(d),
378            crate::atp::types::Value::Reference(r) => Value::Reference(r),
379            crate::atp::types::Value::Identifier(i) => Value::Identifier(i),
380        }
381    }
382    fn convert_ops_value_to_types_value(&self, ops_value: crate::atp::value::Value) -> Value {
383        match ops_value {
384            crate::atp::value::Value::String(s) => Value::String(s),
385            crate::atp::value::Value::Number(n) => Value::Number(n),
386            crate::atp::value::Value::Bool(b) => Value::Bool(b),
387            crate::atp::value::Value::Array(arr) => {
388                Value::Array(arr.into_iter().map(|v| self.convert_ops_value_to_types_value(v)).collect())
389            }
390            crate::atp::value::Value::Object(obj) => {
391                Value::Object(obj.into_iter().map(|(k, v)| (k, self.convert_ops_value_to_types_value(v))).collect())
392            }
393            crate::atp::value::Value::Null => Value::Null,
394            crate::atp::value::Value::Duration(d) => Value::Duration(d),
395            crate::atp::value::Value::Reference(r) => Value::Reference(r),
396            crate::atp::value::Value::Identifier(i) => Value::Identifier(i),
397        }
398    }
399}