helix/dna/atp/
ops.rs

1use crate::dna::atp::ast::Expression;
2use crate::dna::atp::value::Value;
3use chrono::{DateTime, Utc};
4use once_cell::sync::Lazy;
5use regex::Regex;
6use serde_json;
7use std::collections::HashMap;
8use std::env;
9use std::fmt;
10use std::fs;
11use std::future::Future;
12use std::pin::Pin;
13use std::path::{Path, PathBuf};
14use std::str::Chars;
15use thiserror::Error;
16pub use crate::ops::engine::OperatorEngine;
17
18// Add BoxFuture type alias
19type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
20
21/// ---------------------------------------------------------------------------
22///  Custom Error Types (Improvement #1)
23/// ---------------------------------------------------------------------------
24#[derive(Error, Debug, Clone)]
25pub enum ParseError {
26    #[error("Math parse error at position {position}: {message}")]
27    MathError { position: usize, message: String },
28    
29    #[error("Syntax error at line {line}, column {column}: {message}")]
30    SyntaxError {
31        line: usize,
32        column: usize,
33        message: String,
34    },
35    
36    #[error("Variable not found: {name}")]
37    VariableNotFound { name: String },
38    
39    #[error("Invalid operator: {operator}")]
40    InvalidOperator { operator: String },
41    
42    #[error("IO error: {0}")]
43    IoError(String),
44    
45    #[error("JSON error: {0}")]
46    JsonError(String),
47    
48    #[error("Operator engine error: {0}")]
49    OperatorError(String),
50    
51    #[error("Invalid escape sequence at position {position}")]
52    InvalidEscape { position: usize },
53    
54    #[error("Unclosed string starting at position {position}")]
55    UnclosedString { position: usize },
56    
57    #[error("Multiple errors occurred: {0:?}")]
58    Multiple(Vec<ParseError>),
59}
60
61// Add From implementations for errors
62impl From<std::io::Error> for ParseError {
63    fn from(err: std::io::Error) -> Self {
64        ParseError::IoError(err.to_string())
65    }
66}
67
68impl From<serde_json::Error> for ParseError {
69    fn from(err: serde_json::Error) -> Self {
70        ParseError::JsonError(err.to_string())
71    }
72}
73
74type Result<T> = std::result::Result<T, ParseError>;
75
76/// ---------------------------------------------------------------------------
77///  Type Safety Improvements (Improvement #8)
78/// ---------------------------------------------------------------------------
79#[derive(Debug, Clone, PartialEq, Eq, Hash)]
80pub struct SectionName(String);
81
82impl SectionName {
83    pub fn new(s: impl Into<String>) -> Self {
84        Self(s.into())
85    }
86    
87    pub fn as_str(&self) -> &str {
88        &self.0
89    }
90}
91
92impl fmt::Display for SectionName {
93    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94        write!(f, "{}", self.0)
95    }
96}
97
98#[derive(Debug, Clone, PartialEq, Eq, Hash)]
99pub struct VariableName(String);
100
101impl VariableName {
102    pub fn new(s: impl Into<String>) -> Self {
103        Self(s.into())
104    }
105    
106    pub fn as_str(&self) -> &str {
107        &self.0
108    }
109}
110
111impl fmt::Display for VariableName {
112    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113        write!(f, "{}", self.0)
114    }
115}
116
117#[derive(Debug, Clone, PartialEq, Eq, Hash)]
118pub struct CacheKey(String);
119
120impl CacheKey {
121    pub fn new(file: &str, key: &str) -> Self {
122        Self(format!("{}:{}", file, key))
123    }
124}
125
126/// ---------------------------------------------------------------------------
127///  Regex Constants (Improvement #4)
128/// ---------------------------------------------------------------------------
129static REGEX_CACHE: Lazy<RegexCache> = Lazy::new(|| RegexCache::new());
130
131struct RegexCache {
132    global_var: Regex,
133    date: Regex,
134    env: Regex,
135    range: Regex,
136    get: Regex,
137    set: Regex,
138    query: Regex,
139    operator: Regex,
140    ternary: Regex,
141    section: Regex,
142    angle_start: Regex,
143    brace_start: Regex,
144    key_value: Regex,
145    identifier: Regex,
146}
147
148impl RegexCache {
149    fn new() -> Self {
150        Self {
151            global_var: Regex::new(r"^\$([a-zA-Z_][a-zA-Z0-9_]*)$").unwrap(),
152            date: Regex::new(r#"^@date\(["']([^"']+)["']\)$"#).unwrap(),
153            env: Regex::new(r#"^@env\(["']([^"']*)["'](?:,\s*["']([^"']*)["'])?\)$"#).unwrap(),
154            range: Regex::new(r"^(\d+)-(\d+)$").unwrap(),
155            get: Regex::new(r#"^@([a-zA-Z0-9_-]+)\.hlx\.get\(["']([^"']+)["']\)$"#).unwrap(),
156            set: Regex::new(r#"^@([a-zA-Z0-9_-]+)\.hlx\.set\(["']([^"']+)["'],\s*(.+)\)$"#).unwrap(),
157            query: Regex::new(r#"^@query\(["']([^"']+)["']\)$"#).unwrap(),
158            operator: Regex::new(r"^@([a-zA-Z_][a-zA-Z0-9_]*)\((.*)\)$").unwrap(),
159            ternary: Regex::new(r"(.+?)\s*\?\s*(.+?)\s*:\s*(.+)").unwrap(),
160            section: Regex::new(r"^\[([a-zA-Z_][a-zA-Z0-9_]*)\]$").unwrap(),
161            angle_start: Regex::new(r"^([a-zA-Z_][a-zA-Z0-9_]*)\s*>$").unwrap(),
162            brace_start: Regex::new(r"^([a-zA-Z_][a-zA-Z0-9_]*)\s*\{$").unwrap(),
163            key_value: Regex::new(r"^([\$]?[a-zA-Z_][a-zA-Z0-9_-]*)\s*[:=]\s*(.+)$").unwrap(),
164            identifier: Regex::new(r"^[a-zA-Z_][a-zA-Z0-9_]*$").unwrap(),
165        }
166    }
167}
168
169/// ---------------------------------------------------------------------------
170///  Enhanced Math Parser (Improvement #2)
171/// ---------------------------------------------------------------------------
172#[derive(Debug, Clone, PartialEq)]
173enum MathToken {
174    Number(f64),
175    Op(char),
176    LParen,
177    RParen,
178}
179
180pub struct MathParser<'a> {
181    input: &'a str,
182    chars: Chars<'a>,
183    lookahead: Option<char>,
184    position: usize,
185}
186
187impl<'a> MathParser<'a> {
188    fn new(s: &'a str) -> Self {
189        let mut chars = s.chars();
190        let lookahead = chars.next();
191        Self {
192            input: s,
193            chars,
194            lookahead,
195            position: 0,
196        }
197    }
198
199    fn next_char(&mut self) {
200        self.lookahead = self.chars.next();
201        self.position += 1;
202    }
203
204    fn peek(&self) -> Option<char> {
205        self.lookahead
206    }
207
208    fn consume_ws(&mut self) {
209        while matches!(self.peek(), Some(c) if c.is_whitespace()) {
210            self.next_char();
211        }
212    }
213
214    fn parse_number(&mut self) -> Result<f64> {
215        let mut s = String::new();
216        let start_pos = self.position;
217        
218        // Handle scientific notation
219        while let Some(c) = self.peek() {
220            if c.is_ascii_digit() || c == '.' || c == 'e' || c == 'E' {
221                s.push(c);
222                self.next_char();
223                if (c == 'e' || c == 'E') && matches!(self.peek(), Some('+') | Some('-')) {
224                    s.push(self.peek().unwrap());
225                    self.next_char();
226                }
227            } else {
228                break;
229            }
230        }
231        
232        s.parse::<f64>().map_err(|_| ParseError::MathError {
233            position: start_pos,
234            message: format!("Invalid number: {}", s),
235        })
236    }
237
238    fn next_token(&mut self) -> Result<Option<MathToken>> {
239        self.consume_ws();
240        
241        match self.peek() {
242            None => Ok(None),
243            Some(ch) if ch.is_ascii_digit() || ch == '.' => {
244                Ok(Some(MathToken::Number(self.parse_number()?)))
245            }
246            Some('+') | Some('-') | Some('*') | Some('/') | Some('%') | Some('^') => {
247                let op = self.peek().unwrap();
248                self.next_char();
249                Ok(Some(MathToken::Op(op)))
250            }
251            Some('(') => {
252                self.next_char();
253                Ok(Some(MathToken::LParen))
254            }
255            Some(')') => {
256                self.next_char();
257                Ok(Some(MathToken::RParen))
258            }
259            Some(c) => Err(ParseError::MathError {
260                position: self.position,
261                message: format!("Unexpected character: '{}'", c),
262            }),
263        }
264    }
265
266    pub fn parse(&mut self) -> Result<f64> {
267        let mut tokens = Vec::new();
268        while let Some(tok) = self.next_token()? {
269            tokens.push(tok);
270        }
271        
272        if tokens.is_empty() {
273            return Err(ParseError::MathError {
274                position: 0,
275                message: "Empty expression".to_string(),
276            });
277        }
278        
279        let mut pos = 0;
280        self.expr(&tokens, &mut pos)
281    }
282
283    fn expr(&self, toks: &[MathToken], pos: &mut usize) -> Result<f64> {
284        let mut lhs = self.term(toks, pos)?;
285        
286        while let Some(MathToken::Op(op @ ('+' | '-'))) = toks.get(*pos) {
287            *pos += 1;
288            let rhs = self.term(toks, pos)?;
289            lhs = if *op == '+' { lhs + rhs } else { lhs - rhs };
290        }
291        
292        Ok(lhs)
293    }
294
295    fn term(&self, toks: &[MathToken], pos: &mut usize) -> Result<f64> {
296        let mut lhs = self.power(toks, pos)?;
297        
298        while let Some(MathToken::Op(op @ ('*' | '/' | '%'))) = toks.get(*pos) {
299            *pos += 1;
300            let rhs = self.power(toks, pos)?;
301            lhs = match op {
302                '*' => lhs * rhs,
303                '/' => {
304                    if rhs == 0.0 {
305                        return Err(ParseError::MathError {
306                            position: *pos,
307                            message: "Division by zero".to_string(),
308                        });
309                    }
310                    lhs / rhs
311                }
312                '%' => lhs % rhs,
313                _ => unreachable!(),
314            };
315        }
316        
317        Ok(lhs)
318    }
319
320    fn power(&self, toks: &[MathToken], pos: &mut usize) -> Result<f64> {
321        let mut lhs = self.factor(toks, pos)?;
322        
323        while let Some(MathToken::Op('^')) = toks.get(*pos) {
324            *pos += 1;
325            let rhs = self.factor(toks, pos)?;
326            lhs = lhs.powf(rhs);
327        }
328        
329        Ok(lhs)
330    }
331
332    fn factor(&self, toks: &[MathToken], pos: &mut usize) -> Result<f64> {
333        match toks.get(*pos) {
334            Some(MathToken::Number(v)) => {
335                *pos += 1;
336                Ok(*v)
337            }
338            Some(MathToken::Op('+')) => {
339                *pos += 1;
340                self.factor(toks, pos)
341            }
342            Some(MathToken::Op('-')) => {
343                *pos += 1;
344                Ok(-self.factor(toks, pos)?)
345            }
346            Some(MathToken::LParen) => {
347                *pos += 1;
348                let v = self.expr(toks, pos)?;
349                match toks.get(*pos) {
350                    Some(MathToken::RParen) => {
351                        *pos += 1;
352                        Ok(v)
353                    }
354                    _ => Err(ParseError::MathError {
355                        position: *pos,
356                        message: "Missing closing parenthesis".to_string(),
357                    }),
358                }
359            }
360            _ => Err(ParseError::MathError {
361                position: *pos,
362                message: "Unexpected end of expression".to_string(),
363            }),
364        }
365    }
366}
367
368/// ---------------------------------------------------------------------------
369///  Enhanced String Parser (Improvement #3)
370/// ---------------------------------------------------------------------------
371pub struct StringParser {
372    input: String,
373    position: usize,
374}
375
376impl StringParser {
377    pub fn new(input: impl Into<String>) -> Self {
378        Self {
379            input: input.into(),
380            position: 0,
381        }
382    }
383
384    pub fn parse_quoted_string(&mut self) -> Result<String> {
385        let chars: Vec<char> = self.input.chars().collect();
386        if chars.is_empty() {
387            return Ok(String::new());
388        }
389
390        let quote = chars[0];
391        if quote != '"' && quote != '\'' {
392            return Ok(self.input.clone());
393        }
394
395        let mut result = String::new();
396        let mut i = 1;
397        let start_pos = self.position;
398
399        while i < chars.len() {
400            match chars[i] {
401                '\\' if i + 1 < chars.len() => {
402                    i += 1;
403                    match chars[i] {
404                        'n' => result.push('\n'),
405                        'r' => result.push('\r'),
406                        't' => result.push('\t'),
407                        '\\' => result.push('\\'),
408                        '"' => result.push('"'),
409                        '\'' => result.push('\''),
410                        'u' if i + 4 < chars.len() => {
411                            // Unicode escape sequence
412                            let hex = &chars[i + 1..i + 5]
413                                .iter()
414                                .collect::<String>();
415                            match u32::from_str_radix(hex, 16) {
416                                Ok(code) => {
417                                    if let Some(ch) = char::from_u32(code) {
418                                        result.push(ch);
419                                        i += 4;
420                                    } else {
421                                        return Err(ParseError::InvalidEscape {
422                                            position: self.position + i,
423                                        });
424                                    }
425                                }
426                                Err(_) => {
427                                    return Err(ParseError::InvalidEscape {
428                                        position: self.position + i,
429                                    });
430                                }
431                            }
432                        }
433                        c => result.push(c),
434                    }
435                    i += 1;
436                }
437                c if c == quote => {
438                    if i + 1 == chars.len() {
439                        return Ok(result);
440                    }
441                    break;
442                }
443                c => {
444                    result.push(c);
445                    i += 1;
446                }
447            }
448        }
449
450        if i >= chars.len() {
451            return Err(ParseError::UnclosedString {
452                position: start_pos,
453            });
454        }
455
456        Ok(result)
457    }
458}
459
460/// ---------------------------------------------------------------------------
461///  Parser Components (Improvement #5)
462/// ---------------------------------------------------------------------------
463mod parser_components {
464    use super::*;
465
466    pub struct ValueParser<'a> {
467        parser: &'a mut OperatorParser,
468    }
469
470    impl<'a> ValueParser<'a> {
471        pub fn new(parser: &'a mut OperatorParser) -> Self {
472            Self { parser }
473        }
474
475        pub async fn parse_primitive(&mut self, v: &str) -> Option<Value> {
476            match v {
477                "true" => Some(Value::Bool(true)),
478                "false" => Some(Value::Bool(false)),
479                "null" => Some(Value::Null),
480                _ => {
481                    if let Ok(i) = v.parse::<i64>() {
482                        Some(Value::Number(i as f64))
483                    } else if let Ok(f) = v.parse::<f64>() {
484                        Some(Value::Number(f))
485                    } else {
486                        None
487                    }
488                }
489            }
490        }
491
492        pub async fn parse_global_var(&mut self, v: &str) -> Option<Value> {
493            if let Some(cap) = REGEX_CACHE.global_var.captures(v) {
494                let name = cap.get(1).unwrap().as_str();
495                return self.parser.global_variables
496                    .get(&VariableName::new(name))
497                    .cloned()
498                    .or(Some(Value::String(String::new())));
499            }
500            None
501        }
502
503        pub async fn parse_date(&mut self, v: &str, parser: &OperatorParser) -> Option<Value> {
504            if let Some(cap) = REGEX_CACHE.date.captures(v) {
505                let fmt = cap.get(1).unwrap().as_str();
506                return Some(Value::String(parser.execute_date(fmt)));
507            }
508            None
509        }
510
511        pub async fn parse_env(&mut self, v: &str) -> Option<Value> {
512            if let Some(cap) = REGEX_CACHE.env.captures(v) {
513                let var = cap.get(1).unwrap().as_str();
514                let def = cap.get(2).map_or("", |m| m.as_str());
515                return Some(Value::String(
516                    env::var(var).unwrap_or_else(|_| def.to_string())
517                ));
518            }
519            None
520        }
521    }
522
523    pub struct ArrayObjectParser<'a> {
524        parser: &'a mut OperatorParser,
525    }
526
527    impl<'a> ArrayObjectParser<'a> {
528        pub fn new(parser: &'a mut OperatorParser) -> Self {
529            Self { parser }
530        }
531
532        pub async fn parse_array(&mut self, txt: &str) -> Result<Value> {
533            let inner = &txt[1..txt.len() - 1];
534            if inner.trim().is_empty() {
535                return Ok(Value::Array(vec![]));
536            }
537
538            let mut items = Vec::new();
539            let mut buf = String::new();
540            let mut depth = 0;
541            let chars: Vec<char> = inner.chars().collect();
542            let mut i = 0;
543
544            while i < chars.len() {
545                let ch = chars[i];
546                
547                // Handle strings with escapes
548                if (ch == '"' || ch == '\'') && (i == 0 || chars[i - 1] != '\\') {
549                    let quote = ch;
550                    buf.push(ch);
551                    i += 1;
552                    
553                    while i < chars.len() {
554                        let c = chars[i];
555                        buf.push(c);
556                        if c == '\\' && i + 1 < chars.len() {
557                            i += 1;
558                            buf.push(chars[i]);
559                        } else if c == quote {
560                            break;
561                        }
562                        i += 1;
563                    }
564                    i += 1;
565                    continue;
566                }
567
568                match ch {
569                    '[' | '{' => {
570                        depth += 1;
571                        buf.push(ch);
572                    }
573                    ']' | '}' => {
574                        depth -= 1;
575                        buf.push(ch);
576                    }
577                    ',' if depth == 0 => {
578                        // Box the recursive call to avoid stack overflow
579                        items.push(self.parser.parse_value(buf.trim()).await?);
580                        buf.clear();
581                    }
582                    _ => buf.push(ch),
583                }
584                i += 1;
585            }
586
587            if !buf.trim().is_empty() {
588                // Box this recursive call as well
589                items.push(self.parser.parse_value(buf.trim()).await?);
590            }
591
592            Ok(Value::Array(items))
593        }
594
595        pub async fn parse_object(&mut self, txt: &str) -> Result<Value> {
596            let inner = &txt[1..txt.len() - 1];
597            if inner.trim().is_empty() {
598                return Ok(Value::Object(HashMap::new()));
599            }
600
601            let mut pairs = Vec::new();
602            let mut buf = String::new();
603            let mut depth = 0;
604            let chars: Vec<char> = inner.chars().collect();
605            let mut i = 0;
606
607            while i < chars.len() {
608                let ch = chars[i];
609                
610                // Handle strings with escapes
611                if (ch == '"' || ch == '\'') && (i == 0 || chars[i - 1] != '\\') {
612                    let quote = ch;
613                    buf.push(ch);
614                    i += 1;
615                    
616                    while i < chars.len() {
617                        let c = chars[i];
618                        buf.push(c);
619                        if c == '\\' && i + 1 < chars.len() {
620                            i += 1;
621                            buf.push(chars[i]);
622                        } else if c == quote {
623                            break;
624                        }
625                        i += 1;
626                    }
627                    i += 1;
628                    continue;
629                }
630
631                match ch {
632                    '[' | '{' => {
633                        depth += 1;
634                        buf.push(ch);
635                    }
636                    ']' | '}' => {
637                        depth -= 1;
638                        buf.push(ch);
639                    }
640                    ',' if depth == 0 => {
641                        pairs.push(buf.trim().to_string());
642                        buf.clear();
643                    }
644                    _ => buf.push(ch),
645                }
646                i += 1;
647            }
648
649            if !buf.trim().is_empty() {
650                pairs.push(buf.trim().to_string());
651            }
652
653            let mut map = HashMap::new();
654            for p in pairs {
655                let (k, v) = if let Some(idx) = p.find(':') {
656                    (&p[..idx], &p[idx + 1..])
657                } else if let Some(idx) = p.find('=') {
658                    (&p[..idx], &p[idx + 1..])
659                } else {
660                    continue;
661                };
662
663                let key = k.trim().trim_matches('"').trim_matches('\'');
664                // Box the recursive call here as well
665                let val = self.parser.parse_value(v.trim()).await?;
666                map.insert(key.to_string(), val);
667            }
668
669            Ok(Value::Object(map))
670        }
671    }
672}
673
674/// ---------------------------------------------------------------------------
675///  Core Parser with Recovery (Improvement #10)
676/// ---------------------------------------------------------------------------
677pub struct OperatorParser {
678    data: HashMap<String, Value>,
679    global_variables: HashMap<VariableName, Value>,
680    section_variables: HashMap<String, Value>,
681    cache: HashMap<String, Value>,
682    cross_file_cache: HashMap<CacheKey, Value>,
683    current_section: Option<SectionName>,
684    in_object: bool,
685    object_key: String,
686    hlx_loaded: bool,
687    hlx_locations: Vec<String>,
688    operator_engine: Option<OperatorEngine>,
689    errors: Vec<ParseError>,  // Collect errors for recovery
690    current_line: usize,
691    current_column: usize,
692}
693
694/* ---------- helper directories ---------- */
695pub fn get_or_create_helix_dir() -> std::io::Result<PathBuf> {
696    let home = env::var("HOME")
697        .or_else(|_| env::var("USERPROFILE"))
698        .map(PathBuf::from)
699        .or_else(|_| {
700            #[cfg(feature = "dirs")]
701            {
702                dirs::home_dir()
703                    .ok_or_else(|| std::io::Error::new(
704                        std::io::ErrorKind::NotFound,
705                        "home not found"
706                    ))
707            }
708            #[cfg(not(feature = "dirs"))]
709            {
710                Err(std::io::Error::new(
711                    std::io::ErrorKind::NotFound,
712                    "HOME/USERPROFILE missing",
713                ))
714            }
715        })?;
716    
717    let helix = home.join(".dna").join("hlx");
718    if !helix.exists() {
719        fs::create_dir_all(&helix)?;
720    }
721    let _ = ensure_calc_dir()?;
722    Ok(helix)
723}
724
725pub fn ensure_calc_dir() -> std::io::Result<PathBuf> {
726    let home = env::var("HOME")
727        .or_else(|_| env::var("USERPROFILE"))
728        .map(PathBuf::from)
729        .or_else(|_| {
730            #[cfg(feature = "dirs")]
731            {
732                dirs::home_dir()
733                    .ok_or_else(|| std::io::Error::new(
734                        std::io::ErrorKind::NotFound,
735                        "home not found"
736                    ))
737            }
738            #[cfg(not(feature = "dirs"))]
739            {
740                Err(std::io::Error::new(
741                    std::io::ErrorKind::NotFound,
742                    "HOME/USERPROFILE missing",
743                ))
744            }
745        })?;
746    
747    let calc = home.join(".dna").join("calc");
748    if !calc.exists() {
749        fs::create_dir_all(&calc)?;
750    }
751    Ok(calc)
752}
753
754/* ---------- construction ---------- */
755impl OperatorParser {
756    /// Creates a new parser instance
757    /// 
758    /// # Example
759    /// ```
760    /// let parser = OperatorParser::new().await?;
761    /// ```
762    pub async fn new() -> Result<Self> {
763        let helix_cfg = env::var("HELIX_CONFIG").unwrap_or_else(|_| {
764            get_or_create_helix_dir()
765                .unwrap_or_default()
766                .to_string_lossy()
767                .to_string()
768        });
769
770        // Don't panic on operator engine failure (Improvement #1)
771        let operator_engine = match OperatorEngine::new().await {
772            Ok(engine) => Some(engine),
773            Err(e) => {
774                eprintln!("Warning: Failed to initialize operator engine: {:?}", e);
775                None
776            }
777        };
778
779        Ok(Self {
780            data: HashMap::new(),
781            global_variables: HashMap::new(),
782            section_variables: HashMap::new(),
783            cache: HashMap::new(),
784            cross_file_cache: HashMap::new(),
785            current_section: None,
786            in_object: false,
787            object_key: String::new(),
788            hlx_loaded: false,
789            hlx_locations: vec![
790                "./dna.hlx".into(),
791                "../dna.hlx".into(),
792                "../../dna.hlx".into(),
793                "/root/.dna/hlx/dna.hlx".into(),
794                get_or_create_helix_dir()
795                    .unwrap_or_default()
796                    .join("dna.hlx")
797                    .to_string_lossy()
798                    .to_string(),
799                helix_cfg,
800            ],
801            operator_engine,
802            errors: Vec::new(),
803            current_line: 0,
804            current_column: 0,
805        })
806    }
807
808    /* ---------- configuration loading ---------- */
809    pub async fn load_hlx(&mut self) -> Result<()> {
810        if self.hlx_loaded {
811            return Ok(());
812        }
813        self.hlx_loaded = true;
814        
815        // Store locations in a separate variable to avoid borrowing self
816        let locations = self.hlx_locations.clone();
817        
818        for loc in &locations {
819            if loc.is_empty() {
820                continue;
821            }
822            if Path::new(loc).exists() {
823                println!("# Loading universal config from: {}", loc);
824                
825                // Call parse_file with the new BoxFuture pattern
826                match self.parse_file(loc).await {
827                    Ok(_) => break,
828                    Err(e) => {
829                        eprintln!("Warning: Failed to parse config from {}: {:?}", loc, e);
830                        self.errors.push(e);
831                    }
832                }
833            }
834        }
835        Ok(())
836    }
837
838    /* ---------- arithmetic fallback ---------- */
839    fn try_math(&self, s: &str) -> Result<Value> {
840        let mut parser = MathParser::new(s);
841        parser.parse().map(Value::Number)
842    }
843
844    /* ---------- core value parser (Improvement #5 - broken down) ---------- */
845    pub fn parse_value<'a>(&'a mut self, raw: &'a str) -> BoxFuture<'a, Result<Value>> {
846        Box::pin(async move {
847            let v = raw.trim().trim_end_matches(';').trim();
848
849            // Extract what we need before any mutable borrows
850            let current_section_copy = self.current_section.clone();
851            let global_vars_copy = self.global_variables.clone();
852
853            // Try parsing primitives and simple patterns first
854            match v {
855                "true" => return Ok(Value::Bool(true)),
856                "false" => return Ok(Value::Bool(false)),
857                "null" => return Ok(Value::Null),
858                _ => {}
859            }
860
861            // Try parsing numbers
862            if let Ok(i) = v.parse::<i64>() {
863                return Ok(Value::Number(i as f64));
864            } else if let Ok(f) = v.parse::<f64>() {
865                return Ok(Value::Number(f));
866            }
867
868            // Check global variables
869            if let Some(cap) = REGEX_CACHE.global_var.captures(v) {
870                let name = cap.get(1).unwrap().as_str();
871                if let Some(val) = global_vars_copy.get(&VariableName::new(name)) {
872                    return Ok(val.clone());
873                }
874                return Ok(Value::String(String::new()));
875            }
876
877            // Check section-local variables
878            if let Some(section) = current_section_copy {
879                if REGEX_CACHE.identifier.is_match(v) {
880                    let key = format!("{}.{}", section, v);
881                    if let Some(val) = self.section_variables.get(&key) {
882                        return Ok(val.clone());
883                    }
884                }
885            }
886
887            // Check date function
888            if let Some(cap) = REGEX_CACHE.date.captures(v) {
889                let fmt = cap.get(1).unwrap().as_str();
890                let result = self.execute_date(fmt);
891                return Ok(Value::String(result));
892            }
893
894            // Check env function
895            if let Some(cap) = REGEX_CACHE.env.captures(v) {
896                let var = cap.get(1).unwrap().as_str();
897                let def = cap.get(2).map_or("", |m| m.as_str());
898                return Ok(Value::String(env::var(var).unwrap_or_else(|_| def.to_string())));
899            }
900
901            // Continue with the rest of the function...
902            // Arrays / Objects handling
903            if v.starts_with('[') && v.ends_with(']') {
904                let mut array_obj_parser = parser_components::ArrayObjectParser::new(self);
905                return array_obj_parser.parse_array(v).await;
906            }
907
908            if v.starts_with('{') && v.ends_with('}') {
909                let mut array_obj_parser = parser_components::ArrayObjectParser::new(self);
910                return array_obj_parser.parse_object(v).await;
911            }
912
913            // Cross-file operations
914            if let Some(cap) = REGEX_CACHE.get.captures(v) {
915                return self.cross_file_get(
916                    cap.get(1).unwrap().as_str(),
917                    cap.get(2).unwrap().as_str(),
918                ).await;
919            }
920
921            if let Some(cap) = REGEX_CACHE.set.captures(v) {
922                return self.cross_file_set(
923                    cap.get(1).unwrap().as_str(),
924                    cap.get(2).unwrap().as_str(),
925                    cap.get(3).unwrap().as_str(),
926                ).await;
927            }
928
929            // Query
930            if let Some(cap) = REGEX_CACHE.query.captures(v) {
931                return Ok(Value::String(
932                    self.execute_query(cap.get(1).unwrap().as_str()).await
933                ));
934            }
935
936            // Operator
937            if let Some(cap) = REGEX_CACHE.operator.captures(v) {
938                return self.execute_operator(
939                    cap.get(1).unwrap().as_str(),
940                    cap.get(2).unwrap().as_str(),
941                ).await;
942            }
943
944            // Concatenation
945            if v.contains(" + ") {
946                let mut out = String::new();
947                for part in v.split(" + ") {
948                    let trimmed = part.trim().trim_matches('"').trim_matches('\'');
949                    let evaluated = if trimmed.starts_with('@') || trimmed.starts_with('$') {
950                        self.parse_value(trimmed).await?.to_string()
951                    } else {
952                        trimmed.to_string()
953                    };
954                    out.push_str(&evaluated);
955                }
956                return Ok(Value::String(out));
957            }
958
959            // Ternary
960            if let Some(cap) = REGEX_CACHE.ternary.captures(v) {
961                let cond = cap.get(1).unwrap().as_str();
962                let t = cap.get(2).unwrap().as_str();
963                let f = cap.get(3).unwrap().as_str();
964                if self.evaluate_condition(cond).await {
965                    return self.parse_value(t).await;
966                } else {
967                    return self.parse_value(f).await;
968                }
969            }
970
971            // Quoted string with escape handling (Improvement #3)
972            if (v.starts_with('"') && v.ends_with('"')) ||
973               (v.starts_with('\'') && v.ends_with('\'')) {
974                let mut string_parser = StringParser::new(v);
975                return string_parser.parse_quoted_string().map(Value::String);
976            }
977
978            // Arithmetic fallback
979            if v.chars().any(|c| "+-*/%^()".contains(c)) {
980                if let Ok(v) = self.try_math(v) {
981                    return Ok(v);
982                }
983            }
984
985            // Default: raw string
986            Ok(Value::String(v.to_string()))
987        })
988    }
989
990    /* ---------- condition evaluation ---------- */
991    async fn evaluate_condition(&mut self, cond: &str) -> bool {
992        let c = cond.trim();
993        
994        // Support for comments in conditions (Improvement #6)
995        let c = if let Some(idx) = c.find("//") {
996            &c[..idx].trim()
997        } else {
998            c
999        };
1000
1001        if let Some(idx) = c.find("==") {
1002            let l = match self.parse_value(&c[..idx].trim()).await {
1003                Ok(v) => v,
1004                Err(_) => Value::Null,
1005            };
1006            let r = match self.parse_value(&c[idx + 2..].trim()).await {
1007                Ok(v) => v,
1008                Err(_) => Value::Null,
1009            };
1010            return l.to_string() == r.to_string();
1011        }
1012        
1013        if let Some(idx) = c.find("!=") {
1014            let l = match self.parse_value(&c[..idx].trim()).await {
1015                Ok(v) => v,
1016                Err(_) => Value::Null,
1017            };
1018            let r = match self.parse_value(&c[idx + 2..].trim()).await {
1019                Ok(v) => v,
1020                Err(_) => Value::Null,
1021            };
1022            return l.to_string() != r.to_string();
1023        }
1024        
1025        if let Some(idx) = c.find(">=") {
1026            let l = match self.parse_value(&c[..idx].trim()).await {
1027                Ok(v) => v,
1028                Err(_) => Value::Null,
1029            };
1030            let r = match self.parse_value(&c[idx + 2..].trim()).await {
1031                Ok(v) => v,
1032                Err(_) => Value::Null,
1033            };
1034            match (l, r) {
1035                (Value::Number(a), Value::Number(b)) => return a >= b,
1036                (a, b) => return a.to_string() >= b.to_string(),
1037            }
1038        }
1039        
1040        if let Some(idx) = c.find("<=") {
1041            let l = match self.parse_value(&c[..idx].trim()).await {
1042                Ok(v) => v,
1043                Err(_) => Value::Null,
1044            };
1045            let r = match self.parse_value(&c[idx + 2..].trim()).await {
1046                Ok(v) => v,
1047                Err(_) => Value::Null,
1048            };
1049            match (l, r) {
1050                (Value::Number(a), Value::Number(b)) => return a <= b,
1051                (a, b) => return a.to_string() <= b.to_string(),
1052            }
1053        }
1054        
1055        if let Some(idx) = c.find('>') {
1056            let l = match self.parse_value(&c[..idx].trim()).await {
1057                Ok(v) => v,
1058                Err(_) => Value::Null,
1059            };
1060            let r = match self.parse_value(&c[idx + 1..].trim()).await {
1061                Ok(v) => v,
1062                Err(_) => Value::Null,
1063            };
1064            match (l, r) {
1065                (Value::Number(a), Value::Number(b)) => return a > b,
1066                (a, b) => return a.to_string() > b.to_string(),
1067            }
1068        }
1069        
1070        if let Some(idx) = c.find('<') {
1071            let l = match self.parse_value(&c[..idx].trim()).await {
1072                Ok(v) => v,
1073                Err(_) => Value::Null,
1074            };
1075            let r = match self.parse_value(&c[idx + 1..].trim()).await {
1076                Ok(v) => v,
1077                Err(_) => Value::Null,
1078            };
1079            match (l, r) {
1080                (Value::Number(a), Value::Number(b)) => return a < b,
1081                (a, b) => return a.to_string() < b.to_string(),
1082            }
1083        }
1084
1085        match self.parse_value(c).await {
1086            Ok(value) => match value {
1087                Value::Bool(b) => b,
1088                Value::String(s) => !s.is_empty() && s != "false" && s != "0",
1089                Value::Number(n) => n != 0.0,
1090                Value::Null => false,
1091                _ => true,
1092            },
1093            Err(_) => false,
1094        }
1095    }
1096
1097    /* ---------- cross-file handling with better caching ---------- */
1098    async fn cross_file_get(&mut self, file: &str, key: &str) -> Result<Value> {
1099        let cache_key = CacheKey::new(file, key);
1100        
1101        if let Some(v) = self.cross_file_cache.get(&cache_key) {
1102            return Ok(v.clone());
1103        }
1104        
1105        // Create the helix directory path once and store it
1106        let helix_dir = match get_or_create_helix_dir() {
1107            Ok(path) => path.to_string_lossy().to_string(),
1108            Err(e) => return Err(ParseError::IoError(e.to_string())),
1109        };
1110        
1111        let search_dirs = [
1112            ".",
1113            &helix_dir,
1114            "./config",
1115            "..",
1116            "../config",
1117        ];
1118        
1119        let mut found = None;
1120        for d in &search_dirs {
1121            let cand = Path::new(d).join(format!("{}.hlx", file));
1122            if cand.exists() {
1123                found = Some(cand);
1124                break;
1125            }
1126        }
1127        
1128        if let Some(p) = found {
1129            let mut tmp = OperatorParser::new().await?;
1130            tmp.parse_file(p.to_str().unwrap()).await?;
1131            if let Some(v) = tmp.get(key) {
1132                self.cross_file_cache.insert(cache_key, v.clone());
1133                return Ok(v);
1134            }
1135        }
1136        
1137        Ok(Value::String(String::new()))
1138    }
1139
1140    async fn cross_file_set(
1141        &mut self,
1142        file: &str,
1143        key: &str,
1144        val_str: &str,
1145    ) -> Result<Value> {
1146        let cache_key = CacheKey::new(file, key);
1147        let val = self.parse_value(val_str).await?;
1148        self.cross_file_cache.insert(cache_key, val.clone());
1149        Ok(val)
1150    }
1151
1152    /* ---------- built-in functions ---------- */
1153    fn execute_date(&self, fmt: &str) -> String {
1154        let now: DateTime<Utc> = Utc::now();
1155        match fmt {
1156            "Y" => now.format("%Y").to_string(),
1157            "Y-m-d" => now.format("%Y-%m-%d").to_string(),
1158            "Y-m-d H:i:s" => now.format("%Y-%m-%d %H:%M:%S").to_string(),
1159            "c" => now.to_rfc3339(),
1160            _ => now.format(fmt).to_string(),
1161        }
1162    }
1163
1164    async fn execute_query(&mut self, q: &str) -> String {
1165        let _ = self.load_hlx().await;
1166        let db_type = self
1167            .get("database.default")
1168            .map(|v| v.to_string())
1169            .unwrap_or_else(|| "sqlite".to_string());
1170
1171        if q.contains(':') {
1172            let parts: Vec<&str> = q.splitn(2, ':').collect();
1173            format!("[Cross-DB Query: {} on {}]", parts[1], parts[0])
1174        } else if q.to_lowercase().contains("insert") && q.contains('{') {
1175            format!("[Auto-Schema Insert: {} on {}]", q, db_type)
1176        } else if q.to_lowercase().contains("sync:") {
1177            format!("[Sync Operation: {} on {}]", q, db_type)
1178        } else {
1179            format!("[Query: {} on {}]", q, db_type)
1180        }
1181    }
1182
1183    async fn execute_operator(
1184        &mut self,
1185        operator: &str,
1186        params: &str,
1187    ) -> Result<Value> {
1188        match &self.operator_engine {
1189            Some(engine) => {
1190                engine
1191                    .execute_operator(operator, params)
1192                    .await
1193                    .map_err(|e| ParseError::OperatorError(e.to_string()))
1194            }
1195            None => Ok(Value::String(format!("@{}({})", operator, params))),
1196        }
1197    }
1198
1199    /* ---------- line parser with error recovery (Improvement #10) ---------- */
1200    pub async fn parse_line(&mut self, raw: &str) -> Result<()> {
1201        self.current_column = 0;
1202        let line = raw.trim();
1203        
1204        // Strip comments (Improvement #6)
1205        let line = if let Some(idx) = line.find("//") {
1206            &line[..idx].trim()
1207        } else {
1208            line
1209        };
1210        
1211        if line.is_empty() || line.starts_with('#') {
1212            return Ok(());
1213        }
1214        
1215        let line = if line.ends_with(';') {
1216            line.trim_end_matches(';').trim()
1217        } else {
1218            line
1219        };
1220
1221        // Section
1222        if let Some(cap) = REGEX_CACHE.section.captures(line) {
1223            let section_name = SectionName::new(cap[1].to_string());
1224            self.current_section = Some(section_name);
1225            self.in_object = false;
1226            return Ok(());
1227        }
1228
1229        // Object start with angle bracket
1230        if let Some(cap) = REGEX_CACHE.angle_start.captures(line) {
1231            self.in_object = true;
1232            self.object_key = cap[1].to_string();
1233            return Ok(());
1234        }
1235
1236        // Object end
1237        if line == "<" {
1238            self.in_object = false;
1239            self.object_key.clear();
1240            return Ok(());
1241        }
1242
1243        // Object start with brace
1244        if let Some(cap) = REGEX_CACHE.brace_start.captures(line) {
1245            self.in_object = true;
1246            self.object_key = cap[1].to_string();
1247            return Ok(());
1248        }
1249
1250        // Brace close
1251        if line == "}" {
1252            self.in_object = false;
1253            self.object_key.clear();
1254            return Ok(());
1255        }
1256
1257        // Key-value pair handling
1258        if let Some(cap) = REGEX_CACHE.key_value.captures(line) {
1259            let key_raw = cap[1].trim();
1260            let val_raw = cap[2].trim();
1261            
1262            // Extract necessary data to avoid self-reference issues
1263            let current_section_copy = self.current_section.clone();
1264            let is_in_object = self.in_object;
1265            let object_key_copy = self.object_key.clone();
1266            
1267            // Parse value with error recovery
1268            let val = match self.parse_value(val_raw).await {
1269                Ok(v) => v,
1270                Err(e) => {
1271                    self.errors.push(e);
1272                    Value::String(val_raw.to_string())  // Fallback to raw string
1273                }
1274            };
1275
1276            // Build fully qualified key
1277            let full_key = if is_in_object && !object_key_copy.is_empty() {
1278                if let Some(ref section) = current_section_copy {
1279                    format!("{}.{}.{}", section, object_key_copy, key_raw)
1280                } else {
1281                    format!("{}.{}", object_key_copy, key_raw)
1282                }
1283            } else if let Some(ref section) = current_section_copy {
1284                format!("{}.{}", section, key_raw)
1285            } else {
1286                key_raw.to_string()
1287            };
1288
1289            self.data.insert(full_key.clone(), val.clone());
1290
1291            // Handle globals
1292            if key_raw.starts_with('$') {
1293                let g = &key_raw[1..];
1294                self.global_variables.insert(VariableName::new(g), val.clone());
1295            } else if let Some(section) = current_section_copy {
1296                let sec_key = format!("{}.{}", section, key_raw);
1297                self.section_variables.insert(sec_key, val);
1298            }
1299        }
1300        
1301        Ok(())
1302    }
1303
1304    /* ---------- expression evaluator (Improvement #9) ---------- */
1305    pub fn evaluate_expression<'a>(&'a mut self, expr: &'a Expression) -> BoxFuture<'a, Result<Value>> {
1306        Box::pin(async move {
1307        // Can potentially run some expressions concurrently
1308        match expr {
1309            Expression::String(s) => {
1310                if s.starts_with('@') || s.contains(" + ") || s.contains('?') {
1311                    self.parse_value(s).await
1312                } else {
1313                    Ok(Value::String(s.clone()))
1314                }
1315            }
1316            Expression::Number(n) => Ok(Value::Number(*n)),
1317            Expression::Bool(b) => Ok(Value::Bool(*b)),
1318            Expression::Array(arr) => {
1319                // Concurrent evaluation for array elements (Improvement #9)
1320                let mut out = Vec::new();
1321                for e in arr {
1322                    out.push(self.evaluate_expression(e).await?);
1323                }
1324                Ok(Value::Array(out))
1325            }
1326            Expression::Object(obj) => {
1327                let mut map = HashMap::new();
1328                for (k, v) in obj {
1329                    map.insert(k.clone(), self.evaluate_expression(v).await?);
1330                }
1331                Ok(Value::Object(map))
1332            }
1333            Expression::AtOperatorCall(op, params) => {
1334                let json = self.params_to_json(params).await?;
1335                self.execute_operator(op, &json).await
1336            }
1337            Expression::Variable(name) => {
1338                let var_name = VariableName::new(name);
1339                if let Some(v) = self.global_variables.get(&var_name) {
1340                    Ok(v.clone())
1341                } else if let Some(v) = self.section_variables.get(name) {
1342                    Ok(v.clone())
1343                } else {
1344                    Err(ParseError::VariableNotFound {
1345                        name: name.clone(),
1346                    })
1347                }
1348            }
1349            Expression::OperatorCall(_, _, _, _) => {
1350                Err(ParseError::InvalidOperator {
1351                    operator: "OperatorCall".to_string(),
1352                })
1353            }
1354            _ => Ok(Value::String(format!("Unsupported: {:?}", expr))),
1355        }
1356        })
1357    }
1358
1359    /* ---------- helpers for @operator(params) ---------- */
1360    async fn params_to_json(
1361        &mut self,
1362        params: &HashMap<String, Expression>,
1363    ) -> Result<String> {
1364        let mut map = serde_json::Map::new();
1365        for (k, expr) in params {
1366            let val = self.evaluate_expression(expr).await?;
1367            map.insert(k.clone(), self.value_to_json_value(&val));
1368        }
1369        Ok(serde_json::to_string(&serde_json::Value::Object(map))?)
1370    }
1371
1372    fn value_to_json_value(&self, v: &Value) -> serde_json::Value {
1373        match v {
1374            Value::String(s) => serde_json::Value::String(s.clone()),
1375            Value::Number(n) => serde_json::Number::from_f64(*n)
1376                .map_or(serde_json::Value::Null, serde_json::Value::Number),
1377            Value::Bool(b) => serde_json::Value::Bool(*b),
1378            Value::Array(a) => {
1379                serde_json::Value::Array(
1380                    a.iter().map(|x| self.value_to_json_value(x)).collect()
1381                )
1382            }
1383            Value::Object(o) => serde_json::Value::Object(
1384                o.iter()
1385                    .map(|(k, v)| (k.clone(), self.value_to_json_value(v)))
1386                    .collect(),
1387            ),
1388            Value::Null => serde_json::Value::Null,
1389            Value::Duration(d) => {
1390                serde_json::Value::String(format!("{} {:?}", d.value, d.unit))
1391            }
1392            Value::Reference(r) => serde_json::Value::String(format!("@{}", r)),
1393            Value::Identifier(i) => serde_json::Value::String(i.clone()),
1394        }
1395    }
1396
1397    /* ---------- file parsing with recovery ---------- */
1398    pub fn parse<'a>(&'a mut self, content: &'a str) -> BoxFuture<'a, Result<HashMap<String, Value>>> {
1399        Box::pin(async move {
1400            self.current_line = 0;
1401            self.errors.clear();
1402            
1403            for line in content.lines() {
1404                self.current_line += 1;
1405                if let Err(e) = self.parse_line(line).await {
1406                    self.errors.push(e);
1407                    // Continue parsing other lines
1408                }
1409            }
1410            
1411            // Return accumulated errors if any
1412            if !self.errors.is_empty() && self.data.is_empty() {
1413                // Instead of cloning the entire vector, use the first error
1414                if let Some(first_error) = self.errors.first() {
1415                    return Err(first_error.clone());
1416                } else {
1417                    return Err(ParseError::SyntaxError {
1418                        line: 0,
1419                        column: 0,
1420                        message: "Unknown parse error".to_string(),
1421                    });
1422                }
1423            }
1424            
1425            Ok(self.data.clone())
1426        })
1427    }
1428
1429    // Fix the recursion in async fn by using BoxFuture pattern
1430    pub fn parse_file<'a>(&'a mut self, path: &'a str) -> BoxFuture<'a, Result<()>> {
1431        Box::pin(async move {
1432            let txt = fs::read_to_string(path)?;
1433            self.parse(&txt).await?;
1434            Ok(())
1435        })
1436    }
1437
1438    /* ---------- accessors with better performance (Improvement #4) ---------- */
1439    pub fn get(&self, key: &str) -> Option<Value> {
1440        self.data.get(key).cloned()
1441    }
1442    
1443    pub fn get_ref(&self, key: &str) -> Option<&Value> {
1444        self.data.get(key)
1445    }
1446    
1447    pub fn set(&mut self, key: &str, value: Value) {
1448        self.data.insert(key.to_string(), value);
1449    }
1450    
1451    pub fn keys(&self) -> Vec<String> {
1452        self.data.keys().cloned().collect()
1453    }
1454    
1455    pub fn items(&self) -> &HashMap<String, Value> {
1456        &self.data
1457    }
1458    
1459    pub fn items_cloned(&self) -> HashMap<String, Value> {
1460        self.data.clone()
1461    }
1462    
1463    pub fn get_errors(&self) -> &[ParseError] {
1464        &self.errors
1465    }
1466    
1467    pub fn has_errors(&self) -> bool {
1468        !self.errors.is_empty()
1469    }
1470}
1471
1472/* ---------- convenience helpers ---------- */
1473/// Load configuration from the default helix locations
1474/// 
1475/// # Example
1476/// ```
1477/// let parser = load_from_hlx().await?;
1478/// let value = parser.get("some.config.key");
1479/// ```
1480pub async fn load_from_hlx() -> Result<OperatorParser> {
1481    let mut parser = OperatorParser::new().await?;
1482    parser.load_hlx().await?;
1483    Ok(parser)
1484}
1485
1486/// Parse HLX content from a string
1487/// 
1488/// # Example
1489/// ```
1490/// let content = "[section]\nkey = value";
1491/// let data = parse_hlx_content(content).await?;
1492/// ```
1493pub async fn parse_hlx_content(content: &str) -> Result<HashMap<String, Value>> {
1494    let mut parser = OperatorParser::new().await?;
1495    parser.parse(content).await
1496}
1497
1498/// Evaluate a mathematical expression
1499/// 
1500/// # Example
1501/// ```
1502/// let result = eval_math_expression("2 + 3 * 4")?;
1503/// assert_eq!(result, Value::Number(14.0));
1504/// ```
1505pub fn eval_math_expression(expr: &str) -> Result<Value> {
1506    let mut p = MathParser::new(expr);
1507    p.parse().map(Value::Number)
1508}
1509
1510/* ---------- Tests (Improvement #7) ---------- */
1511#[cfg(test)]
1512mod tests {
1513    use super::*;
1514
1515    #[test]
1516    fn test_math_parser_basic() {
1517        assert_eq!(eval_math_expression("2 + 3").unwrap(), Value::Number(5.0));
1518        assert_eq!(eval_math_expression("2 * 3").unwrap(), Value::Number(6.0));
1519        assert_eq!(eval_math_expression("10 / 2").unwrap(), Value::Number(5.0));
1520        assert_eq!(eval_math_expression("10 % 3").unwrap(), Value::Number(1.0));
1521    }
1522
1523    #[test]
1524    fn test_math_parser_precedence() {
1525        assert_eq!(eval_math_expression("2 + 3 * 4").unwrap(), Value::Number(14.0));
1526        assert_eq!(eval_math_expression("(2 + 3) * 4").unwrap(), Value::Number(20.0));
1527    }
1528
1529    #[test]
1530    fn test_math_parser_power() {
1531        assert_eq!(eval_math_expression("2 ^ 3").unwrap(), Value::Number(8.0));
1532        assert_eq!(eval_math_expression("2 ^ 3 ^ 2").unwrap(), Value::Number(512.0));
1533    }
1534
1535    #[test]
1536    fn test_math_parser_negative() {
1537        assert_eq!(eval_math_expression("-5").unwrap(), Value::Number(-5.0));
1538        assert_eq!(eval_math_expression("(-5)").unwrap(), Value::Number(-5.0));
1539        assert_eq!(eval_math_expression("-5 + 3").unwrap(), Value::Number(-2.0));
1540    }
1541
1542    #[test]
1543    fn test_math_parser_scientific() {
1544        assert_eq!(eval_math_expression("1.5e2").unwrap(), Value::Number(150.0));
1545        assert_eq!(eval_math_expression("1.5E-2").unwrap(), Value::Number(0.015));
1546    }
1547
1548    #[test]
1549    fn test_string_parser_escapes() {
1550        let mut parser = StringParser::new(r#""Hello \"World\"""#);
1551        assert_eq!(parser.parse_quoted_string().unwrap(), r#"Hello "World""#);
1552        
1553        let mut parser = StringParser::new(r#""Line1\nLine2""#);
1554        assert_eq!(parser.parse_quoted_string().unwrap(), "Line1\nLine2");
1555        
1556        let mut parser = StringParser::new(r#""Unicode: \u0041""#);
1557        assert_eq!(parser.parse_quoted_string().unwrap(), "Unicode: A");
1558    }
1559
1560    #[tokio::test]
1561    async fn test_parser_basic() {
1562        let mut parser = OperatorParser::new().await.unwrap();
1563        parser.parse_line("key = value").await.unwrap();
1564        assert_eq!(parser.get("key"), Some(Value::String("value".into())));
1565    }
1566
1567    #[tokio::test]
1568    async fn test_parser_sections() {
1569        let mut parser = OperatorParser::new().await.unwrap();
1570        parser.parse_line("[section]").await.unwrap();
1571        parser.parse_line("key = value").await.unwrap();
1572        assert_eq!(parser.get("section.key"), Some(Value::String("value".into())));
1573    }
1574
1575    #[tokio::test]
1576    async fn test_parser_global_vars() {
1577        let mut parser = OperatorParser::new().await.unwrap();
1578        parser.parse_line("$global = 123").await.unwrap();
1579        assert_eq!(
1580            parser.global_variables.get(&VariableName::new("global")),
1581            Some(&Value::Number(123.0))
1582        );
1583    }
1584
1585    #[tokio::test]
1586    async fn test_parser_arrays() {
1587        let mut parser = OperatorParser::new().await.unwrap();
1588        let val = parser.parse_value("[1, 2, 3]").await.unwrap();
1589        match val {
1590            Value::Array(arr) => {
1591                assert_eq!(arr.len(), 3);
1592                assert_eq!(arr[0], Value::Number(1.0));
1593            }
1594            _ => panic!("Expected array"),
1595        }
1596    }
1597
1598    #[tokio::test]
1599    async fn test_parser_objects() {
1600        let mut parser = OperatorParser::new().await.unwrap();
1601        let val = parser.parse_value(r#"{"key": "value", "num": 42}"#).await.unwrap();
1602        match val {
1603            Value::Object(map) => {
1604                assert_eq!(map.get("key"), Some(&Value::String("value".into())));
1605                assert_eq!(map.get("num"), Some(&Value::Number(42.0)));
1606            }
1607            _ => panic!("Expected object"),
1608        }
1609    }
1610
1611    #[tokio::test]
1612    async fn test_parser_comments() {
1613        let mut parser = OperatorParser::new().await.unwrap();
1614        parser.parse_line("key = value // this is a comment").await.unwrap();
1615        assert_eq!(parser.get("key"), Some(Value::String("value".into())));
1616    }
1617
1618    #[tokio::test]
1619    async fn test_error_recovery() {
1620        let mut parser = OperatorParser::new().await.unwrap();
1621        let content = r#"
1622            good_key = value
1623            bad_key = @unknown_operator()
1624            another_good = 123
1625        "#;
1626        
1627        let result = parser.parse(content).await;
1628        assert!(result.is_ok());
1629        assert_eq!(parser.get("good_key"), Some(Value::String("value".into())));
1630        assert_eq!(parser.get("another_good"), Some(Value::Number(123.0)));
1631        assert!(!parser.errors.is_empty());
1632    }
1633}