wolf_ast/lib.rs
1//! The syntax tree of wolfpack (spec chapters 2 and 3).
2//!
3//! The tree mirrors the source closely: it keeps sections in written order, doc comments and
4//! spans, and it may contain [`ExprKind::Error`] and similar nodes where the parser recovered from
5//! an error. Meaning is assigned by later phases; for example `a.b.c` is a chain of field accesses
6//! here, whether `a` turns out to be a module, a type or a variable.
7
8mod dump;
9
10use wolf_span::Span;
11
12pub use dump::dump;
13
14/// Identifies an expression, pattern or type node, for side tables in later phases.
15#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
16pub struct NodeId(pub u32);
17
18/// A name with its position.
19#[derive(Clone, Debug, PartialEq)]
20pub struct Ident {
21 /// The text of the name.
22 pub name: String,
23 /// Where it is.
24 pub span: Span,
25}
26
27/// A dotted name such as `users.model` or `StorageError.Full`.
28#[derive(Clone, Debug, PartialEq)]
29pub struct Path {
30 /// The parts between the dots, at least one.
31 pub segments: Vec<Ident>,
32 /// The whole path.
33 pub span: Span,
34}
35
36/// A doc comment.
37#[derive(Clone, Debug, PartialEq)]
38pub struct Doc {
39 /// The text after the marker.
40 pub text: String,
41 /// `true` for `//!` and `/*! */`.
42 pub inner: bool,
43 /// Where it is.
44 pub span: Span,
45}
46
47/// A whole source file.
48#[derive(Clone, Debug, PartialEq)]
49pub struct File {
50 /// Inner doc comments before the `module` line: the module documentation.
51 pub docs: Vec<Doc>,
52 /// The `module` line, if present.
53 pub module: Option<Path>,
54 /// Sections in the order they are written.
55 pub sections: Vec<Section>,
56}
57
58/// The nine parts of a file, in their required order (spec chapter 2, section 2).
59#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
60pub enum SectionKind {
61 /// `imports`
62 Imports,
63 /// `extern`
64 Extern,
65 /// `config`
66 Config,
67 /// `types`
68 Types,
69 /// `interfaces`
70 Interfaces,
71 /// `impl`
72 Impl,
73 /// `main`: the entry point (spec chapter 2, section 3.7)
74 Main,
75 /// `functions`
76 Functions,
77 /// `tests`
78 Tests,
79}
80
81impl SectionKind {
82 /// All sections in their required order.
83 pub const ALL: [SectionKind; 9] = [
84 SectionKind::Imports,
85 SectionKind::Extern,
86 SectionKind::Config,
87 SectionKind::Types,
88 SectionKind::Interfaces,
89 SectionKind::Impl,
90 SectionKind::Main,
91 SectionKind::Functions,
92 SectionKind::Tests,
93 ];
94
95 /// The name of the section as written in source.
96 pub fn name(self) -> &'static str {
97 match self {
98 SectionKind::Imports => "imports",
99 SectionKind::Extern => "extern",
100 SectionKind::Config => "config",
101 SectionKind::Types => "types",
102 SectionKind::Interfaces => "interfaces",
103 SectionKind::Impl => "impl",
104 SectionKind::Main => "main",
105 SectionKind::Functions => "functions",
106 SectionKind::Tests => "tests",
107 }
108 }
109
110 /// The section with this name.
111 pub fn from_name(name: &str) -> Option<SectionKind> {
112 SectionKind::ALL
113 .into_iter()
114 .find(|kind| kind.name() == name)
115 }
116}
117
118/// A section and its entries.
119#[derive(Clone, Debug, PartialEq)]
120pub struct Section {
121 /// Which section.
122 pub kind: SectionKind,
123 /// The section name in the header.
124 pub name_span: Span,
125 /// From the name to the closing `}`.
126 pub span: Span,
127 /// The entries. They may include entries that belong to another section; the parser reports
128 /// those (E0205) and keeps them.
129 pub items: Vec<Item>,
130}
131
132/// A declaration inside a section.
133#[derive(Clone, Debug, PartialEq)]
134pub struct Item {
135 /// Outer doc comments before it.
136 pub docs: Vec<Doc>,
137 /// What it is.
138 pub kind: ItemKind,
139 /// The whole declaration.
140 pub span: Span,
141}
142
143/// The kinds of declarations.
144#[derive(Clone, Debug, PartialEq)]
145pub enum ItemKind {
146 /// An entry of `imports`.
147 Import(Import),
148 /// A target block of `extern`: `go { ... }`.
149 ExternTarget(ExternTarget),
150 /// A constant of `config`.
151 Config(ConfigEntry),
152 /// `struct`
153 Struct(StructDecl),
154 /// `enum`
155 Enum(EnumDecl),
156 /// `type Name = Type`
157 Alias(AliasDecl),
158 /// `intrinsic type Name<T>`: a built-in type declared in std (chapter 7, section 1).
159 IntrinsicType(IntrinsicTypeDecl),
160 /// `interface`
161 Interface(InterfaceDecl),
162 /// A block of `impl`.
163 Impl(ImplBlock),
164 /// `fn`
165 Fn(FnDecl),
166 /// `test "name" { ... }`
167 Test(TestDecl),
168}
169
170impl ItemKind {
171 /// The section this kind of declaration belongs in. Functions are also allowed in `tests`.
172 pub fn home(&self) -> SectionKind {
173 match self {
174 ItemKind::Import(_) => SectionKind::Imports,
175 ItemKind::ExternTarget(_) => SectionKind::Extern,
176 ItemKind::Config(_) => SectionKind::Config,
177 ItemKind::Struct(_)
178 | ItemKind::Enum(_)
179 | ItemKind::Alias(_)
180 | ItemKind::IntrinsicType(_) => SectionKind::Types,
181 ItemKind::Interface(_) => SectionKind::Interfaces,
182 ItemKind::Impl(_) => SectionKind::Impl,
183 ItemKind::Fn(_) => SectionKind::Functions,
184 ItemKind::Test(_) => SectionKind::Tests,
185 }
186 }
187
188 /// A short description for diagnostics: "`struct`", "import", ...
189 pub fn describe(&self) -> &'static str {
190 match self {
191 ItemKind::Import(_) => "import",
192 ItemKind::ExternTarget(_) => "extern block",
193 ItemKind::Config(_) => "constant",
194 ItemKind::Struct(_) => "`struct`",
195 ItemKind::Enum(_) => "`enum`",
196 ItemKind::Alias(_) => "type alias",
197 ItemKind::IntrinsicType(_) => "`intrinsic type`",
198 ItemKind::Interface(_) => "`interface`",
199 ItemKind::Impl(_) => "`impl` block",
200 ItemKind::Fn(_) => "`fn`",
201 ItemKind::Test(_) => "test",
202 }
203 }
204}
205
206/// An import (spec chapter 6, section 2).
207#[derive(Clone, Debug, PartialEq)]
208pub struct Import {
209 /// `pub` import (a re-export).
210 pub public: bool,
211 /// The module path.
212 pub path: Path,
213 /// `as name` after a whole-module import.
214 pub alias: Option<Ident>,
215 /// The `.{A, B as C}` group, if present.
216 pub names: Option<Vec<ImportName>>,
217}
218
219/// One name in an import group.
220#[derive(Clone, Debug, PartialEq)]
221pub struct ImportName {
222 /// The imported name.
223 pub name: Ident,
224 /// `as` alias.
225 pub alias: Option<Ident>,
226}
227
228/// A target block inside `extern`.
229#[derive(Clone, Debug, PartialEq)]
230pub struct ExternTarget {
231 /// `ts`, `go` or `rust` (anything else is reported).
232 pub target: Ident,
233 /// The declarations.
234 pub decls: Vec<ExternDecl>,
235}
236
237/// A declaration inside an extern target block.
238#[derive(Clone, Debug, PartialEq)]
239pub struct ExternDecl {
240 /// Doc comments.
241 pub docs: Vec<Doc>,
242 /// `pub`
243 pub public: bool,
244 /// Function or type.
245 pub kind: ExternDeclKind,
246 /// The target path after `from`.
247 pub from: StrLit,
248 /// The whole declaration.
249 pub span: Span,
250 /// For a function of a native module (spec chapter 7, section 8.7): the Rust types of its
251 /// parameters and result as the reader found them. `None` for written declarations.
252 pub native: Option<NativeSig>,
253 /// For a record of a native module (spec chapter 8, section 8a): the name in the target code
254 /// and the type the reader found of each field, in order. Empty for written declarations.
255 pub native_fields: Vec<(String, NativeTy)>,
256}
257
258/// The Rust types of a function of a native module, which the generated call must match.
259#[derive(Clone, Debug, PartialEq)]
260pub struct NativeSig {
261 /// One per parameter.
262 pub params: Vec<NativeTy>,
263 /// The result; `Unit` when there is none.
264 pub ret: NativeTy,
265}
266
267/// A Rust type of a native function, in the forms of spec chapter 7, section 8.7, rule 3.
268#[derive(Clone, Debug, PartialEq)]
269pub enum NativeTy {
270 /// An integer type, by name: `i32`, `usize`.
271 Int(String),
272 /// `f32` or `f64`.
273 Float(String),
274 /// `bool`
275 Bool,
276 /// `&str`
277 Str,
278 /// `String`
279 String,
280 /// `&String`
281 RefString,
282 /// `&[T]`
283 Slice(Box<NativeTy>),
284 /// `Vec<T>`
285 Vec(Box<NativeTy>),
286 /// `&Vec<T>`
287 RefVec(Box<NativeTy>),
288 /// `HashMap<K, V>` or `BTreeMap<K, V>`, by reference or by value.
289 Map {
290 /// `HashMap` or `BTreeMap`
291 kind: String,
292 /// `&`
293 by_ref: bool,
294 /// The key type.
295 key: Box<NativeTy>,
296 /// The value type.
297 value: Box<NativeTy>,
298 },
299 /// `Option<T>`
300 Option(Box<NativeTy>),
301 /// `Result<T, E>`; the error converts with its `Display` text.
302 Result(Box<NativeTy>),
303 /// `()`, or no result.
304 Unit,
305 /// A type of the module, by value or by reference.
306 Named {
307 /// Its name.
308 name: String,
309 /// `&`
310 by_ref: bool,
311 },
312 /// A callback parameter, passed as the backend passes every callback.
313 Callback,
314 /// A record of the module (spec chapter 7, section 8.7), by value or by reference.
315 Record {
316 /// Its name.
317 name: String,
318 /// `&`
319 by_ref: bool,
320 },
321}
322
323/// What an extern declaration declares.
324#[derive(Clone, Debug, PartialEq)]
325pub enum ExternDeclKind {
326 /// `fn name(params) -> T`
327 Fn(FnSig),
328 /// `type Name`
329 Type(Ident),
330 /// `struct Name`: a struct of the module bound to a struct type of the target (0.2).
331 Struct(Ident),
332}
333
334/// A string literal with its position.
335#[derive(Clone, Debug, PartialEq)]
336pub struct StrLit {
337 /// The value with escapes resolved.
338 pub value: String,
339 /// Where it is.
340 pub span: Span,
341}
342
343/// `name: Type = value` in `config`.
344#[derive(Clone, Debug, PartialEq)]
345pub struct ConfigEntry {
346 /// `pub`
347 pub public: bool,
348 /// The name.
349 pub name: Ident,
350 /// The written type.
351 pub ty: Ty,
352 /// The initializer.
353 pub value: Expr,
354}
355
356/// A type parameter with its bounds: `T: Comparable + Copyable`.
357#[derive(Clone, Debug, PartialEq)]
358pub struct GenericParam {
359 /// The name.
360 pub name: Ident,
361 /// The interfaces after `:`.
362 pub bounds: Vec<Ty>,
363}
364
365/// `struct Name<T> { fields }`
366#[derive(Clone, Debug, PartialEq)]
367pub struct StructDecl {
368 /// `pub`
369 pub public: bool,
370 /// The name.
371 pub name: Ident,
372 /// Type parameters.
373 pub generics: Vec<GenericParam>,
374 /// The fields.
375 pub fields: Vec<Field>,
376}
377
378/// A field of a struct or of a variant.
379#[derive(Clone, Debug, PartialEq)]
380pub struct Field {
381 /// Doc comments.
382 pub docs: Vec<Doc>,
383 /// `pub` (always `false` in variants).
384 pub public: bool,
385 /// The name.
386 pub name: Ident,
387 /// The type.
388 pub ty: Ty,
389 /// The whole field.
390 pub span: Span,
391}
392
393/// `enum Name<T> { variants }`
394#[derive(Clone, Debug, PartialEq)]
395pub struct EnumDecl {
396 /// `pub`
397 pub public: bool,
398 /// The name.
399 pub name: Ident,
400 /// Type parameters.
401 pub generics: Vec<GenericParam>,
402 /// The variants.
403 pub variants: Vec<Variant>,
404}
405
406/// A variant of an enum.
407#[derive(Clone, Debug, PartialEq)]
408pub struct Variant {
409 /// Doc comments.
410 pub docs: Vec<Doc>,
411 /// The name.
412 pub name: Ident,
413 /// The payload.
414 pub payload: VariantPayload,
415 /// The whole variant.
416 pub span: Span,
417}
418
419/// The data a variant carries.
420#[derive(Clone, Debug, PartialEq)]
421pub enum VariantPayload {
422 /// `Full`
423 None,
424 /// `Io(String)`
425 Tuple(Vec<Ty>),
426 /// `Moved { x: Int, y: Int }`
427 Struct(Vec<Field>),
428}
429
430/// `type Name<T> = Type`
431#[derive(Clone, Debug, PartialEq)]
432pub struct AliasDecl {
433 /// `pub`
434 pub public: bool,
435 /// The name.
436 pub name: Ident,
437 /// Type parameters.
438 pub generics: Vec<GenericParam>,
439 /// The aliased type.
440 pub ty: Ty,
441}
442
443/// `intrinsic type Name<T>`
444#[derive(Clone, Debug, PartialEq)]
445pub struct IntrinsicTypeDecl {
446 /// `pub`
447 pub public: bool,
448 /// The name.
449 pub name: Ident,
450 /// Type parameters.
451 pub generics: Vec<GenericParam>,
452}
453
454/// `interface Name<T> { signatures }`
455#[derive(Clone, Debug, PartialEq)]
456pub struct InterfaceDecl {
457 /// `pub`
458 pub public: bool,
459 /// The name.
460 pub name: Ident,
461 /// Type parameters.
462 pub generics: Vec<GenericParam>,
463 /// The methods: signatures, and defaults with a body.
464 pub methods: Vec<MethodSig>,
465}
466
467/// A method of an interface: a signature, or a default with its body (spec chapter 4,
468/// section 8.2, rule 4).
469#[derive(Clone, Debug, PartialEq)]
470pub struct MethodSig {
471 /// Doc comments.
472 pub docs: Vec<Doc>,
473 /// The method; its body is the default.
474 pub decl: FnDecl,
475}
476
477/// A block in `impl`: `Stack<T: Comparable>: Container<T> { methods }`.
478#[derive(Clone, Debug, PartialEq)]
479pub struct ImplBlock {
480 /// The implemented type.
481 pub type_name: Ident,
482 /// Type parameters declared in the head.
483 pub generics: Vec<GenericParam>,
484 /// The interface after `:`, if this is an interface implementation.
485 pub interface: Option<Ty>,
486 /// The methods, each with its doc comments.
487 pub methods: Vec<Method>,
488}
489
490/// A method inside an impl block.
491#[derive(Clone, Debug, PartialEq)]
492pub struct Method {
493 /// Doc comments.
494 pub docs: Vec<Doc>,
495 /// The function.
496 pub decl: FnDecl,
497 /// The whole method.
498 pub span: Span,
499}
500
501/// A function or method declaration.
502#[derive(Clone, Debug, PartialEq)]
503pub struct FnDecl {
504 /// `pub`
505 pub public: bool,
506 /// `intrinsic`
507 pub intrinsic: bool,
508 /// The signature.
509 pub sig: FnSig,
510 /// The body; absent for `intrinsic` functions and on some errors.
511 pub body: Option<Block>,
512 /// The word `override` before `fn`, which replaces a default (spec chapter 4, section 8.3).
513 pub overrides: Option<Span>,
514}
515
516/// Name, type parameters, parameters and result.
517#[derive(Clone, Debug, PartialEq)]
518pub struct FnSig {
519 /// The name.
520 pub name: Ident,
521 /// Type parameters.
522 pub generics: Vec<GenericParam>,
523 /// Parameters, `self` included.
524 pub params: Vec<Param>,
525 /// The written result type; `None` means `Void`.
526 pub ret: Option<Ty>,
527 /// `where T: Bound` after the result type: bounds that a method adds to the type parameters
528 /// of its `impl` block (spec chapter 4, section 8.6).
529 pub where_bounds: Vec<GenericParam>,
530 /// From `fn` to the end of the result type.
531 pub span: Span,
532}
533
534/// How a value is passed (spec chapter 5, section 5).
535#[derive(Clone, Copy, Debug, PartialEq, Eq)]
536pub enum Mode {
537 /// No marker: read access.
538 Read,
539 /// `mut`
540 Mut,
541 /// `own`
542 Own,
543}
544
545/// A parameter.
546#[derive(Clone, Debug, PartialEq)]
547pub struct Param {
548 /// The mode.
549 pub mode: Mode,
550 /// `self` or a named parameter.
551 pub kind: ParamKind,
552 /// The whole parameter.
553 pub span: Span,
554}
555
556/// The two kinds of parameters.
557#[derive(Clone, Debug, PartialEq)]
558pub enum ParamKind {
559 /// `self`
560 SelfParam,
561 /// `name: Type`
562 Named {
563 /// The name.
564 name: Ident,
565 /// The type.
566 ty: Ty,
567 },
568}
569
570/// `test "name" { body }`
571#[derive(Clone, Debug, PartialEq)]
572pub struct TestDecl {
573 /// The test name.
574 pub name: StrLit,
575 /// The body.
576 pub body: Block,
577}
578
579/// A written type.
580#[derive(Clone, Debug, PartialEq)]
581pub struct Ty {
582 /// Node id.
583 pub id: NodeId,
584 /// What it is.
585 pub kind: TyKind,
586 /// Where it is.
587 pub span: Span,
588}
589
590/// The forms of a written type.
591#[derive(Clone, Debug, PartialEq)]
592pub enum TyKind {
593 /// `Int`, `List<User>`, `model.User`.
594 Path {
595 /// The name.
596 path: Path,
597 /// Type arguments.
598 args: Vec<Ty>,
599 },
600 /// `fn(Int, mut List<Int>) -> Bool`
601 Fn {
602 /// Parameter modes and types.
603 params: Vec<(Mode, Ty)>,
604 /// The result; `None` means `Void`.
605 ret: Option<Box<Ty>>,
606 },
607 /// `Self`
608 SelfType,
609 /// A type that could not be parsed.
610 Error,
611}
612
613/// A block of statements.
614#[derive(Clone, Debug, PartialEq)]
615pub struct Block {
616 /// The statements. A final expression statement is the value of the block.
617 pub stmts: Vec<Stmt>,
618 /// From `{` to `}`.
619 pub span: Span,
620}
621
622/// A statement.
623#[derive(Clone, Debug, PartialEq)]
624pub struct Stmt {
625 /// What it is.
626 pub kind: StmtKind,
627 /// Where it is.
628 pub span: Span,
629}
630
631/// The forms of statements.
632#[derive(Clone, Debug, PartialEq)]
633pub enum StmtKind {
634 /// `let x: T = e`, `var x = e`, `let _ = e`.
635 Let {
636 /// `var`
637 mutable: bool,
638 /// The name; `None` for `let _`.
639 name: Option<Ident>,
640 /// The written type.
641 ty: Option<Ty>,
642 /// The initializer.
643 value: Expr,
644 },
645 /// `let Point { x, y } = e`, `var Config { name, .. } = e`: a destructuring `let` (0.2).
646 LetPattern {
647 /// `var`
648 mutable: bool,
649 /// The pattern; the types check that it always matches.
650 pattern: Pat,
651 /// The initializer.
652 value: Expr,
653 },
654 /// `place op= value`
655 Assign {
656 /// The place.
657 target: Expr,
658 /// `=`, `+=`, ...
659 op: AssignOp,
660 /// The value.
661 value: Expr,
662 },
663 /// `label: while cond { body }`
664 While {
665 /// The label of the loop.
666 label: Option<Ident>,
667 /// The condition.
668 cond: Expr,
669 /// The body.
670 body: Block,
671 },
672 /// `label: while let pattern = mode? value { body }` (0.2).
673 WhileLet {
674 /// The label of the loop.
675 label: Option<Ident>,
676 /// The pattern.
677 pattern: Pat,
678 /// `mut`, `own` or read.
679 mode: Mode,
680 /// The value, evaluated before every iteration.
681 value: Expr,
682 /// The body.
683 body: Block,
684 },
685 /// `label: for x in mode? collection { body }` or `for i in a..b { body }`.
686 For {
687 /// The label of the loop.
688 label: Option<Ident>,
689 /// The loop variable.
690 var: Ident,
691 /// What is iterated.
692 iter: ForIter,
693 /// The body.
694 body: Block,
695 },
696 /// An expression used as a statement.
697 Expr(Expr),
698}
699
700/// What a `for` loop walks over.
701#[derive(Clone, Debug, PartialEq)]
702pub enum ForIter {
703 /// A collection with an optional mode.
704 Collection {
705 /// `mut`, `own` or read.
706 mode: Mode,
707 /// The collection.
708 expr: Expr,
709 },
710 /// `start..end` or `start..=end`.
711 Range {
712 /// The first value.
713 start: Expr,
714 /// The bound.
715 end: Expr,
716 /// `..=`
717 inclusive: bool,
718 },
719}
720
721/// Assignment operators.
722#[derive(Clone, Copy, Debug, PartialEq, Eq)]
723#[allow(missing_docs)]
724pub enum AssignOp {
725 Assign,
726 Add,
727 Sub,
728 Mul,
729 Div,
730 Rem,
731 BitAnd,
732 BitOr,
733 BitXor,
734 Shl,
735 Shr,
736}
737
738/// An expression.
739#[derive(Clone, Debug, PartialEq)]
740pub struct Expr {
741 /// Node id.
742 pub id: NodeId,
743 /// What it is.
744 pub kind: ExprKind,
745 /// Where it is.
746 pub span: Span,
747}
748
749/// The forms of expressions.
750#[derive(Clone, Debug, PartialEq)]
751pub enum ExprKind {
752 /// An integer literal.
753 Int(u64),
754 /// A float literal.
755 Float(f64),
756 /// A string literal.
757 Str(String),
758 /// An interpolated string `f"..."` (0.2).
759 FStr(Vec<FStrPart>),
760 /// `true` or `false`.
761 Bool(bool),
762 /// `()`
763 Unit,
764 /// A name.
765 Name(Ident),
766 /// `self`
767 SelfValue,
768 /// `Self`
769 SelfType,
770 /// `(e)`
771 Paren(Box<Expr>),
772 /// `[a, b]`
773 List(Vec<Expr>),
774 /// `["a": 1]`, `[:]`
775 Map(Vec<(Expr, Expr)>),
776 /// `Path.<T> { field: value, shorthand, ..base }`
777 StructLit {
778 /// The type name.
779 path: Path,
780 /// Explicit type arguments `.<T>`.
781 type_args: Vec<Ty>,
782 /// The fields.
783 fields: Vec<FieldInit>,
784 /// The base of the update syntax `..base` (0.2).
785 base: Option<Box<Expr>>,
786 },
787 /// `base.name`
788 Field {
789 /// The left side.
790 base: Box<Expr>,
791 /// The name after the dot.
792 name: Ident,
793 },
794 /// `base.<T, U>`
795 TypeArgs {
796 /// The left side.
797 base: Box<Expr>,
798 /// The type arguments.
799 args: Vec<Ty>,
800 },
801 /// `callee(args)`
802 Call {
803 /// What is called.
804 callee: Box<Expr>,
805 /// The arguments.
806 args: Vec<Arg>,
807 },
808 /// `base[index]`
809 Index {
810 /// The collection.
811 base: Box<Expr>,
812 /// The index.
813 index: Box<Expr>,
814 },
815 /// `base[a..b]` and the other slice forms.
816 Slice {
817 /// The collection.
818 base: Box<Expr>,
819 /// The start, if written.
820 start: Option<Box<Expr>>,
821 /// The end, if written.
822 end: Option<Box<Expr>>,
823 /// `..=`
824 inclusive: bool,
825 },
826 /// `e?`
827 Try(Box<Expr>),
828 /// `-e`, `!e`, `~e`
829 Unary {
830 /// The operator.
831 op: UnaryOp,
832 /// The operand.
833 operand: Box<Expr>,
834 },
835 /// `a op b`
836 Binary {
837 /// The operator.
838 op: BinaryOp,
839 /// Left operand.
840 lhs: Box<Expr>,
841 /// Right operand.
842 rhs: Box<Expr>,
843 },
844 /// `|x, y: Int| body` or `|x| -> T { body }`.
845 Closure {
846 /// The parameters.
847 params: Vec<ClosureParam>,
848 /// The written result type.
849 ret: Option<Ty>,
850 /// The body.
851 body: Box<Expr>,
852 },
853 /// `{ ... }` as the body of a closure or a match arm.
854 Block(Block),
855 /// `if cond { } else ...`
856 If {
857 /// The condition.
858 cond: Box<Expr>,
859 /// The first branch.
860 then: Block,
861 /// `else` followed by a block or another `if`.
862 otherwise: Option<Box<Expr>>,
863 },
864 /// `if let pattern = mode? value { } else ...` (0.2).
865 IfLet {
866 /// The pattern.
867 pattern: Pat,
868 /// The mode marker of the value.
869 mode: Mode,
870 /// The matched value.
871 value: Box<Expr>,
872 /// The branch taken when the value matches.
873 then: Block,
874 /// `else` followed by a block or another `if`.
875 otherwise: Option<Box<Expr>>,
876 },
877 /// `label: loop { body }` (0.2).
878 Loop {
879 /// The label of the loop.
880 label: Option<Ident>,
881 /// The body.
882 body: Block,
883 },
884 /// `match mode? scrutinee { arms }`
885 Match {
886 /// The mode marker.
887 mode: Mode,
888 /// The matched value.
889 scrutinee: Box<Expr>,
890 /// The arms.
891 arms: Vec<Arm>,
892 },
893 /// `return e?`
894 Return(Option<Box<Expr>>),
895 /// `break`, `break label`, `break value`. The parser takes a name after `break` as a label
896 /// when an enclosing loop has that label.
897 Break {
898 /// The label of the loop that is left.
899 label: Option<Ident>,
900 /// The value of the `loop` that is left.
901 value: Option<Box<Expr>>,
902 },
903 /// `continue`, `continue label`.
904 Continue {
905 /// The label of the loop that is continued.
906 label: Option<Ident>,
907 },
908 /// Something that could not be parsed; a diagnostic was reported.
909 Error,
910}
911
912/// A part of an interpolated string.
913#[derive(Clone, Debug, PartialEq)]
914pub enum FStrPart {
915 /// Text.
916 Text(String),
917 /// An interpolated expression, with its format specification.
918 Expr(Expr, Option<FormatSpec>),
919}
920
921/// How an interpolation is aligned in its width.
922#[derive(Clone, Copy, Debug, PartialEq, Eq)]
923pub enum Align {
924 /// `<`
925 Left,
926 /// `^`
927 Center,
928 /// `>`
929 Right,
930}
931
932/// A format specification `[[fill] align] ["0"] [width] ["." precision]` after the `:` of an
933/// interpolation (spec chapter 1, section 5.3a; chapter 7, section 4.4).
934#[derive(Clone, Debug, PartialEq, Eq)]
935pub struct FormatSpec {
936 /// The fill character, if one is written.
937 pub fill: Option<char>,
938 /// The alignment, if one is written.
939 pub align: Option<Align>,
940 /// `0`: pad a number with zeros after its sign.
941 pub zero: bool,
942 /// The width.
943 pub width: Option<u32>,
944 /// The number of digits after the point of a `Float`.
945 pub precision: Option<u32>,
946 /// Where the specification is, after the `:`.
947 pub span: Span,
948}
949
950impl FormatSpec {
951 /// The specification as it is written, such as `*>8.2`.
952 pub fn text(&self) -> String {
953 let mut out = String::new();
954 if let Some(f) = self.fill {
955 out.push(f);
956 }
957 match self.align {
958 Some(Align::Left) => out.push('<'),
959 Some(Align::Center) => out.push('^'),
960 Some(Align::Right) => out.push('>'),
961 None => {}
962 }
963 if self.zero {
964 out.push('0');
965 }
966 if let Some(w) = self.width {
967 out.push_str(&w.to_string());
968 }
969 if let Some(p) = self.precision {
970 out.push_str(&format!(".{p}"));
971 }
972 out
973 }
974}
975
976/// A field in a struct literal.
977#[derive(Clone, Debug, PartialEq)]
978pub struct FieldInit {
979 /// Node id, for what a shorthand field names.
980 pub id: NodeId,
981 /// The field name.
982 pub name: Ident,
983 /// The value; `None` for the shorthand `User { id }`.
984 pub value: Option<Expr>,
985}
986
987/// An argument of a call.
988#[derive(Clone, Debug, PartialEq)]
989pub struct Arg {
990 /// `mut`, `own` or none.
991 pub mode: Mode,
992 /// The value.
993 pub value: Expr,
994}
995
996/// A closure parameter.
997#[derive(Clone, Debug, PartialEq)]
998pub struct ClosureParam {
999 /// The name.
1000 pub name: Ident,
1001 /// The written type.
1002 pub ty: Option<Ty>,
1003}
1004
1005/// An arm of a `match`.
1006#[derive(Clone, Debug, PartialEq)]
1007pub struct Arm {
1008 /// The pattern.
1009 pub pattern: Pat,
1010 /// `if` guard.
1011 pub guard: Option<Expr>,
1012 /// The result.
1013 pub body: Expr,
1014 /// The whole arm.
1015 pub span: Span,
1016}
1017
1018/// Unary operators.
1019#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1020pub enum UnaryOp {
1021 /// `-`
1022 Neg,
1023 /// `!`
1024 Not,
1025 /// `~`
1026 BitNot,
1027}
1028
1029/// Binary operators.
1030#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1031#[allow(missing_docs)]
1032pub enum BinaryOp {
1033 Mul,
1034 Div,
1035 Rem,
1036 Add,
1037 Sub,
1038 Shl,
1039 Shr,
1040 BitAnd,
1041 BitXor,
1042 BitOr,
1043 Eq,
1044 NotEq,
1045 Lt,
1046 Le,
1047 Gt,
1048 Ge,
1049 And,
1050 Or,
1051}
1052
1053impl BinaryOp {
1054 /// The operator as written.
1055 pub fn symbol(self) -> &'static str {
1056 match self {
1057 BinaryOp::Mul => "*",
1058 BinaryOp::Div => "/",
1059 BinaryOp::Rem => "%",
1060 BinaryOp::Add => "+",
1061 BinaryOp::Sub => "-",
1062 BinaryOp::Shl => "<<",
1063 BinaryOp::Shr => ">>",
1064 BinaryOp::BitAnd => "&",
1065 BinaryOp::BitXor => "^",
1066 BinaryOp::BitOr => "|",
1067 BinaryOp::Eq => "==",
1068 BinaryOp::NotEq => "!=",
1069 BinaryOp::Lt => "<",
1070 BinaryOp::Le => "<=",
1071 BinaryOp::Gt => ">",
1072 BinaryOp::Ge => ">=",
1073 BinaryOp::And => "&&",
1074 BinaryOp::Or => "||",
1075 }
1076 }
1077
1078 /// Whether this is one of the non-associative comparison operators.
1079 pub fn is_comparison(self) -> bool {
1080 matches!(
1081 self,
1082 BinaryOp::Eq
1083 | BinaryOp::NotEq
1084 | BinaryOp::Lt
1085 | BinaryOp::Le
1086 | BinaryOp::Gt
1087 | BinaryOp::Ge
1088 )
1089 }
1090}
1091
1092/// A pattern in a `match` arm.
1093#[derive(Clone, Debug, PartialEq)]
1094pub struct Pat {
1095 /// Node id.
1096 pub id: NodeId,
1097 /// What it is.
1098 pub kind: PatKind,
1099 /// Where it is.
1100 pub span: Span,
1101}
1102
1103/// The forms of patterns (spec chapter 3, section 7).
1104#[derive(Clone, Debug, PartialEq)]
1105pub enum PatKind {
1106 /// `_`
1107 Wild,
1108 /// A lone name: a binding, or a payload-less variant or constant (decided later).
1109 Name(Ident),
1110 /// An integer, possibly negative.
1111 Int {
1112 /// `-`
1113 negative: bool,
1114 /// The magnitude.
1115 value: u64,
1116 },
1117 /// A string.
1118 Str(String),
1119 /// `true` or `false`.
1120 Bool(bool),
1121 /// A dotted path without payload: `StorageError.Full`.
1122 Path(Path),
1123 /// `Some(x)`, `Shape.Circle(r)`.
1124 Tuple {
1125 /// The variant.
1126 path: Path,
1127 /// The payload patterns.
1128 items: Vec<Pat>,
1129 },
1130 /// `Point { x, y: 0, .. }`.
1131 Struct {
1132 /// The struct or variant.
1133 path: Path,
1134 /// The field patterns.
1135 fields: Vec<FieldPat>,
1136 /// `..` at the end.
1137 rest: bool,
1138 },
1139 /// `A | B`
1140 Or(Vec<Pat>),
1141 /// A pattern that could not be parsed.
1142 Error,
1143}
1144
1145/// A field in a struct pattern.
1146#[derive(Clone, Debug, PartialEq)]
1147pub struct FieldPat {
1148 /// Node id, for the binding of a shorthand field.
1149 pub id: NodeId,
1150 /// The field name.
1151 pub name: Ident,
1152 /// The sub-pattern; `None` for the shorthand `{ x }`.
1153 pub pat: Option<Pat>,
1154}