1use crate::ast::*;
17use crate::ty::TypeExpr;
18use std::fmt::Write;
19
20pub fn format(program: &Program) -> String {
22 let mut formatter = Formatter::new();
23 formatter.format_program(program);
24 formatter.output
25}
26
27struct Formatter {
28 output: String,
29 indent: usize,
30}
31
32impl Formatter {
33 fn new() -> Self {
34 Self {
35 output: String::new(),
36 indent: 0,
37 }
38 }
39
40 fn write(&mut self, s: &str) {
41 self.output.push_str(s);
42 }
43
44 fn writeln(&mut self, s: &str) {
45 self.write_indent();
46 self.output.push_str(s);
47 self.output.push('\n');
48 }
49
50 fn newline(&mut self) {
51 self.output.push('\n');
52 }
53
54 fn write_indent(&mut self) {
55 for _ in 0..self.indent {
56 self.output.push_str(" ");
57 }
58 }
59
60 fn indent(&mut self) {
61 self.indent += 1;
62 }
63
64 fn dedent(&mut self) {
65 self.indent = self.indent.saturating_sub(1);
66 }
67
68 fn format_program(&mut self, program: &Program) {
69 let mut first = true;
70
71 for m in &program.mod_decls {
73 if !first {
74 self.newline();
75 }
76 first = false;
77 self.format_mod_decl(m);
78 }
79
80 for u in &program.use_decls {
82 if !first {
83 self.newline();
84 }
85 first = false;
86 self.format_use_decl(u);
87 }
88
89 for c in &program.consts {
91 if !first {
92 self.newline();
93 }
94 first = false;
95 self.format_const_decl(c);
96 }
97
98 for r in &program.records {
100 if !first {
101 self.newline();
102 }
103 first = false;
104 self.format_record_decl(r);
105 }
106
107 for e in &program.enums {
109 if !first {
110 self.newline();
111 }
112 first = false;
113 self.format_enum_decl(e);
114 }
115
116 for t in &program.tools {
118 if !first {
119 self.newline();
120 }
121 first = false;
122 self.format_tool_decl(t);
123 }
124
125 for f in &program.functions {
127 if !first {
128 self.newline();
129 }
130 first = false;
131 self.format_fn_decl(f);
132 }
133
134 for a in &program.agents {
136 if !first {
137 self.newline();
138 }
139 first = false;
140 self.format_agent_decl(a);
141 }
142
143 for t in &program.tests {
145 if !first {
146 self.newline();
147 }
148 first = false;
149 self.format_test_decl(t);
150 }
151
152 if let Some(run_agent) = &program.run_agent {
154 if !first {
155 self.newline();
156 self.newline();
157 }
158 self.write("run ");
159 self.write(&run_agent.name);
160 self.writeln(";");
161 }
162 }
163
164 fn format_mod_decl(&mut self, m: &ModDecl) {
165 if m.is_pub {
166 self.write("pub ");
167 }
168 self.write("mod ");
169 self.write(&m.name.name);
170 self.writeln(";");
171 }
172
173 fn format_use_decl(&mut self, u: &UseDecl) {
174 if u.is_pub {
175 self.write("pub ");
176 }
177 self.write("use ");
178 self.write(
179 &u.path
180 .iter()
181 .map(|i| i.name.as_str())
182 .collect::<Vec<_>>()
183 .join("::"),
184 );
185 match &u.kind {
186 UseKind::Simple(alias) => {
187 if let Some(a) = alias {
188 self.write(" as ");
189 self.write(&a.name);
190 }
191 }
192 UseKind::Glob => {
193 self.write("::*");
194 }
195 UseKind::Group(names) => {
196 self.write("::{");
197 for (i, (name, alias)) in names.iter().enumerate() {
198 if i > 0 {
199 self.write(", ");
200 }
201 self.write(&name.name);
202 if let Some(a) = alias {
203 self.write(" as ");
204 self.write(&a.name);
205 }
206 }
207 self.write("}");
208 }
209 }
210 self.writeln(";");
211 }
212
213 fn format_const_decl(&mut self, c: &ConstDecl) {
214 if c.is_pub {
215 self.write("pub ");
216 }
217 self.write("const ");
218 self.write(&c.name.name);
219 self.write(": ");
220 self.format_type(&c.ty);
221 self.write(" = ");
222 self.format_expr(&c.value);
223 self.writeln(";");
224 }
225
226 fn format_record_decl(&mut self, r: &RecordDecl) {
227 if r.is_pub {
228 self.write("pub ");
229 }
230 self.write("record ");
231 self.write(&r.name.name);
232 self.write(" {\n");
233 self.indent();
234 for field in &r.fields {
235 self.write_indent();
236 self.write(&field.name.name);
237 self.write(": ");
238 self.format_type(&field.ty);
239 self.write("\n");
240 }
241 self.dedent();
242 self.writeln("}");
243 }
244
245 fn format_enum_decl(&mut self, e: &EnumDecl) {
246 if e.is_pub {
247 self.write("pub ");
248 }
249 self.write("enum ");
250 self.write(&e.name.name);
251 self.write(" {\n");
252 self.indent();
253 for variant in &e.variants {
254 self.write_indent();
255 self.write(&variant.name.name);
256 if let Some(payload) = &variant.payload {
257 self.write("(");
258 self.format_type(payload);
259 self.write(")");
260 }
261 self.write("\n");
262 }
263 self.dedent();
264 self.writeln("}");
265 }
266
267 fn format_tool_decl(&mut self, t: &ToolDecl) {
268 if t.is_pub {
269 self.write("pub ");
270 }
271 self.write("tool ");
272 self.write(&t.name.name);
273 self.write(" {\n");
274 self.indent();
275 for func in &t.functions {
276 self.write_indent();
277 self.write("fn ");
278 self.write(&func.name.name);
279 self.write("(");
280 for (i, param) in func.params.iter().enumerate() {
281 if i > 0 {
282 self.write(", ");
283 }
284 self.write(¶m.name.name);
285 self.write(": ");
286 self.format_type(¶m.ty);
287 }
288 self.write(") -> ");
289 self.format_type(&func.return_ty);
290 self.write("\n");
291 }
292 self.dedent();
293 self.writeln("}");
294 }
295
296 fn format_fn_decl(&mut self, f: &FnDecl) {
297 if f.is_pub {
298 self.write("pub ");
299 }
300 self.write("fn ");
301 self.write(&f.name.name);
302 self.write("(");
303 for (i, param) in f.params.iter().enumerate() {
304 if i > 0 {
305 self.write(", ");
306 }
307 self.write(¶m.name.name);
308 self.write(": ");
309 self.format_type(¶m.ty);
310 }
311 self.write(") -> ");
312 self.format_type(&f.return_ty);
313 if f.is_fallible {
314 self.write(" fails");
315 }
316 self.write(" {\n");
317 self.indent();
318 self.format_block(&f.body);
319 self.dedent();
320 self.writeln("}");
321 }
322
323 fn format_agent_decl(&mut self, agent: &AgentDecl) {
324 if agent.is_pub {
325 self.write("pub ");
326 }
327 self.write("agent ");
328 self.write(&agent.name.name);
329
330 if let Some(recv) = &agent.receives {
332 self.write(" receives ");
333 self.format_type(recv);
334 }
335
336 if !agent.tool_uses.is_empty() {
338 self.write(" uses ");
339 for (i, tool) in agent.tool_uses.iter().enumerate() {
340 if i > 0 {
341 self.write(", ");
342 }
343 self.write(&tool.name);
344 }
345 }
346
347 self.write(" {\n");
348 self.indent();
349
350 for belief in &agent.beliefs {
352 self.write_indent();
353 self.write(&belief.name.name);
354 self.write(": ");
355 self.format_type(&belief.ty);
356 self.write("\n");
357 }
358
359 if !agent.beliefs.is_empty() && !agent.handlers.is_empty() {
361 self.newline();
362 }
363
364 let mut sorted_handlers: Vec<&HandlerDecl> = agent.handlers.iter().collect();
366 sorted_handlers.sort_by_key(|h| match &h.event {
367 EventKind::Start => 0,
368 EventKind::Message { .. } => 1,
369 EventKind::Error { .. } => 2,
370 EventKind::Stop => 3,
371 });
372
373 for (i, handler) in sorted_handlers.iter().enumerate() {
374 if i > 0 {
375 self.newline();
376 }
377 self.format_handler(handler);
378 }
379
380 self.dedent();
381 self.writeln("}");
382 }
383
384 fn format_handler(&mut self, handler: &HandlerDecl) {
385 self.write_indent();
386 match &handler.event {
387 EventKind::Start => {
388 self.write("on start {\n");
389 }
390 EventKind::Message { param_name, param_ty } => {
391 self.write("on message(");
392 self.write(¶m_name.name);
393 self.write(": ");
394 self.format_type(param_ty);
395 self.write(") {\n");
396 }
397 EventKind::Error { param_name } => {
398 self.write("on error(");
399 self.write(¶m_name.name);
400 self.write(": Error) {\n");
401 }
402 EventKind::Stop => {
403 self.write("on stop {\n");
404 }
405 }
406 self.indent();
407 self.format_block(&handler.body);
408 self.dedent();
409 self.writeln("}");
410 }
411
412 fn format_test_decl(&mut self, t: &TestDecl) {
413 self.write("test \"");
414 for c in t.name.chars() {
415 match c {
416 '\\' => self.write("\\\\"),
417 '"' => self.write("\\\""),
418 '\n' => self.write("\\n"),
419 _ => self.output.push(c),
420 }
421 }
422 self.write("\" {\n");
423 self.indent();
424 self.format_block(&t.body);
425 self.dedent();
426 self.writeln("}");
427 }
428
429 fn format_block(&mut self, block: &Block) {
430 for stmt in &block.stmts {
431 self.format_stmt(stmt);
432 }
433 }
434
435 fn format_stmt(&mut self, stmt: &Stmt) {
436 match stmt {
437 Stmt::Let { name, ty, value, .. } => {
438 self.write_indent();
439 self.write("let ");
440 self.write(&name.name);
441 if let Some(t) = ty {
442 self.write(": ");
443 self.format_type(t);
444 }
445 self.write(" = ");
446 self.format_expr(value);
447 self.write(";\n");
448 }
449 Stmt::LetTuple { names, ty, value, .. } => {
450 self.write_indent();
451 self.write("let (");
452 for (i, name) in names.iter().enumerate() {
453 if i > 0 {
454 self.write(", ");
455 }
456 self.write(&name.name);
457 }
458 self.write(")");
459 if let Some(t) = ty {
460 self.write(": ");
461 self.format_type(t);
462 }
463 self.write(" = ");
464 self.format_expr(value);
465 self.write(";\n");
466 }
467 Stmt::Assign { name, value, .. } => {
468 self.write_indent();
469 self.write(&name.name);
470 self.write(" = ");
471 self.format_expr(value);
472 self.write(";\n");
473 }
474 Stmt::Expr { expr, .. } => {
475 self.write_indent();
476 self.format_expr(expr);
477 self.write(";\n");
478 }
479 Stmt::Return { value, .. } => {
480 self.write_indent();
481 self.write("return");
482 if let Some(v) = value {
483 self.write(" ");
484 self.format_expr(v);
485 }
486 self.write(";\n");
487 }
488 Stmt::While { condition, body, .. } => {
489 self.write_indent();
490 self.write("while ");
491 self.format_expr(condition);
492 self.write(" {\n");
493 self.indent();
494 self.format_block(body);
495 self.dedent();
496 self.writeln("}");
497 }
498 Stmt::For { pattern, iter, body, .. } => {
499 self.write_indent();
500 self.write("for ");
501 self.format_pattern(pattern);
502 self.write(" in ");
503 self.format_expr(iter);
504 self.write(" {\n");
505 self.indent();
506 self.format_block(body);
507 self.dedent();
508 self.writeln("}");
509 }
510 Stmt::Loop { body, .. } => {
511 self.writeln("loop {");
512 self.indent();
513 self.format_block(body);
514 self.dedent();
515 self.writeln("}");
516 }
517 Stmt::Break { .. } => {
518 self.writeln("break;");
519 }
520 Stmt::If {
521 condition,
522 then_block,
523 else_block,
524 ..
525 } => {
526 self.write_indent();
527 self.write("if ");
528 self.format_expr(condition);
529 self.write(" {\n");
530 self.indent();
531 self.format_block(then_block);
532 self.dedent();
533 self.write_indent();
534 self.write("}");
535 if let Some(else_b) = else_block {
536 self.write(" else ");
537 match else_b {
538 ElseBranch::ElseIf(if_stmt) => {
539 if let Stmt::If {
541 condition,
542 then_block,
543 else_block,
544 ..
545 } = if_stmt.as_ref()
546 {
547 self.write("if ");
548 self.format_expr(condition);
549 self.write(" {\n");
550 self.indent();
551 self.format_block(then_block);
552 self.dedent();
553 self.write_indent();
554 self.write("}");
555 if let Some(eb) = else_block {
556 self.format_else_branch(eb);
557 }
558 }
559 }
560 ElseBranch::Block(block) => {
561 self.write("{\n");
562 self.indent();
563 self.format_block(block);
564 self.dedent();
565 self.write_indent();
566 self.write("}");
567 }
568 }
569 }
570 self.write("\n");
571 }
572 Stmt::MockInfer { value, .. } => {
573 self.write_indent();
574 self.write("mock infer -> ");
575 self.format_mock_value(value);
576 self.write(";\n");
577 }
578 }
579 }
580
581 fn format_else_branch(&mut self, else_branch: &ElseBranch) {
582 self.write(" else ");
583 match else_branch {
584 ElseBranch::ElseIf(if_stmt) => {
585 if let Stmt::If {
586 condition,
587 then_block,
588 else_block,
589 ..
590 } = if_stmt.as_ref()
591 {
592 self.write("if ");
593 self.format_expr(condition);
594 self.write(" {\n");
595 self.indent();
596 self.format_block(then_block);
597 self.dedent();
598 self.write_indent();
599 self.write("}");
600 if let Some(eb) = else_block {
601 self.format_else_branch(eb);
602 }
603 }
604 }
605 ElseBranch::Block(block) => {
606 self.write("{\n");
607 self.indent();
608 self.format_block(block);
609 self.dedent();
610 self.write_indent();
611 self.write("}");
612 }
613 }
614 }
615
616 fn format_mock_value(&mut self, value: &MockValue) {
617 match value {
618 MockValue::Value(expr) => self.format_expr(expr),
619 MockValue::Fail(expr) => {
620 self.write("fail(");
621 self.format_expr(expr);
622 self.write(")");
623 }
624 }
625 }
626
627 fn format_pattern(&mut self, pattern: &Pattern) {
628 match pattern {
629 Pattern::Wildcard { .. } => self.write("_"),
630 Pattern::Binding { name, .. } => self.write(&name.name),
631 Pattern::Variant {
632 enum_name,
633 variant,
634 payload,
635 ..
636 } => {
637 if let Some(en) = enum_name {
638 self.write(&en.name);
639 self.write("::");
640 }
641 self.write(&variant.name);
642 if let Some(p) = payload {
643 self.write("(");
644 self.format_pattern(p);
645 self.write(")");
646 }
647 }
648 Pattern::Literal { value, .. } => self.format_literal(value),
649 Pattern::Tuple { elements, .. } => {
650 self.write("(");
651 for (i, p) in elements.iter().enumerate() {
652 if i > 0 {
653 self.write(", ");
654 }
655 self.format_pattern(p);
656 }
657 self.write(")");
658 }
659 }
660 }
661
662 fn format_expr(&mut self, expr: &Expr) {
663 match expr {
664 Expr::Literal { value, .. } => self.format_literal(value),
665 Expr::Var { name, .. } => self.write(&name.name),
666 Expr::Binary { left, op, right, .. } => {
667 self.format_expr(left);
668 self.write(" ");
669 self.write(&op.to_string());
670 self.write(" ");
671 self.format_expr(right);
672 }
673 Expr::Unary { op, operand, .. } => {
674 self.write(&op.to_string());
675 self.format_expr(operand);
676 }
677 Expr::Call { name, args, .. } => {
678 self.write(&name.name);
679 self.write("(");
680 for (i, arg) in args.iter().enumerate() {
681 if i > 0 {
682 self.write(", ");
683 }
684 self.format_expr(arg);
685 }
686 self.write(")");
687 }
688 Expr::SelfMethodCall { method, args, .. } => {
689 self.write("self.");
690 self.write(&method.name);
691 self.write("(");
692 for (i, arg) in args.iter().enumerate() {
693 if i > 0 {
694 self.write(", ");
695 }
696 self.format_expr(arg);
697 }
698 self.write(")");
699 }
700 Expr::SelfField { field, .. } => {
701 self.write("self.");
702 self.write(&field.name);
703 }
704 Expr::FieldAccess { object, field, .. } => {
705 self.format_expr(object);
706 self.write(".");
707 self.write(&field.name);
708 }
709 Expr::TupleIndex { tuple, index, .. } => {
710 self.format_expr(tuple);
711 self.write(".");
712 let _ = write!(self.output, "{}", index);
713 }
714 Expr::List { elements, .. } => {
715 self.write("[");
716 for (i, elem) in elements.iter().enumerate() {
717 if i > 0 {
718 self.write(", ");
719 }
720 self.format_expr(elem);
721 }
722 self.write("]");
723 }
724 Expr::Tuple { elements, .. } => {
725 self.write("(");
726 for (i, elem) in elements.iter().enumerate() {
727 if i > 0 {
728 self.write(", ");
729 }
730 self.format_expr(elem);
731 }
732 if elements.len() == 1 {
733 self.write(",");
734 }
735 self.write(")");
736 }
737 Expr::RecordConstruct { name, fields, .. } => {
738 self.write(&name.name);
739 self.write(" { ");
740 for (i, field) in fields.iter().enumerate() {
741 if i > 0 {
742 self.write(", ");
743 }
744 self.write(&field.name.name);
745 self.write(": ");
746 self.format_expr(&field.value);
747 }
748 self.write(" }");
749 }
750 Expr::Map { entries, .. } => {
751 self.write("{");
752 for (i, entry) in entries.iter().enumerate() {
753 if i > 0 {
754 self.write(", ");
755 }
756 self.format_expr(&entry.key);
757 self.write(": ");
758 self.format_expr(&entry.value);
759 }
760 self.write("}");
761 }
762 Expr::VariantConstruct {
763 enum_name,
764 variant,
765 payload,
766 ..
767 } => {
768 self.write(&enum_name.name);
769 self.write(".");
770 self.write(&variant.name);
771 if let Some(p) = payload {
772 self.write("(");
773 self.format_expr(p);
774 self.write(")");
775 }
776 }
777 Expr::Match { scrutinee, arms, .. } => {
778 self.write("match ");
779 self.format_expr(scrutinee);
780 self.write(" {\n");
781 self.indent();
782 for arm in arms {
783 self.format_match_arm(arm);
784 }
785 self.dedent();
786 self.write_indent();
787 self.write("}");
788 }
789 Expr::Closure { params, body, .. } => {
790 self.write("|");
791 for (i, param) in params.iter().enumerate() {
792 if i > 0 {
793 self.write(", ");
794 }
795 self.write(¶m.name.name);
796 if let Some(ty) = ¶m.ty {
797 self.write(": ");
798 self.format_type(ty);
799 }
800 }
801 self.write("| ");
802 self.format_expr(body);
803 }
804 Expr::Paren { inner, .. } => {
805 self.write("(");
806 self.format_expr(inner);
807 self.write(")");
808 }
809 Expr::StringInterp { template, .. } => {
810 self.format_string_template(template);
811 }
812 Expr::Spawn { agent, fields, .. } => {
813 self.write("spawn ");
814 self.write(&agent.name);
815 if fields.is_empty() {
816 self.write(" {}");
817 } else if fields.len() <= 2 {
818 self.write(" { ");
819 for (i, field) in fields.iter().enumerate() {
820 if i > 0 {
821 self.write(", ");
822 }
823 self.write(&field.name.name);
824 self.write(": ");
825 self.format_expr(&field.value);
826 }
827 self.write(" }");
828 } else {
829 self.write(" {\n");
830 self.indent();
831 for field in fields {
832 self.write_indent();
833 self.write(&field.name.name);
834 self.write(": ");
835 self.format_expr(&field.value);
836 self.write(",\n");
837 }
838 self.dedent();
839 self.write_indent();
840 self.write("}");
841 }
842 }
843 Expr::Await { handle, timeout, .. } => {
844 self.write("await ");
845 self.format_expr(handle);
846 if let Some(t) = timeout {
847 self.write(" timeout(");
848 self.format_expr(t);
849 self.write(")");
850 }
851 }
852 Expr::Emit { value, .. } => {
853 self.write("emit(");
854 self.format_expr(value);
855 self.write(")");
856 }
857 Expr::Send { handle, message, .. } => {
858 self.write("send(");
859 self.format_expr(handle);
860 self.write(", ");
861 self.format_expr(message);
862 self.write(")");
863 }
864 Expr::Receive { .. } => {
865 self.write("receive()");
866 }
867 Expr::Infer {
868 template,
869 result_ty,
870 ..
871 } => {
872 self.write("infer(");
873 self.format_string_template(template);
874 if let Some(ty) = result_ty {
875 self.write(" -> ");
876 self.format_type(ty);
877 }
878 self.write(")");
879 }
880 Expr::Try { expr, .. } => {
881 self.write("try ");
882 self.format_expr(expr);
883 }
884 Expr::Catch {
885 expr,
886 error_bind,
887 recovery,
888 ..
889 } => {
890 self.format_expr(expr);
891 self.write(" catch");
892 if let Some(name) = error_bind {
893 self.write("(");
894 self.write(&name.name);
895 self.write(")");
896 }
897 self.write(" { ");
898 self.format_expr(recovery);
899 self.write(" }");
900 }
901 Expr::Fail { error, .. } => {
902 self.write("fail ");
903 self.format_expr(error);
904 }
905 Expr::Retry {
906 count, delay, body, ..
907 } => {
908 self.write("retry(");
909 self.format_expr(count);
910 if let Some(d) = delay {
911 self.write(", delay: ");
912 self.format_expr(d);
913 }
914 self.write(") {\n");
915 self.indent();
916 self.write_indent();
917 self.format_expr(body);
918 self.write("\n");
919 self.dedent();
920 self.write_indent();
921 self.write("}");
922 }
923 Expr::Trace { message, .. } => {
924 self.write("trace(");
925 self.format_expr(message);
926 self.write(")");
927 }
928 Expr::ToolCall {
929 tool,
930 function,
931 args,
932 ..
933 } => {
934 self.write(&tool.name);
935 self.write(".");
936 self.write(&function.name);
937 self.write("(");
938 for (i, arg) in args.iter().enumerate() {
939 if i > 0 {
940 self.write(", ");
941 }
942 self.format_expr(arg);
943 }
944 self.write(")");
945 }
946 }
947 }
948
949 fn format_string_template(&mut self, template: &StringTemplate) {
950 self.write("\"");
951 for part in &template.parts {
952 match part {
953 StringPart::Literal(s) => {
954 for c in s.chars() {
955 match c {
956 '\\' => self.write("\\\\"),
957 '"' => self.write("\\\""),
958 '\n' => self.write("\\n"),
959 '\r' => self.write("\\r"),
960 '\t' => self.write("\\t"),
961 '{' => self.write("{{"),
962 '}' => self.write("}}"),
963 _ => self.output.push(c),
964 }
965 }
966 }
967 StringPart::Interpolation(interp) => {
968 self.write("{");
969 self.format_interp_expr(interp);
970 self.write("}");
971 }
972 }
973 }
974 self.write("\"");
975 }
976
977 fn format_interp_expr(&mut self, interp: &InterpExpr) {
978 match interp {
979 InterpExpr::Ident(ident) => {
980 self.write(&ident.name);
981 }
982 InterpExpr::FieldAccess { base, field, .. } => {
983 self.format_interp_expr(base);
984 self.write(".");
985 self.write(&field.name);
986 }
987 InterpExpr::TupleIndex { base, index, .. } => {
988 self.format_interp_expr(base);
989 self.write(".");
990 let _ = write!(self.output, "{}", index);
991 }
992 }
993 }
994
995 fn format_match_arm(&mut self, arm: &MatchArm) {
996 self.write_indent();
997 self.format_pattern(&arm.pattern);
998 self.write(" => ");
999 self.format_expr(&arm.body);
1000 self.write(",\n");
1001 }
1002
1003 fn format_literal(&mut self, lit: &Literal) {
1004 match lit {
1005 Literal::Int(n) => {
1006 let _ = write!(self.output, "{}", n);
1007 }
1008 Literal::Float(f) => {
1009 let _ = write!(self.output, "{}", f);
1010 }
1011 Literal::String(s) => {
1012 self.write("\"");
1013 for c in s.chars() {
1014 match c {
1015 '\\' => self.write("\\\\"),
1016 '"' => self.write("\\\""),
1017 '\n' => self.write("\\n"),
1018 '\r' => self.write("\\r"),
1019 '\t' => self.write("\\t"),
1020 _ => self.output.push(c),
1021 }
1022 }
1023 self.write("\"");
1024 }
1025 Literal::Bool(b) => {
1026 self.write(if *b { "true" } else { "false" });
1027 }
1028 }
1029 }
1030
1031 fn format_type(&mut self, ty: &TypeExpr) {
1032 match ty {
1033 TypeExpr::Int => self.write("Int"),
1034 TypeExpr::Float => self.write("Float"),
1035 TypeExpr::Bool => self.write("Bool"),
1036 TypeExpr::String => self.write("String"),
1037 TypeExpr::Unit => self.write("Unit"),
1038 TypeExpr::Error => self.write("Error"),
1039 TypeExpr::Named(name) => self.write(&name.name),
1040 TypeExpr::List(inner) => {
1041 self.write("List<");
1042 self.format_type(inner);
1043 self.write(">");
1044 }
1045 TypeExpr::Option(inner) => {
1046 self.write("Option<");
1047 self.format_type(inner);
1048 self.write(">");
1049 }
1050 TypeExpr::Result(ok, err) => {
1051 self.write("Result<");
1052 self.format_type(ok);
1053 self.write(", ");
1054 self.format_type(err);
1055 self.write(">");
1056 }
1057 TypeExpr::Tuple(types) => {
1058 self.write("(");
1059 for (i, t) in types.iter().enumerate() {
1060 if i > 0 {
1061 self.write(", ");
1062 }
1063 self.format_type(t);
1064 }
1065 self.write(")");
1066 }
1067 TypeExpr::Inferred(inner) => {
1068 self.write("Inferred<");
1069 self.format_type(inner);
1070 self.write(">");
1071 }
1072 TypeExpr::Fn(params, ret) => {
1073 self.write("Fn(");
1074 for (i, p) in params.iter().enumerate() {
1075 if i > 0 {
1076 self.write(", ");
1077 }
1078 self.format_type(p);
1079 }
1080 self.write(") -> ");
1081 self.format_type(ret);
1082 }
1083 TypeExpr::Map(key, value) => {
1084 self.write("Map<");
1085 self.format_type(key);
1086 self.write(", ");
1087 self.format_type(value);
1088 self.write(">");
1089 }
1090 TypeExpr::Agent(name) => {
1091 self.write("Agent<");
1092 self.write(&name.name);
1093 self.write(">");
1094 }
1095 }
1096 }
1097}
1098
1099#[cfg(test)]
1100mod tests {
1101 use super::*;
1102 use crate::{lex, parse};
1103 use std::sync::Arc;
1104
1105 fn format_source(source: &str) -> String {
1106 let lex_result = lex(source).unwrap();
1107 let source_arc: Arc<str> = Arc::from(source);
1108 let (program, errors) = parse(lex_result.tokens(), source_arc);
1109 assert!(errors.is_empty(), "Parse errors: {:?}", errors);
1110 let program = program.unwrap();
1111 format(&program)
1112 }
1113
1114 #[test]
1115 fn test_format_simple_agent() {
1116 let source = r#"agent Greeter{name:String on start{print("Hello");emit(0);}}run Greeter;"#;
1117 let formatted = format_source(source);
1118 assert!(formatted.contains("agent Greeter {"));
1119 assert!(formatted.contains(" name: String"));
1120 assert!(formatted.contains(" on start {"));
1121 }
1122
1123 #[test]
1124 fn test_format_binary_operators() {
1125 let source = r#"agent Test{on start{let x=1+2*3;emit(x);}}run Test;"#;
1126 let formatted = format_source(source);
1127 assert!(formatted.contains("1 + 2 * 3"));
1128 }
1129}