microsoft/qdk

Public

mirrored fromhttps://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
alex/pythontelem

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

compiler/qsc_ast/src/ast.rs

1957lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! The abstract syntax tree (AST) for Q#. The AST directly corresponds to the surface syntax of Q#.
5
6#![warn(missing_docs)]
7
8use indenter::{indented, Format, Indented};
9use num_bigint::BigInt;
10use qsc_data_structures::span::{Span, WithSpan};
11use std::{
12 cmp::Ordering,
13 fmt::{self, Display, Formatter, Write},
14 hash::{Hash, Hasher},
15 iter::once,
16 rc::Rc,
17};
18
19fn set_indentation<'a, 'b>(
20 indent: Indented<'a, Formatter<'b>>,
21 level: usize,
22) -> Indented<'a, Formatter<'b>> {
23 match level {
24 0 => indent.with_str(""),
25 1 => indent.with_str(" "),
26 2 => indent.with_str(" "),
27 _ => unimplemented!("indentation level not supported"),
28 }
29}
30
31/// The unique identifier for an AST node.
32/// This could be assigned or unassigned. If unassigned, the value will be `u32::MAX`.
33/// Assignment happens after symbol resolution. Use [`NodeId::is_default`] to check if the node
34/// has been assigned yet.
35#[derive(Clone, Copy, Debug)]
36pub struct NodeId(u32);
37
38impl NodeId {
39 const DEFAULT_VALUE: u32 = u32::MAX;
40
41 /// The ID of the first node.
42 pub const FIRST: Self = Self(0);
43
44 /// The successor of this ID.
45 #[must_use]
46 pub fn successor(self) -> Self {
47 Self(self.0 + 1)
48 }
49
50 /// True if this is the default ID.
51 #[must_use]
52 pub fn is_default(self) -> bool {
53 self.0 == Self::DEFAULT_VALUE
54 }
55}
56
57impl Default for NodeId {
58 fn default() -> Self {
59 Self(Self::DEFAULT_VALUE)
60 }
61}
62
63impl Display for NodeId {
64 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
65 if self.is_default() {
66 f.write_str("_id_")
67 } else {
68 self.0.fmt(f)
69 }
70 }
71}
72
73impl From<usize> for NodeId {
74 fn from(value: usize) -> Self {
75 Self(u32::try_from(value).expect("node ID should fit in u32"))
76 }
77}
78
79impl From<NodeId> for usize {
80 fn from(value: NodeId) -> Self {
81 assert!(!value.is_default(), "default node ID should be replaced");
82 value.0 as usize
83 }
84}
85
86impl PartialEq for NodeId {
87 fn eq(&self, other: &Self) -> bool {
88 assert!(!self.is_default(), "default node ID should be replaced");
89 self.0 == other.0
90 }
91}
92
93impl Eq for NodeId {}
94
95impl PartialOrd for NodeId {
96 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
97 Some(self.cmp(other))
98 }
99}
100
101impl Ord for NodeId {
102 fn cmp(&self, other: &Self) -> Ordering {
103 assert!(!self.is_default(), "default node ID should be replaced");
104 self.0.cmp(&other.0)
105 }
106}
107
108impl Hash for NodeId {
109 fn hash<H: Hasher>(&self, state: &mut H) {
110 self.0.hash(state);
111 }
112}
113
114/// The root node of an AST.
115#[derive(Clone, Debug, Default, PartialEq)]
116pub struct Package {
117 /// The node ID.
118 pub id: NodeId,
119 /// The top-level syntax nodes in the package.
120 pub nodes: Box<[TopLevelNode]>,
121 /// The entry expression for an executable package.
122 pub entry: Option<Box<Expr>>,
123}
124
125impl Display for Package {
126 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
127 let mut indent = set_indentation(indented(f), 0);
128 write!(indent, "Package {}:", self.id)?;
129 indent = set_indentation(indent, 1);
130 if let Some(e) = &self.entry {
131 write!(indent, "\nentry expression: {e}")?;
132 }
133 for node in &self.nodes {
134 write!(indent, "\n{node}")?;
135 }
136 Ok(())
137 }
138}
139
140/// A node that can exist at the top level of a package.
141#[derive(Clone, Debug, PartialEq)]
142pub enum TopLevelNode {
143 /// A namespace
144 Namespace(Namespace),
145 /// A statement
146 Stmt(Box<Stmt>),
147}
148
149impl Display for TopLevelNode {
150 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
151 match self {
152 Self::Namespace(n) => n.fmt(f),
153 Self::Stmt(s) => s.fmt(f),
154 }
155 }
156}
157
158/// A namespace.
159#[derive(Clone, Debug, PartialEq)]
160pub struct Namespace {
161 /// The node ID.
162 pub id: NodeId,
163 /// The span.
164 pub span: Span,
165 /// The documentation.
166 pub doc: Rc<str>,
167 /// The namespace name.
168 pub name: Box<[Ident]>,
169 /// The items in the namespace.
170 pub items: Box<[Box<Item>]>,
171}
172
173impl Namespace {
174 /// Returns an iterator over the items in the namespace that are exported.
175 pub fn exports(&self) -> impl Iterator<Item = &ImportOrExportItem> {
176 self.items.iter().flat_map(|i| match i.kind.as_ref() {
177 ItemKind::ImportOrExport(decl) if decl.is_export() => &decl.items[..],
178 _ => &[],
179 })
180 }
181}
182
183impl Display for Namespace {
184 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
185 let mut indent = set_indentation(indented(f), 0);
186 write!(indent, "Namespace {} {} (", self.id, self.span)?;
187
188 let mut buf = Vec::with_capacity(self.name.len());
189
190 for ident in &self.name {
191 buf.push(format!("{ident}"));
192 }
193 if buf.len() > 1 {
194 // use square brackets only if there are more than one ident
195 write!(indent, "[{}]", buf.join(", "))?;
196 } else {
197 write!(indent, "{}", buf[0])?;
198 }
199
200 write!(indent, "):",)?;
201 indent = set_indentation(indent, 1);
202
203 if !self.doc.is_empty() {
204 write!(indent, "\ndoc:")?;
205 indent = set_indentation(indent, 2);
206 write!(indent, "\n{}", self.doc)?;
207 indent = set_indentation(indent, 1);
208 }
209
210 for i in &self.items {
211 write!(indent, "\n{i}")?;
212 }
213
214 Ok(())
215 }
216}
217
218/// An item.
219#[derive(Clone, Debug, PartialEq)]
220pub struct Item {
221 /// The ID.
222 pub id: NodeId,
223 /// The span.
224 pub span: Span,
225 /// The documentation.
226 pub doc: Rc<str>,
227 /// The attributes.
228 pub attrs: Box<[Box<Attr>]>,
229 /// The item kind.
230 pub kind: Box<ItemKind>,
231}
232
233impl Default for Item {
234 fn default() -> Self {
235 Self {
236 id: NodeId::default(),
237 span: Span::default(),
238 doc: "".into(),
239 attrs: Box::default(),
240 kind: Box::default(),
241 }
242 }
243}
244
245impl Display for Item {
246 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
247 let mut indent = set_indentation(indented(f), 0);
248 write!(indent, "Item {} {}:", self.id, self.span)?;
249 indent = set_indentation(indent, 1);
250
251 if !self.doc.is_empty() {
252 write!(indent, "\ndoc:")?;
253 indent = set_indentation(indent, 2);
254 write!(indent, "\n{}", self.doc)?;
255 indent = set_indentation(indent, 1);
256 }
257
258 for attr in &self.attrs {
259 write!(indent, "\n{attr}")?;
260 }
261
262 write!(indent, "\n{}", self.kind)?;
263 Ok(())
264 }
265}
266
267/// An item kind.
268#[derive(Clone, Debug, Default, PartialEq)]
269pub enum ItemKind {
270 /// A `function` or `operation` declaration.
271 Callable(Box<CallableDecl>),
272 /// Default item when nothing has been parsed.
273 #[default]
274 Err,
275 /// An `open` item for a namespace with an optional alias.
276 Open(PathKind, Option<Box<Ident>>),
277 /// A `newtype` declaration.
278 Ty(Box<Ident>, Box<TyDef>),
279 /// A `struct` declaration.
280 Struct(Box<StructDecl>),
281 /// An export declaration
282 ImportOrExport(ImportOrExportDecl),
283}
284
285impl Display for ItemKind {
286 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
287 match &self {
288 ItemKind::Callable(decl) => write!(f, "{decl}")?,
289 ItemKind::Err => write!(f, "Err")?,
290 ItemKind::Open(name, alias) => match alias {
291 Some(a) => write!(f, "Open ({name}) ({a})")?,
292 None => write!(f, "Open ({name})")?,
293 },
294 ItemKind::Ty(name, t) => write!(f, "New Type ({name}): {t}")?,
295 ItemKind::Struct(s) => write!(f, "{s}")?,
296 ItemKind::ImportOrExport(item) if item.is_export => write!(f, "Export ({item})")?,
297 ItemKind::ImportOrExport(item) => write!(f, "Import ({item})")?,
298 }
299 Ok(())
300 }
301}
302
303/// An attribute.
304#[derive(Clone, Debug, PartialEq)]
305pub struct Attr {
306 /// The node ID.
307 pub id: NodeId,
308 /// The span.
309 pub span: Span,
310 /// The name of the attribute.
311 pub name: Box<Ident>,
312 /// The argument to the attribute.
313 pub arg: Box<Expr>,
314}
315
316impl Display for Attr {
317 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
318 let mut indent = set_indentation(indented(f), 0);
319 write!(indent, "Attr {} {} ({}):", self.id, self.span, self.name)?;
320 indent = set_indentation(indent, 1);
321 write!(indent, "\n{}", self.arg)?;
322 Ok(())
323 }
324}
325
326/// A type definition.
327#[derive(Clone, Debug, PartialEq, Default)]
328pub struct TyDef {
329 /// The node ID.
330 pub id: NodeId,
331 /// The span.
332 pub span: Span,
333 /// The type definition kind.
334 pub kind: Box<TyDefKind>,
335}
336
337impl TyDef {
338 /// Returns true if the tye definition satisfies the conditions for a struct.
339 /// Conditions for a struct are that the `TyDef` is a tuple with all its top-level fields named.
340 /// Otherwise, returns false.
341 #[must_use]
342 pub fn is_struct(&self) -> bool {
343 match self.kind.as_ref() {
344 TyDefKind::Paren(inner) => inner.is_struct(),
345 TyDefKind::Tuple(fields) => fields
346 .iter()
347 .all(|field| matches!(field.kind.as_ref(), TyDefKind::Field(Some(_), _))),
348 TyDefKind::Err | TyDefKind::Field(..) => false,
349 }
350 }
351}
352
353impl Display for TyDef {
354 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
355 write!(f, "TyDef {} {}: {}", self.id, self.span, self.kind)
356 }
357}
358
359impl WithSpan for TyDef {
360 fn with_span(self, span: Span) -> Self {
361 Self { span, ..self }
362 }
363}
364
365/// A type definition kind.
366#[derive(Clone, Debug, PartialEq, Default)]
367pub enum TyDefKind {
368 /// A field definition with an optional name but required type.
369 Field(Option<Box<Ident>>, Box<Ty>),
370 /// A parenthesized type definition.
371 Paren(Box<TyDef>),
372 /// A tuple.
373 Tuple(Box<[Box<TyDef>]>),
374 /// An invalid type definition.
375 #[default]
376 Err,
377}
378
379impl Display for TyDefKind {
380 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
381 let mut indent = set_indentation(indented(f), 0);
382 match &self {
383 TyDefKind::Field(name, t) => {
384 write!(indent, "Field:")?;
385 indent = set_indentation(indent, 1);
386 if let Some(n) = name {
387 write!(indent, "\n{n}")?;
388 }
389 write!(indent, "\n{t}")?;
390 }
391 TyDefKind::Paren(t) => {
392 write!(indent, "Paren:")?;
393 indent = set_indentation(indent, 1);
394 write!(indent, "\n{t}")?;
395 }
396 TyDefKind::Tuple(ts) => {
397 if ts.is_empty() {
398 write!(indent, "Unit")?;
399 } else {
400 write!(indent, "Tuple:")?;
401 indent = set_indentation(indent, 1);
402 for t in ts {
403 write!(indent, "\n{t}")?;
404 }
405 }
406 }
407 TyDefKind::Err => write!(indent, "Err")?,
408 }
409 Ok(())
410 }
411}
412
413/// A struct definition.
414#[derive(Clone, Debug, PartialEq, Default)]
415pub struct StructDecl {
416 /// The node ID.
417 pub id: NodeId,
418 /// The span.
419 pub span: Span,
420 /// The name of the struct.
421 pub name: Box<Ident>,
422 /// The type definition kind.
423 pub fields: Box<[Box<FieldDef>]>,
424}
425
426impl Display for StructDecl {
427 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
428 let mut indent = set_indentation(indented(f), 0);
429 write!(indent, "Struct {} {} ({}):", self.id, self.span, self.name)?;
430 if self.fields.is_empty() {
431 write!(indent, " <empty>")?;
432 } else {
433 indent = set_indentation(indent, 1);
434 for field in &self.fields {
435 write!(indent, "\n{field}")?;
436 }
437 }
438 Ok(())
439 }
440}
441
442impl WithSpan for StructDecl {
443 fn with_span(self, span: Span) -> Self {
444 Self { span, ..self }
445 }
446}
447
448/// A struct field definition.
449#[derive(Clone, Debug, PartialEq, Default)]
450pub struct FieldDef {
451 /// The node ID.
452 pub id: NodeId,
453 /// The span.
454 pub span: Span,
455 /// The name of the field.
456 pub name: Box<Ident>,
457 /// The type of the field.
458 pub ty: Box<Ty>,
459}
460
461impl Display for FieldDef {
462 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
463 write!(
464 f,
465 "FieldDef {} {} ({}): {}",
466 self.id, self.span, self.name, self.ty
467 )
468 }
469}
470
471impl WithSpan for FieldDef {
472 fn with_span(self, span: Span) -> Self {
473 Self { span, ..self }
474 }
475}
476
477/// A callable declaration header.
478#[derive(Clone, Debug, PartialEq)]
479pub struct CallableDecl {
480 /// The node ID.
481 pub id: NodeId,
482 /// The span.
483 pub span: Span,
484 /// The callable kind.
485 pub kind: CallableKind,
486 /// The name of the callable.
487 pub name: Box<Ident>,
488 /// The generic parameters to the callable.
489 pub generics: Box<[Box<Ident>]>,
490 /// The input to the callable.
491 pub input: Box<Pat>,
492 /// The return type of the callable.
493 pub output: Box<Ty>,
494 /// The functors supported by the callable.
495 pub functors: Option<Box<FunctorExpr>>,
496 /// The body of the callable.
497 pub body: Box<CallableBody>,
498}
499
500impl Display for CallableDecl {
501 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
502 let mut indent = set_indentation(indented(f), 0);
503 write!(
504 indent,
505 "Callable {} {} ({:?}):",
506 self.id, self.span, self.kind
507 )?;
508 indent = set_indentation(indent, 1);
509 write!(indent, "\nname: {}", self.name)?;
510 if !self.generics.is_empty() {
511 write!(indent, "\ngenerics:")?;
512 indent = set_indentation(indent, 2);
513 for param in &self.generics {
514 write!(indent, "\n{param}")?;
515 }
516 indent = set_indentation(indent, 1);
517 }
518 write!(indent, "\ninput: {}", self.input)?;
519 write!(indent, "\noutput: {}", self.output)?;
520 if let Some(f) = &self.functors {
521 write!(indent, "\nfunctors: {}", f.as_ref())?;
522 }
523 write!(indent, "\nbody: {}", self.body)?;
524 Ok(())
525 }
526}
527
528/// The body of a callable.
529#[derive(Clone, Debug, PartialEq)]
530pub enum CallableBody {
531 /// A block for the callable's body specialization.
532 Block(Box<Block>),
533 /// One or more explicit specializations.
534 Specs(Box<[Box<SpecDecl>]>),
535}
536
537impl Display for CallableBody {
538 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
539 match self {
540 CallableBody::Block(body) => write!(f, "Block: {body}")?,
541 CallableBody::Specs(specs) => {
542 let mut indent = set_indentation(indented(f), 0);
543 write!(indent, "Specializations:")?;
544 indent = set_indentation(indent, 1);
545 for spec in specs {
546 write!(indent, "\n{spec}")?;
547 }
548 }
549 }
550 Ok(())
551 }
552}
553
554/// A specialization declaration.
555#[derive(Clone, Debug, PartialEq)]
556pub struct SpecDecl {
557 /// The node ID.
558 pub id: NodeId,
559 /// The span.
560 pub span: Span,
561 /// Which specialization is being declared.
562 pub spec: Spec,
563 /// The body of the specialization.
564 pub body: SpecBody,
565}
566
567impl Display for SpecDecl {
568 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
569 write!(
570 f,
571 "SpecDecl {} {} ({:?}): {}",
572 self.id, self.span, self.spec, self.body
573 )
574 }
575}
576
577/// The body of a specialization.
578#[derive(Clone, Debug, PartialEq)]
579pub enum SpecBody {
580 /// The strategy to use to automatically generate the specialization.
581 Gen(SpecGen),
582 /// A manual implementation of the specialization.
583 Impl(Box<Pat>, Box<Block>),
584}
585
586impl Display for SpecBody {
587 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
588 let mut indent = set_indentation(indented(f), 0);
589 match self {
590 SpecBody::Gen(sg) => write!(indent, "Gen: {sg:?}")?,
591 SpecBody::Impl(p, b) => {
592 write!(indent, "Impl:")?;
593 indent = set_indentation(indent, 1);
594 write!(indent, "\n{p}")?;
595 write!(indent, "\n{b}")?;
596 }
597 }
598 Ok(())
599 }
600}
601
602/// An expression that describes a set of functors.
603#[derive(Clone, Debug, Eq, Hash, PartialEq)]
604pub struct FunctorExpr {
605 /// The node ID.
606 pub id: NodeId,
607 /// The span.
608 pub span: Span,
609 /// The functor expression kind.
610 pub kind: Box<FunctorExprKind>,
611}
612
613impl Display for FunctorExpr {
614 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
615 write!(f, "Functor Expr {} {}: {}", self.id, self.span, self.kind)
616 }
617}
618
619/// A functor expression kind.
620#[derive(Clone, Debug, Eq, Hash, PartialEq)]
621pub enum FunctorExprKind {
622 /// A binary operation.
623 BinOp(SetOp, Box<FunctorExpr>, Box<FunctorExpr>),
624 /// A literal for a specific functor.
625 Lit(Functor),
626 /// A parenthesized group.
627 Paren(Box<FunctorExpr>),
628}
629
630impl Display for FunctorExprKind {
631 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
632 match self {
633 FunctorExprKind::BinOp(op, l, r) => write!(f, "BinOp {op:?}: ({l}) ({r})"),
634 FunctorExprKind::Lit(func) => write!(f, "{func:?}"),
635 FunctorExprKind::Paren(func) => write!(f, "Paren: {func}"),
636 }
637 }
638}
639
640/// A type.
641#[derive(Clone, Debug, Eq, Hash, PartialEq, Default)]
642pub struct Ty {
643 /// The node ID.
644 pub id: NodeId,
645 /// The span.
646 pub span: Span,
647 /// The type kind.
648 pub kind: Box<TyKind>,
649}
650
651impl Display for Ty {
652 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
653 write!(f, "Type {} {}: {}", self.id, self.span, self.kind)
654 }
655}
656
657impl WithSpan for Ty {
658 fn with_span(self, span: Span) -> Self {
659 Self { span, ..self }
660 }
661}
662
663/// A type kind.
664#[derive(Clone, Debug, Eq, Hash, PartialEq, Default)]
665pub enum TyKind {
666 /// An array type.
667 Array(Box<Ty>),
668 /// An arrow type: `->` for a function or `=>` for an operation.
669 Arrow(CallableKind, Box<Ty>, Box<Ty>, Option<Box<FunctorExpr>>),
670 /// An unspecified type, `_`, which may be inferred.
671 Hole,
672 /// A type wrapped in parentheses.
673 Paren(Box<Ty>),
674 /// A named type.
675 Path(PathKind),
676 /// A type parameter.
677 Param(Box<Ident>),
678 /// A tuple type.
679 Tuple(Box<[Ty]>),
680 /// An invalid type.
681 #[default]
682 Err,
683}
684
685impl Display for TyKind {
686 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
687 let mut indent = set_indentation(indented(f), 0);
688 match self {
689 TyKind::Array(item) => write!(indent, "Array: {item}")?,
690 TyKind::Arrow(ck, param, rtrn, functors) => {
691 write!(indent, "Arrow ({ck:?}):")?;
692 indent = set_indentation(indent, 1);
693 write!(indent, "\nparam: {param}")?;
694 write!(indent, "\nreturn: {rtrn}")?;
695 if let Some(f) = functors {
696 write!(indent, "\nfunctors: {f}")?;
697 }
698 }
699 TyKind::Hole => write!(indent, "Hole")?,
700 TyKind::Paren(t) => write!(indent, "Paren: {t}")?,
701 TyKind::Path(p) => write!(indent, "Path: {p}")?,
702 TyKind::Param(name) => write!(indent, "Type Param: {name}")?,
703 TyKind::Tuple(ts) => {
704 if ts.is_empty() {
705 write!(indent, "Unit")?;
706 } else {
707 write!(indent, "Tuple:")?;
708 indent = indent.with_format(Format::Uniform {
709 indentation: " ",
710 });
711 for t in ts {
712 write!(indent, "\n{t}")?;
713 }
714 }
715 }
716 TyKind::Err => write!(indent, "Err")?,
717 }
718 Ok(())
719 }
720}
721
722/// A sequenced block of statements.
723#[derive(Clone, Debug, PartialEq)]
724pub struct Block {
725 /// The node ID.
726 pub id: NodeId,
727 /// The span.
728 pub span: Span,
729 /// The statements in the block.
730 pub stmts: Box<[Box<Stmt>]>,
731}
732
733impl Display for Block {
734 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
735 if self.stmts.is_empty() {
736 write!(f, "Block {} {}: <empty>", self.id, self.span)?;
737 } else {
738 let mut indent = set_indentation(indented(f), 0);
739 write!(indent, "Block {} {}:", self.id, self.span)?;
740 indent = set_indentation(indent, 1);
741 for s in &self.stmts {
742 write!(indent, "\n{s}")?;
743 }
744 }
745 Ok(())
746 }
747}
748
749/// A statement.
750#[derive(Clone, Debug, Default, PartialEq)]
751pub struct Stmt {
752 /// The node ID.
753 pub id: NodeId,
754 /// The span.
755 pub span: Span,
756 /// The statement kind.
757 pub kind: Box<StmtKind>,
758}
759
760impl Display for Stmt {
761 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
762 write!(f, "Stmt {} {}: {}", self.id, self.span, self.kind)
763 }
764}
765
766/// A statement kind.
767#[derive(Clone, Debug, Default, PartialEq)]
768pub enum StmtKind {
769 /// An empty statement.
770 Empty,
771 /// An expression without a trailing semicolon.
772 Expr(Box<Expr>),
773 /// A let or mutable binding: `let a = b;` or `mutable x = b;`.
774 Local(Mutability, Box<Pat>, Box<Expr>),
775 /// An item.
776 Item(Box<Item>),
777 /// A use or borrow qubit allocation: `use a = b;` or `borrow a = b;`.
778 Qubit(QubitSource, Box<Pat>, Box<QubitInit>, Option<Box<Block>>),
779 /// An expression with a trailing semicolon.
780 Semi(Box<Expr>),
781 /// An invalid statement.
782 #[default]
783 Err,
784}
785
786impl Display for StmtKind {
787 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
788 let mut indent = set_indentation(indented(f), 0);
789 match self {
790 StmtKind::Empty => write!(indent, "Empty")?,
791 StmtKind::Expr(e) => write!(indent, "Expr: {e}")?,
792 StmtKind::Item(item) => write!(indent, "Item: {item}")?,
793 StmtKind::Local(m, lhs, rhs) => {
794 write!(indent, "Local ({m:?}):")?;
795 indent = set_indentation(indent, 1);
796 write!(indent, "\n{lhs}")?;
797 write!(indent, "\n{rhs}")?;
798 }
799 StmtKind::Qubit(s, lhs, rhs, block) => {
800 write!(indent, "Qubit ({s:?})")?;
801 indent = set_indentation(indent, 1);
802 write!(indent, "\n{lhs}")?;
803 write!(indent, "\n{rhs}")?;
804 if let Some(b) = block {
805 write!(indent, "\n{b}")?;
806 }
807 }
808 StmtKind::Semi(e) => write!(indent, "Semi: {e}")?,
809 StmtKind::Err => indent.write_str("Err")?,
810 }
811 Ok(())
812 }
813}
814
815/// An expression.
816#[derive(Clone, Debug, Default, PartialEq)]
817pub struct Expr {
818 /// The node ID.
819 pub id: NodeId,
820 /// The span.
821 pub span: Span,
822 /// The expression kind.
823 pub kind: Box<ExprKind>,
824}
825
826impl Display for Expr {
827 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
828 write!(f, "Expr {} {}: {}", self.id, self.span, self.kind)
829 }
830}
831
832impl WithSpan for Expr {
833 fn with_span(self, span: Span) -> Self {
834 Self { span, ..self }
835 }
836}
837
838/// An expression kind.
839#[derive(Clone, Debug, Default, PartialEq)]
840pub enum ExprKind {
841 /// An array: `[a, b, c]`.
842 Array(Box<[Box<Expr>]>),
843 /// An array constructed by repeating a value: `[a, size = b]`.
844 ArrayRepeat(Box<Expr>, Box<Expr>),
845 /// An assignment: `set a = b`.
846 Assign(Box<Expr>, Box<Expr>),
847 /// An assignment with a compound operator. For example: `set a += b`.
848 AssignOp(BinOp, Box<Expr>, Box<Expr>),
849 /// An assignment with a compound update operator: `set a w/= b <- c`.
850 AssignUpdate(Box<Expr>, Box<Expr>, Box<Expr>),
851 /// A binary operator.
852 BinOp(BinOp, Box<Expr>, Box<Expr>),
853 /// A block: `{ ... }`.
854 Block(Box<Block>),
855 /// A call: `a(b)`.
856 Call(Box<Expr>, Box<Expr>),
857 /// A conjugation: `within { ... } apply { ... }`.
858 Conjugate(Box<Block>, Box<Block>),
859 /// An expression with invalid syntax that can't be parsed.
860 #[default]
861 Err,
862 /// A failure: `fail "message"`.
863 Fail(Box<Expr>),
864 /// A field accessor: `a::F` or `a.F`.
865 Field(Box<Expr>, Box<Ident>),
866 /// A for loop: `for a in b { ... }`.
867 For(Box<Pat>, Box<Expr>, Box<Block>),
868 /// An unspecified expression, _, which may indicate partial application or a typed hole.
869 Hole,
870 /// An if expression with an optional else block: `if a { ... } else { ... }`.
871 ///
872 /// Note that, as a special case, `elif ...` is effectively parsed as `else if ...`, without a
873 /// block wrapping the `if`. This distinguishes `elif ...` from `else { if ... }`, which does
874 /// have a block.
875 If(Box<Expr>, Box<Block>, Option<Box<Expr>>),
876 /// An index accessor: `a[b]`.
877 Index(Box<Expr>, Box<Expr>),
878 /// An interpolated string.
879 Interpolate(Box<[StringComponent]>),
880 /// A lambda: `a -> b` for a function and `a => b` for an operation.
881 Lambda(CallableKind, Box<Pat>, Box<Expr>),
882 /// A literal.
883 Lit(Box<Lit>),
884 /// Parentheses: `(a)`.
885 Paren(Box<Expr>),
886 /// A path: `a` or `a.b`.
887 Path(PathKind),
888 /// A range: `start..step..end`, `start..end`, `start...`, `...end`, or `...`.
889 Range(Option<Box<Expr>>, Option<Box<Expr>>, Option<Box<Expr>>),
890 /// A repeat-until loop with an optional fixup: `repeat { ... } until a fixup { ... }`.
891 Repeat(Box<Block>, Box<Expr>, Option<Box<Block>>),
892 /// A return: `return a`.
893 Return(Box<Expr>),
894 /// A struct constructor.
895 Struct(PathKind, Option<Box<Expr>>, Box<[Box<FieldAssign>]>),
896 /// A ternary operator.
897 TernOp(TernOp, Box<Expr>, Box<Expr>, Box<Expr>),
898 /// A tuple: `(a, b, c)`.
899 Tuple(Box<[Box<Expr>]>),
900 /// A unary operator.
901 UnOp(UnOp, Box<Expr>),
902 /// A while loop: `while a { ... }`.
903 While(Box<Expr>, Box<Block>),
904}
905
906impl Display for ExprKind {
907 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
908 let mut indent = set_indentation(indented(f), 0);
909 match self {
910 ExprKind::Array(exprs) => display_array(indent, exprs)?,
911 ExprKind::ArrayRepeat(val, size) => display_array_repeat(indent, val, size)?,
912 ExprKind::Assign(lhs, rhs) => display_assign(indent, lhs, rhs)?,
913 ExprKind::AssignOp(op, lhs, rhs) => display_assign_op(indent, *op, lhs, rhs)?,
914 ExprKind::AssignUpdate(container, item, val) => {
915 display_assign_update(indent, container, item, val)?;
916 }
917 ExprKind::BinOp(op, lhs, rhs) => display_bin_op(indent, *op, lhs, rhs)?,
918 ExprKind::Block(block) => write!(indent, "Expr Block: {block}")?,
919 ExprKind::Call(callable, arg) => display_call(indent, callable, arg)?,
920 ExprKind::Conjugate(within, apply) => display_conjugate(indent, within, apply)?,
921 ExprKind::Err => write!(indent, "Err")?,
922 ExprKind::Fail(e) => write!(indent, "Fail: {e}")?,
923 ExprKind::Field(expr, id) => display_field(indent, expr, id)?,
924 ExprKind::For(iter, iterable, body) => display_for(indent, iter, iterable, body)?,
925 ExprKind::Hole => write!(indent, "Hole")?,
926 ExprKind::If(cond, body, els) => display_if(indent, cond, body, els)?,
927 ExprKind::Index(array, index) => display_index(indent, array, index)?,
928 ExprKind::Interpolate(components) => display_interpolate(indent, components)?,
929 ExprKind::Lambda(kind, param, expr) => display_lambda(indent, *kind, param, expr)?,
930 ExprKind::Lit(lit) => write!(indent, "Lit: {lit}")?,
931 ExprKind::Paren(e) => write!(indent, "Paren: {e}")?,
932 ExprKind::Path(p) => write!(indent, "Path: {p}")?,
933 ExprKind::Range(start, step, end) => display_range(indent, start, step, end)?,
934 ExprKind::Repeat(repeat, until, fixup) => display_repeat(indent, repeat, until, fixup)?,
935 ExprKind::Return(e) => write!(indent, "Return: {e}")?,
936 ExprKind::Struct(name, copy, fields) => display_struct(indent, name, copy, fields)?,
937 ExprKind::TernOp(op, expr1, expr2, expr3) => {
938 display_tern_op(indent, *op, expr1, expr2, expr3)?;
939 }
940 ExprKind::Tuple(exprs) => display_tuple(indent, exprs)?,
941 ExprKind::UnOp(op, expr) => display_un_op(indent, *op, expr)?,
942 ExprKind::While(cond, block) => display_while(indent, cond, block)?,
943 }
944 Ok(())
945 }
946}
947
948fn display_array(mut indent: Indented<Formatter>, exprs: &[Box<Expr>]) -> fmt::Result {
949 write!(indent, "Array:")?;
950 indent = set_indentation(indent, 1);
951 for e in exprs {
952 write!(indent, "\n{e}")?;
953 }
954 Ok(())
955}
956
957fn display_array_repeat(mut indent: Indented<Formatter>, val: &Expr, size: &Expr) -> fmt::Result {
958 write!(indent, "ArrayRepeat:")?;
959 indent = set_indentation(indent, 1);
960 write!(indent, "\n{val}")?;
961 write!(indent, "\n{size}")?;
962 Ok(())
963}
964
965fn display_assign(mut indent: Indented<Formatter>, lhs: &Expr, rhs: &Expr) -> fmt::Result {
966 write!(indent, "Assign:")?;
967 indent = set_indentation(indent, 1);
968 write!(indent, "\n{lhs}")?;
969 write!(indent, "\n{rhs}")?;
970 Ok(())
971}
972
973fn display_assign_op(
974 mut indent: Indented<Formatter>,
975 op: BinOp,
976 lhs: &Expr,
977 rhs: &Expr,
978) -> fmt::Result {
979 write!(indent, "AssignOp ({op:?}):")?;
980 indent = set_indentation(indent, 1);
981 write!(indent, "\n{lhs}")?;
982 write!(indent, "\n{rhs}")?;
983 Ok(())
984}
985
986fn display_assign_update(
987 mut indent: Indented<Formatter>,
988 container: &Expr,
989 item: &Expr,
990 val: &Expr,
991) -> fmt::Result {
992 write!(indent, "AssignUpdate:")?;
993 indent = set_indentation(indent, 1);
994 write!(indent, "\n{container}")?;
995 write!(indent, "\n{item}")?;
996 write!(indent, "\n{val}")?;
997 Ok(())
998}
999
1000fn display_bin_op(
1001 mut indent: Indented<Formatter>,
1002 op: BinOp,
1003 lhs: &Expr,
1004 rhs: &Expr,
1005) -> fmt::Result {
1006 write!(indent, "BinOp ({op:?}):")?;
1007 indent = set_indentation(indent, 1);
1008 write!(indent, "\n{lhs}")?;
1009 write!(indent, "\n{rhs}")?;
1010 Ok(())
1011}
1012
1013fn display_call(mut indent: Indented<Formatter>, callable: &Expr, arg: &Expr) -> fmt::Result {
1014 write!(indent, "Call:")?;
1015 indent = set_indentation(indent, 1);
1016 write!(indent, "\n{callable}")?;
1017 write!(indent, "\n{arg}")?;
1018 Ok(())
1019}
1020
1021fn display_conjugate(
1022 mut indent: Indented<Formatter>,
1023 within: &Block,
1024 apply: &Block,
1025) -> fmt::Result {
1026 write!(indent, "Conjugate:")?;
1027 indent = set_indentation(indent, 1);
1028 write!(indent, "\n{within}")?;
1029 write!(indent, "\n{apply}")?;
1030 Ok(())
1031}
1032
1033fn display_field(mut indent: Indented<Formatter>, expr: &Expr, id: &Ident) -> fmt::Result {
1034 write!(indent, "Field:")?;
1035 indent = set_indentation(indent, 1);
1036 write!(indent, "\n{expr}")?;
1037 write!(indent, "\n{id}")?;
1038 Ok(())
1039}
1040
1041fn display_for(
1042 mut indent: Indented<Formatter>,
1043 iter: &Pat,
1044 iterable: &Expr,
1045 body: &Block,
1046) -> fmt::Result {
1047 write!(indent, "For:")?;
1048 indent = set_indentation(indent, 1);
1049 write!(indent, "\n{iter}")?;
1050 write!(indent, "\n{iterable}")?;
1051 write!(indent, "\n{body}")?;
1052 Ok(())
1053}
1054
1055fn display_if(
1056 mut indent: Indented<Formatter>,
1057 cond: &Expr,
1058 body: &Block,
1059 els: &Option<Box<Expr>>,
1060) -> fmt::Result {
1061 write!(indent, "If:")?;
1062 indent = set_indentation(indent, 1);
1063 write!(indent, "\n{cond}")?;
1064 write!(indent, "\n{body}")?;
1065 if let Some(e) = els {
1066 write!(indent, "\n{e}")?;
1067 }
1068 Ok(())
1069}
1070
1071fn display_index(mut indent: Indented<Formatter>, array: &Expr, index: &Expr) -> fmt::Result {
1072 write!(indent, "Index:")?;
1073 indent = set_indentation(indent, 1);
1074 write!(indent, "\n{array}")?;
1075 write!(indent, "\n{index}")?;
1076 Ok(())
1077}
1078
1079fn display_interpolate(
1080 mut indent: Indented<Formatter>,
1081 components: &[StringComponent],
1082) -> fmt::Result {
1083 write!(indent, "Interpolate:")?;
1084 indent = set_indentation(indent, 1);
1085 for component in components {
1086 match component {
1087 StringComponent::Expr(expr) => write!(indent, "\nExpr: {expr}")?,
1088 StringComponent::Lit(str) => write!(indent, "\nLit: {str:?}")?,
1089 }
1090 }
1091
1092 Ok(())
1093}
1094
1095fn display_lambda(
1096 mut indent: Indented<Formatter>,
1097 kind: CallableKind,
1098 param: &Pat,
1099 expr: &Expr,
1100) -> fmt::Result {
1101 write!(indent, "Lambda ({kind:?}):")?;
1102 indent = set_indentation(indent, 1);
1103 write!(indent, "\n{param}")?;
1104 write!(indent, "\n{expr}")?;
1105 Ok(())
1106}
1107
1108fn display_range(
1109 mut indent: Indented<Formatter>,
1110 start: &Option<Box<Expr>>,
1111 step: &Option<Box<Expr>>,
1112 end: &Option<Box<Expr>>,
1113) -> fmt::Result {
1114 write!(indent, "Range:")?;
1115 indent = set_indentation(indent, 1);
1116 match start {
1117 Some(e) => write!(indent, "\n{e}")?,
1118 None => write!(indent, "\n<no start>")?,
1119 }
1120 match step {
1121 Some(e) => write!(indent, "\n{e}")?,
1122 None => write!(indent, "\n<no step>")?,
1123 }
1124 match end {
1125 Some(e) => write!(indent, "\n{e}")?,
1126 None => write!(indent, "\n<no end>")?,
1127 }
1128 Ok(())
1129}
1130
1131fn display_repeat(
1132 mut indent: Indented<Formatter>,
1133 repeat: &Block,
1134 until: &Expr,
1135 fixup: &Option<Box<Block>>,
1136) -> fmt::Result {
1137 write!(indent, "Repeat:")?;
1138 indent = set_indentation(indent, 1);
1139 write!(indent, "\n{repeat}")?;
1140 write!(indent, "\n{until}")?;
1141 match fixup {
1142 Some(b) => write!(indent, "\n{b}")?,
1143 None => write!(indent, "\n<no fixup>")?,
1144 }
1145 Ok(())
1146}
1147
1148fn display_struct(
1149 mut indent: Indented<Formatter>,
1150 name: &PathKind,
1151 copy: &Option<Box<Expr>>,
1152 fields: &[Box<FieldAssign>],
1153) -> fmt::Result {
1154 write!(indent, "Struct ({name}):")?;
1155 if copy.is_none() && fields.is_empty() {
1156 write!(indent, " <empty>")?;
1157 return Ok(());
1158 }
1159 indent = set_indentation(indent, 1);
1160 if let Some(copy) = copy {
1161 write!(indent, "\nCopy: {copy}")?;
1162 }
1163 for field in fields {
1164 write!(indent, "\n{field}")?;
1165 }
1166 Ok(())
1167}
1168
1169fn display_tern_op(
1170 mut indent: Indented<Formatter>,
1171 op: TernOp,
1172 expr1: &Expr,
1173 expr2: &Expr,
1174 expr3: &Expr,
1175) -> fmt::Result {
1176 write!(indent, "TernOp ({op:?}):")?;
1177 indent = set_indentation(indent, 1);
1178 write!(indent, "\n{expr1}")?;
1179 write!(indent, "\n{expr2}")?;
1180 write!(indent, "\n{expr3}")?;
1181 Ok(())
1182}
1183
1184fn display_tuple(mut indent: Indented<Formatter>, exprs: &[Box<Expr>]) -> fmt::Result {
1185 if exprs.is_empty() {
1186 write!(indent, "Unit")?;
1187 } else {
1188 write!(indent, "Tuple:")?;
1189 indent = set_indentation(indent, 1);
1190 for e in exprs {
1191 write!(indent, "\n{e}")?;
1192 }
1193 }
1194 Ok(())
1195}
1196
1197fn display_un_op(mut indent: Indented<Formatter>, op: UnOp, expr: &Expr) -> fmt::Result {
1198 write!(indent, "UnOp ({op}):")?;
1199 indent = set_indentation(indent, 1);
1200 write!(indent, "\n{expr}")?;
1201 Ok(())
1202}
1203
1204fn display_while(mut indent: Indented<Formatter>, cond: &Expr, block: &Block) -> fmt::Result {
1205 write!(indent, "While:")?;
1206 indent = set_indentation(indent, 1);
1207 write!(indent, "\n{cond}")?;
1208 write!(indent, "\n{block}")?;
1209 Ok(())
1210}
1211
1212/// A field assignment in a struct constructor expression.
1213#[derive(Clone, Debug, Default, PartialEq)]
1214pub struct FieldAssign {
1215 /// The node ID.
1216 pub id: NodeId,
1217 /// The span.
1218 pub span: Span,
1219 /// The field to assign.
1220 pub field: Box<Ident>,
1221 /// The value to assign to the field.
1222 pub value: Box<Expr>,
1223}
1224
1225impl WithSpan for FieldAssign {
1226 fn with_span(self, span: Span) -> Self {
1227 Self { span, ..self }
1228 }
1229}
1230
1231impl Display for FieldAssign {
1232 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1233 write!(
1234 f,
1235 "FieldsAssign {} {}: ({}) {}",
1236 self.id, self.span, self.field, self.value
1237 )
1238 }
1239}
1240
1241/// An interpolated string component.
1242#[derive(Clone, Debug, PartialEq)]
1243pub enum StringComponent {
1244 /// An expression.
1245 Expr(Box<Expr>),
1246 /// A string literal.
1247 Lit(Rc<str>),
1248}
1249
1250/// A pattern.
1251#[derive(Clone, Debug, Eq, Hash, PartialEq, Default)]
1252pub struct Pat {
1253 /// The node ID.
1254 pub id: NodeId,
1255 /// The span.
1256 pub span: Span,
1257 /// The pattern kind.
1258 pub kind: Box<PatKind>,
1259}
1260
1261impl Display for Pat {
1262 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1263 write!(f, "Pat {} {}: {}", self.id, self.span, self.kind)
1264 }
1265}
1266
1267impl WithSpan for Pat {
1268 fn with_span(self, span: Span) -> Self {
1269 Self { span, ..self }
1270 }
1271}
1272
1273/// A pattern kind.
1274#[derive(Clone, Debug, Eq, Hash, PartialEq, Default)]
1275pub enum PatKind {
1276 /// A binding with an optional type annotation.
1277 Bind(Box<Ident>, Option<Box<Ty>>),
1278 /// A discarded binding, `_`, with an optional type annotation.
1279 Discard(Option<Box<Ty>>),
1280 /// An elided pattern, `...`, used by specializations.
1281 Elided,
1282 /// Parentheses: `(a)`.
1283 Paren(Box<Pat>),
1284 /// A tuple: `(a, b, c)`.
1285 Tuple(Box<[Box<Pat>]>),
1286 /// An invalid pattern.
1287 #[default]
1288 Err,
1289}
1290
1291impl Display for PatKind {
1292 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1293 let mut indent = set_indentation(indented(f), 0);
1294 match self {
1295 PatKind::Bind(id, ty) => {
1296 write!(indent, "Bind:")?;
1297 indent = set_indentation(indent, 1);
1298 write!(indent, "\n{id}")?;
1299 if let Some(t) = ty {
1300 write!(indent, "\n{t}")?;
1301 }
1302 }
1303 PatKind::Discard(d) => match d {
1304 Some(t) => {
1305 write!(indent, "Discard:")?;
1306 indent = set_indentation(indent, 1);
1307 write!(indent, "\n{t}")?;
1308 }
1309 None => write!(indent, "Discard")?,
1310 },
1311 PatKind::Elided => write!(indent, "Elided")?,
1312 PatKind::Paren(p) => {
1313 write!(indent, "Paren:")?;
1314 indent = set_indentation(indent, 1);
1315 write!(indent, "\n{p}")?;
1316 }
1317 PatKind::Tuple(ps) => {
1318 if ps.is_empty() {
1319 write!(indent, "Unit")?;
1320 } else {
1321 write!(indent, "Tuple:")?;
1322 indent = set_indentation(indent, 1);
1323 for p in ps {
1324 write!(indent, "\n{p}")?;
1325 }
1326 }
1327 }
1328 PatKind::Err => write!(indent, "Err")?,
1329 }
1330 Ok(())
1331 }
1332}
1333
1334/// A qubit initializer.
1335#[derive(Clone, Debug, PartialEq, Default)]
1336pub struct QubitInit {
1337 /// The node ID.
1338 pub id: NodeId,
1339 /// The span.
1340 pub span: Span,
1341 /// The qubit initializer kind.
1342 pub kind: Box<QubitInitKind>,
1343}
1344
1345impl Display for QubitInit {
1346 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1347 write!(f, "QubitInit {} {} {}", self.id, self.span, self.kind)
1348 }
1349}
1350
1351impl WithSpan for QubitInit {
1352 fn with_span(self, span: Span) -> Self {
1353 Self { span, ..self }
1354 }
1355}
1356
1357/// A qubit initializer kind.
1358#[derive(Clone, Debug, PartialEq, Default)]
1359pub enum QubitInitKind {
1360 /// An array of qubits: `Qubit[a]`.
1361 Array(Box<Expr>),
1362 /// A parenthesized initializer: `(a)`.
1363 Paren(Box<QubitInit>),
1364 /// A single qubit: `Qubit()`.
1365 Single,
1366 /// A tuple: `(a, b, c)`.
1367 Tuple(Box<[Box<QubitInit>]>),
1368 /// An invalid initializer.
1369 #[default]
1370 Err,
1371}
1372
1373impl Display for QubitInitKind {
1374 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1375 let mut indent = set_indentation(indented(f), 0);
1376 match self {
1377 QubitInitKind::Array(e) => {
1378 write!(indent, "Array:")?;
1379 indent = set_indentation(indent, 1);
1380 write!(indent, "\n{e}")?;
1381 }
1382 QubitInitKind::Paren(qi) => {
1383 write!(indent, "Parens:")?;
1384 indent = set_indentation(indent, 1);
1385 write!(indent, "\n{qi}")?;
1386 }
1387 QubitInitKind::Single => write!(indent, "Single")?,
1388 QubitInitKind::Tuple(qis) => {
1389 if qis.is_empty() {
1390 write!(indent, "Unit")?;
1391 } else {
1392 write!(indent, "Tuple:")?;
1393 indent = set_indentation(indent, 1);
1394 for qi in qis {
1395 write!(indent, "\n{qi}")?;
1396 }
1397 }
1398 }
1399 QubitInitKind::Err => write!(indent, "Err")?,
1400 }
1401 Ok(())
1402 }
1403}
1404
1405/// A path that may or may not have been successfully parsed.
1406#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1407pub enum PathKind {
1408 /// A successfully parsed path.
1409 Ok(Box<Path>),
1410
1411 /// An invalid path.
1412 Err(Option<Box<IncompletePath>>),
1413}
1414
1415impl Default for PathKind {
1416 fn default() -> Self {
1417 PathKind::Err(None)
1418 }
1419}
1420
1421/// A path that was successfully parsed up to a certain `.`,
1422/// but is missing its final identifier.
1423#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1424pub struct IncompletePath {
1425 /// The whole span of the incomplete path,
1426 /// including the final `.` and any whitespace or keyword
1427 /// that follows it.
1428 pub span: Span,
1429 /// Any segments that were successfully parsed before the final `.`.
1430 pub segments: Box<[Ident]>,
1431 /// Whether a keyword exists after the final `.`.
1432 /// This keyword can be presumed to be a partially typed identifier.
1433 pub keyword: bool,
1434}
1435
1436impl Display for PathKind {
1437 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1438 match self {
1439 PathKind::Ok(path) => write!(f, "{path}")?,
1440 PathKind::Err(Some(incomplete_path)) => {
1441 let mut indent = set_indentation(indented(f), 0);
1442 write!(indent, "Err IncompletePath {}:", incomplete_path.span)?;
1443 indent = set_indentation(indent, 1);
1444 for part in &incomplete_path.segments {
1445 write!(indent, "\n{part}")?;
1446 }
1447 }
1448 PathKind::Err(None) => write!(f, "Err",)?,
1449 }
1450 Ok(())
1451 }
1452}
1453
1454/// A path to a declaration or a field access expression,
1455/// to be disambiguated during name resolution.
1456#[derive(Clone, Debug, Eq, Hash, PartialEq)]
1457pub struct Path {
1458 /// The node ID.
1459 pub id: NodeId,
1460 /// The span.
1461 pub span: Span,
1462 /// The segments that make up the front of the path before the final `.`.
1463 pub segments: Option<Box<[Ident]>>,
1464 /// The declaration or field name.
1465 pub name: Box<Ident>,
1466}
1467
1468impl Display for Path {
1469 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1470 if self.segments.is_none() {
1471 write!(f, "Path {} {} ({})", self.id, self.span, self.name)?;
1472 } else {
1473 let mut indent = set_indentation(indented(f), 0);
1474 write!(indent, "Path {} {}:", self.id, self.span)?;
1475 indent = set_indentation(indent, 1);
1476 if let Some(parts) = &self.segments {
1477 for part in parts {
1478 write!(indent, "\n{part}")?;
1479 }
1480 }
1481 write!(indent, "\n{}", self.name)?;
1482 }
1483 Ok(())
1484 }
1485}
1486
1487impl WithSpan for Path {
1488 fn with_span(self, span: Span) -> Self {
1489 Self { span, ..self }
1490 }
1491}
1492
1493/// An identifier.
1494#[derive(Clone, Debug, Eq, Hash, PartialEq)]
1495pub struct Ident {
1496 /// The node ID.
1497 pub id: NodeId,
1498 /// The span.
1499 pub span: Span,
1500 /// The identifier name.
1501 pub name: Rc<str>,
1502}
1503
1504impl Default for Ident {
1505 fn default() -> Self {
1506 Ident {
1507 id: NodeId::default(),
1508 span: Span::default(),
1509 name: "".into(),
1510 }
1511 }
1512}
1513
1514impl WithSpan for Ident {
1515 fn with_span(self, span: Span) -> Self {
1516 Self { span, ..self }
1517 }
1518}
1519
1520impl Display for Ident {
1521 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1522 write!(f, "Ident {} {} \"{}\"", self.id, self.span, self.name)
1523 }
1524}
1525
1526/// Trait for working with dot-separated sequences of identifiers,
1527/// intended to unify the different representations that can appear
1528/// in the AST (`Path`s and `Ident` slices).
1529pub trait Idents {
1530 /// Iterates over the [`Ident`]s in this sequence.
1531 fn iter(&self) -> impl Iterator<Item = &Ident>;
1532
1533 /// The full dot-separated name represented by this [`Ident`] sequence.
1534 /// E.g. `a.b.c`
1535 fn full_name(&self) -> Rc<str> {
1536 let mut strs = self.rc_str_iter();
1537 let first = strs.next();
1538 let Some(first) = first else {
1539 // No parts, empty string
1540 return "".into();
1541 };
1542
1543 let next = strs.next();
1544 let Some(mut part) = next else {
1545 // Only one ident, return it directly
1546 return first.clone();
1547 };
1548
1549 // More than one ident, build up a dotted string
1550 let mut buf = String::new();
1551 buf.push_str(first);
1552 loop {
1553 buf.push('.');
1554 buf.push_str(part);
1555 part = match strs.next() {
1556 Some(part) => part,
1557 None => {
1558 break;
1559 }
1560 };
1561 }
1562 buf.into()
1563 }
1564
1565 /// Iterates over the identifier names as string slices.
1566 fn str_iter(&self) -> impl Iterator<Item = &str> {
1567 self.iter().map(|ident| ident.name.as_ref())
1568 }
1569
1570 /// Iterates over the identifier names as `Rc<str>`s.
1571 fn rc_str_iter(&self) -> impl Iterator<Item = &Rc<str>> {
1572 self.iter().map(|ident| &ident.name)
1573 }
1574
1575 /// Returns the conjoined span of all [`Ident`]s in this collection.
1576 #[must_use]
1577 fn full_span(&self) -> Span {
1578 let mut idents = self.iter().peekable();
1579 Span {
1580 lo: idents.peek().map(|i| i.span.lo).unwrap_or_default(),
1581 hi: idents.last().map(|i| i.span.hi).unwrap_or_default(),
1582 }
1583 }
1584}
1585
1586impl Idents for Box<[Ident]> {
1587 fn iter(&self) -> impl Iterator<Item = &Ident> {
1588 self.as_ref().iter() // invokes the slice iterator
1589 }
1590}
1591
1592impl Idents for &[Ident] {
1593 fn iter(&self) -> impl Iterator<Item = &Ident> {
1594 (*self).iter() // invokes the slice iterator
1595 }
1596}
1597
1598impl<T, U> Idents for (&T, &U)
1599where
1600 T: Idents,
1601 U: Idents,
1602{
1603 fn iter(&self) -> impl Iterator<Item = &Ident> {
1604 self.0.iter().chain(self.1.iter())
1605 }
1606}
1607
1608impl Idents for Ident {
1609 fn iter(&self) -> impl Iterator<Item = &Ident> {
1610 once(self)
1611 }
1612}
1613
1614impl Idents for Path {
1615 fn iter(&self) -> impl Iterator<Item = &Ident> {
1616 self.segments
1617 .iter()
1618 .flat_map(Idents::iter)
1619 .chain(once(self.name.as_ref()))
1620 }
1621}
1622
1623/// A callable kind.
1624#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1625pub enum CallableKind {
1626 /// A function.
1627 Function,
1628 /// An operation.
1629 Operation,
1630}
1631
1632/// The mutability of a binding.
1633#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1634pub enum Mutability {
1635 /// An immutable binding.
1636 Immutable,
1637 /// A mutable binding.
1638 Mutable,
1639}
1640
1641/// The source of an allocated qubit.
1642#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1643pub enum QubitSource {
1644 /// A qubit initialized to the zero state.
1645 Fresh,
1646 /// A qubit borrowed from another part of the program that may be in any state, and is expected
1647 /// to be returned to that state before being released.
1648 Dirty,
1649}
1650
1651/// A literal.
1652#[derive(Clone, Debug, PartialEq)]
1653pub enum Lit {
1654 /// A big integer literal.
1655 BigInt(Box<BigInt>),
1656 /// A boolean literal.
1657 Bool(bool),
1658 /// A floating-point literal.
1659 Double(f64),
1660 /// An integer literal.
1661 Int(i64),
1662 /// A Pauli operator literal.
1663 Pauli(Pauli),
1664 /// A measurement result literal.
1665 Result(Result),
1666 /// A string literal.
1667 String(Rc<str>),
1668}
1669
1670impl Display for Lit {
1671 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1672 match self {
1673 Lit::BigInt(val) => write!(f, "BigInt({val})")?,
1674 Lit::Bool(val) => write!(f, "Bool({val})")?,
1675 Lit::Double(val) => write!(f, "Double({val})")?,
1676 Lit::Int(val) => write!(f, "Int({val})")?,
1677 Lit::Pauli(val) => write!(f, "Pauli({val:?})")?,
1678 Lit::Result(val) => write!(f, "Result({val:?})")?,
1679 Lit::String(val) => write!(f, "String({val:?})")?,
1680 }
1681 Ok(())
1682 }
1683}
1684
1685/// A measurement result.
1686#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1687pub enum Result {
1688 /// The zero eigenvalue.
1689 Zero,
1690 /// The one eigenvalue.
1691 One,
1692}
1693
1694impl From<bool> for Result {
1695 fn from(b: bool) -> Self {
1696 if b {
1697 Result::One
1698 } else {
1699 Result::Zero
1700 }
1701 }
1702}
1703
1704/// A Pauli operator.
1705#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1706pub enum Pauli {
1707 /// The Pauli I operator.
1708 I,
1709 /// The Pauli X operator.
1710 X,
1711 /// The Pauli Y operator.
1712 Y,
1713 /// The Pauli Z operator.
1714 Z,
1715}
1716
1717/// A functor that may be applied to an operation.
1718#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1719pub enum Functor {
1720 /// The adjoint functor.
1721 Adj,
1722 /// The controlled functor.
1723 Ctl,
1724}
1725
1726/// A specialization that may be implemented for an operation.
1727#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1728pub enum Spec {
1729 /// The default specialization.
1730 Body,
1731 /// The adjoint specialization.
1732 Adj,
1733 /// The controlled specialization.
1734 Ctl,
1735 /// The controlled adjoint specialization.
1736 CtlAdj,
1737}
1738
1739impl Display for Spec {
1740 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1741 match self {
1742 Spec::Body => f.write_str("body"),
1743 Spec::Adj => f.write_str("adjoint"),
1744 Spec::Ctl => f.write_str("controlled"),
1745 Spec::CtlAdj => f.write_str("controlled adjoint"),
1746 }
1747 }
1748}
1749
1750/// A strategy for generating a specialization.
1751#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1752pub enum SpecGen {
1753 /// Choose a strategy automatically.
1754 Auto,
1755 /// Distributes controlled qubits.
1756 Distribute,
1757 /// A specialization implementation is not generated, but is instead left as an opaque
1758 /// declaration.
1759 Intrinsic,
1760 /// Inverts the order of operations.
1761 Invert,
1762 /// Uses the body specialization without modification.
1763 Slf,
1764}
1765
1766/// A unary operator.
1767#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1768pub enum UnOp {
1769 /// A functor application.
1770 Functor(Functor),
1771 /// Negation: `-`.
1772 Neg,
1773 /// Bitwise NOT: `~~~`.
1774 NotB,
1775 /// Logical NOT: `not`.
1776 NotL,
1777 /// A leading `+`.
1778 Pos,
1779 /// Unwrap a user-defined type: `!`.
1780 Unwrap,
1781}
1782
1783impl Display for UnOp {
1784 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1785 match self {
1786 UnOp::Functor(func) => write!(f, "Functor {func:?}")?,
1787 _ => fmt::Debug::fmt(self, f)?,
1788 }
1789 Ok(())
1790 }
1791}
1792
1793/// A binary operator.
1794#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1795pub enum BinOp {
1796 /// Addition: `+`.
1797 Add,
1798 /// Bitwise AND: `&&&`.
1799 AndB,
1800 /// Logical AND: `and`.
1801 AndL,
1802 /// Division: `/`.
1803 Div,
1804 /// Equality: `==`.
1805 Eq,
1806 /// Exponentiation: `^`.
1807 Exp,
1808 /// Greater than: `>`.
1809 Gt,
1810 /// Greater than or equal: `>=`.
1811 Gte,
1812 /// Less than: `<`.
1813 Lt,
1814 /// Less than or equal: `<=`.
1815 Lte,
1816 /// Modulus: `%`.
1817 Mod,
1818 /// Multiplication: `*`.
1819 Mul,
1820 /// Inequality: `!=`.
1821 Neq,
1822 /// Bitwise OR: `|||`.
1823 OrB,
1824 /// Logical OR: `or`.
1825 OrL,
1826 /// Shift left: `<<<`.
1827 Shl,
1828 /// Shift right: `>>>`.
1829 Shr,
1830 /// Subtraction: `-`.
1831 Sub,
1832 /// Bitwise XOR: `^^^`.
1833 XorB,
1834}
1835
1836/// A ternary operator.
1837#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1838pub enum TernOp {
1839 /// Conditional: `a ? b | c`.
1840 Cond,
1841 /// Aggregate update: `a w/ b <- c`.
1842 Update,
1843}
1844
1845/// A set operator.
1846#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1847pub enum SetOp {
1848 /// The set union.
1849 Union,
1850 /// The set intersection.
1851 Intersect,
1852}
1853
1854#[derive(Clone, Debug, Eq, PartialEq)]
1855/// Represents an export declaration.
1856pub struct ImportOrExportDecl {
1857 /// The span.
1858 pub span: Span,
1859 /// The items being exported from this namespace.
1860 pub items: Box<[ImportOrExportItem]>,
1861 /// Whether this is an export declaration or not. If `false`, then this is an `Import`.
1862 is_export: bool,
1863}
1864
1865impl Display for ImportOrExportDecl {
1866 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1867 let items_str = self
1868 .items
1869 .iter()
1870 .map(std::string::ToString::to_string)
1871 .collect::<Vec<_>>()
1872 .join(", ");
1873 write!(f, "ImportOrExportDecl {}: [{items_str}]", self.span)
1874 }
1875}
1876
1877impl ImportOrExportDecl {
1878 /// Creates a new `ImportOrExportDecl` with the given span, items, and export flag.
1879 #[must_use]
1880 pub fn new(span: Span, items: Box<[ImportOrExportItem]>, is_export: bool) -> Self {
1881 Self {
1882 span,
1883 items,
1884 is_export,
1885 }
1886 }
1887
1888 /// Returns true if this is an export declaration.
1889 #[must_use]
1890 pub fn is_export(&self) -> bool {
1891 self.is_export
1892 }
1893
1894 /// Returns true if this is an import declaration.
1895 #[must_use]
1896 pub fn is_import(&self) -> bool {
1897 !self.is_export
1898 }
1899
1900 /// Returns an iterator over the items being exported from this namespace.
1901 pub fn items(&self) -> impl Iterator<Item = &ImportOrExportItem> {
1902 self.items.iter()
1903 }
1904}
1905
1906/// An individual item within an [`ImportOrExportDecl`]. This can be a path or a path with an alias.
1907#[derive(Clone, Debug, Eq, PartialEq, Default)]
1908pub struct ImportOrExportItem {
1909 /// The span of the import path including the glob and alias, if any.
1910 pub span: Span,
1911 /// The path to the item being exported.
1912 pub path: PathKind,
1913 /// An optional alias for the item being exported.
1914 pub alias: Option<Ident>,
1915 /// Whether this is a glob import/export.
1916 pub is_glob: bool,
1917}
1918
1919impl Display for ImportOrExportItem {
1920 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1921 let ImportOrExportItem {
1922 span: _,
1923 ref path,
1924 ref alias,
1925 is_glob,
1926 } = self;
1927 let is_glob = if *is_glob { ".*" } else { "" };
1928 match alias {
1929 Some(alias) => write!(f, "{path}{is_glob} as {alias}",),
1930 None => write!(f, "{path}{is_glob}"),
1931 }
1932 }
1933}
1934
1935impl WithSpan for ImportOrExportItem {
1936 fn with_span(self, span: Span) -> Self {
1937 Self { span, ..self }
1938 }
1939}
1940
1941impl ImportOrExportItem {
1942 /// Returns the alias ident, if any, or the name from the path if no alias is present.
1943 /// Returns `None` if the path has an error.
1944 #[must_use]
1945 pub fn name(&self) -> Option<&Ident> {
1946 match &self.alias {
1947 Some(_) => self.alias.as_ref(),
1948 None => {
1949 if let PathKind::Ok(path) = &self.path {
1950 Some(&path.name)
1951 } else {
1952 None
1953 }
1954 }
1955 }
1956 }
1957}
1958