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            let current_token = self.current_token().clone();
300            match current_token {
301                Token::Keyword(keyword) => {
302                    self.recovery_points.push(self.current);
303                    match self.parse_declaration(keyword.clone()) {
304                        Ok(decl) => {
305                            ast.add_declaration(decl);
306                            self.recovery_points.pop();
307                        }
308                        Err(err) => {
309                            self.add_error(
310                                err.clone(),
311                                Some(format!("valid {:?} declaration", keyword)),
312                            );
313                            self.recover_to_next_declaration();
314                            self.recovery_points.pop();
315                        }
316                    }
317                }
318                Token::Identifier(section_name) => {
319                    // Handle arbitrary identifiers as section declarations
320                    self.recovery_points.push(self.current);
321                    self.advance(); // consume the identifier
322                    self.expect(Token::LeftBrace)?;
323                    let properties = self.parse_properties()?;
324                    self.expect(Token::RightBrace)?;
325                    ast.add_declaration(Declaration::Section(SectionDecl {
326                        name: section_name.clone(),
327                        properties,
328                    }));
329                    self.recovery_points.pop();
330                }
331                Token::Eof => break,
332                _ => {
333                    self.add_error(
334                        format!("Unexpected token: {:?}", current_token),
335                        Some("declaration keyword or identifier".to_string()),
336                    );
337                    self.recover_to_next_declaration();
338                }
339            }
340            self.skip_newlines();
341        }
342        if !self.errors.is_empty() {
343            let error_summary = self
344                .errors
345                .iter()
346                .map(|e| format!("{} at token {}", e.message, e.token_index))
347                .collect::<Vec<_>>()
348                .join("; ");
349            Err(format!("Parse errors: {}", error_summary))
350        } else {
351            Ok(ast)
352        }
353    }
354    fn parse_declaration(&mut self, keyword: Keyword) -> Result<Declaration, String> {
355        match keyword {
356            Keyword::Project => {
357                self.advance();
358                let name = self.expect_identifier()?;
359                self.expect(Token::LeftBrace)?;
360                let properties = self.parse_properties()?;
361                self.expect(Token::RightBrace)?;
362                Ok(Declaration::Project(ProjectDecl { name, properties }))
363            }
364            Keyword::Agent => {
365                self.advance();
366                let name = self.expect_identifier()?;
367                self.expect(Token::LeftBrace)?;
368                let mut properties = HashMap::new();
369                let mut capabilities = None;
370                let mut backstory = None;
371                let tools = None;
372                while self.current_token() != &Token::RightBrace {
373                    self.skip_newlines();
374                    match self.current_token() {
375                        Token::Keyword(Keyword::Capabilities) => {
376                            self.advance();
377                            capabilities = Some(self.parse_string_array()?);
378                        }
379                        Token::Keyword(Keyword::Backstory) => {
380                            self.advance();
381                            backstory = Some(self.parse_backstory_block()?);
382                        }
383                        Token::Identifier(key) => {
384                            let key = key.clone();
385                            self.advance();
386                            self.expect(Token::Assign)?;
387                            let value = self.parse_expression()?;
388                            properties.insert(key, value);
389                        }
390                        Token::Keyword(keyword) => {
391                            match keyword {
392                                Keyword::Capabilities | Keyword::Backstory => {
393                                    return Err(
394                                        format!(
395                                            "Unexpected token in agent: {:?}", self.current_token()
396                                        ),
397                                    );
398                                }
399                                _ => {
400                                    let key = format!("{:?}", keyword).to_lowercase();
401                                    self.advance();
402                                    self.expect(Token::Assign)?;
403                                    let value = self.parse_expression()?;
404                                    properties.insert(key, value);
405                                }
406                            }
407                        }
408                        Token::RightBrace => break,
409                        _ => {
410                            return Err(
411                                format!(
412                                    "Unexpected token in agent: {:?}", self.current_token()
413                                ),
414                            );
415                        }
416                    }
417                    self.skip_newlines();
418                }
419                self.expect(Token::RightBrace)?;
420                Ok(
421                    Declaration::Agent(AgentDecl {
422                        name,
423                        properties,
424                        capabilities,
425                        backstory,
426                        tools,
427                    }),
428                )
429            }
430            Keyword::Workflow => {
431                self.advance();
432                let name = self.expect_identifier()?;
433                self.expect(Token::LeftBrace)?;
434                let mut trigger = None;
435                let mut steps = Vec::new();
436                let mut pipeline = None;
437                let mut properties = HashMap::new();
438                while self.current_token() != &Token::RightBrace {
439                    self.skip_newlines();
440                    match self.current_token() {
441                        Token::Keyword(Keyword::Trigger) => {
442                            self.advance();
443                            self.expect(Token::Assign)?;
444                            trigger = Some(self.parse_trigger_config()?);
445                        }
446                        Token::Keyword(Keyword::Step) => {
447                            steps.push(self.parse_step()?);
448                        }
449                        Token::Keyword(Keyword::Pipeline) => {
450                            self.advance();
451                            pipeline = Some(self.parse_pipeline_block()?);
452                        }
453                        Token::Keyword(Keyword::Timeout) => {
454                            self.advance();
455                            self.expect(Token::Assign)?;
456                            let timeout_value = self.parse_expression()?;
457                            properties.insert("timeout".to_string(), timeout_value);
458                        }
459                        Token::Identifier(key) => {
460                            let key = key.clone();
461                            self.advance();
462                            self.expect(Token::Assign)?;
463                            let value = self.parse_expression()?;
464                            properties.insert(key, value);
465                        }
466                        Token::RightBrace => break,
467                        _ => {
468                            return Err(
469                                format!(
470                                    "Unexpected token in workflow: {:?}", self.current_token()
471                                ),
472                            );
473                        }
474                    }
475                    self.skip_newlines();
476                }
477                self.expect(Token::RightBrace)?;
478                Ok(
479                    Declaration::Workflow(WorkflowDecl {
480                        name,
481                        trigger,
482                        steps,
483                        pipeline,
484                        properties,
485                    }),
486                )
487            }
488            Keyword::Memory => {
489                self.advance();
490                self.expect(Token::LeftBrace)?;
491                let mut provider = String::new();
492                let mut connection = String::new();
493                let mut embeddings = None;
494                let mut properties = HashMap::new();
495                while self.current_token() != &Token::RightBrace {
496                    self.skip_newlines();
497                    match self.current_token() {
498                        Token::Keyword(Keyword::Embeddings) => {
499                            self.advance();
500                            embeddings = Some(self.parse_embeddings_block()?);
501                        }
502                        Token::Identifier(key) => {
503                            let key = key.clone();
504                            self.advance();
505                            self.expect(Token::Assign)?;
506                            let value = self.parse_expression()?;
507                            match key.as_str() {
508                                "provider" => {
509                                    provider = value.as_string().unwrap_or_default();
510                                }
511                                "connection" => {
512                                    connection = value.as_string().unwrap_or_default();
513                                }
514                                _ => {
515                                    properties.insert(key, value);
516                                }
517                            }
518                        }
519                        Token::RightBrace => break,
520                        _ => {
521                            return Err(
522                                format!(
523                                    "Unexpected token in memory: {:?}", self.current_token()
524                                ),
525                            );
526                        }
527                    }
528                    self.skip_newlines();
529                }
530                self.expect(Token::RightBrace)?;
531                Ok(
532                    Declaration::Memory(MemoryDecl {
533                        provider,
534                        connection,
535                        embeddings,
536                        properties,
537                    }),
538                )
539            }
540            Keyword::Context => {
541                self.advance();
542                let name = self.expect_identifier()?;
543                self.expect(Token::LeftBrace)?;
544                let mut environment = String::new();
545                let mut secrets = None;
546                let mut variables = None;
547                let mut properties = HashMap::new();
548                while self.current_token() != &Token::RightBrace {
549                    self.skip_newlines();
550                    match self.current_token() {
551                        Token::Keyword(Keyword::Secrets) => {
552                            self.advance();
553                            secrets = Some(self.parse_secrets_block()?);
554                        }
555                        Token::Keyword(Keyword::Variables) => {
556                            self.advance();
557                            variables = Some(self.parse_variables_block()?);
558                        }
559                        Token::Identifier(key) => {
560                            let key = key.clone();
561                            self.advance();
562                            self.expect(Token::Assign)?;
563                            let value = self.parse_expression()?;
564                            if key == "environment" {
565                                environment = value.as_string().unwrap_or_default();
566                            } else {
567                                properties.insert(key, value);
568                            }
569                        }
570                        Token::RightBrace => break,
571                        _ => {
572                            return Err(
573                                format!(
574                                    "Unexpected token in context: {:?}", self.current_token()
575                                ),
576                            );
577                        }
578                    }
579                    self.skip_newlines();
580                }
581                self.expect(Token::RightBrace)?;
582                Ok(
583                    Declaration::Context(ContextDecl {
584                        name,
585                        environment,
586                        secrets,
587                        variables,
588                        properties,
589                    }),
590                )
591            }
592            Keyword::Crew => {
593                self.advance();
594                let name = self.expect_identifier()?;
595                self.expect(Token::LeftBrace)?;
596                let mut agents = Vec::new();
597                let mut process_type = None;
598                let mut properties = HashMap::new();
599                while self.current_token() != &Token::RightBrace {
600                    self.skip_newlines();
601                    match self.current_token() {
602                        Token::Identifier(key) => {
603                            let key = key.clone();
604                            self.advance();
605                            if key == "agents" {
606                                agents = self.parse_string_array()?;
607                            } else {
608                                self.expect(Token::Assign)?;
609                                let value = self.parse_expression()?;
610                                if key == "process" {
611                                    process_type = value.as_string();
612                                } else {
613                                    properties.insert(key, value);
614                                }
615                            }
616                        }
617                        Token::RightBrace => break,
618                        _ => {
619                            return Err(
620                                format!(
621                                    "Unexpected token in crew: {:?}", self.current_token()
622                                ),
623                            );
624                        }
625                    }
626                    self.skip_newlines();
627                }
628                self.expect(Token::RightBrace)?;
629                Ok(
630                    Declaration::Crew(CrewDecl {
631                        name,
632                        agents,
633                        process_type,
634                        properties,
635                    }),
636                )
637            }
638            Keyword::Pipeline => {
639                self.advance();
640                self.expect(Token::LeftBrace)?;
641                let pipeline = self.parse_pipeline_block()?;
642                self.expect(Token::RightBrace)?;
643                Ok(Declaration::Pipeline(pipeline))
644            }
645            Keyword::Load => {
646                self.advance();
647                let file_name = self.expect_identifier()?;
648                self.expect(Token::LeftBrace)?;
649                let properties = self.parse_properties()?;
650                self.expect(Token::RightBrace)?;
651                Ok(Declaration::Load(LoadDecl { file_name, properties }))
652            }
653            _ => Err(format!("Unexpected keyword: {:?}", keyword)),
654        }
655    }
656    fn parse_step(&mut self) -> Result<StepDecl, String> {
657        self.advance();
658        let name = self.expect_identifier()?;
659        self.expect(Token::LeftBrace)?;
660        let mut agent = None;
661        let mut crew = None;
662        let mut task = None;
663        let mut properties = HashMap::new();
664        while self.current_token() != &Token::RightBrace {
665            self.skip_newlines();
666            match self.current_token() {
667                Token::Keyword(Keyword::Timeout) => {
668                    self.advance();
669                    self.expect(Token::Assign)?;
670                    let timeout_value = self.parse_expression()?;
671                    properties.insert("timeout".to_string(), timeout_value);
672                }
673                Token::Identifier(key) => {
674                    let key = key.clone();
675                    self.advance();
676                    match key.as_str() {
677                        "agent" => {
678                            self.expect(Token::Assign)?;
679                            agent = self.parse_expression()?.as_string();
680                        }
681                        "crew" => {
682                            self.expect(Token::Assign)?;
683                            if self.current_token() == &Token::LeftBracket {
684                                crew = Some(self.parse_string_array()?);
685                            }
686                        }
687                        "task" => {
688                            self.expect(Token::Assign)?;
689                            task = self.parse_expression()?.as_string();
690                        }
691                        "retry" => {
692                            let retry_config = self.parse_retry_block()?;
693                            properties
694                                .insert(
695                                    "retry".to_string(),
696                                    Expression::Object(retry_config),
697                                );
698                        }
699                        _ => {
700                            self.expect(Token::Assign)?;
701                            let value = self.parse_expression()?;
702                            properties.insert(key, value);
703                        }
704                    }
705                }
706                Token::Keyword(keyword) => {
707                    let key = format!("{:?}", keyword).to_lowercase();
708                    self.advance();
709                    self.expect(Token::Assign)?;
710                    match key.as_str() {
711                        "agent" => {
712                            agent = self.parse_expression()?.as_string();
713                        }
714                        _ => {
715                            let value = self.parse_expression()?;
716                            properties.insert(key, value);
717                        }
718                    }
719                }
720                Token::RightBrace => break,
721                _ => {
722                    return Err(
723                        format!("Unexpected token in step: {:?}", self.current_token()),
724                    );
725                }
726            }
727            self.skip_newlines();
728        }
729        self.expect(Token::RightBrace)?;
730        Ok(StepDecl {
731            name,
732            agent,
733            crew,
734            task,
735            properties,
736        })
737    }
738    fn parse_retry_block(&mut self) -> Result<HashMap<String, Expression>, String> {
739        self.expect(Token::LeftBrace)?;
740        let mut retry_config = HashMap::new();
741        while self.current_token() != &Token::RightBrace {
742            self.skip_newlines();
743            if self.current_token() == &Token::RightBrace {
744                break;
745            }
746            let key = self.expect_identifier()?;
747            if self.peek_token() != &Token::Assign
748                && self.current_token() != &Token::Assign
749            {
750                return Err(
751                    format!(
752                        "Expected '=' after property key '{}', found {:?}", key, self
753                        .current_token()
754                    ),
755                );
756            }
757            self.expect(Token::Assign)?;
758            let value = self.parse_expression()?;
759            retry_config.insert(key, value);
760            self.skip_newlines();
761        }
762        self.expect(Token::RightBrace)?;
763        Ok(retry_config)
764    }
765    fn parse_trigger_config(&mut self) -> Result<Expression, String> {
766        if self.current_token() == &Token::LeftBrace {
767            self.advance();
768            let trigger_obj = self.parse_object()?;
769            Ok(Expression::Object(trigger_obj))
770        } else {
771            self.parse_expression()
772        }
773    }
774    fn parse_expression(&mut self) -> Result<Expression, String> {
775        match self.current_token() {
776            Token::LeftParen | Token::LeftBracket => self.parse_enhanced_expression(),
777            _ => self.parse_expression_with_precedence(Precedence::Lowest),
778        }
779    }
780    fn parse_expression_with_precedence(
781        &mut self,
782        min_precedence: Precedence,
783    ) -> Result<Expression, String> {
784        let mut left = self.parse_primary_expression()?;
785        while !self.is_at_end() {
786            let precedence = self.get_token_precedence(self.current_token());
787            if precedence < min_precedence {
788                break;
789            }
790            match self.current_token() {
791                Token::Arrow => {
792                    self.advance();
793                    let mut pipeline = vec![];
794                    if let Expression::Identifier(id) = left {
795                        pipeline.push(id);
796                    } else if let Expression::Pipeline(mut p) = left {
797                        pipeline.append(&mut p);
798                    } else {
799                        return Err(format!("Invalid left side of pipeline: {:?}", left));
800                    }
801                    let right = self
802                        .parse_expression_with_precedence(Precedence::Pipeline)?;
803                    if let Expression::Identifier(id) = right {
804                        pipeline.push(id);
805                    } else if let Expression::Pipeline(mut p) = right {
806                        pipeline.append(&mut p);
807                    } else {
808                        return Err(
809                            format!("Invalid right side of pipeline: {:?}", right),
810                        );
811                    }
812                    left = Expression::Pipeline(pipeline);
813                }
814                _ => {
815                    break;
816                }
817            }
818        }
819        Ok(left)
820    }
821    fn parse_primary_expression(&mut self) -> Result<Expression, String> {
822        match self.current_token() {
823            Token::String(s) => {
824                let s = s.clone();
825                self.advance();
826                Ok(Expression::String(s))
827            }
828            Token::Number(n) => {
829                let n = *n;
830                self.advance();
831                Ok(Expression::Number(n))
832            }
833            Token::Bool(b) => {
834                let b = *b;
835                self.advance();
836                Ok(Expression::Bool(b))
837            }
838            Token::Duration(value, unit) => {
839                let duration = Duration {
840                    value: *value,
841                    unit: match unit {
842                        TimeUnit::Seconds => crate::types::TimeUnit::Seconds,
843                        TimeUnit::Minutes => crate::types::TimeUnit::Minutes,
844                        TimeUnit::Hours => crate::types::TimeUnit::Hours,
845                        TimeUnit::Days => crate::types::TimeUnit::Days,
846                    },
847                };
848                self.advance();
849                Ok(Expression::Duration(duration))
850            }
851            Token::Variable(v) => {
852                let v = v.clone();
853                self.advance();
854                Ok(Expression::Variable(v))
855            }
856            Token::Reference(r) => {
857                let r = r.clone();
858                self.advance();
859                if self.current_token() == &Token::LeftBracket {
860                    self.advance();
861                    let key = self.expect_identifier()?;
862                    self.expect(Token::RightBracket)?;
863                    Ok(Expression::IndexedReference(r, key))
864                } else {
865                    Ok(Expression::Reference(r))
866                }
867            }
868            Token::Identifier(i) => {
869                let i = i.clone();
870                self.advance();
871                Ok(Expression::Identifier(i))
872            }
873            Token::LeftBracket => {
874                self.advance();
875                let array = self.parse_array()?;
876                Ok(Expression::Array(array))
877            }
878            Token::LeftBrace => {
879                self.advance();
880                let object = self.parse_object()?;
881                Ok(Expression::Object(object))
882            }
883            Token::LeftParen => {
884                self.advance();
885                let expr = self.parse_expression()?;
886                self.expect(Token::RightParen)?;
887                Ok(expr)
888            }
889            _ => {
890                Err(
891                    format!("Unexpected token in expression: {:?}", self.current_token()),
892                )
893            }
894        }
895    }
896    fn get_token_precedence(&self, token: &Token) -> Precedence {
897        match token {
898            Token::Arrow => Precedence::Pipeline,
899            _ => Precedence::Lowest,
900        }
901    }
902    fn is_at_end(&self) -> bool {
903        self.current_token() == &Token::Eof
904    }
905    fn parse_array(&mut self) -> Result<Vec<Expression>, String> {
906        let mut elements = Vec::new();
907        while self.current_token() != &Token::RightBracket {
908            self.skip_newlines();
909            if self.current_token() == &Token::RightBracket {
910                break;
911            }
912            elements.push(self.parse_expression()?);
913            if self.current_token() == &Token::Comma {
914                self.advance();
915            }
916            self.skip_newlines();
917        }
918        self.expect(Token::RightBracket)?;
919        Ok(elements)
920    }
921    fn parse_object(&mut self) -> Result<HashMap<String, Expression>, String> {
922        let mut object = HashMap::new();
923        while self.current_token() != &Token::RightBrace {
924            self.skip_newlines();
925            if self.current_token() == &Token::RightBrace {
926                break;
927            }
928            let key = self.expect_identifier()?;
929            if self.peek_token() != &Token::Assign
930                && self.current_token() != &Token::Assign
931            {
932                return Err(
933                    format!(
934                        "Expected '=' after property key '{}', found {:?}", key, self
935                        .current_token()
936                    ),
937                );
938            }
939            self.expect(Token::Assign)?;
940            let value = self.parse_expression()?;
941            object.insert(key, value);
942            if self.current_token() == &Token::Comma {
943                self.advance();
944            }
945            self.skip_newlines();
946        }
947        self.expect(Token::RightBrace)?;
948        Ok(object)
949    }
950    fn parse_string_array(&mut self) -> Result<Vec<String>, String> {
951        self.expect(Token::LeftBracket)?;
952        let mut items = Vec::new();
953        while self.current_token() != &Token::RightBracket {
954            self.skip_newlines();
955            if self.current_token() == &Token::RightBracket {
956                break;
957            }
958            items.push(self.expect_identifier()?);
959            if self.current_token() == &Token::Comma {
960                self.advance();
961            }
962            self.skip_newlines();
963        }
964        self.expect(Token::RightBracket)?;
965        Ok(items)
966    }
967    fn parse_properties(&mut self) -> Result<HashMap<String, Expression>, String> {
968        let mut properties = HashMap::new();
969        while self.current_token() != &Token::RightBrace {
970            self.skip_newlines();
971            if self.current_token() == &Token::RightBrace {
972                break;
973            }
974            let key = self.expect_identifier()?;
975            if self.peek_token() != &Token::Assign
976                && self.current_token() != &Token::Assign
977            {
978                return Err(
979                    format!(
980                        "Expected '=' after property key '{}', found {:?}", key, self
981                        .current_token()
982                    ),
983                );
984            }
985            self.expect(Token::Assign)?;
986            let value = self.parse_expression()?;
987            properties.insert(key, value);
988            self.skip_newlines();
989        }
990        Ok(properties)
991    }
992    fn parse_backstory_block(&mut self) -> Result<BackstoryBlock, String> {
993        self.expect(Token::LeftBrace)?;
994        let mut lines = Vec::new();
995        while self.current_token() != &Token::RightBrace {
996            self.skip_newlines();
997            match self.current_token() {
998                Token::Identifier(text) | Token::String(text) => {
999                    lines.push(text.clone());
1000                    self.advance();
1001                }
1002                Token::RightBrace => break,
1003                _ => {
1004                    self.advance();
1005                }
1006            }
1007        }
1008        self.expect(Token::RightBrace)?;
1009        Ok(BackstoryBlock { lines })
1010    }
1011    fn parse_pipeline_block(&mut self) -> Result<PipelineDecl, String> {
1012        self.expect(Token::LeftBrace)?;
1013        let mut flow = Vec::new();
1014        while self.current_token() != &Token::RightBrace {
1015            self.skip_newlines();
1016            if let Token::Identifier(step) = self.current_token() {
1017                flow.push(PipelineNode::Step(step.clone()));
1018                self.advance();
1019                if self.current_token() == &Token::Arrow {
1020                    self.advance();
1021                }
1022            } else if self.current_token() == &Token::RightBrace {
1023                break;
1024            } else {
1025                self.advance();
1026            }
1027            self.skip_newlines();
1028        }
1029        self.expect(Token::RightBrace)?;
1030        Ok(PipelineDecl { flow })
1031    }
1032    fn parse_embeddings_block(&mut self) -> Result<EmbeddingsDecl, String> {
1033        self.expect(Token::LeftBrace)?;
1034        let mut model = String::new();
1035        let mut dimensions = 0;
1036        let mut properties = HashMap::new();
1037        while self.current_token() != &Token::RightBrace {
1038            self.skip_newlines();
1039            let key = self.expect_identifier()?;
1040            if self.peek_token() != &Token::Assign
1041                && self.current_token() != &Token::Assign
1042            {
1043                return Err(
1044                    format!(
1045                        "Expected '=' after property key '{}', found {:?}", key, self
1046                        .current_token()
1047                    ),
1048                );
1049            }
1050            self.expect(Token::Assign)?;
1051            let value = self.parse_expression()?;
1052            match key.as_str() {
1053                "model" => model = value.as_string().unwrap_or_default(),
1054                "dimensions" => dimensions = value.as_number().unwrap_or(0.0) as u32,
1055                _ => {
1056                    properties.insert(key, value);
1057                }
1058            }
1059            self.skip_newlines();
1060        }
1061        self.expect(Token::RightBrace)?;
1062        Ok(EmbeddingsDecl {
1063            model,
1064            dimensions,
1065            properties,
1066        })
1067    }
1068    fn parse_variables_block(&mut self) -> Result<HashMap<String, Expression>, String> {
1069        self.expect(Token::LeftBrace)?;
1070        let mut variables = HashMap::new();
1071        while self.current_token() != &Token::RightBrace {
1072            self.skip_newlines();
1073            if self.current_token() == &Token::RightBrace {
1074                break;
1075            }
1076            let key = match self.current_token().clone() {
1077                Token::Identifier(id) => {
1078                    self.advance();
1079                    id.clone()
1080                }
1081                Token::Keyword(kw) => {
1082                    self.advance();
1083                    format!("{:?}", kw).to_lowercase()
1084                }
1085                _ => {
1086                    return Err(
1087                        format!(
1088                            "Expected identifier or keyword for variable name, found {:?}",
1089                            self.current_token()
1090                        ),
1091                    );
1092                }
1093            };
1094            self.expect(Token::Assign)?;
1095            let value = self.parse_expression()?;
1096            variables.insert(key, value);
1097            self.skip_newlines();
1098        }
1099        self.expect(Token::RightBrace)?;
1100        Ok(variables)
1101    }
1102    fn parse_secrets_block(&mut self) -> Result<HashMap<String, SecretRef>, String> {
1103        self.expect(Token::LeftBrace)?;
1104        let mut secrets = HashMap::new();
1105        while self.current_token() != &Token::RightBrace {
1106            self.skip_newlines();
1107            let key = self.expect_identifier()?;
1108            self.expect(Token::Assign)?;
1109            let secret_ref = match self.current_token() {
1110                Token::Variable(var) => {
1111                    let var = var.clone();
1112                    self.advance();
1113                    SecretRef::Environment(var)
1114                }
1115                Token::String(path) if path.starts_with("vault:") => {
1116                    let path = path.clone();
1117                    self.advance();
1118                    SecretRef::Vault(path.trim_start_matches("vault:").to_string())
1119                }
1120                Token::String(path) if path.starts_with("file:") => {
1121                    let path = path.clone();
1122                    self.advance();
1123                    SecretRef::File(path.trim_start_matches("file:").to_string())
1124                }
1125                _ => {
1126                    return Err(
1127                        format!("Invalid secret reference: {:?}", self.current_token()),
1128                    );
1129                }
1130            };
1131            secrets.insert(key, secret_ref);
1132            self.skip_newlines();
1133        }
1134        self.expect(Token::RightBrace)?;
1135        Ok(secrets)
1136    }
1137}
1138pub fn parse(tokens: Vec<Token>) -> Result<HelixAst, ParseError> {
1139    let mut parser = Parser::new(tokens);
1140    parser
1141        .parse()
1142        .map_err(|msg| ParseError {
1143            message: msg,
1144            location: None,
1145            token_index: 0,
1146            expected: None,
1147            found: String::new(),
1148            context: String::new(),
1149        })
1150}