1use crate::dsl::ast::*;
6use crate::dsl::lexer::{Keyword, Token, TokenType};
7use crate::error::{ReplError, Result};
8
9pub struct Parser {
11 tokens: Vec<Token>,
12 current: usize,
13}
14
15impl Parser {
16 pub fn new(tokens: Vec<Token>) -> Self {
18 Self { tokens, current: 0 }
19 }
20
21 pub fn parse(&mut self) -> Result<Program> {
23 let start_span = self.current_span();
24 let mut declarations = Vec::new();
25
26 self.skip_trivia();
28
29 while !self.is_at_end() {
30 if self.check_eof() {
31 break;
32 }
33
34 match self.parse_declaration() {
35 Ok(decl) => declarations.push(decl),
36 Err(e) => {
37 self.synchronize();
39 return Err(e);
40 }
41 }
42
43 self.skip_trivia();
44 }
45
46 let end_span = if declarations.is_empty() {
47 start_span.clone()
48 } else {
49 self.previous_span()
50 };
51
52 Ok(Program {
53 declarations,
54 span: Span {
55 start: start_span.start,
56 end: end_span.end,
57 },
58 })
59 }
60
61 fn parse_declaration(&mut self) -> Result<Declaration> {
63 if self.match_keyword(Keyword::Agent) {
64 Ok(Declaration::Agent(self.parse_agent_definition()?))
65 } else if self.match_keyword(Keyword::Behavior) {
66 Ok(Declaration::Behavior(self.parse_behavior_definition()?))
67 } else if self.match_keyword(Keyword::Function) {
68 Ok(Declaration::Function(self.parse_function_definition()?))
69 } else if self.match_keyword(Keyword::On) {
70 Ok(Declaration::EventHandler(self.parse_event_handler()?))
71 } else if self.match_keyword(Keyword::Struct) {
72 Ok(Declaration::Struct(self.parse_struct_definition()?))
73 } else {
74 Err(ReplError::Parsing(format!(
75 "Expected declaration, found {:?} at line {}",
76 self.peek().token_type,
77 self.peek().line
78 )))
79 }
80 }
81
82 fn parse_agent_definition(&mut self) -> Result<AgentDefinition> {
84 let start_span = self.previous_span();
85
86 let name = if let TokenType::Identifier(name) = &self.advance().token_type {
87 name.clone()
88 } else {
89 return Err(ReplError::Parsing("Expected agent name".to_string()));
90 };
91
92 self.consume_token(TokenType::LeftBrace, "Expected '{' after agent name")?;
93
94 let mut metadata = AgentMetadata {
95 name: None,
96 version: None,
97 author: None,
98 description: None,
99 };
100 let mut resources = None;
101 let mut security = None;
102 let mut policies = None;
103
104 while !self.check_token(&TokenType::RightBrace) && !self.is_at_end() {
105 self.skip_trivia();
106
107 if self.check_token(&TokenType::RightBrace) {
109 break;
110 }
111
112 if self.match_keyword(Keyword::Name) {
113 self.consume_token(TokenType::Colon, "Expected ':' after 'name'")?;
114 metadata.name = Some(self.parse_string_literal()?);
115 } else if self.match_keyword(Keyword::Version) {
116 self.consume_token(TokenType::Colon, "Expected ':' after 'version'")?;
117 metadata.version = Some(self.parse_string_literal()?);
118 } else if self.match_keyword(Keyword::Author) {
119 self.consume_token(TokenType::Colon, "Expected ':' after 'author'")?;
120 metadata.author = Some(self.parse_string_literal()?);
121 } else if self.match_keyword(Keyword::Description) {
122 self.consume_token(TokenType::Colon, "Expected ':' after 'description'")?;
123 metadata.description = Some(self.parse_string_literal()?);
124 } else if self.match_keyword(Keyword::Resources) {
125 resources = Some(self.parse_resource_config()?);
126 } else if self.match_keyword(Keyword::Security) {
127 security = Some(self.parse_security_config()?);
128 } else if self.match_keyword(Keyword::Policies) {
129 policies = Some(self.parse_policy_config()?);
130 } else {
131 return Err(ReplError::Parsing(format!(
132 "Unexpected token in agent definition: {:?}",
133 self.peek().token_type
134 )));
135 }
136
137 self.skip_trivia();
138 }
139
140 self.consume_token(TokenType::RightBrace, "Expected '}' after agent definition")?;
141
142 let end_span = self.previous_span();
143
144 Ok(AgentDefinition {
145 name,
146 metadata,
147 resources,
148 security,
149 policies,
150 span: Span {
151 start: start_span.start,
152 end: end_span.end,
153 },
154 })
155 }
156
157 fn parse_behavior_definition(&mut self) -> Result<BehaviorDefinition> {
159 let start_span = self.previous_span();
160
161 let name = if let TokenType::Identifier(name) = &self.advance().token_type {
162 name.clone()
163 } else {
164 return Err(ReplError::Parsing("Expected behavior name".to_string()));
165 };
166
167 self.consume_token(TokenType::LeftBrace, "Expected '{' after behavior name")?;
168
169 let mut input = None;
170 let mut output = None;
171 let mut steps = None;
172
173 while !self.check_token(&TokenType::RightBrace) && !self.is_at_end() {
174 self.skip_trivia();
175
176 if self.match_keyword(Keyword::Input) {
177 input = Some(self.parse_parameter_block()?);
178 } else if self.match_keyword(Keyword::Output) {
179 output = Some(self.parse_parameter_block()?);
180 } else if self.match_keyword(Keyword::Steps) {
181 steps = Some(self.parse_block()?);
182 } else {
183 return Err(ReplError::Parsing(format!(
184 "Unexpected token in behavior definition: {:?}",
185 self.peek().token_type
186 )));
187 }
188
189 self.skip_trivia();
190 }
191
192 self.consume_token(
193 TokenType::RightBrace,
194 "Expected '}' after behavior definition",
195 )?;
196
197 let steps = steps
198 .ok_or_else(|| ReplError::Parsing("Behavior must have steps block".to_string()))?;
199 let end_span = self.previous_span();
200
201 Ok(BehaviorDefinition {
202 name,
203 input,
204 output,
205 steps,
206 span: Span {
207 start: start_span.start,
208 end: end_span.end,
209 },
210 })
211 }
212
213 fn parse_function_definition(&mut self) -> Result<FunctionDefinition> {
215 let start_span = self.previous_span();
216
217 let name = if let TokenType::Identifier(name) = &self.advance().token_type {
218 name.clone()
219 } else {
220 return Err(ReplError::Parsing("Expected function name".to_string()));
221 };
222
223 self.consume_token(TokenType::LeftParen, "Expected '(' after function name")?;
224 let parameters = self.parse_parameter_list()?;
225 self.consume_token(TokenType::RightParen, "Expected ')' after parameters")?;
226
227 let return_type = if self.match_token(&TokenType::Arrow) {
228 Some(self.parse_type()?)
229 } else {
230 None
231 };
232
233 let body = self.parse_block()?;
234 let end_span = self.previous_span();
235
236 Ok(FunctionDefinition {
237 name,
238 parameters,
239 return_type,
240 body,
241 span: Span {
242 start: start_span.start,
243 end: end_span.end,
244 },
245 })
246 }
247
248 fn parse_event_handler(&mut self) -> Result<EventHandler> {
250 let start_span = self.previous_span();
251
252 let event_name = if let TokenType::Identifier(name) = &self.advance().token_type {
253 name.clone()
254 } else {
255 return Err(ReplError::Parsing("Expected event name".to_string()));
256 };
257
258 self.consume_token(TokenType::LeftParen, "Expected '(' after event name")?;
259 let parameters = self.parse_parameter_list()?;
260 self.consume_token(TokenType::RightParen, "Expected ')' after parameters")?;
261
262 let body = self.parse_block()?;
263 let end_span = self.previous_span();
264
265 Ok(EventHandler {
266 event_name,
267 parameters,
268 body,
269 span: Span {
270 start: start_span.start,
271 end: end_span.end,
272 },
273 })
274 }
275
276 fn parse_struct_definition(&mut self) -> Result<StructDefinition> {
278 let start_span = self.previous_span();
279
280 let name = if let TokenType::Identifier(name) = &self.advance().token_type {
281 name.clone()
282 } else {
283 return Err(ReplError::Parsing("Expected struct name".to_string()));
284 };
285
286 self.consume_token(TokenType::LeftBrace, "Expected '{' after struct name")?;
287
288 let mut fields = Vec::new();
289 while !self.check_token(&TokenType::RightBrace) && !self.is_at_end() {
290 self.skip_trivia();
291 if self.check_token(&TokenType::RightBrace) {
292 break;
293 }
294
295 let field_start = self.current_span();
296 let field_name = if let TokenType::Identifier(name) = &self.advance().token_type {
297 name.clone()
298 } else {
299 return Err(ReplError::Parsing("Expected field name".to_string()));
300 };
301
302 self.consume_token(TokenType::Colon, "Expected ':' after field name")?;
303 let field_type = self.parse_type()?;
304 let field_end = self.previous_span();
305
306 fields.push(StructField {
307 name: field_name,
308 field_type,
309 span: Span {
310 start: field_start.start,
311 end: field_end.end,
312 },
313 });
314
315 self.skip_trivia();
316 }
317
318 self.consume_token(TokenType::RightBrace, "Expected '}' after struct fields")?;
319 let end_span = self.previous_span();
320
321 Ok(StructDefinition {
322 name,
323 fields,
324 span: Span {
325 start: start_span.start,
326 end: end_span.end,
327 },
328 })
329 }
330
331 fn parse_block(&mut self) -> Result<Block> {
333 let start_span = self.current_span();
334 self.consume_token(TokenType::LeftBrace, "Expected '{'")?;
335
336 let mut statements = Vec::new();
337 while !self.check_token(&TokenType::RightBrace) && !self.is_at_end() {
338 self.skip_trivia();
339 if self.check_token(&TokenType::RightBrace) {
340 break;
341 }
342
343 statements.push(self.parse_statement()?);
344 self.skip_trivia();
345 }
346
347 self.consume_token(TokenType::RightBrace, "Expected '}'")?;
348 let end_span = self.previous_span();
349
350 Ok(Block {
351 statements,
352 span: Span {
353 start: start_span.start,
354 end: end_span.end,
355 },
356 })
357 }
358
359 fn parse_statement(&mut self) -> Result<Statement> {
361 if self.match_keyword(Keyword::Let) {
362 Ok(Statement::Let(self.parse_let_statement()?))
363 } else if self.match_keyword(Keyword::If) {
364 Ok(Statement::If(self.parse_if_statement()?))
365 } else if self.match_keyword(Keyword::Return) {
366 Ok(Statement::Return(self.parse_return_statement()?))
367 } else if self.match_keyword(Keyword::Emit) {
368 Ok(Statement::Emit(self.parse_emit_statement()?))
369 } else if self.match_keyword(Keyword::Require) {
370 Ok(Statement::Require(self.parse_require_statement()?))
371 } else {
372 let expr = self.parse_expression()?;
374 Ok(Statement::Expression(expr))
375 }
376 }
377
378 fn parse_let_statement(&mut self) -> Result<LetStatement> {
380 let start_span = self.previous_span();
381
382 let name = if let TokenType::Identifier(name) = &self.advance().token_type {
383 name.clone()
384 } else {
385 return Err(ReplError::Parsing("Expected variable name".to_string()));
386 };
387
388 let var_type = if self.match_token(&TokenType::Colon) {
389 Some(self.parse_type()?)
390 } else {
391 None
392 };
393
394 self.consume_token(TokenType::Assign, "Expected '=' in let statement")?;
395 let value = self.parse_expression()?;
396 let end_span = self.previous_span();
397
398 Ok(LetStatement {
399 name,
400 var_type,
401 value,
402 span: Span {
403 start: start_span.start,
404 end: end_span.end,
405 },
406 })
407 }
408
409 fn parse_if_statement(&mut self) -> Result<IfStatement> {
411 let start_span = self.previous_span();
412
413 let condition = self.parse_expression()?;
414 let then_block = self.parse_block()?;
415
416 let mut else_ifs = Vec::new();
417 while self.match_keyword(Keyword::Else) {
418 if self.match_keyword(Keyword::If) {
419 let else_if_start = self.previous_span();
420 let else_if_condition = self.parse_expression()?;
421 let else_if_block = self.parse_block()?;
422 let else_if_end = self.previous_span();
423
424 else_ifs.push(ElseIf {
425 condition: else_if_condition,
426 block: else_if_block,
427 span: Span {
428 start: else_if_start.start,
429 end: else_if_end.end,
430 },
431 });
432 } else {
433 let else_block = self.parse_block()?;
435 let end_span = self.previous_span();
436
437 return Ok(IfStatement {
438 condition,
439 then_block,
440 else_ifs,
441 else_block: Some(else_block),
442 span: Span {
443 start: start_span.start,
444 end: end_span.end,
445 },
446 });
447 }
448 }
449
450 let end_span = self.previous_span();
451
452 Ok(IfStatement {
453 condition,
454 then_block,
455 else_ifs,
456 else_block: None,
457 span: Span {
458 start: start_span.start,
459 end: end_span.end,
460 },
461 })
462 }
463
464 fn parse_return_statement(&mut self) -> Result<ReturnStatement> {
466 let start_span = self.previous_span();
467
468 let value = if self.check_token(&TokenType::Newline)
469 || self.check_token(&TokenType::RightBrace)
470 || self.is_at_end()
471 {
472 None
473 } else {
474 Some(self.parse_expression()?)
475 };
476
477 let end_span = self.previous_span();
478
479 Ok(ReturnStatement {
480 value,
481 span: Span {
482 start: start_span.start,
483 end: end_span.end,
484 },
485 })
486 }
487
488 fn parse_emit_statement(&mut self) -> Result<EmitStatement> {
490 let start_span = self.previous_span();
491
492 let event_name = if let TokenType::Identifier(name) = &self.advance().token_type {
493 name.clone()
494 } else {
495 return Err(ReplError::Parsing("Expected event name".to_string()));
496 };
497
498 let data = if self.check_token(&TokenType::LeftBrace) {
499 Some(self.parse_expression()?)
500 } else {
501 None
502 };
503
504 let end_span = self.previous_span();
505
506 Ok(EmitStatement {
507 event_name,
508 data,
509 span: Span {
510 start: start_span.start,
511 end: end_span.end,
512 },
513 })
514 }
515
516 fn parse_require_statement(&mut self) -> Result<RequireStatement> {
518 let start_span = self.previous_span();
519
520 let requirement = if self.match_keyword(Keyword::Capability) {
521 let cap_name = if let TokenType::Identifier(name) = &self.advance().token_type {
522 name.clone()
523 } else {
524 return Err(ReplError::Parsing("Expected capability name".to_string()));
525 };
526 RequirementType::Capability(cap_name)
527 } else if self.match_keyword(Keyword::Capabilities) {
528 self.consume_token(TokenType::LeftBracket, "Expected '[' after 'capabilities'")?;
529 let mut capabilities = Vec::new();
530
531 while !self.check_token(&TokenType::RightBracket) && !self.is_at_end() {
532 if let TokenType::Identifier(name) = &self.advance().token_type {
533 capabilities.push(name.clone());
534 } else {
535 return Err(ReplError::Parsing("Expected capability name".to_string()));
536 }
537
538 if !self.check_token(&TokenType::RightBracket) {
539 self.consume_token(TokenType::Comma, "Expected ',' between capabilities")?;
540 }
541 }
542
543 self.consume_token(TokenType::RightBracket, "Expected ']' after capabilities")?;
544 RequirementType::Capabilities(capabilities)
545 } else {
546 return Err(ReplError::Parsing(
547 "Expected 'capability' or 'capabilities'".to_string(),
548 ));
549 };
550
551 let end_span = self.previous_span();
552
553 Ok(RequireStatement {
554 requirement,
555 span: Span {
556 start: start_span.start,
557 end: end_span.end,
558 },
559 })
560 }
561
562 fn parse_expression(&mut self) -> Result<Expression> {
564 self.parse_assignment()
565 }
566
567 fn parse_assignment(&mut self) -> Result<Expression> {
569 let expr = self.parse_logical_or()?;
570
571 if self.match_token(&TokenType::Assign) {
572 let start_span = self.get_expression_span(&expr);
573 let value = self.parse_assignment()?;
574 let end_span = self.get_expression_span(&value);
575
576 return Ok(Expression::Assignment(Assignment {
577 target: Box::new(expr),
578 value: Box::new(value),
579 span: Span {
580 start: start_span.start,
581 end: end_span.end,
582 },
583 }));
584 }
585
586 Ok(expr)
587 }
588
589 fn parse_logical_or(&mut self) -> Result<Expression> {
591 let mut expr = self.parse_logical_and()?;
592
593 while self.match_token(&TokenType::Or) {
594 let start_span = self.get_expression_span(&expr);
595 let operator = BinaryOperator::Or;
596 let right = self.parse_logical_and()?;
597 let end_span = self.get_expression_span(&right);
598
599 expr = Expression::BinaryOp(BinaryOperation {
600 left: Box::new(expr),
601 operator,
602 right: Box::new(right),
603 span: Span {
604 start: start_span.start,
605 end: end_span.end,
606 },
607 });
608 }
609
610 Ok(expr)
611 }
612
613 fn parse_logical_and(&mut self) -> Result<Expression> {
615 let mut expr = self.parse_equality()?;
616
617 while self.match_token(&TokenType::And) {
618 let start_span = self.get_expression_span(&expr);
619 let operator = BinaryOperator::And;
620 let right = self.parse_equality()?;
621 let end_span = self.get_expression_span(&right);
622
623 expr = Expression::BinaryOp(BinaryOperation {
624 left: Box::new(expr),
625 operator,
626 right: Box::new(right),
627 span: Span {
628 start: start_span.start,
629 end: end_span.end,
630 },
631 });
632 }
633
634 Ok(expr)
635 }
636
637 fn parse_equality(&mut self) -> Result<Expression> {
639 let mut expr = self.parse_comparison()?;
640
641 while let Some(op) = self.match_binary_operator(&[TokenType::Equal, TokenType::NotEqual]) {
642 let start_span = self.get_expression_span(&expr);
643 let right = self.parse_comparison()?;
644 let end_span = self.get_expression_span(&right);
645
646 expr = Expression::BinaryOp(BinaryOperation {
647 left: Box::new(expr),
648 operator: op,
649 right: Box::new(right),
650 span: Span {
651 start: start_span.start,
652 end: end_span.end,
653 },
654 });
655 }
656
657 Ok(expr)
658 }
659
660 fn parse_comparison(&mut self) -> Result<Expression> {
662 let mut expr = self.parse_addition()?;
663
664 while let Some(op) = self.match_binary_operator(&[
665 TokenType::GreaterThan,
666 TokenType::GreaterThanOrEqual,
667 TokenType::LessThan,
668 TokenType::LessThanOrEqual,
669 ]) {
670 let start_span = self.get_expression_span(&expr);
671 let right = self.parse_addition()?;
672 let end_span = self.get_expression_span(&right);
673
674 expr = Expression::BinaryOp(BinaryOperation {
675 left: Box::new(expr),
676 operator: op,
677 right: Box::new(right),
678 span: Span {
679 start: start_span.start,
680 end: end_span.end,
681 },
682 });
683 }
684
685 Ok(expr)
686 }
687
688 fn parse_addition(&mut self) -> Result<Expression> {
690 let mut expr = self.parse_multiplication()?;
691
692 while let Some(op) = self.match_binary_operator(&[TokenType::Plus, TokenType::Minus]) {
693 let start_span = self.get_expression_span(&expr);
694 let right = self.parse_multiplication()?;
695 let end_span = self.get_expression_span(&right);
696
697 expr = Expression::BinaryOp(BinaryOperation {
698 left: Box::new(expr),
699 operator: op,
700 right: Box::new(right),
701 span: Span {
702 start: start_span.start,
703 end: end_span.end,
704 },
705 });
706 }
707
708 Ok(expr)
709 }
710
711 fn parse_multiplication(&mut self) -> Result<Expression> {
713 let mut expr = self.parse_unary()?;
714
715 while let Some(op) =
716 self.match_binary_operator(&[TokenType::Multiply, TokenType::Divide, TokenType::Modulo])
717 {
718 let start_span = self.get_expression_span(&expr);
719 let right = self.parse_unary()?;
720 let end_span = self.get_expression_span(&right);
721
722 expr = Expression::BinaryOp(BinaryOperation {
723 left: Box::new(expr),
724 operator: op,
725 right: Box::new(right),
726 span: Span {
727 start: start_span.start,
728 end: end_span.end,
729 },
730 });
731 }
732
733 Ok(expr)
734 }
735
736 fn parse_unary(&mut self) -> Result<Expression> {
738 if let Some(op) = self.match_unary_operator(&[TokenType::Not, TokenType::Minus]) {
739 let start_span = self.previous_span();
740 let operand = self.parse_unary()?;
741 let end_span = self.get_expression_span(&operand);
742
743 return Ok(Expression::UnaryOp(UnaryOperation {
744 operator: op,
745 operand: Box::new(operand),
746 span: Span {
747 start: start_span.start,
748 end: end_span.end,
749 },
750 }));
751 }
752
753 self.parse_postfix()
754 }
755
756 fn parse_postfix(&mut self) -> Result<Expression> {
758 let mut expr = self.parse_primary()?;
759
760 loop {
761 if self.match_token(&TokenType::Dot) {
762 let start_span = self.get_expression_span(&expr);
763 let field = if let TokenType::Identifier(name) = &self.advance().token_type {
764 name.clone()
765 } else {
766 return Err(ReplError::Parsing(
767 "Expected field name after '.'".to_string(),
768 ));
769 };
770
771 if self.check_token(&TokenType::LeftParen) {
773 self.advance(); let arguments = self.parse_argument_list()?;
775 self.consume_token(TokenType::RightParen, "Expected ')' after arguments")?;
776 let end_span = self.previous_span();
777
778 expr = Expression::MethodCall(MethodCall {
779 object: Box::new(expr),
780 method: field,
781 arguments,
782 span: Span {
783 start: start_span.start,
784 end: end_span.end,
785 },
786 });
787 } else {
788 let end_span = self.previous_span();
789
790 expr = Expression::FieldAccess(FieldAccess {
791 object: Box::new(expr),
792 field,
793 span: Span {
794 start: start_span.start,
795 end: end_span.end,
796 },
797 });
798 }
799 } else if self.match_token(&TokenType::LeftBracket) {
800 let start_span = self.get_expression_span(&expr);
801 let index = self.parse_expression()?;
802 self.consume_token(TokenType::RightBracket, "Expected ']' after index")?;
803 let end_span = self.previous_span();
804
805 expr = Expression::IndexAccess(IndexAccess {
806 object: Box::new(expr),
807 index: Box::new(index),
808 span: Span {
809 start: start_span.start,
810 end: end_span.end,
811 },
812 });
813 } else {
814 break;
815 }
816 }
817
818 Ok(expr)
819 }
820
821 fn parse_primary(&mut self) -> Result<Expression> {
823 let token = self.advance();
824 let span = self.token_span(&token);
825
826 match &token.token_type {
827 TokenType::String(s) => Ok(Expression::Literal(Literal::String(s.clone()))),
828 TokenType::Number(n) => Ok(Expression::Literal(Literal::Number(*n))),
829 TokenType::Integer(i) => Ok(Expression::Literal(Literal::Integer(*i))),
830 TokenType::Duration(value, unit) => {
831 let duration_unit = match unit.as_str() {
832 "ms" => DurationUnit::Milliseconds,
833 "s" => DurationUnit::Seconds,
834 "m" => DurationUnit::Minutes,
835 "h" => DurationUnit::Hours,
836 "d" => DurationUnit::Days,
837 _ => {
838 return Err(ReplError::Parsing(format!(
839 "Invalid duration unit: {}",
840 unit
841 )))
842 }
843 };
844 Ok(Expression::Literal(Literal::Duration(DurationValue {
845 value: *value,
846 unit: duration_unit,
847 })))
848 }
849 TokenType::Size(value, unit) => {
850 let size_unit = match unit.as_str() {
851 "B" => SizeUnit::Bytes,
852 "KB" => SizeUnit::KB,
853 "MB" => SizeUnit::MB,
854 "GB" => SizeUnit::GB,
855 "TB" => SizeUnit::TB,
856 _ => return Err(ReplError::Parsing(format!("Invalid size unit: {}", unit))),
857 };
858 Ok(Expression::Literal(Literal::Size(SizeValue {
859 value: *value,
860 unit: size_unit,
861 })))
862 }
863 TokenType::Keyword(Keyword::True) => Ok(Expression::Literal(Literal::Boolean(true))),
864 TokenType::Keyword(Keyword::False) => Ok(Expression::Literal(Literal::Boolean(false))),
865 TokenType::Keyword(Keyword::Null) => Ok(Expression::Literal(Literal::Null)),
866 TokenType::Identifier(name) => {
867 if self.check_token(&TokenType::LeftParen) {
869 self.advance(); let arguments = self.parse_argument_list()?;
871 self.consume_token(TokenType::RightParen, "Expected ')' after arguments")?;
872 let end_span = self.previous_span();
873
874 Ok(Expression::FunctionCall(FunctionCall {
875 function: name.clone(),
876 arguments,
877 span: Span {
878 start: span.start,
879 end: end_span.end,
880 },
881 }))
882 } else {
883 Ok(Expression::Identifier(Identifier {
884 name: name.clone(),
885 span,
886 }))
887 }
888 }
889 TokenType::LeftParen => {
890 let expr = self.parse_expression()?;
891 self.consume_token(TokenType::RightParen, "Expected ')' after expression")?;
892 Ok(expr)
893 }
894 TokenType::LeftBracket => {
895 let elements = self.parse_expression_list(&TokenType::RightBracket)?;
896 self.consume_token(TokenType::RightBracket, "Expected ']' after list elements")?;
897 let end_span = self.previous_span();
898
899 Ok(Expression::List(ListExpression {
900 elements,
901 span: Span {
902 start: span.start,
903 end: end_span.end,
904 },
905 }))
906 }
907 TokenType::LeftBrace => {
908 let entries = self.parse_map_entries()?;
909 self.consume_token(TokenType::RightBrace, "Expected '}' after map entries")?;
910 let end_span = self.previous_span();
911
912 Ok(Expression::Map(MapExpression {
913 entries,
914 span: Span {
915 start: span.start,
916 end: end_span.end,
917 },
918 }))
919 }
920 _ => Err(ReplError::Parsing(format!(
921 "Unexpected token in expression: {:?}",
922 token.token_type
923 ))),
924 }
925 }
926
927 fn parse_resource_config(&mut self) -> Result<ResourceConfig> {
929 self.consume_token(TokenType::LeftBrace, "Expected '{' after 'resources'")?;
930
931 let mut memory = None;
932 let mut cpu = None;
933 let mut network = None;
934 let mut storage = None;
935
936 while !self.check_token(&TokenType::RightBrace) && !self.is_at_end() {
937 self.skip_trivia();
938
939 if self.match_keyword(Keyword::Memory) {
940 self.consume_token(TokenType::Colon, "Expected ':' after 'memory'")?;
941 memory = Some(self.parse_size_value()?);
942 } else if self.match_keyword(Keyword::Cpu) {
943 self.consume_token(TokenType::Colon, "Expected ':' after 'cpu'")?;
944 cpu = Some(self.parse_duration_value()?);
945 } else if self.match_keyword(Keyword::Network) {
946 self.consume_token(TokenType::Colon, "Expected ':' after 'network'")?;
947 network = Some(self.parse_boolean_value()?);
948 } else if self.match_keyword(Keyword::Storage) {
949 self.consume_token(TokenType::Colon, "Expected ':' after 'storage'")?;
950 storage = Some(self.parse_size_value()?);
951 } else {
952 return Err(ReplError::Parsing(
953 "Unexpected token in resources block".to_string(),
954 ));
955 }
956
957 self.skip_trivia();
958 }
959
960 self.consume_token(TokenType::RightBrace, "Expected '}' after resources")?;
961
962 Ok(ResourceConfig {
963 memory,
964 cpu,
965 network,
966 storage,
967 })
968 }
969
970 fn parse_security_config(&mut self) -> Result<SecurityConfig> {
971 self.consume_token(TokenType::LeftBrace, "Expected '{' after 'security'")?;
972
973 let mut tier = None;
974 let mut capabilities = Vec::new();
975 let mut sandbox = None;
976
977 while !self.check_token(&TokenType::RightBrace) && !self.is_at_end() {
978 self.skip_trivia();
979
980 if self.match_keyword(Keyword::Tier) {
981 self.consume_token(TokenType::Colon, "Expected ':' after 'tier'")?;
982 tier = Some(self.parse_security_tier()?);
983 } else if self.match_keyword(Keyword::Capabilities) {
984 self.consume_token(TokenType::Colon, "Expected ':' after 'capabilities'")?;
985 capabilities = self.parse_string_list()?;
986 } else if self.match_keyword(Keyword::Sandbox) {
987 self.consume_token(TokenType::Colon, "Expected ':' after 'sandbox'")?;
988 sandbox = Some(self.parse_sandbox_mode()?);
989 } else {
990 return Err(ReplError::Parsing(
991 "Unexpected token in security block".to_string(),
992 ));
993 }
994
995 self.skip_trivia();
996 }
997
998 self.consume_token(TokenType::RightBrace, "Expected '}' after security")?;
999
1000 Ok(SecurityConfig {
1001 tier,
1002 capabilities,
1003 sandbox,
1004 })
1005 }
1006
1007 fn parse_policy_config(&mut self) -> Result<PolicyConfig> {
1008 self.consume_token(TokenType::LeftBrace, "Expected '{' after 'policies'")?;
1009
1010 let mut execution_timeout = None;
1011 let mut retry_count = None;
1012 let mut failure_action = None;
1013
1014 while !self.check_token(&TokenType::RightBrace) && !self.is_at_end() {
1015 self.skip_trivia();
1016
1017 if self.match_keyword(Keyword::Timeout) {
1018 self.consume_token(TokenType::Colon, "Expected ':' after 'timeout'")?;
1019 execution_timeout = Some(self.parse_duration_value()?);
1020 } else if self.match_keyword(Keyword::Retry) {
1021 self.consume_token(TokenType::Colon, "Expected ':' after 'retry'")?;
1022 retry_count = Some(self.parse_integer_value()?);
1023 } else if self.match_keyword(Keyword::Failure) {
1024 self.consume_token(TokenType::Colon, "Expected ':' after 'failure'")?;
1025 failure_action = Some(self.parse_failure_action()?);
1026 } else {
1027 return Err(ReplError::Parsing(
1028 "Unexpected token in policies block".to_string(),
1029 ));
1030 }
1031
1032 self.skip_trivia();
1033 }
1034
1035 self.consume_token(TokenType::RightBrace, "Expected '}' after policies")?;
1036
1037 Ok(PolicyConfig {
1038 execution_timeout,
1039 retry_count,
1040 failure_action,
1041 })
1042 }
1043
1044 fn parse_parameter_block(&mut self) -> Result<ParameterList> {
1045 self.consume_token(TokenType::LeftBrace, "Expected '{' after parameter block")?;
1046 let parameters = self.parse_parameter_list()?;
1047 self.consume_token(TokenType::RightBrace, "Expected '}' after parameter block")?;
1048 Ok(parameters)
1049 }
1050
1051 fn parse_parameter_list(&mut self) -> Result<ParameterList> {
1052 let mut parameters = Vec::new();
1053
1054 while !self.check_token(&TokenType::RightParen)
1055 && !self.check_token(&TokenType::RightBrace)
1056 && !self.is_at_end()
1057 {
1058 self.skip_trivia();
1059
1060 if self.check_token(&TokenType::RightParen) || self.check_token(&TokenType::RightBrace)
1061 {
1062 break;
1063 }
1064
1065 let param_start = self.current_span();
1066 let name = if let TokenType::Identifier(name) = &self.advance().token_type {
1067 name.clone()
1068 } else {
1069 return Err(ReplError::Parsing("Expected parameter name".to_string()));
1070 };
1071
1072 self.consume_token(TokenType::Colon, "Expected ':' after parameter name")?;
1073 let param_type = self.parse_type()?;
1074
1075 let default_value = if self.match_token(&TokenType::Assign) {
1076 Some(self.parse_expression()?)
1077 } else {
1078 None
1079 };
1080
1081 let param_end = self.previous_span();
1082
1083 parameters.push(Parameter {
1084 name,
1085 param_type,
1086 default_value,
1087 span: Span {
1088 start: param_start.start,
1089 end: param_end.end,
1090 },
1091 });
1092
1093 self.skip_trivia();
1094
1095 if !self.check_token(&TokenType::RightParen)
1096 && !self.check_token(&TokenType::RightBrace)
1097 {
1098 self.consume_token(TokenType::Comma, "Expected ',' between parameters")?;
1099 self.skip_trivia();
1100 }
1101 }
1102
1103 Ok(ParameterList { parameters })
1104 }
1105
1106 fn parse_type(&mut self) -> Result<Type> {
1107 if let TokenType::Identifier(name) = &self.advance().token_type {
1108 match name.as_str() {
1109 "string" => Ok(Type::String),
1110 "number" => Ok(Type::Number),
1111 "boolean" => Ok(Type::Boolean),
1112 "datetime" => Ok(Type::DateTime),
1113 "duration" => Ok(Type::Duration),
1114 "size" => Ok(Type::Size),
1115 "any" => Ok(Type::Any),
1116 "list" => {
1117 if self.match_token(&TokenType::LessThan) {
1118 let inner_type = self.parse_type()?;
1119 self.consume_token(TokenType::GreaterThan, "Expected '>' after list type")?;
1120 Ok(Type::List(Box::new(inner_type)))
1121 } else {
1122 Ok(Type::List(Box::new(Type::Any)))
1123 }
1124 }
1125 "map" => {
1126 if self.match_token(&TokenType::LessThan) {
1127 let key_type = self.parse_type()?;
1128 self.consume_token(TokenType::Comma, "Expected ',' between map types")?;
1129 let value_type = self.parse_type()?;
1130 self.consume_token(TokenType::GreaterThan, "Expected '>' after map type")?;
1131 Ok(Type::Map(Box::new(key_type), Box::new(value_type)))
1132 } else {
1133 Ok(Type::Map(Box::new(Type::String), Box::new(Type::Any)))
1134 }
1135 }
1136 _ => Ok(Type::Custom(name.clone())),
1137 }
1138 } else {
1139 Err(ReplError::Parsing("Expected type name".to_string()))
1140 }
1141 }
1142
1143 fn parse_string_literal(&mut self) -> Result<String> {
1145 if let TokenType::String(s) = &self.advance().token_type {
1146 Ok(s.clone())
1147 } else {
1148 Err(ReplError::Parsing("Expected string literal".to_string()))
1149 }
1150 }
1151
1152 fn parse_size_value(&mut self) -> Result<SizeValue> {
1153 if let TokenType::Size(value, unit) = &self.advance().token_type {
1154 let size_unit = match unit.as_str() {
1155 "B" => SizeUnit::Bytes,
1156 "KB" => SizeUnit::KB,
1157 "MB" => SizeUnit::MB,
1158 "GB" => SizeUnit::GB,
1159 "TB" => SizeUnit::TB,
1160 _ => return Err(ReplError::Parsing(format!("Invalid size unit: {}", unit))),
1161 };
1162 Ok(SizeValue {
1163 value: *value,
1164 unit: size_unit,
1165 })
1166 } else {
1167 Err(ReplError::Parsing("Expected size value".to_string()))
1168 }
1169 }
1170
1171 fn parse_duration_value(&mut self) -> Result<DurationValue> {
1172 if let TokenType::Duration(value, unit) = &self.advance().token_type {
1173 let duration_unit = match unit.as_str() {
1174 "ms" => DurationUnit::Milliseconds,
1175 "s" => DurationUnit::Seconds,
1176 "m" => DurationUnit::Minutes,
1177 "h" => DurationUnit::Hours,
1178 "d" => DurationUnit::Days,
1179 _ => {
1180 return Err(ReplError::Parsing(format!(
1181 "Invalid duration unit: {}",
1182 unit
1183 )))
1184 }
1185 };
1186 Ok(DurationValue {
1187 value: *value,
1188 unit: duration_unit,
1189 })
1190 } else {
1191 Err(ReplError::Parsing("Expected duration value".to_string()))
1192 }
1193 }
1194
1195 fn parse_boolean_value(&mut self) -> Result<bool> {
1196 match &self.advance().token_type {
1197 TokenType::Keyword(Keyword::True) => Ok(true),
1198 TokenType::Keyword(Keyword::False) => Ok(false),
1199 TokenType::Keyword(Keyword::Allow) => Ok(true),
1200 _ => Err(ReplError::Parsing("Expected boolean value".to_string())),
1201 }
1202 }
1203
1204 fn parse_integer_value(&mut self) -> Result<u32> {
1205 if let TokenType::Integer(i) = &self.advance().token_type {
1206 Ok(*i as u32)
1207 } else {
1208 Err(ReplError::Parsing("Expected integer value".to_string()))
1209 }
1210 }
1211
1212 fn parse_security_tier(&mut self) -> Result<SecurityTier> {
1213 match &self.advance().token_type {
1214 TokenType::Keyword(Keyword::Tier1) => Ok(SecurityTier::Tier1),
1215 TokenType::Keyword(Keyword::Tier2) => Ok(SecurityTier::Tier2),
1216 TokenType::Keyword(Keyword::Tier3) => Ok(SecurityTier::Tier3),
1217 TokenType::Keyword(Keyword::Tier4) => Ok(SecurityTier::Tier4),
1218 _ => Err(ReplError::Parsing("Expected security tier".to_string())),
1219 }
1220 }
1221
1222 fn parse_sandbox_mode(&mut self) -> Result<SandboxMode> {
1223 match &self.advance().token_type {
1224 TokenType::Keyword(Keyword::Strict) => Ok(SandboxMode::Strict),
1225 TokenType::Keyword(Keyword::Moderate) => Ok(SandboxMode::Moderate),
1226 TokenType::Keyword(Keyword::Permissive) => Ok(SandboxMode::Permissive),
1227 _ => Err(ReplError::Parsing("Expected sandbox mode".to_string())),
1228 }
1229 }
1230
1231 fn parse_failure_action(&mut self) -> Result<FailureAction> {
1232 match &self.advance().token_type {
1233 TokenType::Keyword(Keyword::Terminate) => Ok(FailureAction::Terminate),
1234 TokenType::Keyword(Keyword::Restart) => Ok(FailureAction::Restart),
1235 TokenType::Keyword(Keyword::Escalate) => Ok(FailureAction::Escalate),
1236 TokenType::Keyword(Keyword::Ignore) => Ok(FailureAction::Ignore),
1237 _ => Err(ReplError::Parsing("Expected failure action".to_string())),
1238 }
1239 }
1240
1241 fn parse_string_list(&mut self) -> Result<Vec<String>> {
1242 self.consume_token(TokenType::LeftBracket, "Expected '[' for string list")?;
1243
1244 let mut strings = Vec::new();
1245 while !self.check_token(&TokenType::RightBracket) && !self.is_at_end() {
1246 strings.push(self.parse_string_literal()?);
1247
1248 if !self.check_token(&TokenType::RightBracket) {
1249 self.consume_token(TokenType::Comma, "Expected ',' between list items")?;
1250 }
1251 }
1252
1253 self.consume_token(TokenType::RightBracket, "Expected ']' after string list")?;
1254 Ok(strings)
1255 }
1256
1257 fn parse_argument_list(&mut self) -> Result<Vec<Expression>> {
1258 let mut arguments = Vec::new();
1259
1260 while !self.check_token(&TokenType::RightParen) && !self.is_at_end() {
1261 arguments.push(self.parse_expression()?);
1262
1263 if !self.check_token(&TokenType::RightParen) {
1264 self.consume_token(TokenType::Comma, "Expected ',' between arguments")?;
1265 }
1266 }
1267
1268 Ok(arguments)
1269 }
1270
1271 fn parse_expression_list(&mut self, terminator: &TokenType) -> Result<Vec<Expression>> {
1272 let mut expressions = Vec::new();
1273
1274 while !self.check_token(terminator) && !self.is_at_end() {
1275 expressions.push(self.parse_expression()?);
1276
1277 if !self.check_token(terminator) {
1278 self.consume_token(TokenType::Comma, "Expected ',' between expressions")?;
1279 }
1280 }
1281
1282 Ok(expressions)
1283 }
1284
1285 fn parse_map_entries(&mut self) -> Result<Vec<MapEntry>> {
1286 let mut entries = Vec::new();
1287
1288 while !self.check_token(&TokenType::RightBrace) && !self.is_at_end() {
1289 let entry_start = self.current_span();
1290 let key = self.parse_expression()?;
1291 self.consume_token(TokenType::Colon, "Expected ':' after map key")?;
1292 let value = self.parse_expression()?;
1293 let entry_end = self.previous_span();
1294
1295 entries.push(MapEntry {
1296 key,
1297 value,
1298 span: Span {
1299 start: entry_start.start,
1300 end: entry_end.end,
1301 },
1302 });
1303
1304 if !self.check_token(&TokenType::RightBrace) {
1305 self.consume_token(TokenType::Comma, "Expected ',' between map entries")?;
1306 }
1307 }
1308
1309 Ok(entries)
1310 }
1311
1312 fn match_keyword(&mut self, keyword: Keyword) -> bool {
1314 if let TokenType::Keyword(k) = &self.peek().token_type {
1315 if *k == keyword {
1316 self.advance();
1317 return true;
1318 }
1319 }
1320 false
1321 }
1322
1323 fn match_token(&mut self, token_type: &TokenType) -> bool {
1324 if std::mem::discriminant(&self.peek().token_type) == std::mem::discriminant(token_type) {
1325 self.advance();
1326 true
1327 } else {
1328 false
1329 }
1330 }
1331
1332 fn match_binary_operator(&mut self, operators: &[TokenType]) -> Option<BinaryOperator> {
1333 for op_token in operators {
1334 if std::mem::discriminant(&self.peek().token_type) == std::mem::discriminant(op_token) {
1335 self.advance();
1336 return self.token_to_binary_operator(op_token);
1337 }
1338 }
1339 None
1340 }
1341
1342 fn match_unary_operator(&mut self, operators: &[TokenType]) -> Option<UnaryOperator> {
1343 for op_token in operators {
1344 if std::mem::discriminant(&self.peek().token_type) == std::mem::discriminant(op_token) {
1345 self.advance();
1346 return self.token_to_unary_operator(op_token);
1347 }
1348 }
1349 None
1350 }
1351
1352 fn token_to_binary_operator(&self, token: &TokenType) -> Option<BinaryOperator> {
1353 match token {
1354 TokenType::Plus => Some(BinaryOperator::Add),
1355 TokenType::Minus => Some(BinaryOperator::Subtract),
1356 TokenType::Multiply => Some(BinaryOperator::Multiply),
1357 TokenType::Divide => Some(BinaryOperator::Divide),
1358 TokenType::Modulo => Some(BinaryOperator::Modulo),
1359 TokenType::Equal => Some(BinaryOperator::Equal),
1360 TokenType::NotEqual => Some(BinaryOperator::NotEqual),
1361 TokenType::LessThan => Some(BinaryOperator::LessThan),
1362 TokenType::LessThanOrEqual => Some(BinaryOperator::LessThanOrEqual),
1363 TokenType::GreaterThan => Some(BinaryOperator::GreaterThan),
1364 TokenType::GreaterThanOrEqual => Some(BinaryOperator::GreaterThanOrEqual),
1365 TokenType::And => Some(BinaryOperator::And),
1366 TokenType::Or => Some(BinaryOperator::Or),
1367 _ => None,
1368 }
1369 }
1370
1371 fn token_to_unary_operator(&self, token: &TokenType) -> Option<UnaryOperator> {
1372 match token {
1373 TokenType::Not => Some(UnaryOperator::Not),
1374 TokenType::Minus => Some(UnaryOperator::Negate),
1375 _ => None,
1376 }
1377 }
1378
1379 fn consume_token(&mut self, expected: TokenType, message: &str) -> Result<Token> {
1380 if std::mem::discriminant(&self.peek().token_type) == std::mem::discriminant(&expected) {
1381 Ok(self.advance())
1382 } else {
1383 Err(ReplError::Parsing(format!(
1384 "{}: expected {:?}, found {:?} at line {}",
1385 message,
1386 expected,
1387 self.peek().token_type,
1388 self.peek().line
1389 )))
1390 }
1391 }
1392
1393 fn check_token(&self, token_type: &TokenType) -> bool {
1394 std::mem::discriminant(&self.peek().token_type) == std::mem::discriminant(token_type)
1395 }
1396
1397 fn check_eof(&self) -> bool {
1398 matches!(self.peek().token_type, TokenType::Eof)
1399 }
1400
1401 fn is_at_end(&self) -> bool {
1402 self.current >= self.tokens.len() || matches!(self.peek().token_type, TokenType::Eof)
1403 }
1404
1405 fn peek(&self) -> Token {
1406 if self.current < self.tokens.len() {
1407 self.tokens[self.current].clone()
1408 } else {
1409 Token {
1411 token_type: TokenType::Eof,
1412 line: if self.tokens.is_empty() {
1413 1
1414 } else {
1415 self.tokens.last().unwrap().line
1416 },
1417 column: 0,
1418 offset: if self.tokens.is_empty() {
1419 0
1420 } else {
1421 self.tokens.last().unwrap().offset
1422 },
1423 length: 0,
1424 }
1425 }
1426 }
1427
1428 fn advance(&mut self) -> Token {
1429 if !self.is_at_end() {
1430 self.current += 1;
1431 }
1432 self.previous()
1433 }
1434
1435 fn previous(&self) -> Token {
1436 if self.current > 0 {
1437 self.tokens[self.current - 1].clone()
1438 } else {
1439 self.tokens[0].clone()
1440 }
1441 }
1442
1443 fn skip_trivia(&mut self) {
1444 while !self.is_at_end() {
1445 match &self.peek().token_type {
1446 TokenType::Newline | TokenType::Comment(_) => {
1447 self.advance();
1448 }
1449 _ => break,
1450 }
1451 }
1452 }
1453
1454 fn synchronize(&mut self) {
1455 self.advance();
1456
1457 while !self.is_at_end() {
1458 if matches!(
1459 self.previous().token_type,
1460 TokenType::Semicolon | TokenType::Newline
1461 ) {
1462 return;
1463 }
1464
1465 match &self.peek().token_type {
1466 TokenType::Keyword(Keyword::Agent)
1467 | TokenType::Keyword(Keyword::Behavior)
1468 | TokenType::Keyword(Keyword::Function)
1469 | TokenType::Keyword(Keyword::Struct)
1470 | TokenType::Keyword(Keyword::Let)
1471 | TokenType::Keyword(Keyword::If)
1472 | TokenType::Keyword(Keyword::Return) => return,
1473 _ => {}
1474 }
1475
1476 self.advance();
1477 }
1478 }
1479
1480 fn current_span(&self) -> Span {
1482 let token = self.peek();
1483 self.token_span(&token)
1484 }
1485
1486 fn previous_span(&self) -> Span {
1487 let token = self.previous();
1488 self.token_span(&token)
1489 }
1490
1491 fn token_span(&self, token: &Token) -> Span {
1492 Span {
1493 start: SourceLocation {
1494 line: token.line,
1495 column: token.column,
1496 offset: token.offset,
1497 },
1498 end: SourceLocation {
1499 line: token.line,
1500 column: token.column + token.length,
1501 offset: token.offset + token.length,
1502 },
1503 }
1504 }
1505
1506 fn get_expression_span(&self, expr: &Expression) -> Span {
1507 match expr {
1508 Expression::Literal(_) => self.current_span(),
1509 Expression::Identifier(id) => id.span.clone(),
1510 Expression::FieldAccess(fa) => fa.span.clone(),
1511 Expression::IndexAccess(ia) => ia.span.clone(),
1512 Expression::FunctionCall(fc) => fc.span.clone(),
1513 Expression::MethodCall(mc) => mc.span.clone(),
1514 Expression::BinaryOp(bo) => bo.span.clone(),
1515 Expression::UnaryOp(uo) => uo.span.clone(),
1516 Expression::Assignment(a) => a.span.clone(),
1517 Expression::List(l) => l.span.clone(),
1518 Expression::Map(m) => m.span.clone(),
1519 Expression::Invoke(i) => i.span.clone(),
1520 Expression::Lambda(l) => l.span.clone(),
1521 Expression::Conditional(c) => c.span.clone(),
1522 }
1523 }
1524}
1525
1526#[cfg(test)]
1527mod tests {
1528 use super::*;
1529 use crate::dsl::lexer::Lexer;
1530
1531 fn parse_source(source: &str) -> Result<Program> {
1532 let mut lexer = Lexer::new(source);
1533 let tokens = lexer.tokenize()?;
1534 let mut parser = Parser::new(tokens);
1535 parser.parse()
1536 }
1537
1538 #[test]
1539 fn test_simple_agent() {
1540 let source = r#"
1541 agent TestAgent {
1542 name: "Test Agent"
1543 version: "1.0.0"
1544 }
1545 "#;
1546
1547 let program = parse_source(source).unwrap();
1548 assert_eq!(program.declarations.len(), 1);
1549
1550 if let Declaration::Agent(agent) = &program.declarations[0] {
1551 assert_eq!(agent.name, "TestAgent");
1552 assert_eq!(agent.metadata.name, Some("Test Agent".to_string()));
1553 assert_eq!(agent.metadata.version, Some("1.0.0".to_string()));
1554 } else {
1555 panic!("Expected agent declaration");
1556 }
1557 }
1558
1559 #[test]
1560 fn test_simple_behavior() {
1561 let source = r#"
1562 behavior ProcessData {
1563 input {
1564 data: string
1565 }
1566 output {
1567 result: string
1568 }
1569 steps {
1570 let processed = data.upper()
1571 return processed
1572 }
1573 }
1574 "#;
1575
1576 let program = parse_source(source).unwrap();
1577 assert_eq!(program.declarations.len(), 1);
1578
1579 if let Declaration::Behavior(behavior) = &program.declarations[0] {
1580 assert_eq!(behavior.name, "ProcessData");
1581 assert!(behavior.input.is_some());
1582 assert!(behavior.output.is_some());
1583 assert!(!behavior.steps.statements.is_empty());
1584 } else {
1585 panic!("Expected behavior declaration");
1586 }
1587 }
1588
1589 #[test]
1590 fn test_function_definition() {
1591 let source = r#"
1592 function add(a: number, b: number) -> number {
1593 return a + b
1594 }
1595 "#;
1596
1597 let program = parse_source(source).unwrap();
1598 assert_eq!(program.declarations.len(), 1);
1599
1600 if let Declaration::Function(func) = &program.declarations[0] {
1601 assert_eq!(func.name, "add");
1602 assert_eq!(func.parameters.parameters.len(), 2);
1603 assert!(func.return_type.is_some());
1604 } else {
1605 panic!("Expected function declaration");
1606 }
1607 }
1608}