Skip to main content

palladium/ast/
mod.rs

1// Abstract Syntax Tree for Palladium
2// "The blueprint of legends"
3
4use crate::errors::Span;
5
6/// The root of a Palladium program
7#[derive(Debug, Clone)]
8pub struct Program {
9    pub imports: Vec<Import>,
10    pub items: Vec<Item>,
11}
12
13/// Import statement
14#[derive(Debug, Clone)]
15pub struct Import {
16    pub path: Vec<String>,          // e.g., ["std", "math"] for std::math
17    pub items: Option<Vec<String>>, // e.g., Some(["pd_abs", "pd_sin"]) for specific imports, None for wildcard
18    pub alias: Option<String>,      // e.g., Some("m") for std::math as m
19    pub span: Span,
20}
21
22/// Top-level items in a program
23#[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/// Visibility modifier
35#[derive(Debug, Clone, PartialEq)]
36pub enum Visibility {
37    Public,
38    Private,
39}
40
41/// Generic parameter (type or const)
42#[derive(Debug, Clone)]
43pub enum GenericParam {
44    /// Type parameter: T
45    Type(String),
46    /// Const parameter: const N: usize
47    Const { name: String, ty: Type },
48}
49
50/// Array size (can be a literal or const generic)
51#[derive(Debug, Clone, PartialEq)]
52pub enum ArraySize {
53    /// Literal size: [T; 5]
54    Literal(usize),
55    /// Const generic parameter: [T; N]
56    ConstParam(String),
57    /// Expression (for future use): [T; N + 1]
58    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>"), // Placeholder
67        }
68    }
69}
70
71/// Generic argument (can be a type or const value)
72#[derive(Debug, Clone, PartialEq)]
73pub enum GenericArg {
74    /// Type argument: Vec<T>
75    Type(Type),
76    /// Const argument: Array<T, 5>
77    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/// Const value for const generics
93#[derive(Debug, Clone, PartialEq)]
94pub enum ConstValue {
95    /// Integer literal
96    Integer(i64),
97    /// Const parameter reference
98    ConstParam(String),
99}
100
101/// Function parameter
102#[derive(Debug, Clone)]
103pub struct Param {
104    pub name: String,
105    pub ty: Type,
106    pub mutable: bool,
107}
108
109/// Function definition
110#[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>, // Lifetime parameters like ["'a", "'b"]
116    pub type_params: Vec<String>,     // Generic type parameters like ["T", "U"]
117    pub const_params: Vec<(String, Type)>, // Const parameters like [("N", Type::U64)]
118    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>>, // Effect annotations like ["io", "async"]
123}
124
125/// Struct definition
126#[derive(Debug, Clone)]
127pub struct StructDef {
128    pub visibility: Visibility,
129    pub name: String,
130    pub lifetime_params: Vec<String>, // Lifetime parameters like ["'a", "'b"]
131    pub type_params: Vec<String>,     // Generic type parameters like ["T", "U"]
132    pub const_params: Vec<(String, Type)>, // Const parameters like [("N", Type::U64)]
133    pub fields: Vec<(String, Type)>,
134    pub span: Span,
135}
136
137/// Enum definition
138#[derive(Debug, Clone)]
139pub struct EnumDef {
140    pub name: String,
141    pub lifetime_params: Vec<String>, // Lifetime parameters like ["'a", "'b"]
142    pub type_params: Vec<String>,     // Generic type parameters like ["T", "U"]
143    pub const_params: Vec<(String, Type)>, // Const parameters like [("N", Type::U64)]
144    pub variants: Vec<EnumVariant>,
145    pub span: Span,
146}
147
148/// Enum variant
149#[derive(Debug, Clone)]
150pub struct EnumVariant {
151    pub name: String,
152    pub data: EnumVariantData,
153}
154
155/// Enum variant data
156#[derive(Debug, Clone)]
157pub enum EnumVariantData {
158    /// Unit variant (no data)
159    Unit,
160    /// Tuple variant with types
161    Tuple(Vec<Type>),
162    /// Struct variant with named fields
163    Struct(Vec<(String, Type)>),
164}
165
166/// Trait definition
167#[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/// Trait method
178#[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/// Implementation block
191#[derive(Debug, Clone)]
192pub struct ImplBlock {
193    pub lifetime_params: Vec<String>,
194    pub type_params: Vec<String>,
195    pub trait_type: Option<Type>, // None for inherent impl, Some for trait impl
196    pub for_type: Type,
197    pub methods: Vec<Function>,
198    pub span: Span,
199}
200
201/// Type alias definition
202#[derive(Debug, Clone)]
203pub struct TypeAlias {
204    pub visibility: Visibility,
205    pub name: String,
206    pub lifetime_params: Vec<String>, // Lifetime parameters like ["'a", "'b"]
207    pub type_params: Vec<String>,     // Generic type parameters like ["T", "U"]
208    pub ty: Type,
209    pub span: Span,
210}
211
212/// Type representation
213#[derive(Debug, Clone, PartialEq)]
214pub enum Type {
215    /// Primitive types
216    I32,
217    I64,
218    U32,
219    U64,
220    Bool,
221    String,
222    /// Unit type (void)
223    Unit,
224    /// Array type: element type and size
225    Array(Box<Type>, ArraySize),
226    /// Custom type
227    Custom(String),
228    /// Generic type parameter (e.g., T, U)
229    TypeParam(String),
230    /// Generic type with concrete arguments (e.g., Vec<i32>, Array<i32, 5>)
231    Generic {
232        name: String,
233        args: Vec<GenericArg>,
234    },
235    /// Reference type (&T or &mut T)
236    Reference {
237        lifetime: Option<String>,
238        mutable: bool,
239        inner: Box<Type>,
240    },
241    /// Future type for async functions
242    Future {
243        output: Box<Type>,
244    },
245}
246
247/// Statements
248#[derive(Debug, Clone)]
249pub enum Stmt {
250    /// Expression statement
251    Expr(Expr),
252    /// Return statement
253    Return(Option<Expr>),
254    /// Let binding
255    Let {
256        name: String,
257        ty: Option<Type>,
258        value: Expr,
259        mutable: bool,
260        span: Span,
261    },
262    /// Assignment statement
263    Assign {
264        target: AssignTarget,
265        value: Expr,
266        span: Span,
267    },
268    /// If statement
269    If {
270        condition: Expr,
271        then_branch: Vec<Stmt>,
272        else_branch: Option<Vec<Stmt>>,
273        span: Span,
274    },
275    /// While loop
276    While {
277        condition: Expr,
278        body: Vec<Stmt>,
279        span: Span,
280    },
281    /// For loop
282    For {
283        var: String,
284        iter: Expr,
285        body: Vec<Stmt>,
286        span: Span,
287    },
288    /// Break statement
289    Break { span: Span },
290    /// Continue statement
291    Continue { span: Span },
292    /// Match statement
293    Match {
294        expr: Expr,
295        arms: Vec<MatchArm>,
296        span: Span,
297    },
298    /// Unsafe block
299    Unsafe { body: Vec<Stmt>, span: Span },
300}
301
302/// Match arm
303#[derive(Debug, Clone)]
304pub struct MatchArm {
305    pub pattern: Pattern,
306    pub body: Vec<Stmt>,
307}
308
309/// Pattern for matching
310#[derive(Debug, Clone, PartialEq)]
311pub enum Pattern {
312    /// Wildcard pattern (_)
313    Wildcard,
314    /// Identifier pattern (binds value)
315    Ident(String),
316    /// Enum pattern
317    EnumPattern {
318        enum_name: String,
319        variant: String,
320        data: Option<PatternData>,
321    },
322}
323
324/// Pattern data for enum variants
325#[derive(Debug, Clone, PartialEq)]
326pub enum PatternData {
327    /// Tuple pattern: Some(x)
328    Tuple(Vec<Pattern>),
329    /// Struct pattern: Rectangle { width: w, height: h }
330    Struct(Vec<(String, Pattern)>),
331}
332
333/// Expressions
334#[derive(Debug, Clone, PartialEq)]
335pub enum Expr {
336    /// String literal
337    String(String),
338    /// Integer literal (for future use)
339    Integer(i64),
340    /// Boolean literal
341    Bool(bool),
342    /// Identifier
343    Ident(String),
344    /// Array literal
345    ArrayLiteral { elements: Vec<Expr>, span: Span },
346    /// Array repeat literal [value; count]
347    ArrayRepeat {
348        value: Box<Expr>,
349        count: Box<Expr>,
350        span: Span,
351    },
352    /// Array indexing
353    Index {
354        array: Box<Expr>,
355        index: Box<Expr>,
356        span: Span,
357    },
358    /// Function call
359    Call {
360        func: Box<Expr>,
361        args: Vec<Expr>,
362        span: Span,
363    },
364    /// Binary operation (for future use)
365    Binary {
366        left: Box<Expr>,
367        op: BinOp,
368        right: Box<Expr>,
369        span: Span,
370    },
371    /// Unary operation
372    Unary {
373        op: UnaryOp,
374        operand: Box<Expr>,
375        span: Span,
376    },
377    /// Struct literal
378    StructLiteral {
379        name: String,
380        fields: Vec<(String, Expr)>,
381        span: Span,
382    },
383    /// Field access
384    FieldAccess {
385        object: Box<Expr>,
386        field: String,
387        span: Span,
388    },
389    /// Enum constructor
390    EnumConstructor {
391        enum_name: String,
392        variant: String,
393        data: Option<EnumConstructorData>,
394        span: Span,
395    },
396    /// Range expression (start..end)
397    Range {
398        start: Box<Expr>,
399        end: Box<Expr>,
400        span: Span,
401    },
402    /// Reference expression (&expr or &mut expr)
403    Reference {
404        mutable: bool,
405        expr: Box<Expr>,
406        span: Span,
407    },
408    /// Dereference expression (*expr)
409    Deref { expr: Box<Expr>, span: Span },
410    /// Question mark operator (expr?)
411    Question { expr: Box<Expr>, span: Span },
412    /// Macro invocation
413    MacroInvocation {
414        name: String,
415        args: Vec<Token>, // Token stream for arguments
416        span: Span,
417    },
418    /// Await expression
419    Await { expr: Box<Expr>, span: Span },
420}
421
422/// Enum constructor data
423#[derive(Debug, Clone, PartialEq)]
424pub enum EnumConstructorData {
425    /// Tuple constructor: Color::Red(255)
426    Tuple(Vec<Expr>),
427    /// Struct constructor: Shape::Rectangle { width: 10, height: 20 }
428    Struct(Vec<(String, Expr)>),
429}
430
431/// Assignment targets
432#[derive(Debug, Clone)]
433pub enum AssignTarget {
434    /// Simple variable assignment
435    Ident(String),
436    /// Array element assignment
437    Index { array: Box<Expr>, index: Box<Expr> },
438    /// Field assignment
439    FieldAccess { object: Box<Expr>, field: String },
440    /// Dereference assignment (*ptr = value)
441    Deref { expr: Box<Expr> },
442}
443
444/// Binary operators
445#[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/// Unary operators
463#[derive(Debug, Clone, Copy, PartialEq, Eq)]
464pub enum UnaryOp {
465    /// Negation (-)
466    Neg,
467    /// Logical not (!)
468    Not,
469}
470
471impl Expr {
472    pub fn span(&self) -> Span {
473        match self {
474            Expr::String(_) => Span::dummy(), // TODO: track spans
475            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
497/// AST visitor trait for traversing the tree
498pub 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
505/// Pretty printing for AST nodes
506impl 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/// Macro definition
604#[derive(Debug, Clone)]
605pub struct MacroDef {
606    pub name: String,
607    pub params: Vec<String>, // Macro parameters
608    pub body: Vec<Token>,    // Token stream for the macro body
609    pub span: Span,
610}
611
612/// Token for macro expansion (simplified token representation)
613#[derive(Debug, Clone, PartialEq)]
614pub enum Token {
615    Ident(String),
616    Literal(String),
617    Punct(char),
618    Group(Delimiter, Vec<Token>),
619}
620
621/// Delimiter for grouped tokens
622#[derive(Debug, Clone, PartialEq)]
623pub enum Delimiter {
624    Paren,   // ()
625    Brace,   // {}
626    Bracket, // []
627}
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        // Generic parameters
686        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            // Method generic parameters
711            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        // Generic parameters
762        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        // Generic parameters
806        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)?; // TODO: better formatting
1045                }
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}