helix_core/
parser.rs

1use super::lexer::{
2    Token, Keyword, TimeUnit, TokenWithLocation, SourceLocation, SourceMap,
3};
4use super::ast::*;
5use crate::types::Duration;
6use std::collections::HashMap;
7pub struct Parser {
8    tokens: Vec<TokenWithLocation>,
9    source_map: Option<SourceMap>,
10    current: usize,
11    errors: Vec<ParseError>,
12    recovery_points: Vec<usize>,
13}
14#[derive(Debug, Clone)]
15pub struct ParseError {
16    pub message: String,
17    pub location: Option<SourceLocation>,
18    pub token_index: usize,
19    pub expected: Option<String>,
20    pub found: String,
21    pub context: String,
22}
23impl std::fmt::Display for ParseError {
24    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25        write!(f, "{}", self.message)?;
26        if let Some(expected) = &self.expected {
27            write!(f, " (expected: {}, found: {})", expected, self.found)?;
28        }
29        if !self.context.is_empty() {
30            write!(f, " in {}", self.context)?;
31        }
32        Ok(())
33    }
34}
35impl std::error::Error for ParseError {}
36impl ParseError {
37    pub fn format_with_source(&self, source: &str, tokens: &[Token]) -> String {
38        let mut line = 1;
39        let mut col = 1;
40        for (i, ch) in source.chars().enumerate() {
41            if i >= self.token_index {
42                break;
43            }
44            if ch == '\n' {
45                line += 1;
46                col = 1;
47            } else {
48                col += 1;
49            }
50        }
51        let lines: Vec<&str> = source.lines().collect();
52        let error_line = if line > 0 && line <= lines.len() {
53            lines[line - 1]
54        } else {
55            ""
56        };
57        let mut result = format!("Error at line {}, column {}:\n", line, col);
58        result.push_str(&format!("    {}\n", error_line));
59        result.push_str(&format!("    {}^\n", " ".repeat(col - 1)));
60        let token_info = if self.token_index < tokens.len() {
61            format!("{:?}", tokens[self.token_index])
62        } else {
63            "<EOF>".to_string()
64        };
65        if let Some(expected) = &self.expected {
66            result
67                .push_str(
68                    &format!("Expected {}, found token {}\n", expected, token_info),
69                );
70        } else {
71            result.push_str(&format!("{}\n", self.message));
72        }
73        if !self.context.is_empty() {
74            result.push_str(&format!("Context: {}\n", self.context));
75        }
76        result
77    }
78}
79#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
80#[allow(dead_code)]
81enum Precedence {
82    Lowest = 0,
83    Pipeline = 1,
84    Logical = 2,
85    Equality = 3,
86    Comparison = 4,
87    Addition = 5,
88    Multiplication = 6,
89    Unary = 7,
90    Call = 8,
91    Index = 9,
92    Highest = 10,
93}
94impl Parser {
95    pub fn new(tokens: Vec<Token>) -> Self {
96        let tokens_with_location = tokens
97            .into_iter()
98            .enumerate()
99            .map(|(i, token)| {
100                TokenWithLocation {
101                    token,
102                    location: SourceLocation {
103                        line: 1,
104                        column: i + 1,
105                        position: i,
106                    },
107                }
108            })
109            .collect();
110        Parser {
111            tokens: tokens_with_location,
112            source_map: None,
113            current: 0,
114            errors: Vec::new(),
115            recovery_points: Vec::new(),
116        }
117    }
118    pub fn new_enhanced(tokens: Vec<TokenWithLocation>) -> Self {
119        Parser {
120            tokens,
121            source_map: None,
122            current: 0,
123            errors: Vec::new(),
124            recovery_points: Vec::new(),
125        }
126    }
127    pub fn new_with_source_map(source_map: SourceMap) -> Self {
128        let tokens = source_map.tokens.clone();
129        Parser {
130            tokens,
131            source_map: Some(source_map),
132            current: 0,
133            errors: Vec::new(),
134            recovery_points: Vec::new(),
135        }
136    }
137    fn add_error(&mut self, message: String, expected: Option<String>) {
138        let error = ParseError {
139            message,
140            location: self.current_location(),
141            token_index: self.current,
142            expected,
143            found: format!("{:?}", self.current_token()),
144            context: self.get_enhanced_context(),
145        };
146        self.errors.push(error);
147    }
148    fn get_context(&self) -> String {
149        if self.recovery_points.is_empty() {
150            "top-level".to_string()
151        } else {
152            match self.recovery_points.last() {
153                Some(_) => "inside declaration".to_string(),
154                None => "unknown".to_string(),
155            }
156        }
157    }
158    fn get_enhanced_context(&self) -> String {
159        let basic_context = self.get_context();
160        if let (Some(source_map), Some(location)) = (
161            &self.source_map,
162            &self.current_location(),
163        ) {
164            let source_context = source_map.get_context(location, 2);
165            format!("{} - Source context:\n{}", basic_context, source_context)
166        } else {
167            basic_context
168        }
169    }
170    fn recover_to_next_declaration(&mut self) {
171        while self.current_token() != &Token::Eof {
172            match self.current_token() {
173                Token::Keyword(k) => {
174                    match k {
175                        Keyword::Agent
176                        | Keyword::Workflow
177                        | Keyword::Memory
178                        | Keyword::Context
179                        | Keyword::Crew
180                        | Keyword::Project
181                        | Keyword::Pipeline
182                        | Keyword::Load => {
183                            break;
184                        }
185                        _ => {}
186                    }
187                }
188                _ => {}
189            }
190            self.advance();
191        }
192    }
193    #[allow(dead_code)]
194    fn recover_to_closing_brace(&mut self) {
195        let mut brace_depth = 1;
196        while self.current_token() != &Token::Eof && brace_depth > 0 {
197            match self.current_token() {
198                Token::LeftBrace => brace_depth += 1,
199                Token::RightBrace => brace_depth -= 1,
200                _ => {}
201            }
202            if brace_depth > 0 {
203                self.advance();
204            }
205        }
206    }
207    fn current_token(&self) -> &Token {
208        self.tokens
209            .get(self.current)
210            .map(|token_with_loc| &token_with_loc.token)
211            .unwrap_or(&Token::Eof)
212    }
213    fn current_location(&self) -> Option<SourceLocation> {
214        self.tokens
215            .get(self.current)
216            .map(|token_with_loc| token_with_loc.location.clone())
217    }
218    fn peek_token(&self) -> &Token {
219        self.tokens
220            .get(self.current + 1)
221            .map(|token_with_loc| &token_with_loc.token)
222            .unwrap_or(&Token::Eof)
223    }
224    fn parse_enhanced_expression(&mut self) -> Result<Expression, String> {
225        let next_token = self.peek_token().clone();
226        match (self.current_token().clone(), &next_token) {
227            (Token::Identifier(name), Token::Assign) => {
228                self.advance();
229                Ok(Expression::Identifier(name))
230            }
231            (Token::LeftParen, _) => {
232                self.advance();
233                let expr = self.parse_enhanced_expression()?;
234                self.expect(Token::RightParen)?;
235                Ok(expr)
236            }
237            (Token::LeftBracket, _) => {
238                self.advance();
239                let mut elements = Vec::new();
240                while self.current_token() != &Token::RightBracket
241                    && self.current_token() != &Token::Eof
242                {
243                    self.skip_newlines();
244                    if self.current_token() == &Token::RightBracket {
245                        break;
246                    }
247                    elements.push(self.parse_enhanced_expression()?);
248                    self.skip_newlines();
249                    if self.current_token() == &Token::Comma {
250                        self.advance();
251                    }
252                }
253                self.expect(Token::RightBracket)?;
254                Ok(Expression::Array(elements))
255            }
256            _ => self.parse_primary_expression(),
257        }
258    }
259    fn advance(&mut self) -> Token {
260        let token = self.current_token().clone();
261        if self.current < self.tokens.len() {
262            self.current += 1;
263        }
264        token
265    }
266    fn expect(&mut self, expected: Token) -> Result<(), String> {
267        let token = self.current_token().clone();
268        if token == expected {
269            self.advance();
270            Ok(())
271        } else {
272            Err(format!("Expected {:?}, found {:?}", expected, token))
273        }
274    }
275    fn expect_identifier(&mut self) -> Result<String, String> {
276        match self.current_token() {
277            Token::Identifier(name) => {
278                let name = name.clone();
279                self.advance();
280                Ok(name)
281            }
282            Token::String(name) => {
283                let name = name.clone();
284                self.advance();
285                Ok(name)
286            }
287            _ => Err(format!("Expected identifier, found {:?}", self.current_token())),
288        }
289    }
290    fn skip_newlines(&mut self) {
291        while self.current_token() == &Token::Newline {
292            self.advance();
293        }
294    }
295    pub fn parse(&mut self) -> Result<HelixAst, String> {
296        let mut ast = HelixAst::new();
297        while self.current_token() != &Token::Eof {
298            self.skip_newlines();
299            if let Token::Keyword(keyword) = self.current_token().clone() {
300                self.recovery_points.push(self.current);
301                match self.parse_declaration(keyword.clone()) {
302                    Ok(decl) => {
303                        ast.add_declaration(decl);
304                        self.recovery_points.pop();
305                    }
306                    Err(err) => {
307                        self.add_error(
308                            err.clone(),
309                            Some(format!("valid {:?} declaration", keyword)),
310                        );
311                        self.recover_to_next_declaration();
312                        self.recovery_points.pop();
313                    }
314                }
315            } else {
316                match self.current_token() {
317                    Token::Eof => break,
318                    _ => {
319                        self.add_error(
320                            format!("Unexpected token: {:?}", self.current_token()),
321                            Some("declaration keyword".to_string()),
322                        );
323                        self.recover_to_next_declaration();
324                    }
325                }
326            }
327            self.skip_newlines();
328        }
329        if !self.errors.is_empty() {
330            let error_summary = self
331                .errors
332                .iter()
333                .map(|e| format!("{} at token {}", e.message, e.token_index))
334                .collect::<Vec<_>>()
335                .join("; ");
336            Err(format!("Parse errors: {}", error_summary))
337        } else {
338            Ok(ast)
339        }
340    }
341    fn parse_declaration(&mut self, keyword: Keyword) -> Result<Declaration, String> {
342        match keyword {
343            Keyword::Project => {
344                self.advance();
345                let name = self.expect_identifier()?;
346                self.expect(Token::LeftBrace)?;
347                let properties = self.parse_properties()?;
348                self.expect(Token::RightBrace)?;
349                Ok(Declaration::Project(ProjectDecl { name, properties }))
350            }
351            Keyword::Agent => {
352                self.advance();
353                let name = self.expect_identifier()?;
354                self.expect(Token::LeftBrace)?;
355                let mut properties = HashMap::new();
356                let mut capabilities = None;
357                let mut backstory = None;
358                let tools = None;
359                while self.current_token() != &Token::RightBrace {
360                    self.skip_newlines();
361                    match self.current_token() {
362                        Token::Keyword(Keyword::Capabilities) => {
363                            self.advance();
364                            capabilities = Some(self.parse_string_array()?);
365                        }
366                        Token::Keyword(Keyword::Backstory) => {
367                            self.advance();
368                            backstory = Some(self.parse_backstory_block()?);
369                        }
370                        Token::Identifier(key) => {
371                            let key = key.clone();
372                            self.advance();
373                            self.expect(Token::Assign)?;
374                            let value = self.parse_expression()?;
375                            properties.insert(key, value);
376                        }
377                        Token::Keyword(keyword) => {
378                            match keyword {
379                                Keyword::Capabilities | Keyword::Backstory => {
380                                    return Err(
381                                        format!(
382                                            "Unexpected token in agent: {:?}", self.current_token()
383                                        ),
384                                    );
385                                }
386                                _ => {
387                                    let key = format!("{:?}", keyword).to_lowercase();
388                                    self.advance();
389                                    self.expect(Token::Assign)?;
390                                    let value = self.parse_expression()?;
391                                    properties.insert(key, value);
392                                }
393                            }
394                        }
395                        Token::RightBrace => break,
396                        _ => {
397                            return Err(
398                                format!(
399                                    "Unexpected token in agent: {:?}", self.current_token()
400                                ),
401                            );
402                        }
403                    }
404                    self.skip_newlines();
405                }
406                self.expect(Token::RightBrace)?;
407                Ok(
408                    Declaration::Agent(AgentDecl {
409                        name,
410                        properties,
411                        capabilities,
412                        backstory,
413                        tools,
414                    }),
415                )
416            }
417            Keyword::Workflow => {
418                self.advance();
419                let name = self.expect_identifier()?;
420                self.expect(Token::LeftBrace)?;
421                let mut trigger = None;
422                let mut steps = Vec::new();
423                let mut pipeline = None;
424                let mut properties = HashMap::new();
425                while self.current_token() != &Token::RightBrace {
426                    self.skip_newlines();
427                    match self.current_token() {
428                        Token::Keyword(Keyword::Trigger) => {
429                            self.advance();
430                            self.expect(Token::Assign)?;
431                            trigger = Some(self.parse_trigger_config()?);
432                        }
433                        Token::Keyword(Keyword::Step) => {
434                            steps.push(self.parse_step()?);
435                        }
436                        Token::Keyword(Keyword::Pipeline) => {
437                            self.advance();
438                            pipeline = Some(self.parse_pipeline_block()?);
439                        }
440                        Token::Keyword(Keyword::Timeout) => {
441                            self.advance();
442                            self.expect(Token::Assign)?;
443                            let timeout_value = self.parse_expression()?;
444                            properties.insert("timeout".to_string(), timeout_value);
445                        }
446                        Token::Identifier(key) => {
447                            let key = key.clone();
448                            self.advance();
449                            self.expect(Token::Assign)?;
450                            let value = self.parse_expression()?;
451                            properties.insert(key, value);
452                        }
453                        Token::RightBrace => break,
454                        _ => {
455                            return Err(
456                                format!(
457                                    "Unexpected token in workflow: {:?}", self.current_token()
458                                ),
459                            );
460                        }
461                    }
462                    self.skip_newlines();
463                }
464                self.expect(Token::RightBrace)?;
465                Ok(
466                    Declaration::Workflow(WorkflowDecl {
467                        name,
468                        trigger,
469                        steps,
470                        pipeline,
471                        properties,
472                    }),
473                )
474            }
475            Keyword::Memory => {
476                self.advance();
477                self.expect(Token::LeftBrace)?;
478                let mut provider = String::new();
479                let mut connection = String::new();
480                let mut embeddings = None;
481                let mut properties = HashMap::new();
482                while self.current_token() != &Token::RightBrace {
483                    self.skip_newlines();
484                    match self.current_token() {
485                        Token::Keyword(Keyword::Embeddings) => {
486                            self.advance();
487                            embeddings = Some(self.parse_embeddings_block()?);
488                        }
489                        Token::Identifier(key) => {
490                            let key = key.clone();
491                            self.advance();
492                            self.expect(Token::Assign)?;
493                            let value = self.parse_expression()?;
494                            match key.as_str() {
495                                "provider" => {
496                                    provider = value.as_string().unwrap_or_default();
497                                }
498                                "connection" => {
499                                    connection = value.as_string().unwrap_or_default();
500                                }
501                                _ => {
502                                    properties.insert(key, value);
503                                }
504                            }
505                        }
506                        Token::RightBrace => break,
507                        _ => {
508                            return Err(
509                                format!(
510                                    "Unexpected token in memory: {:?}", self.current_token()
511                                ),
512                            );
513                        }
514                    }
515                    self.skip_newlines();
516                }
517                self.expect(Token::RightBrace)?;
518                Ok(
519                    Declaration::Memory(MemoryDecl {
520                        provider,
521                        connection,
522                        embeddings,
523                        properties,
524                    }),
525                )
526            }
527            Keyword::Context => {
528                self.advance();
529                let name = self.expect_identifier()?;
530                self.expect(Token::LeftBrace)?;
531                let mut environment = String::new();
532                let mut secrets = None;
533                let mut variables = None;
534                let mut properties = HashMap::new();
535                while self.current_token() != &Token::RightBrace {
536                    self.skip_newlines();
537                    match self.current_token() {
538                        Token::Keyword(Keyword::Secrets) => {
539                            self.advance();
540                            secrets = Some(self.parse_secrets_block()?);
541                        }
542                        Token::Keyword(Keyword::Variables) => {
543                            self.advance();
544                            variables = Some(self.parse_variables_block()?);
545                        }
546                        Token::Identifier(key) => {
547                            let key = key.clone();
548                            self.advance();
549                            self.expect(Token::Assign)?;
550                            let value = self.parse_expression()?;
551                            if key == "environment" {
552                                environment = value.as_string().unwrap_or_default();
553                            } else {
554                                properties.insert(key, value);
555                            }
556                        }
557                        Token::RightBrace => break,
558                        _ => {
559                            return Err(
560                                format!(
561                                    "Unexpected token in context: {:?}", self.current_token()
562                                ),
563                            );
564                        }
565                    }
566                    self.skip_newlines();
567                }
568                self.expect(Token::RightBrace)?;
569                Ok(
570                    Declaration::Context(ContextDecl {
571                        name,
572                        environment,
573                        secrets,
574                        variables,
575                        properties,
576                    }),
577                )
578            }
579            Keyword::Crew => {
580                self.advance();
581                let name = self.expect_identifier()?;
582                self.expect(Token::LeftBrace)?;
583                let mut agents = Vec::new();
584                let mut process_type = None;
585                let mut properties = HashMap::new();
586                while self.current_token() != &Token::RightBrace {
587                    self.skip_newlines();
588                    match self.current_token() {
589                        Token::Identifier(key) => {
590                            let key = key.clone();
591                            self.advance();
592                            if key == "agents" {
593                                agents = self.parse_string_array()?;
594                            } else {
595                                self.expect(Token::Assign)?;
596                                let value = self.parse_expression()?;
597                                if key == "process" {
598                                    process_type = value.as_string();
599                                } else {
600                                    properties.insert(key, value);
601                                }
602                            }
603                        }
604                        Token::RightBrace => break,
605                        _ => {
606                            return Err(
607                                format!(
608                                    "Unexpected token in crew: {:?}", self.current_token()
609                                ),
610                            );
611                        }
612                    }
613                    self.skip_newlines();
614                }
615                self.expect(Token::RightBrace)?;
616                Ok(
617                    Declaration::Crew(CrewDecl {
618                        name,
619                        agents,
620                        process_type,
621                        properties,
622                    }),
623                )
624            }
625            Keyword::Pipeline => {
626                self.advance();
627                self.expect(Token::LeftBrace)?;
628                let pipeline = self.parse_pipeline_block()?;
629                self.expect(Token::RightBrace)?;
630                Ok(Declaration::Pipeline(pipeline))
631            }
632            Keyword::Load => {
633                self.advance();
634                let file_name = self.expect_identifier()?;
635                self.expect(Token::LeftBrace)?;
636                let properties = self.parse_properties()?;
637                self.expect(Token::RightBrace)?;
638                Ok(Declaration::Load(LoadDecl { file_name, properties }))
639            }
640            _ => Err(format!("Unexpected keyword: {:?}", keyword)),
641        }
642    }
643    fn parse_step(&mut self) -> Result<StepDecl, String> {
644        self.advance();
645        let name = self.expect_identifier()?;
646        self.expect(Token::LeftBrace)?;
647        let mut agent = None;
648        let mut crew = None;
649        let mut task = None;
650        let mut properties = HashMap::new();
651        while self.current_token() != &Token::RightBrace {
652            self.skip_newlines();
653            match self.current_token() {
654                Token::Keyword(Keyword::Timeout) => {
655                    self.advance();
656                    self.expect(Token::Assign)?;
657                    let timeout_value = self.parse_expression()?;
658                    properties.insert("timeout".to_string(), timeout_value);
659                }
660                Token::Identifier(key) => {
661                    let key = key.clone();
662                    self.advance();
663                    match key.as_str() {
664                        "agent" => {
665                            self.expect(Token::Assign)?;
666                            agent = self.parse_expression()?.as_string();
667                        }
668                        "crew" => {
669                            self.expect(Token::Assign)?;
670                            if self.current_token() == &Token::LeftBracket {
671                                crew = Some(self.parse_string_array()?);
672                            }
673                        }
674                        "task" => {
675                            self.expect(Token::Assign)?;
676                            task = self.parse_expression()?.as_string();
677                        }
678                        "retry" => {
679                            let retry_config = self.parse_retry_block()?;
680                            properties
681                                .insert(
682                                    "retry".to_string(),
683                                    Expression::Object(retry_config),
684                                );
685                        }
686                        _ => {
687                            self.expect(Token::Assign)?;
688                            let value = self.parse_expression()?;
689                            properties.insert(key, value);
690                        }
691                    }
692                }
693                Token::Keyword(keyword) => {
694                    let key = format!("{:?}", keyword).to_lowercase();
695                    self.advance();
696                    self.expect(Token::Assign)?;
697                    match key.as_str() {
698                        "agent" => {
699                            agent = self.parse_expression()?.as_string();
700                        }
701                        _ => {
702                            let value = self.parse_expression()?;
703                            properties.insert(key, value);
704                        }
705                    }
706                }
707                Token::RightBrace => break,
708                _ => {
709                    return Err(
710                        format!("Unexpected token in step: {:?}", self.current_token()),
711                    );
712                }
713            }
714            self.skip_newlines();
715        }
716        self.expect(Token::RightBrace)?;
717        Ok(StepDecl {
718            name,
719            agent,
720            crew,
721            task,
722            properties,
723        })
724    }
725    fn parse_retry_block(&mut self) -> Result<HashMap<String, Expression>, String> {
726        self.expect(Token::LeftBrace)?;
727        let mut retry_config = HashMap::new();
728        while self.current_token() != &Token::RightBrace {
729            self.skip_newlines();
730            if self.current_token() == &Token::RightBrace {
731                break;
732            }
733            let key = self.expect_identifier()?;
734            if self.peek_token() != &Token::Assign
735                && self.current_token() != &Token::Assign
736            {
737                return Err(
738                    format!(
739                        "Expected '=' after property key '{}', found {:?}", key, self
740                        .current_token()
741                    ),
742                );
743            }
744            self.expect(Token::Assign)?;
745            let value = self.parse_expression()?;
746            retry_config.insert(key, value);
747            self.skip_newlines();
748        }
749        self.expect(Token::RightBrace)?;
750        Ok(retry_config)
751    }
752    fn parse_trigger_config(&mut self) -> Result<Expression, String> {
753        if self.current_token() == &Token::LeftBrace {
754            self.advance();
755            let trigger_obj = self.parse_object()?;
756            Ok(Expression::Object(trigger_obj))
757        } else {
758            self.parse_expression()
759        }
760    }
761    fn parse_expression(&mut self) -> Result<Expression, String> {
762        match self.current_token() {
763            Token::LeftParen | Token::LeftBracket => self.parse_enhanced_expression(),
764            _ => self.parse_expression_with_precedence(Precedence::Lowest),
765        }
766    }
767    fn parse_expression_with_precedence(
768        &mut self,
769        min_precedence: Precedence,
770    ) -> Result<Expression, String> {
771        let mut left = self.parse_primary_expression()?;
772        while !self.is_at_end() {
773            let precedence = self.get_token_precedence(self.current_token());
774            if precedence < min_precedence {
775                break;
776            }
777            match self.current_token() {
778                Token::Arrow => {
779                    self.advance();
780                    let mut pipeline = vec![];
781                    if let Expression::Identifier(id) = left {
782                        pipeline.push(id);
783                    } else if let Expression::Pipeline(mut p) = left {
784                        pipeline.append(&mut p);
785                    } else {
786                        return Err(format!("Invalid left side of pipeline: {:?}", left));
787                    }
788                    let right = self
789                        .parse_expression_with_precedence(Precedence::Pipeline)?;
790                    if let Expression::Identifier(id) = right {
791                        pipeline.push(id);
792                    } else if let Expression::Pipeline(mut p) = right {
793                        pipeline.append(&mut p);
794                    } else {
795                        return Err(
796                            format!("Invalid right side of pipeline: {:?}", right),
797                        );
798                    }
799                    left = Expression::Pipeline(pipeline);
800                }
801                _ => {
802                    break;
803                }
804            }
805        }
806        Ok(left)
807    }
808    fn parse_primary_expression(&mut self) -> Result<Expression, String> {
809        match self.current_token() {
810            Token::String(s) => {
811                let s = s.clone();
812                self.advance();
813                Ok(Expression::String(s))
814            }
815            Token::Number(n) => {
816                let n = *n;
817                self.advance();
818                Ok(Expression::Number(n))
819            }
820            Token::Bool(b) => {
821                let b = *b;
822                self.advance();
823                Ok(Expression::Bool(b))
824            }
825            Token::Duration(value, unit) => {
826                let duration = Duration {
827                    value: *value,
828                    unit: match unit {
829                        TimeUnit::Seconds => crate::types::TimeUnit::Seconds,
830                        TimeUnit::Minutes => crate::types::TimeUnit::Minutes,
831                        TimeUnit::Hours => crate::types::TimeUnit::Hours,
832                        TimeUnit::Days => crate::types::TimeUnit::Days,
833                    },
834                };
835                self.advance();
836                Ok(Expression::Duration(duration))
837            }
838            Token::Variable(v) => {
839                let v = v.clone();
840                self.advance();
841                Ok(Expression::Variable(v))
842            }
843            Token::Reference(r) => {
844                let r = r.clone();
845                self.advance();
846                if self.current_token() == &Token::LeftBracket {
847                    self.advance();
848                    let key = self.expect_identifier()?;
849                    self.expect(Token::RightBracket)?;
850                    Ok(Expression::IndexedReference(r, key))
851                } else {
852                    Ok(Expression::Reference(r))
853                }
854            }
855            Token::Identifier(i) => {
856                let i = i.clone();
857                self.advance();
858                Ok(Expression::Identifier(i))
859            }
860            Token::LeftBracket => {
861                self.advance();
862                let array = self.parse_array()?;
863                Ok(Expression::Array(array))
864            }
865            Token::LeftBrace => {
866                self.advance();
867                let object = self.parse_object()?;
868                Ok(Expression::Object(object))
869            }
870            Token::LeftParen => {
871                self.advance();
872                let expr = self.parse_expression()?;
873                self.expect(Token::RightParen)?;
874                Ok(expr)
875            }
876            _ => {
877                Err(
878                    format!("Unexpected token in expression: {:?}", self.current_token()),
879                )
880            }
881        }
882    }
883    fn get_token_precedence(&self, token: &Token) -> Precedence {
884        match token {
885            Token::Arrow => Precedence::Pipeline,
886            _ => Precedence::Lowest,
887        }
888    }
889    fn is_at_end(&self) -> bool {
890        self.current_token() == &Token::Eof
891    }
892    fn parse_array(&mut self) -> Result<Vec<Expression>, String> {
893        let mut elements = Vec::new();
894        while self.current_token() != &Token::RightBracket {
895            self.skip_newlines();
896            if self.current_token() == &Token::RightBracket {
897                break;
898            }
899            elements.push(self.parse_expression()?);
900            if self.current_token() == &Token::Comma {
901                self.advance();
902            }
903            self.skip_newlines();
904        }
905        self.expect(Token::RightBracket)?;
906        Ok(elements)
907    }
908    fn parse_object(&mut self) -> Result<HashMap<String, Expression>, String> {
909        let mut object = HashMap::new();
910        while self.current_token() != &Token::RightBrace {
911            self.skip_newlines();
912            if self.current_token() == &Token::RightBrace {
913                break;
914            }
915            let key = self.expect_identifier()?;
916            if self.peek_token() != &Token::Assign
917                && self.current_token() != &Token::Assign
918            {
919                return Err(
920                    format!(
921                        "Expected '=' after property key '{}', found {:?}", key, self
922                        .current_token()
923                    ),
924                );
925            }
926            self.expect(Token::Assign)?;
927            let value = self.parse_expression()?;
928            object.insert(key, value);
929            if self.current_token() == &Token::Comma {
930                self.advance();
931            }
932            self.skip_newlines();
933        }
934        self.expect(Token::RightBrace)?;
935        Ok(object)
936    }
937    fn parse_string_array(&mut self) -> Result<Vec<String>, String> {
938        self.expect(Token::LeftBracket)?;
939        let mut items = Vec::new();
940        while self.current_token() != &Token::RightBracket {
941            self.skip_newlines();
942            if self.current_token() == &Token::RightBracket {
943                break;
944            }
945            items.push(self.expect_identifier()?);
946            if self.current_token() == &Token::Comma {
947                self.advance();
948            }
949            self.skip_newlines();
950        }
951        self.expect(Token::RightBracket)?;
952        Ok(items)
953    }
954    fn parse_properties(&mut self) -> Result<HashMap<String, Expression>, String> {
955        let mut properties = HashMap::new();
956        while self.current_token() != &Token::RightBrace {
957            self.skip_newlines();
958            if self.current_token() == &Token::RightBrace {
959                break;
960            }
961            let key = self.expect_identifier()?;
962            if self.peek_token() != &Token::Assign
963                && self.current_token() != &Token::Assign
964            {
965                return Err(
966                    format!(
967                        "Expected '=' after property key '{}', found {:?}", key, self
968                        .current_token()
969                    ),
970                );
971            }
972            self.expect(Token::Assign)?;
973            let value = self.parse_expression()?;
974            properties.insert(key, value);
975            self.skip_newlines();
976        }
977        Ok(properties)
978    }
979    fn parse_backstory_block(&mut self) -> Result<BackstoryBlock, String> {
980        self.expect(Token::LeftBrace)?;
981        let mut lines = Vec::new();
982        while self.current_token() != &Token::RightBrace {
983            self.skip_newlines();
984            match self.current_token() {
985                Token::Identifier(text) | Token::String(text) => {
986                    lines.push(text.clone());
987                    self.advance();
988                }
989                Token::RightBrace => break,
990                _ => {
991                    self.advance();
992                }
993            }
994        }
995        self.expect(Token::RightBrace)?;
996        Ok(BackstoryBlock { lines })
997    }
998    fn parse_pipeline_block(&mut self) -> Result<PipelineDecl, String> {
999        self.expect(Token::LeftBrace)?;
1000        let mut flow = Vec::new();
1001        while self.current_token() != &Token::RightBrace {
1002            self.skip_newlines();
1003            if let Token::Identifier(step) = self.current_token() {
1004                flow.push(PipelineNode::Step(step.clone()));
1005                self.advance();
1006                if self.current_token() == &Token::Arrow {
1007                    self.advance();
1008                }
1009            } else if self.current_token() == &Token::RightBrace {
1010                break;
1011            } else {
1012                self.advance();
1013            }
1014            self.skip_newlines();
1015        }
1016        self.expect(Token::RightBrace)?;
1017        Ok(PipelineDecl { flow })
1018    }
1019    fn parse_embeddings_block(&mut self) -> Result<EmbeddingsDecl, String> {
1020        self.expect(Token::LeftBrace)?;
1021        let mut model = String::new();
1022        let mut dimensions = 0;
1023        let mut properties = HashMap::new();
1024        while self.current_token() != &Token::RightBrace {
1025            self.skip_newlines();
1026            let key = self.expect_identifier()?;
1027            if self.peek_token() != &Token::Assign
1028                && self.current_token() != &Token::Assign
1029            {
1030                return Err(
1031                    format!(
1032                        "Expected '=' after property key '{}', found {:?}", key, self
1033                        .current_token()
1034                    ),
1035                );
1036            }
1037            self.expect(Token::Assign)?;
1038            let value = self.parse_expression()?;
1039            match key.as_str() {
1040                "model" => model = value.as_string().unwrap_or_default(),
1041                "dimensions" => dimensions = value.as_number().unwrap_or(0.0) as u32,
1042                _ => {
1043                    properties.insert(key, value);
1044                }
1045            }
1046            self.skip_newlines();
1047        }
1048        self.expect(Token::RightBrace)?;
1049        Ok(EmbeddingsDecl {
1050            model,
1051            dimensions,
1052            properties,
1053        })
1054    }
1055    fn parse_variables_block(&mut self) -> Result<HashMap<String, Expression>, String> {
1056        self.expect(Token::LeftBrace)?;
1057        let mut variables = HashMap::new();
1058        while self.current_token() != &Token::RightBrace {
1059            self.skip_newlines();
1060            if self.current_token() == &Token::RightBrace {
1061                break;
1062            }
1063            let key = match self.current_token().clone() {
1064                Token::Identifier(id) => {
1065                    self.advance();
1066                    id.clone()
1067                }
1068                Token::Keyword(kw) => {
1069                    self.advance();
1070                    format!("{:?}", kw).to_lowercase()
1071                }
1072                _ => {
1073                    return Err(
1074                        format!(
1075                            "Expected identifier or keyword for variable name, found {:?}",
1076                            self.current_token()
1077                        ),
1078                    );
1079                }
1080            };
1081            self.expect(Token::Assign)?;
1082            let value = self.parse_expression()?;
1083            variables.insert(key, value);
1084            self.skip_newlines();
1085        }
1086        self.expect(Token::RightBrace)?;
1087        Ok(variables)
1088    }
1089    fn parse_secrets_block(&mut self) -> Result<HashMap<String, SecretRef>, String> {
1090        self.expect(Token::LeftBrace)?;
1091        let mut secrets = HashMap::new();
1092        while self.current_token() != &Token::RightBrace {
1093            self.skip_newlines();
1094            let key = self.expect_identifier()?;
1095            self.expect(Token::Assign)?;
1096            let secret_ref = match self.current_token() {
1097                Token::Variable(var) => {
1098                    let var = var.clone();
1099                    self.advance();
1100                    SecretRef::Environment(var)
1101                }
1102                Token::String(path) if path.starts_with("vault:") => {
1103                    let path = path.clone();
1104                    self.advance();
1105                    SecretRef::Vault(path.trim_start_matches("vault:").to_string())
1106                }
1107                Token::String(path) if path.starts_with("file:") => {
1108                    let path = path.clone();
1109                    self.advance();
1110                    SecretRef::File(path.trim_start_matches("file:").to_string())
1111                }
1112                _ => {
1113                    return Err(
1114                        format!("Invalid secret reference: {:?}", self.current_token()),
1115                    );
1116                }
1117            };
1118            secrets.insert(key, secret_ref);
1119            self.skip_newlines();
1120        }
1121        self.expect(Token::RightBrace)?;
1122        Ok(secrets)
1123    }
1124}
1125pub fn parse(tokens: Vec<Token>) -> Result<HelixAst, ParseError> {
1126    let mut parser = Parser::new(tokens);
1127    parser
1128        .parse()
1129        .map_err(|msg| ParseError {
1130            message: msg,
1131            location: None,
1132            token_index: 0,
1133            expected: None,
1134            found: String::new(),
1135            context: String::new(),
1136        })
1137}