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