swamp_ast/
lib.rs

1/*
2 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/swamp/swamp
3 * Licensed under the MIT License. See LICENSE in the project root for license information.
4 */
5pub mod prelude;
6
7use std::fmt;
8use std::fmt::{Debug, Formatter};
9use std::hash::Hash;
10
11#[derive(PartialEq, Eq, Hash, Default, Clone)]
12pub struct SpanWithoutFileId {
13    pub offset: u32,
14    pub length: u16,
15}
16
17impl Debug for SpanWithoutFileId {
18    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
19        write!(f, "<{}:{}>", self.offset, self.length)
20    }
21}
22
23// Common metadata that can be shared across all AST nodes
24#[derive(PartialEq, Eq, Hash, Default, Clone)]
25pub struct Node {
26    pub span: SpanWithoutFileId,
27    // TODO: Add comments and attributes
28}
29
30impl Debug for Node {
31    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
32        write!(f, "{:?}", self.span)
33    }
34}
35
36/// Identifiers ================
37#[derive(Debug, PartialEq, Eq, Clone, Hash)]
38pub struct QualifiedTypeIdentifier {
39    pub name: LocalTypeIdentifier,
40    pub module_path: Option<ModulePath>,
41    pub generic_params: Vec<Type>,
42}
43
44impl QualifiedTypeIdentifier {
45    #[must_use]
46    pub fn new(name: LocalTypeIdentifier, module_path: Vec<Node>) -> Self {
47        let module_path = if module_path.is_empty() {
48            None
49        } else {
50            Some(ModulePath(module_path))
51        };
52
53        Self {
54            name,
55            module_path,
56            generic_params: Vec::new(),
57        }
58    }
59
60    #[must_use]
61    pub fn new_with_generics(
62        name: LocalTypeIdentifier,
63        module_path: Vec<Node>,
64        generic_params: Vec<Type>,
65    ) -> Self {
66        let module_path = if module_path.is_empty() {
67            None
68        } else {
69            Some(ModulePath(module_path))
70        };
71
72        Self {
73            name,
74            module_path,
75            generic_params,
76        }
77    }
78}
79
80#[derive(Debug, PartialEq, Eq, Hash, Clone)]
81pub struct QualifiedIdentifier {
82    pub name: Node,
83    pub module_path: Option<ModulePath>,
84    pub generic_params: Vec<Type>,
85}
86
87impl QualifiedIdentifier {
88    #[must_use]
89    pub fn new(name: Node, module_path: Vec<Node>) -> Self {
90        let module_path = if module_path.is_empty() {
91            None
92        } else {
93            Some(ModulePath(module_path))
94        };
95
96        Self {
97            name,
98            module_path,
99            generic_params: vec![],
100        }
101    }
102
103    #[must_use]
104    pub fn new_with_generics(
105        name: Node,
106        module_path: Vec<Node>,
107        generic_params: Vec<Type>,
108    ) -> Self {
109        let module_path = if module_path.is_empty() {
110            None
111        } else {
112            Some(ModulePath(module_path))
113        };
114
115        Self {
116            name,
117            module_path,
118            generic_params,
119        }
120    }
121}
122
123#[derive(Debug, PartialEq, Eq, Hash, Default, Clone)]
124pub struct LocalTypeIdentifier(pub Node);
125
126impl LocalTypeIdentifier {
127    #[must_use]
128    pub const fn new(node: Node) -> Self {
129        Self(node)
130    }
131}
132
133#[derive(Debug, PartialEq, Eq, Hash, Default, Clone)]
134pub struct TypeVariable(pub Node);
135
136#[derive(Debug, PartialEq, Eq, Hash, Default, Clone)]
137pub struct LocalTypeIdentifierWithOptionalTypeVariables {
138    pub name: Node,
139    pub type_variables: Vec<TypeVariable>,
140}
141
142#[derive(PartialEq, Eq, Hash, Debug, Clone)]
143pub struct LocalIdentifier(pub Node);
144
145impl LocalIdentifier {
146    #[must_use]
147    pub const fn new(node: Node) -> Self {
148        Self(node)
149    }
150}
151
152#[derive(Debug, PartialEq, Eq, Hash, Default, Clone)]
153pub struct LocalConstantIdentifier(pub Node);
154
155#[derive(Debug, PartialEq, Eq, Clone, Hash)]
156pub struct QualifiedConstantIdentifier {
157    pub name: Node,
158    pub module_path: Option<ModulePath>,
159}
160
161impl QualifiedConstantIdentifier {
162    #[must_use]
163    pub const fn new(name: Node, module_path: Option<ModulePath>) -> Self {
164        Self { name, module_path }
165    }
166}
167
168#[derive(Debug, Eq, Hash, Clone, PartialEq)]
169pub struct FieldName(pub Node);
170
171#[derive(Debug, Eq, Hash, PartialEq, Clone)]
172pub struct ModulePath(pub Vec<Node>);
173
174impl Default for ModulePath {
175    fn default() -> Self {
176        Self::new()
177    }
178}
179
180impl ModulePath {
181    #[must_use]
182    pub const fn new() -> Self {
183        Self(vec![])
184    }
185}
186
187#[derive(Debug, Clone)]
188pub enum ImportItem {
189    Identifier(LocalIdentifier),
190    Type(LocalTypeIdentifier),
191}
192
193#[derive(Debug, Clone)]
194pub enum ImportItems {
195    Nothing,
196    Items(Vec<ImportItem>),
197    All,
198}
199
200#[derive(Debug, Clone)]
201pub struct Mod {
202    pub module_path: ModulePath,
203    pub items: ImportItems,
204}
205
206#[derive(Debug, Clone)]
207pub struct Use {
208    pub module_path: ModulePath,
209    pub items: ImportItems,
210}
211
212#[derive(Debug, Eq, Clone, PartialEq)]
213pub struct AliasType {
214    pub identifier: LocalTypeIdentifier,
215    pub referenced_type: Type,
216}
217
218#[derive(Debug, Eq, PartialEq, Hash, Clone, Default)]
219pub struct AnonymousStructType {
220    pub fields: Vec<StructTypeField>,
221}
222
223impl AnonymousStructType {
224    #[must_use]
225    pub const fn new(fields: Vec<StructTypeField>) -> Self {
226        Self { fields }
227    }
228}
229
230#[derive(Debug, Clone)]
231pub struct ConstantInfo {
232    pub constant_identifier: LocalConstantIdentifier,
233    pub annotation: Option<Type>,
234    pub expression: Box<Expression>,
235}
236
237#[derive(Debug, Clone)]
238pub struct NamedStructDef {
239    pub identifier: LocalTypeIdentifierWithOptionalTypeVariables,
240    pub struct_type: AnonymousStructType,
241}
242
243#[derive(Debug, Clone)]
244pub enum Definition {
245    AliasDef(AliasType),
246    NamedStructDef(NamedStructDef),
247    EnumDef(
248        LocalTypeIdentifierWithOptionalTypeVariables,
249        Vec<EnumVariantType>,
250    ),
251    FunctionDef(Function),
252    ImplDef(LocalTypeIdentifierWithOptionalTypeVariables, Vec<Function>),
253    Mod(Mod),
254    Use(Use),
255    // Other
256    Constant(ConstantInfo),
257}
258
259#[derive(Debug, Clone)]
260pub struct ForVar {
261    pub identifier: Node,
262    pub is_mut: Option<Node>,
263}
264
265#[derive(Debug, Clone)]
266pub enum ForPattern {
267    Single(ForVar),
268    Pair(ForVar, ForVar),
269}
270
271impl ForPattern {
272    #[must_use]
273    pub fn any_mut(&self) -> Option<Node> {
274        match self {
275            Self::Single(a) => a.is_mut.clone(),
276            Self::Pair(a, b) => a.is_mut.clone().or_else(|| b.is_mut.clone()),
277        }
278    }
279}
280
281#[derive(Debug, Clone)]
282pub struct IterableExpression {
283    pub expression: Box<Expression>,
284}
285
286#[derive(Clone, Eq, PartialEq)]
287pub struct Variable {
288    pub name: Node,
289    pub is_mutable: Option<Node>,
290}
291
292#[derive(Debug, Clone)]
293pub struct VariableBinding {
294    pub variable: Variable,
295    pub expression: Option<Expression>,
296}
297
298impl Variable {
299    #[must_use]
300    pub const fn new(name: Node, is_mutable: Option<Node>) -> Self {
301        Self { name, is_mutable }
302    }
303}
304
305// Since this is a helper struct, we want to implement the debug output for it
306// to have it more concise
307impl Debug for Variable {
308    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
309        if let Some(found) = &self.is_mutable {
310            write!(f, "mut {found:?} {:?}", self.name)
311        } else {
312            write!(f, "{:?}", self.name)
313        }
314    }
315}
316
317#[derive(Debug, Eq, Clone, PartialEq)]
318pub struct Parameter {
319    pub variable: Variable,
320    pub param_type: Type,
321}
322
323#[derive(Debug, Clone)]
324pub struct FunctionDeclaration {
325    pub name: Node,
326    pub params: Vec<Parameter>,
327    pub self_parameter: Option<SelfParameter>,
328    pub return_type: Option<Type>,
329    pub generic_variables: Vec<TypeVariable>,
330}
331
332#[derive(Debug, Clone)]
333pub struct FunctionWithBody {
334    pub declaration: FunctionDeclaration,
335    pub body: Expression,
336}
337
338#[derive(Debug, Clone)]
339pub enum Function {
340    Internal(FunctionWithBody),
341    External(FunctionDeclaration),
342}
343
344#[derive(Debug, Clone)]
345pub struct SelfParameter {
346    pub is_mutable: Option<Node>,
347    pub self_node: Node,
348}
349
350#[derive(Debug, PartialEq, Eq)]
351pub enum AssignmentOperatorKind {
352    Compound(CompoundOperatorKind),
353    Assign, // =
354}
355
356#[derive(Debug, PartialEq, Eq, Clone)]
357pub enum CompoundOperatorKind {
358    Add,    // +=
359    Sub,    // -=
360    Mul,    // *=
361    Div,    // /=
362    Modulo, // %=
363}
364
365#[derive(Debug, Clone)]
366pub struct CompoundOperator {
367    pub node: Node,
368    pub kind: CompoundOperatorKind,
369}
370
371#[derive(Debug, Clone)]
372pub enum RangeMode {
373    Inclusive,
374    Exclusive,
375}
376
377#[derive(Clone)]
378pub struct Expression {
379    pub kind: ExpressionKind,
380    pub node: Node,
381}
382
383impl Debug for Expression {
384    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
385        write!(f, "{:?}{:?}", self.node.span, self.kind)
386    }
387}
388
389#[derive(Debug, Clone)]
390pub enum Postfix {
391    FieldAccess(Node),
392    Subscript(Expression),
393    MemberCall(Node, Option<Vec<Type>>, Vec<Expression>),
394    FunctionCall(Node, Option<Vec<Type>>, Vec<Expression>),
395    OptionalChainingOperator(Node),     // ?-postfix
396    NoneCoalescingOperator(Expression), // ??-postfix
397}
398
399#[derive(Debug, Clone)]
400pub struct PostfixChain {
401    pub base: Box<Expression>,
402    pub postfixes: Vec<Postfix>,
403}
404
405/// Expressions are things that "converts" to a value when evaluated.
406#[derive(Debug, Clone)]
407pub enum ExpressionKind {
408    // Access
409    PostfixChain(PostfixChain),
410
411    // References
412    VariableReference(Variable),
413    ConstantReference(QualifiedConstantIdentifier),
414    StaticMemberFunctionReference(QualifiedTypeIdentifier, Node),
415    IdentifierReference(QualifiedIdentifier),
416
417    // Assignments
418    VariableDefinition(Variable, Option<Type>, Box<Expression>),
419    VariableAssignment(Variable, Box<Expression>),
420    Assignment(Box<Expression>, Box<Expression>),
421    CompoundAssignment(Box<Expression>, CompoundOperator, Box<Expression>),
422    DestructuringAssignment(Vec<Variable>, Box<Expression>),
423
424    // Operators
425    BinaryOp(Box<Expression>, BinaryOperator, Box<Expression>),
426    UnaryOp(UnaryOperator, Box<Expression>),
427
428    //
429    Block(Vec<Expression>),
430    With(Vec<VariableBinding>, Box<Expression>),
431    When(
432        Vec<VariableBinding>,
433        Box<Expression>,
434        Option<Box<Expression>>,
435    ),
436
437    // Control flow
438    ForLoop(
439        ForPattern,
440        IterableExpression,
441        Option<Box<Expression>>,
442        Box<Expression>,
443    ),
444    WhileLoop(Box<Expression>, Box<Expression>),
445
446    // Compare and Matching
447    If(Box<Expression>, Box<Expression>, Option<Box<Expression>>),
448    Match(Box<Expression>, Vec<MatchArm>),
449    Guard(Vec<GuardExpr>),
450
451    InterpolatedString(Vec<StringPart>),
452
453    // Literals
454    AnonymousStructLiteral(Vec<FieldExpression>, bool),
455    NamedStructLiteral(QualifiedTypeIdentifier, Vec<FieldExpression>, bool),
456    Range(Box<Expression>, Box<Expression>, RangeMode),
457    Literal(LiteralKind),
458    Lambda(Vec<Variable>, Box<Expression>),
459}
460
461#[derive(Debug, Clone)]
462pub struct MatchArm {
463    pub pattern: Pattern,
464    pub expression: Expression,
465}
466
467// Are constructed by themselves
468#[derive(Debug, Clone)]
469pub enum LiteralKind {
470    Int,
471    Float,
472    String(String),
473    Bool,
474    EnumVariant(EnumVariantLiteral),
475    Tuple(Vec<Expression>),
476    Slice(Vec<Expression>),
477    SlicePair(Vec<(Expression, Expression)>),
478    None,
479}
480
481#[derive(Debug, Clone)]
482pub struct FieldExpression {
483    pub field_name: FieldName,
484    pub expression: Expression,
485}
486
487#[derive(Debug, Eq, Hash, Clone, PartialEq)]
488pub struct StructTypeField {
489    pub field_name: FieldName,
490    pub field_type: Type,
491}
492
493#[derive(Debug, Clone)]
494pub enum EnumVariantLiteral {
495    Simple(QualifiedTypeIdentifier, LocalTypeIdentifier),
496    Tuple(
497        QualifiedTypeIdentifier,
498        LocalTypeIdentifier,
499        Vec<Expression>,
500    ),
501    Struct(
502        QualifiedTypeIdentifier,
503        LocalTypeIdentifier,
504        Vec<FieldExpression>,
505        bool,
506    ),
507}
508
509impl EnumVariantLiteral {
510    #[must_use]
511    pub const fn node(&self) -> &Node {
512        match self {
513            Self::Tuple(ident, _, _) | Self::Struct(ident, _, _, _) | Self::Simple(ident, _) => {
514                &ident.name.0
515            }
516        }
517    }
518}
519
520#[derive(Debug, Clone)]
521pub enum EnumVariantType {
522    Simple(Node),
523    Tuple(Node, Vec<Type>),
524    Struct(Node, AnonymousStructType),
525}
526
527#[derive(Debug, PartialEq, Eq, Clone, Hash)]
528pub struct TypeForParameter {
529    pub ast_type: Type,
530    pub is_mutable: bool,
531}
532
533#[derive(Debug, PartialEq, Eq, Clone, Hash)]
534pub enum Type {
535    // Composite
536    Slice(Box<Type>),                // Value array
537    SlicePair(Box<Type>, Box<Type>), // Key : Value
538    AnonymousStruct(AnonymousStructType),
539    Unit,
540    Tuple(Vec<Type>),
541    Function(Vec<TypeForParameter>, Box<Type>),
542
543    Named(QualifiedTypeIdentifier),
544
545    Optional(Box<Type>, Node),
546}
547
548#[derive(Debug, Clone)]
549pub struct BinaryOperator {
550    pub kind: BinaryOperatorKind,
551    pub node: Node,
552}
553
554// Takes a left and right side expression
555#[derive(Debug, Clone)]
556pub enum BinaryOperatorKind {
557    Add,
558    Subtract,
559    Multiply,
560    Divide,
561    Modulo,
562    LogicalOr,
563    LogicalAnd,
564    Equal,
565    NotEqual,
566    LessThan,
567    LessEqual,
568    GreaterThan,
569    GreaterEqual,
570    RangeExclusive,
571}
572
573// Only takes one expression argument
574#[derive(Debug, Clone)]
575pub enum UnaryOperator {
576    Not(Node),
577    Negate(Node),
578    BorrowMutRef(Node),
579}
580
581#[derive(Debug, Clone)]
582pub struct GuardExpr {
583    pub clause: GuardClause,
584    pub result: Expression,
585}
586
587#[derive(Debug, Clone)]
588pub enum GuardClause {
589    Wildcard(Node),
590    Expression(Expression),
591}
592
593// Patterns are used in matching and destructuring
594#[derive(Debug, Clone)]
595pub enum Pattern {
596    Wildcard(Node),
597    NormalPattern(Node, NormalPattern, Option<GuardClause>),
598}
599
600// Patterns are used in matching and destructuring
601#[derive(Debug, Clone)]
602pub enum NormalPattern {
603    PatternList(Vec<PatternElement>),
604    EnumPattern(Node, Option<Vec<PatternElement>>),
605    Literal(LiteralKind),
606}
607
608#[derive(Debug, Clone)]
609pub enum PatternElement {
610    Variable(Variable),
611    Expression(Expression),
612    Wildcard(Node),
613}
614
615#[derive(Debug, Clone)]
616pub enum StringPart {
617    Literal(Node, String),
618    Interpolation(Box<Expression>, Option<FormatSpecifier>),
619}
620
621#[derive(Debug, Clone)]
622pub enum FormatSpecifier {
623    LowerHex(Node),                      // :x
624    UpperHex(Node),                      // :X
625    Binary(Node),                        // :b
626    Float(Node),                         // :f
627    Precision(u32, Node, PrecisionType), // :..2f or :..5s
628}
629
630#[derive(Debug, Clone)]
631pub enum PrecisionType {
632    Float(Node),
633    String(Node),
634}
635
636#[derive()]
637pub struct Module {
638    pub expression: Option<Expression>,
639    pub definitions: Vec<Definition>,
640}
641
642impl Debug for Module {
643    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
644        for definition in &self.definitions {
645            writeln!(f, "{definition:?}")?;
646        }
647
648        if !self.definitions.is_empty() && self.expression.is_some() {
649            writeln!(f, "---")?;
650        }
651
652        if let Some(found_expression) = &self.expression {
653            match &found_expression.kind {
654                ExpressionKind::Block(expressions) => {
655                    for expression in expressions {
656                        writeln!(f, "{expression:?}")?;
657                    }
658                }
659                _ => writeln!(f, "{found_expression:?}")?,
660            }
661        }
662
663        Ok(())
664    }
665}
666
667impl Module {
668    #[must_use]
669    pub const fn new(definitions: Vec<Definition>, expression: Option<Expression>) -> Self {
670        Self {
671            expression,
672            definitions,
673        }
674    }
675
676    #[must_use]
677    pub const fn expression(&self) -> &Option<Expression> {
678        &self.expression
679    }
680
681    #[must_use]
682    pub const fn definitions(&self) -> &Vec<Definition> {
683        &self.definitions
684    }
685
686    #[must_use]
687    pub fn imports(&self) -> Vec<&Use> {
688        let mut use_items = Vec::new();
689
690        for def in &self.definitions {
691            if let Definition::Use(use_info) = def {
692                use_items.push(use_info);
693            }
694        }
695
696        use_items
697    }
698}