1use crate::errors::Span;
5
6#[derive(Debug, Clone)]
8pub struct Program {
9 pub imports: Vec<Import>,
10 pub items: Vec<Item>,
11}
12
13#[derive(Debug, Clone)]
15pub struct Import {
16 pub path: Vec<String>, pub items: Option<Vec<String>>, pub alias: Option<String>, pub span: Span,
20}
21
22#[derive(Debug, Clone)]
24pub enum Item {
25 Function(Function),
26 Struct(StructDef),
27 Enum(EnumDef),
28 Trait(TraitDef),
29 Impl(ImplBlock),
30 TypeAlias(TypeAlias),
31 Macro(MacroDef),
32}
33
34#[derive(Debug, Clone, PartialEq)]
36pub enum Visibility {
37 Public,
38 Private,
39}
40
41#[derive(Debug, Clone)]
43pub enum GenericParam {
44 Type(String),
46 Const { name: String, ty: Type },
48}
49
50#[derive(Debug, Clone, PartialEq)]
52pub enum ArraySize {
53 Literal(usize),
55 ConstParam(String),
57 Expr(Box<Expr>),
59}
60
61impl std::fmt::Display for ArraySize {
62 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63 match self {
64 ArraySize::Literal(n) => write!(f, "{}", n),
65 ArraySize::ConstParam(name) => write!(f, "{}", name),
66 ArraySize::Expr(_) => write!(f, "<expr>"), }
68 }
69}
70
71#[derive(Debug, Clone, PartialEq)]
73pub enum GenericArg {
74 Type(Type),
76 Const(ConstValue),
78}
79
80impl std::fmt::Display for GenericArg {
81 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82 match self {
83 GenericArg::Type(t) => write!(f, "{}", t),
84 GenericArg::Const(c) => match c {
85 ConstValue::Integer(n) => write!(f, "{}", n),
86 ConstValue::ConstParam(name) => write!(f, "{}", name),
87 },
88 }
89 }
90}
91
92#[derive(Debug, Clone, PartialEq)]
94pub enum ConstValue {
95 Integer(i64),
97 ConstParam(String),
99}
100
101#[derive(Debug, Clone)]
103pub struct Param {
104 pub name: String,
105 pub ty: Type,
106 pub mutable: bool,
107}
108
109#[derive(Debug, Clone)]
111pub struct Function {
112 pub visibility: Visibility,
113 pub is_async: bool,
114 pub name: String,
115 pub lifetime_params: Vec<String>, pub type_params: Vec<String>, pub const_params: Vec<(String, Type)>, pub params: Vec<Param>,
119 pub return_type: Option<Type>,
120 pub body: Vec<Stmt>,
121 pub span: Span,
122 pub effects: Option<Vec<String>>, }
124
125#[derive(Debug, Clone)]
127pub struct StructDef {
128 pub visibility: Visibility,
129 pub name: String,
130 pub lifetime_params: Vec<String>, pub type_params: Vec<String>, pub const_params: Vec<(String, Type)>, pub fields: Vec<(String, Type)>,
134 pub span: Span,
135}
136
137#[derive(Debug, Clone)]
139pub struct EnumDef {
140 pub name: String,
141 pub lifetime_params: Vec<String>, pub type_params: Vec<String>, pub const_params: Vec<(String, Type)>, pub variants: Vec<EnumVariant>,
145 pub span: Span,
146}
147
148#[derive(Debug, Clone)]
150pub struct EnumVariant {
151 pub name: String,
152 pub data: EnumVariantData,
153}
154
155#[derive(Debug, Clone)]
157pub enum EnumVariantData {
158 Unit,
160 Tuple(Vec<Type>),
162 Struct(Vec<(String, Type)>),
164}
165
166#[derive(Debug, Clone)]
168pub struct TraitDef {
169 pub visibility: Visibility,
170 pub name: String,
171 pub lifetime_params: Vec<String>,
172 pub type_params: Vec<String>,
173 pub methods: Vec<TraitMethod>,
174 pub span: Span,
175}
176
177#[derive(Debug, Clone)]
179pub struct TraitMethod {
180 pub name: String,
181 pub lifetime_params: Vec<String>,
182 pub type_params: Vec<String>,
183 pub params: Vec<Param>,
184 pub return_type: Option<Type>,
185 pub has_body: bool,
186 pub body: Option<Vec<Stmt>>,
187 pub span: Span,
188}
189
190#[derive(Debug, Clone)]
192pub struct ImplBlock {
193 pub lifetime_params: Vec<String>,
194 pub type_params: Vec<String>,
195 pub trait_type: Option<Type>, pub for_type: Type,
197 pub methods: Vec<Function>,
198 pub span: Span,
199}
200
201#[derive(Debug, Clone)]
203pub struct TypeAlias {
204 pub visibility: Visibility,
205 pub name: String,
206 pub lifetime_params: Vec<String>, pub type_params: Vec<String>, pub ty: Type,
209 pub span: Span,
210}
211
212#[derive(Debug, Clone, PartialEq)]
214pub enum Type {
215 I32,
217 I64,
218 U32,
219 U64,
220 Bool,
221 String,
222 Unit,
224 Array(Box<Type>, ArraySize),
226 Custom(String),
228 TypeParam(String),
230 Generic {
232 name: String,
233 args: Vec<GenericArg>,
234 },
235 Reference {
237 lifetime: Option<String>,
238 mutable: bool,
239 inner: Box<Type>,
240 },
241 Future {
243 output: Box<Type>,
244 },
245}
246
247#[derive(Debug, Clone)]
249pub enum Stmt {
250 Expr(Expr),
252 Return(Option<Expr>),
254 Let {
256 name: String,
257 ty: Option<Type>,
258 value: Expr,
259 mutable: bool,
260 span: Span,
261 },
262 Assign {
264 target: AssignTarget,
265 value: Expr,
266 span: Span,
267 },
268 If {
270 condition: Expr,
271 then_branch: Vec<Stmt>,
272 else_branch: Option<Vec<Stmt>>,
273 span: Span,
274 },
275 While {
277 condition: Expr,
278 body: Vec<Stmt>,
279 span: Span,
280 },
281 For {
283 var: String,
284 iter: Expr,
285 body: Vec<Stmt>,
286 span: Span,
287 },
288 Break { span: Span },
290 Continue { span: Span },
292 Match {
294 expr: Expr,
295 arms: Vec<MatchArm>,
296 span: Span,
297 },
298 Unsafe { body: Vec<Stmt>, span: Span },
300}
301
302#[derive(Debug, Clone)]
304pub struct MatchArm {
305 pub pattern: Pattern,
306 pub body: Vec<Stmt>,
307}
308
309#[derive(Debug, Clone, PartialEq)]
311pub enum Pattern {
312 Wildcard,
314 Ident(String),
316 EnumPattern {
318 enum_name: String,
319 variant: String,
320 data: Option<PatternData>,
321 },
322}
323
324#[derive(Debug, Clone, PartialEq)]
326pub enum PatternData {
327 Tuple(Vec<Pattern>),
329 Struct(Vec<(String, Pattern)>),
331}
332
333#[derive(Debug, Clone, PartialEq)]
335pub enum Expr {
336 String(String),
338 Integer(i64),
340 Bool(bool),
342 Ident(String),
344 ArrayLiteral { elements: Vec<Expr>, span: Span },
346 ArrayRepeat {
348 value: Box<Expr>,
349 count: Box<Expr>,
350 span: Span,
351 },
352 Index {
354 array: Box<Expr>,
355 index: Box<Expr>,
356 span: Span,
357 },
358 Call {
360 func: Box<Expr>,
361 args: Vec<Expr>,
362 span: Span,
363 },
364 Binary {
366 left: Box<Expr>,
367 op: BinOp,
368 right: Box<Expr>,
369 span: Span,
370 },
371 Unary {
373 op: UnaryOp,
374 operand: Box<Expr>,
375 span: Span,
376 },
377 StructLiteral {
379 name: String,
380 fields: Vec<(String, Expr)>,
381 span: Span,
382 },
383 FieldAccess {
385 object: Box<Expr>,
386 field: String,
387 span: Span,
388 },
389 EnumConstructor {
391 enum_name: String,
392 variant: String,
393 data: Option<EnumConstructorData>,
394 span: Span,
395 },
396 Range {
398 start: Box<Expr>,
399 end: Box<Expr>,
400 span: Span,
401 },
402 Reference {
404 mutable: bool,
405 expr: Box<Expr>,
406 span: Span,
407 },
408 Deref { expr: Box<Expr>, span: Span },
410 Question { expr: Box<Expr>, span: Span },
412 MacroInvocation {
414 name: String,
415 args: Vec<Token>, span: Span,
417 },
418 Await { expr: Box<Expr>, span: Span },
420}
421
422#[derive(Debug, Clone, PartialEq)]
424pub enum EnumConstructorData {
425 Tuple(Vec<Expr>),
427 Struct(Vec<(String, Expr)>),
429}
430
431#[derive(Debug, Clone)]
433pub enum AssignTarget {
434 Ident(String),
436 Index { array: Box<Expr>, index: Box<Expr> },
438 FieldAccess { object: Box<Expr>, field: String },
440 Deref { expr: Box<Expr> },
442}
443
444#[derive(Debug, Clone, Copy, PartialEq, Eq)]
446pub enum BinOp {
447 Add,
448 Sub,
449 Mul,
450 Div,
451 Mod,
452 Eq,
453 Ne,
454 Lt,
455 Gt,
456 Le,
457 Ge,
458 And,
459 Or,
460}
461
462#[derive(Debug, Clone, Copy, PartialEq, Eq)]
464pub enum UnaryOp {
465 Neg,
467 Not,
469}
470
471impl Expr {
472 pub fn span(&self) -> Span {
473 match self {
474 Expr::String(_) => Span::dummy(), Expr::Integer(_) => Span::dummy(),
476 Expr::Bool(_) => Span::dummy(),
477 Expr::Ident(_) => Span::dummy(),
478 Expr::ArrayLiteral { span, .. } => *span,
479 Expr::ArrayRepeat { span, .. } => *span,
480 Expr::Index { span, .. } => *span,
481 Expr::Call { span, .. } => *span,
482 Expr::Binary { span, .. } => *span,
483 Expr::Unary { span, .. } => *span,
484 Expr::StructLiteral { span, .. } => *span,
485 Expr::FieldAccess { span, .. } => *span,
486 Expr::EnumConstructor { span, .. } => *span,
487 Expr::Range { span, .. } => *span,
488 Expr::Reference { span, .. } => *span,
489 Expr::Deref { span, .. } => *span,
490 Expr::Question { span, .. } => *span,
491 Expr::MacroInvocation { span, .. } => *span,
492 Expr::Await { span, .. } => *span,
493 }
494 }
495}
496
497pub trait Visitor<T> {
499 fn visit_program(&mut self, program: &Program) -> T;
500 fn visit_function(&mut self, func: &Function) -> T;
501 fn visit_stmt(&mut self, stmt: &Stmt) -> T;
502 fn visit_expr(&mut self, expr: &Expr) -> T;
503}
504
505impl std::fmt::Display for Program {
507 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
508 for item in &self.items {
509 writeln!(f, "{}", item)?;
510 }
511 Ok(())
512 }
513}
514
515impl std::fmt::Display for Item {
516 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
517 match self {
518 Item::Function(func) => write!(f, "{}", func),
519 Item::Struct(struct_def) => write!(f, "{}", struct_def),
520 Item::Enum(enum_def) => write!(f, "{}", enum_def),
521 Item::Trait(trait_def) => write!(f, "{}", trait_def),
522 Item::Impl(impl_block) => write!(f, "{}", impl_block),
523 Item::TypeAlias(type_alias) => write!(f, "{}", type_alias),
524 Item::Macro(macro_def) => write!(f, "{}", macro_def),
525 }
526 }
527}
528
529impl std::fmt::Display for Function {
530 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
531 write!(f, "fn {}(", self.name)?;
532 for (i, param) in self.params.iter().enumerate() {
533 if i > 0 {
534 write!(f, ", ")?;
535 }
536 if param.mutable {
537 write!(f, "mut ")?;
538 }
539 write!(f, "{}: {}", param.name, param.ty)?;
540 }
541 write!(f, ")")?;
542 if let Some(ret_type) = &self.return_type {
543 write!(f, " -> {}", ret_type)?;
544 }
545 writeln!(f, " {{")?;
546 for stmt in &self.body {
547 writeln!(f, " {}", stmt)?;
548 }
549 write!(f, "}}")
550 }
551}
552
553impl std::fmt::Display for StructDef {
554 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
555 write!(f, "struct {} {{", self.name)?;
556 for (i, (field_name, field_type)) in self.fields.iter().enumerate() {
557 if i == 0 {
558 writeln!(f)?;
559 }
560 writeln!(f, " {}: {},", field_name, field_type)?;
561 }
562 write!(f, "}}")
563 }
564}
565
566impl std::fmt::Display for EnumDef {
567 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
568 write!(f, "enum {} {{", self.name)?;
569 for (i, variant) in self.variants.iter().enumerate() {
570 if i == 0 {
571 writeln!(f)?;
572 }
573 write!(f, " {}", variant.name)?;
574 match &variant.data {
575 EnumVariantData::Unit => {}
576 EnumVariantData::Tuple(types) => {
577 write!(f, "(")?;
578 for (j, ty) in types.iter().enumerate() {
579 if j > 0 {
580 write!(f, ", ")?;
581 }
582 write!(f, "{}", ty)?;
583 }
584 write!(f, ")")?;
585 }
586 EnumVariantData::Struct(fields) => {
587 write!(f, " {{ ")?;
588 for (j, (fname, ftype)) in fields.iter().enumerate() {
589 if j > 0 {
590 write!(f, ", ")?;
591 }
592 write!(f, "{}: {}", fname, ftype)?;
593 }
594 write!(f, " }}")?;
595 }
596 }
597 writeln!(f, ",")?;
598 }
599 write!(f, "}}")
600 }
601}
602
603#[derive(Debug, Clone)]
605pub struct MacroDef {
606 pub name: String,
607 pub params: Vec<String>, pub body: Vec<Token>, pub span: Span,
610}
611
612#[derive(Debug, Clone, PartialEq)]
614pub enum Token {
615 Ident(String),
616 Literal(String),
617 Punct(char),
618 Group(Delimiter, Vec<Token>),
619}
620
621#[derive(Debug, Clone, PartialEq)]
623pub enum Delimiter {
624 Paren, Brace, Bracket, }
628
629impl std::fmt::Display for MacroDef {
630 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
631 write!(f, "macro {}! {{ ... }}", self.name)
632 }
633}
634
635impl std::fmt::Display for Type {
636 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
637 match self {
638 Type::I32 => write!(f, "i32"),
639 Type::I64 => write!(f, "i64"),
640 Type::U32 => write!(f, "u32"),
641 Type::U64 => write!(f, "u64"),
642 Type::Bool => write!(f, "bool"),
643 Type::String => write!(f, "String"),
644 Type::Unit => write!(f, "()"),
645 Type::Array(elem_type, size) => write!(f, "[{}; {}]", elem_type, size),
646 Type::Custom(name) => write!(f, "{}", name),
647 Type::TypeParam(name) => write!(f, "{}", name),
648 Type::Generic { name, args } => {
649 write!(f, "{}<", name)?;
650 for (i, arg) in args.iter().enumerate() {
651 if i > 0 {
652 write!(f, ", ")?;
653 }
654 write!(f, "{}", arg)?;
655 }
656 write!(f, ">")
657 }
658 Type::Reference {
659 lifetime,
660 mutable,
661 inner,
662 } => {
663 write!(f, "&")?;
664 if let Some(lt) = lifetime {
665 write!(f, "'{} ", lt)?;
666 }
667 if *mutable {
668 write!(f, "mut ")?;
669 }
670 write!(f, "{}", inner)
671 }
672 Type::Future { output } => write!(f, "Future<{}>", output),
673 }
674 }
675}
676
677impl std::fmt::Display for TraitDef {
678 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
679 let vis = match self.visibility {
680 Visibility::Public => "pub ",
681 Visibility::Private => "",
682 };
683 write!(f, "{}trait {}", vis, self.name)?;
684
685 if !self.lifetime_params.is_empty() || !self.type_params.is_empty() {
687 write!(f, "<")?;
688 let mut first = true;
689 for lt in &self.lifetime_params {
690 if !first {
691 write!(f, ", ")?;
692 }
693 write!(f, "{}", lt)?;
694 first = false;
695 }
696 for tp in &self.type_params {
697 if !first {
698 write!(f, ", ")?;
699 }
700 write!(f, "{}", tp)?;
701 first = false;
702 }
703 write!(f, ">")?;
704 }
705
706 writeln!(f, " {{")?;
707 for method in &self.methods {
708 write!(f, " fn {}", method.name)?;
709
710 if !method.lifetime_params.is_empty() || !method.type_params.is_empty() {
712 write!(f, "<")?;
713 let mut first = true;
714 for lt in &method.lifetime_params {
715 if !first {
716 write!(f, ", ")?;
717 }
718 write!(f, "{}", lt)?;
719 first = false;
720 }
721 for tp in &method.type_params {
722 if !first {
723 write!(f, ", ")?;
724 }
725 write!(f, "{}", tp)?;
726 first = false;
727 }
728 write!(f, ">")?;
729 }
730
731 write!(f, "(")?;
732 for (i, param) in method.params.iter().enumerate() {
733 if i > 0 {
734 write!(f, ", ")?;
735 }
736 if param.mutable {
737 write!(f, "mut ")?;
738 }
739 write!(f, "{}: {}", param.name, param.ty)?;
740 }
741 write!(f, ")")?;
742
743 if let Some(ret) = &method.return_type {
744 write!(f, " -> {}", ret)?;
745 }
746
747 if method.has_body {
748 writeln!(f, " {{ ... }}")?;
749 } else {
750 writeln!(f, ";")?;
751 }
752 }
753 write!(f, "}}")
754 }
755}
756
757impl std::fmt::Display for ImplBlock {
758 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
759 write!(f, "impl")?;
760
761 if !self.lifetime_params.is_empty() || !self.type_params.is_empty() {
763 write!(f, "<")?;
764 let mut first = true;
765 for lt in &self.lifetime_params {
766 if !first {
767 write!(f, ", ")?;
768 }
769 write!(f, "{}", lt)?;
770 first = false;
771 }
772 for tp in &self.type_params {
773 if !first {
774 write!(f, ", ")?;
775 }
776 write!(f, "{}", tp)?;
777 first = false;
778 }
779 write!(f, ">")?;
780 }
781
782 if let Some(trait_type) = &self.trait_type {
783 write!(f, " {} for", trait_type)?;
784 }
785
786 write!(f, " {} {{", self.for_type)?;
787
788 for method in &self.methods {
789 writeln!(f)?;
790 write!(f, " {}", method)?;
791 }
792
793 write!(f, "\n}}")
794 }
795}
796
797impl std::fmt::Display for TypeAlias {
798 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
799 let vis = match self.visibility {
800 Visibility::Public => "pub ",
801 Visibility::Private => "",
802 };
803 write!(f, "{}type {}", vis, self.name)?;
804
805 if !self.lifetime_params.is_empty() || !self.type_params.is_empty() {
807 write!(f, "<")?;
808 let mut first = true;
809 for lt in &self.lifetime_params {
810 if !first {
811 write!(f, ", ")?;
812 }
813 write!(f, "{}", lt)?;
814 first = false;
815 }
816 for tp in &self.type_params {
817 if !first {
818 write!(f, ", ")?;
819 }
820 write!(f, "{}", tp)?;
821 first = false;
822 }
823 write!(f, ">")?;
824 }
825
826 write!(f, " = {};", self.ty)
827 }
828}
829
830impl std::fmt::Display for Stmt {
831 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
832 match self {
833 Stmt::Expr(expr) => write!(f, "{};", expr),
834 Stmt::Return(None) => write!(f, "return;"),
835 Stmt::Return(Some(expr)) => write!(f, "return {};", expr),
836 Stmt::Let {
837 name,
838 ty,
839 value,
840 mutable,
841 ..
842 } => {
843 let mut_str = if *mutable { "mut " } else { "" };
844 if let Some(ty) = ty {
845 write!(f, "let {}{}: {} = {};", mut_str, name, ty, value)
846 } else {
847 write!(f, "let {}{} = {};", mut_str, name, value)
848 }
849 }
850 Stmt::Assign { target, value, .. } => match target {
851 AssignTarget::Ident(name) => write!(f, "{} = {};", name, value),
852 AssignTarget::Index { array, index } => {
853 write!(f, "{}[{}] = {};", array, index, value)
854 }
855 AssignTarget::FieldAccess { object, field } => {
856 write!(f, "{}.{} = {};", object, field, value)
857 }
858 AssignTarget::Deref { expr } => {
859 write!(f, "*{} = {};", expr, value)
860 }
861 },
862 Stmt::If {
863 condition,
864 then_branch,
865 else_branch,
866 ..
867 } => {
868 write!(f, "if {} {{", condition)?;
869 for stmt in then_branch {
870 write!(f, " {} ", stmt)?;
871 }
872 write!(f, "}}")?;
873 if let Some(else_stmts) = else_branch {
874 write!(f, " else {{")?;
875 for stmt in else_stmts {
876 write!(f, " {} ", stmt)?;
877 }
878 write!(f, "}}")?;
879 }
880 Ok(())
881 }
882 Stmt::While {
883 condition, body, ..
884 } => {
885 write!(f, "while {} {{", condition)?;
886 for stmt in body {
887 write!(f, " {} ", stmt)?;
888 }
889 write!(f, "}}")
890 }
891 Stmt::For {
892 var, iter, body, ..
893 } => {
894 write!(f, "for {} in {} {{", var, iter)?;
895 for stmt in body {
896 write!(f, " {} ", stmt)?;
897 }
898 write!(f, "}}")
899 }
900 Stmt::Break { .. } => write!(f, "break;"),
901 Stmt::Continue { .. } => write!(f, "continue;"),
902 Stmt::Match { expr, arms, .. } => {
903 writeln!(f, "match {} {{", expr)?;
904 for arm in arms {
905 write!(f, " {} => ", arm.pattern)?;
906 if arm.body.len() == 1 {
907 if let Stmt::Expr(e) = &arm.body[0] {
908 writeln!(f, "{},", e)?;
909 } else {
910 writeln!(f, "{{")?;
911 for stmt in &arm.body {
912 writeln!(f, " {}", stmt)?;
913 }
914 writeln!(f, " }}")?;
915 }
916 } else {
917 writeln!(f, "{{")?;
918 for stmt in &arm.body {
919 writeln!(f, " {}", stmt)?;
920 }
921 writeln!(f, " }}")?;
922 }
923 }
924 write!(f, "}}")
925 }
926 Stmt::Unsafe { body, .. } => {
927 writeln!(f, "unsafe {{")?;
928 for stmt in body {
929 writeln!(f, " {}", stmt)?;
930 }
931 write!(f, "}}")
932 }
933 }
934 }
935}
936
937impl std::fmt::Display for Expr {
938 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
939 match self {
940 Expr::String(s) => write!(f, "\"{}\"", s),
941 Expr::Integer(n) => write!(f, "{}", n),
942 Expr::Bool(b) => write!(f, "{}", b),
943 Expr::Ident(name) => write!(f, "{}", name),
944 Expr::ArrayLiteral { elements, .. } => {
945 write!(f, "[")?;
946 for (i, elem) in elements.iter().enumerate() {
947 if i > 0 {
948 write!(f, ", ")?;
949 }
950 write!(f, "{}", elem)?;
951 }
952 write!(f, "]")
953 }
954 Expr::ArrayRepeat { value, count, .. } => {
955 write!(f, "[{}; {}]", value, count)
956 }
957 Expr::Index { array, index, .. } => {
958 write!(f, "{}[{}]", array, index)
959 }
960 Expr::Call { func, args, .. } => {
961 write!(f, "{}(", func)?;
962 for (i, arg) in args.iter().enumerate() {
963 if i > 0 {
964 write!(f, ", ")?;
965 }
966 write!(f, "{}", arg)?;
967 }
968 write!(f, ")")
969 }
970 Expr::Binary {
971 left, op, right, ..
972 } => {
973 write!(f, "({} {} {})", left, op, right)
974 }
975 Expr::Unary { op, operand, .. } => {
976 write!(f, "({}{})", op, operand)
977 }
978 Expr::StructLiteral { name, fields, .. } => {
979 write!(f, "{} {{ ", name)?;
980 for (i, (field_name, field_expr)) in fields.iter().enumerate() {
981 if i > 0 {
982 write!(f, ", ")?;
983 }
984 write!(f, "{}: {}", field_name, field_expr)?;
985 }
986 write!(f, " }}")
987 }
988 Expr::FieldAccess { object, field, .. } => {
989 write!(f, "{}.{}", object, field)
990 }
991 Expr::EnumConstructor {
992 enum_name,
993 variant,
994 data,
995 ..
996 } => {
997 write!(f, "{}::{}", enum_name, variant)?;
998 match data {
999 Some(EnumConstructorData::Tuple(args)) => {
1000 write!(f, "(")?;
1001 for (i, arg) in args.iter().enumerate() {
1002 if i > 0 {
1003 write!(f, ", ")?;
1004 }
1005 write!(f, "{}", arg)?;
1006 }
1007 write!(f, ")")
1008 }
1009 Some(EnumConstructorData::Struct(fields)) => {
1010 write!(f, " {{ ")?;
1011 for (i, (fname, fexpr)) in fields.iter().enumerate() {
1012 if i > 0 {
1013 write!(f, ", ")?;
1014 }
1015 write!(f, "{}: {}", fname, fexpr)?;
1016 }
1017 write!(f, " }}")
1018 }
1019 None => Ok(()),
1020 }
1021 }
1022 Expr::Range { start, end, .. } => {
1023 write!(f, "{}..{}", start, end)
1024 }
1025 Expr::Reference { mutable, expr, .. } => {
1026 if *mutable {
1027 write!(f, "&mut {}", expr)
1028 } else {
1029 write!(f, "&{}", expr)
1030 }
1031 }
1032 Expr::Deref { expr, .. } => {
1033 write!(f, "*{}", expr)
1034 }
1035 Expr::Question { expr, .. } => {
1036 write!(f, "{}?", expr)
1037 }
1038 Expr::MacroInvocation { name, args, .. } => {
1039 write!(f, "{}!(", name)?;
1040 for (i, token) in args.iter().enumerate() {
1041 if i > 0 {
1042 write!(f, " ")?;
1043 }
1044 write!(f, "{:?}", token)?; }
1046 write!(f, ")")
1047 }
1048 Expr::Await { expr, .. } => write!(f, "{}.await", expr),
1049 }
1050 }
1051}
1052
1053impl std::fmt::Display for Pattern {
1054 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1055 match self {
1056 Pattern::Wildcard => write!(f, "_"),
1057 Pattern::Ident(name) => write!(f, "{}", name),
1058 Pattern::EnumPattern {
1059 enum_name,
1060 variant,
1061 data,
1062 } => {
1063 write!(f, "{}::{}", enum_name, variant)?;
1064 match data {
1065 Some(PatternData::Tuple(patterns)) => {
1066 write!(f, "(")?;
1067 for (i, pattern) in patterns.iter().enumerate() {
1068 if i > 0 {
1069 write!(f, ", ")?;
1070 }
1071 write!(f, "{}", pattern)?;
1072 }
1073 write!(f, ")")
1074 }
1075 Some(PatternData::Struct(field_patterns)) => {
1076 write!(f, " {{ ")?;
1077 for (i, (field_name, pattern)) in field_patterns.iter().enumerate() {
1078 if i > 0 {
1079 write!(f, ", ")?;
1080 }
1081 write!(f, "{}: {}", field_name, pattern)?;
1082 }
1083 write!(f, " }}")
1084 }
1085 None => Ok(()),
1086 }
1087 }
1088 }
1089 }
1090}
1091
1092impl std::fmt::Display for BinOp {
1093 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1094 match self {
1095 BinOp::Add => write!(f, "+"),
1096 BinOp::Sub => write!(f, "-"),
1097 BinOp::Mul => write!(f, "*"),
1098 BinOp::Div => write!(f, "/"),
1099 BinOp::Mod => write!(f, "%"),
1100 BinOp::Eq => write!(f, "=="),
1101 BinOp::Ne => write!(f, "!="),
1102 BinOp::Lt => write!(f, "<"),
1103 BinOp::Gt => write!(f, ">"),
1104 BinOp::Le => write!(f, "<="),
1105 BinOp::Ge => write!(f, ">="),
1106 BinOp::And => write!(f, "&&"),
1107 BinOp::Or => write!(f, "||"),
1108 }
1109 }
1110}
1111
1112impl std::fmt::Display for UnaryOp {
1113 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1114 match self {
1115 UnaryOp::Neg => write!(f, "-"),
1116 UnaryOp::Not => write!(f, "!"),
1117 }
1118 }
1119}