microsoft/qdk

Public

mirrored from https://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
alex/testHarnessIntegTests

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc_ast/src/ast.rs

2110lines · 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<[TypeParameter]>,
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 let mut buf = Vec::with_capacity(self.generics.len());
514 for param in &self.generics {
515 buf.push(format!("{param}"));
516 }
517
518 let buf = buf.join(",\n");
519 write!(indent, "\n{buf}")?;
520 indent = set_indentation(indent, 1);
521 }
522 write!(indent, "\ninput: {}", self.input)?;
523 write!(indent, "\noutput: {}", self.output)?;
524 if let Some(f) = &self.functors {
525 write!(indent, "\nfunctors: {}", f.as_ref())?;
526 }
527 write!(indent, "\nbody: {}", self.body)?;
528 Ok(())
529 }
530}
531
532/// The body of a callable.
533#[derive(Clone, Debug, PartialEq)]
534pub enum CallableBody {
535 /// A block for the callable's body specialization.
536 Block(Box<Block>),
537 /// One or more explicit specializations.
538 Specs(Box<[Box<SpecDecl>]>),
539}
540
541impl Display for CallableBody {
542 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
543 match self {
544 CallableBody::Block(body) => write!(f, "Block: {body}")?,
545 CallableBody::Specs(specs) => {
546 let mut indent = set_indentation(indented(f), 0);
547 write!(indent, "Specializations:")?;
548 indent = set_indentation(indent, 1);
549 for spec in specs {
550 write!(indent, "\n{spec}")?;
551 }
552 }
553 }
554 Ok(())
555 }
556}
557
558/// A specialization declaration.
559#[derive(Clone, Debug, PartialEq)]
560pub struct SpecDecl {
561 /// The node ID.
562 pub id: NodeId,
563 /// The span.
564 pub span: Span,
565 /// Which specialization is being declared.
566 pub spec: Spec,
567 /// The body of the specialization.
568 pub body: SpecBody,
569}
570
571impl Display for SpecDecl {
572 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
573 write!(
574 f,
575 "SpecDecl {} {} ({:?}): {}",
576 self.id, self.span, self.spec, self.body
577 )
578 }
579}
580
581/// The body of a specialization.
582#[derive(Clone, Debug, PartialEq)]
583pub enum SpecBody {
584 /// The strategy to use to automatically generate the specialization.
585 Gen(SpecGen),
586 /// A manual implementation of the specialization.
587 Impl(Box<Pat>, Box<Block>),
588}
589
590impl Display for SpecBody {
591 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
592 let mut indent = set_indentation(indented(f), 0);
593 match self {
594 SpecBody::Gen(sg) => write!(indent, "Gen: {sg:?}")?,
595 SpecBody::Impl(p, b) => {
596 write!(indent, "Impl:")?;
597 indent = set_indentation(indent, 1);
598 write!(indent, "\n{p}")?;
599 write!(indent, "\n{b}")?;
600 }
601 }
602 Ok(())
603 }
604}
605
606/// An expression that describes a set of functors.
607#[derive(Clone, Debug, Eq, Hash, PartialEq)]
608pub struct FunctorExpr {
609 /// The node ID.
610 pub id: NodeId,
611 /// The span.
612 pub span: Span,
613 /// The functor expression kind.
614 pub kind: Box<FunctorExprKind>,
615}
616
617impl Display for FunctorExpr {
618 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
619 write!(f, "Functor Expr {} {}: {}", self.id, self.span, self.kind)
620 }
621}
622
623/// A functor expression kind.
624#[derive(Clone, Debug, Eq, Hash, PartialEq)]
625pub enum FunctorExprKind {
626 /// A binary operation.
627 BinOp(SetOp, Box<FunctorExpr>, Box<FunctorExpr>),
628 /// A literal for a specific functor.
629 Lit(Functor),
630 /// A parenthesized group.
631 Paren(Box<FunctorExpr>),
632}
633
634impl Display for FunctorExprKind {
635 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
636 match self {
637 FunctorExprKind::BinOp(op, l, r) => write!(f, "BinOp {op:?}: ({l}) ({r})"),
638 FunctorExprKind::Lit(func) => write!(f, "{func:?}"),
639 FunctorExprKind::Paren(func) => write!(f, "Paren: {func}"),
640 }
641 }
642}
643
644/// A type.
645#[derive(Clone, Debug, Eq, Hash, PartialEq, Default)]
646pub struct Ty {
647 /// The node ID.
648 pub id: NodeId,
649 /// The span.
650 pub span: Span,
651 /// The type kind.
652 pub kind: Box<TyKind>,
653}
654
655impl Display for Ty {
656 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
657 write!(f, "Type {} {}: {}", self.id, self.span, self.kind)
658 }
659}
660
661impl WithSpan for Ty {
662 fn with_span(self, span: Span) -> Self {
663 Self { span, ..self }
664 }
665}
666
667/// A type kind.
668#[derive(Clone, Debug, Eq, Hash, PartialEq, Default)]
669pub enum TyKind {
670 /// An array type.
671 Array(Box<Ty>),
672 /// An arrow type: `->` for a function or `=>` for an operation.
673 Arrow(CallableKind, Box<Ty>, Box<Ty>, Option<Box<FunctorExpr>>),
674 /// An unspecified type, `_`, which may be inferred.
675 Hole,
676 /// A type wrapped in parentheses.
677 Paren(Box<Ty>),
678 /// A named type.
679 Path(PathKind),
680 /// A type parameter.
681 Param(TypeParameter),
682 /// A tuple type.
683 Tuple(Box<[Ty]>),
684 /// An invalid type.
685 #[default]
686 Err,
687}
688
689impl Display for TyKind {
690 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
691 let mut indent = set_indentation(indented(f), 0);
692 match self {
693 TyKind::Array(item) => write!(indent, "Array: {item}")?,
694 TyKind::Arrow(ck, param, rtrn, functors) => {
695 write!(indent, "Arrow ({ck:?}):")?;
696 indent = set_indentation(indent, 1);
697 write!(indent, "\nparam: {param}")?;
698 write!(indent, "\nreturn: {rtrn}")?;
699 if let Some(f) = functors {
700 write!(indent, "\nfunctors: {f}")?;
701 }
702 }
703 TyKind::Hole => write!(indent, "Hole")?,
704 TyKind::Paren(t) => write!(indent, "Paren: {t}")?,
705 TyKind::Path(p) => write!(indent, "Path: {p}")?,
706 TyKind::Param(name) => write!(indent, "Type Param: {name}")?,
707 TyKind::Tuple(ts) => {
708 if ts.is_empty() {
709 write!(indent, "Unit")?;
710 } else {
711 write!(indent, "Tuple:")?;
712 indent = indent.with_format(Format::Uniform {
713 indentation: " ",
714 });
715 for t in ts {
716 write!(indent, "\n{t}")?;
717 }
718 }
719 }
720 TyKind::Err => write!(indent, "Err")?,
721 }
722 Ok(())
723 }
724}
725
726/// A sequenced block of statements.
727#[derive(Clone, Debug, PartialEq)]
728pub struct Block {
729 /// The node ID.
730 pub id: NodeId,
731 /// The span.
732 pub span: Span,
733 /// The statements in the block.
734 pub stmts: Box<[Box<Stmt>]>,
735}
736
737impl Display for Block {
738 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
739 if self.stmts.is_empty() {
740 write!(f, "Block {} {}: <empty>", self.id, self.span)?;
741 } else {
742 let mut indent = set_indentation(indented(f), 0);
743 write!(indent, "Block {} {}:", self.id, self.span)?;
744 indent = set_indentation(indent, 1);
745 for s in &self.stmts {
746 write!(indent, "\n{s}")?;
747 }
748 }
749 Ok(())
750 }
751}
752
753/// A statement.
754#[derive(Clone, Debug, Default, PartialEq)]
755pub struct Stmt {
756 /// The node ID.
757 pub id: NodeId,
758 /// The span.
759 pub span: Span,
760 /// The statement kind.
761 pub kind: Box<StmtKind>,
762}
763
764impl Display for Stmt {
765 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
766 write!(f, "Stmt {} {}: {}", self.id, self.span, self.kind)
767 }
768}
769
770/// A statement kind.
771#[derive(Clone, Debug, Default, PartialEq)]
772pub enum StmtKind {
773 /// An empty statement.
774 Empty,
775 /// An expression without a trailing semicolon.
776 Expr(Box<Expr>),
777 /// A let or mutable binding: `let a = b;` or `mutable x = b;`.
778 Local(Mutability, Box<Pat>, Box<Expr>),
779 /// An item.
780 Item(Box<Item>),
781 /// A use or borrow qubit allocation: `use a = b;` or `borrow a = b;`.
782 Qubit(QubitSource, Box<Pat>, Box<QubitInit>, Option<Box<Block>>),
783 /// An expression with a trailing semicolon.
784 Semi(Box<Expr>),
785 /// An invalid statement.
786 #[default]
787 Err,
788}
789
790impl Display for StmtKind {
791 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
792 let mut indent = set_indentation(indented(f), 0);
793 match self {
794 StmtKind::Empty => write!(indent, "Empty")?,
795 StmtKind::Expr(e) => write!(indent, "Expr: {e}")?,
796 StmtKind::Item(item) => write!(indent, "Item: {item}")?,
797 StmtKind::Local(m, lhs, rhs) => {
798 write!(indent, "Local ({m:?}):")?;
799 indent = set_indentation(indent, 1);
800 write!(indent, "\n{lhs}")?;
801 write!(indent, "\n{rhs}")?;
802 }
803 StmtKind::Qubit(s, lhs, rhs, block) => {
804 write!(indent, "Qubit ({s:?})")?;
805 indent = set_indentation(indent, 1);
806 write!(indent, "\n{lhs}")?;
807 write!(indent, "\n{rhs}")?;
808 if let Some(b) = block {
809 write!(indent, "\n{b}")?;
810 }
811 }
812 StmtKind::Semi(e) => write!(indent, "Semi: {e}")?,
813 StmtKind::Err => indent.write_str("Err")?,
814 }
815 Ok(())
816 }
817}
818
819/// An expression.
820#[derive(Clone, Debug, Default, PartialEq)]
821pub struct Expr {
822 /// The node ID.
823 pub id: NodeId,
824 /// The span.
825 pub span: Span,
826 /// The expression kind.
827 pub kind: Box<ExprKind>,
828}
829
830impl Display for Expr {
831 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
832 write!(f, "Expr {} {}: {}", self.id, self.span, self.kind)
833 }
834}
835
836impl WithSpan for Expr {
837 fn with_span(self, span: Span) -> Self {
838 Self { span, ..self }
839 }
840}
841
842/// The identifier in a field access expression.
843#[derive(Clone, Debug, Default, PartialEq)]
844pub enum FieldAccess {
845 /// The field name.
846 Ok(Box<Ident>),
847 /// The field access was missing a field name.
848 #[default]
849 Err,
850}
851
852/// An expression kind.
853#[derive(Clone, Debug, Default, PartialEq)]
854pub enum ExprKind {
855 /// An array: `[a, b, c]`.
856 Array(Box<[Box<Expr>]>),
857 /// An array constructed by repeating a value: `[a, size = b]`.
858 ArrayRepeat(Box<Expr>, Box<Expr>),
859 /// An assignment: `set a = b`.
860 Assign(Box<Expr>, Box<Expr>),
861 /// An assignment with a compound operator. For example: `set a += b`.
862 AssignOp(BinOp, Box<Expr>, Box<Expr>),
863 /// An assignment with a compound update operator: `set a w/= b <- c`.
864 AssignUpdate(Box<Expr>, Box<Expr>, Box<Expr>),
865 /// A binary operator.
866 BinOp(BinOp, Box<Expr>, Box<Expr>),
867 /// A block: `{ ... }`.
868 Block(Box<Block>),
869 /// A call: `a(b)`.
870 Call(Box<Expr>, Box<Expr>),
871 /// A conjugation: `within { ... } apply { ... }`.
872 Conjugate(Box<Block>, Box<Block>),
873 /// An expression with invalid syntax that can't be parsed.
874 #[default]
875 Err,
876 /// A failure: `fail "message"`.
877 Fail(Box<Expr>),
878 /// A field accessor: `a::F` or `a.F`.
879 Field(Box<Expr>, FieldAccess),
880 /// A for loop: `for a in b { ... }`.
881 For(Box<Pat>, Box<Expr>, Box<Block>),
882 /// An unspecified expression, _, which may indicate partial application or a typed hole.
883 Hole,
884 /// An if expression with an optional else block: `if a { ... } else { ... }`.
885 ///
886 /// Note that, as a special case, `elif ...` is effectively parsed as `else if ...`, without a
887 /// block wrapping the `if`. This distinguishes `elif ...` from `else { if ... }`, which does
888 /// have a block.
889 If(Box<Expr>, Box<Block>, Option<Box<Expr>>),
890 /// An index accessor: `a[b]`.
891 Index(Box<Expr>, Box<Expr>),
892 /// An interpolated string.
893 Interpolate(Box<[StringComponent]>),
894 /// A lambda: `a -> b` for a function and `a => b` for an operation.
895 Lambda(CallableKind, Box<Pat>, Box<Expr>),
896 /// A literal.
897 Lit(Box<Lit>),
898 /// Parentheses: `(a)`.
899 Paren(Box<Expr>),
900 /// A path: `a` or `a.b`.
901 Path(PathKind),
902 /// A range: `start..step..end`, `start..end`, `start...`, `...end`, or `...`.
903 Range(Option<Box<Expr>>, Option<Box<Expr>>, Option<Box<Expr>>),
904 /// A repeat-until loop with an optional fixup: `repeat { ... } until a fixup { ... }`.
905 Repeat(Box<Block>, Box<Expr>, Option<Box<Block>>),
906 /// A return: `return a`.
907 Return(Box<Expr>),
908 /// A struct constructor.
909 Struct(PathKind, Option<Box<Expr>>, Box<[Box<FieldAssign>]>),
910 /// A ternary operator.
911 TernOp(TernOp, Box<Expr>, Box<Expr>, Box<Expr>),
912 /// A tuple: `(a, b, c)`.
913 Tuple(Box<[Box<Expr>]>),
914 /// A unary operator.
915 UnOp(UnOp, Box<Expr>),
916 /// A while loop: `while a { ... }`.
917 While(Box<Expr>, Box<Block>),
918}
919
920impl Display for ExprKind {
921 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
922 let mut indent = set_indentation(indented(f), 0);
923 match self {
924 ExprKind::Array(exprs) => display_array(indent, exprs)?,
925 ExprKind::ArrayRepeat(val, size) => display_array_repeat(indent, val, size)?,
926 ExprKind::Assign(lhs, rhs) => display_assign(indent, lhs, rhs)?,
927 ExprKind::AssignOp(op, lhs, rhs) => display_assign_op(indent, *op, lhs, rhs)?,
928 ExprKind::AssignUpdate(container, item, val) => {
929 display_assign_update(indent, container, item, val)?;
930 }
931 ExprKind::BinOp(op, lhs, rhs) => display_bin_op(indent, *op, lhs, rhs)?,
932 ExprKind::Block(block) => write!(indent, "Expr Block: {block}")?,
933 ExprKind::Call(callable, arg) => display_call(indent, callable, arg)?,
934 ExprKind::Conjugate(within, apply) => display_conjugate(indent, within, apply)?,
935 ExprKind::Err => write!(indent, "Err")?,
936 ExprKind::Fail(e) => write!(indent, "Fail: {e}")?,
937 ExprKind::Field(expr, id) => display_field(indent, expr, id)?,
938 ExprKind::For(iter, iterable, body) => display_for(indent, iter, iterable, body)?,
939 ExprKind::Hole => write!(indent, "Hole")?,
940 ExprKind::If(cond, body, els) => display_if(indent, cond, body, els)?,
941 ExprKind::Index(array, index) => display_index(indent, array, index)?,
942 ExprKind::Interpolate(components) => display_interpolate(indent, components)?,
943 ExprKind::Lambda(kind, param, expr) => display_lambda(indent, *kind, param, expr)?,
944 ExprKind::Lit(lit) => write!(indent, "Lit: {lit}")?,
945 ExprKind::Paren(e) => write!(indent, "Paren: {e}")?,
946 ExprKind::Path(p) => write!(indent, "Path: {p}")?,
947 ExprKind::Range(start, step, end) => display_range(indent, start, step, end)?,
948 ExprKind::Repeat(repeat, until, fixup) => display_repeat(indent, repeat, until, fixup)?,
949 ExprKind::Return(e) => write!(indent, "Return: {e}")?,
950 ExprKind::Struct(name, copy, fields) => display_struct(indent, name, copy, fields)?,
951 ExprKind::TernOp(op, expr1, expr2, expr3) => {
952 display_tern_op(indent, *op, expr1, expr2, expr3)?;
953 }
954 ExprKind::Tuple(exprs) => display_tuple(indent, exprs)?,
955 ExprKind::UnOp(op, expr) => display_un_op(indent, *op, expr)?,
956 ExprKind::While(cond, block) => display_while(indent, cond, block)?,
957 }
958 Ok(())
959 }
960}
961
962fn display_array(mut indent: Indented<Formatter>, exprs: &[Box<Expr>]) -> fmt::Result {
963 write!(indent, "Array:")?;
964 indent = set_indentation(indent, 1);
965 for e in exprs {
966 write!(indent, "\n{e}")?;
967 }
968 Ok(())
969}
970
971fn display_array_repeat(mut indent: Indented<Formatter>, val: &Expr, size: &Expr) -> fmt::Result {
972 write!(indent, "ArrayRepeat:")?;
973 indent = set_indentation(indent, 1);
974 write!(indent, "\n{val}")?;
975 write!(indent, "\n{size}")?;
976 Ok(())
977}
978
979fn display_assign(mut indent: Indented<Formatter>, lhs: &Expr, rhs: &Expr) -> fmt::Result {
980 write!(indent, "Assign:")?;
981 indent = set_indentation(indent, 1);
982 write!(indent, "\n{lhs}")?;
983 write!(indent, "\n{rhs}")?;
984 Ok(())
985}
986
987fn display_assign_op(
988 mut indent: Indented<Formatter>,
989 op: BinOp,
990 lhs: &Expr,
991 rhs: &Expr,
992) -> fmt::Result {
993 write!(indent, "AssignOp ({op:?}):")?;
994 indent = set_indentation(indent, 1);
995 write!(indent, "\n{lhs}")?;
996 write!(indent, "\n{rhs}")?;
997 Ok(())
998}
999
1000fn display_assign_update(
1001 mut indent: Indented<Formatter>,
1002 container: &Expr,
1003 item: &Expr,
1004 val: &Expr,
1005) -> fmt::Result {
1006 write!(indent, "AssignUpdate:")?;
1007 indent = set_indentation(indent, 1);
1008 write!(indent, "\n{container}")?;
1009 write!(indent, "\n{item}")?;
1010 write!(indent, "\n{val}")?;
1011 Ok(())
1012}
1013
1014fn display_bin_op(
1015 mut indent: Indented<Formatter>,
1016 op: BinOp,
1017 lhs: &Expr,
1018 rhs: &Expr,
1019) -> fmt::Result {
1020 write!(indent, "BinOp ({op:?}):")?;
1021 indent = set_indentation(indent, 1);
1022 write!(indent, "\n{lhs}")?;
1023 write!(indent, "\n{rhs}")?;
1024 Ok(())
1025}
1026
1027fn display_call(mut indent: Indented<Formatter>, callable: &Expr, arg: &Expr) -> fmt::Result {
1028 write!(indent, "Call:")?;
1029 indent = set_indentation(indent, 1);
1030 write!(indent, "\n{callable}")?;
1031 write!(indent, "\n{arg}")?;
1032 Ok(())
1033}
1034
1035fn display_conjugate(
1036 mut indent: Indented<Formatter>,
1037 within: &Block,
1038 apply: &Block,
1039) -> fmt::Result {
1040 write!(indent, "Conjugate:")?;
1041 indent = set_indentation(indent, 1);
1042 write!(indent, "\n{within}")?;
1043 write!(indent, "\n{apply}")?;
1044 Ok(())
1045}
1046
1047fn display_field(mut indent: Indented<Formatter>, expr: &Expr, field: &FieldAccess) -> fmt::Result {
1048 write!(indent, "Field:")?;
1049 indent = set_indentation(indent, 1);
1050 write!(indent, "\n{expr}")?;
1051 match field {
1052 FieldAccess::Ok(i) => write!(indent, "\n{i}")?,
1053 FieldAccess::Err => write!(indent, "\nErr")?,
1054 }
1055 Ok(())
1056}
1057
1058fn display_for(
1059 mut indent: Indented<Formatter>,
1060 iter: &Pat,
1061 iterable: &Expr,
1062 body: &Block,
1063) -> fmt::Result {
1064 write!(indent, "For:")?;
1065 indent = set_indentation(indent, 1);
1066 write!(indent, "\n{iter}")?;
1067 write!(indent, "\n{iterable}")?;
1068 write!(indent, "\n{body}")?;
1069 Ok(())
1070}
1071
1072fn display_if(
1073 mut indent: Indented<Formatter>,
1074 cond: &Expr,
1075 body: &Block,
1076 els: &Option<Box<Expr>>,
1077) -> fmt::Result {
1078 write!(indent, "If:")?;
1079 indent = set_indentation(indent, 1);
1080 write!(indent, "\n{cond}")?;
1081 write!(indent, "\n{body}")?;
1082 if let Some(e) = els {
1083 write!(indent, "\n{e}")?;
1084 }
1085 Ok(())
1086}
1087
1088fn display_index(mut indent: Indented<Formatter>, array: &Expr, index: &Expr) -> fmt::Result {
1089 write!(indent, "Index:")?;
1090 indent = set_indentation(indent, 1);
1091 write!(indent, "\n{array}")?;
1092 write!(indent, "\n{index}")?;
1093 Ok(())
1094}
1095
1096fn display_interpolate(
1097 mut indent: Indented<Formatter>,
1098 components: &[StringComponent],
1099) -> fmt::Result {
1100 write!(indent, "Interpolate:")?;
1101 indent = set_indentation(indent, 1);
1102 for component in components {
1103 match component {
1104 StringComponent::Expr(expr) => write!(indent, "\nExpr: {expr}")?,
1105 StringComponent::Lit(str) => write!(indent, "\nLit: {str:?}")?,
1106 }
1107 }
1108
1109 Ok(())
1110}
1111
1112fn display_lambda(
1113 mut indent: Indented<Formatter>,
1114 kind: CallableKind,
1115 param: &Pat,
1116 expr: &Expr,
1117) -> fmt::Result {
1118 write!(indent, "Lambda ({kind:?}):")?;
1119 indent = set_indentation(indent, 1);
1120 write!(indent, "\n{param}")?;
1121 write!(indent, "\n{expr}")?;
1122 Ok(())
1123}
1124
1125fn display_range(
1126 mut indent: Indented<Formatter>,
1127 start: &Option<Box<Expr>>,
1128 step: &Option<Box<Expr>>,
1129 end: &Option<Box<Expr>>,
1130) -> fmt::Result {
1131 write!(indent, "Range:")?;
1132 indent = set_indentation(indent, 1);
1133 match start {
1134 Some(e) => write!(indent, "\n{e}")?,
1135 None => write!(indent, "\n<no start>")?,
1136 }
1137 match step {
1138 Some(e) => write!(indent, "\n{e}")?,
1139 None => write!(indent, "\n<no step>")?,
1140 }
1141 match end {
1142 Some(e) => write!(indent, "\n{e}")?,
1143 None => write!(indent, "\n<no end>")?,
1144 }
1145 Ok(())
1146}
1147
1148fn display_repeat(
1149 mut indent: Indented<Formatter>,
1150 repeat: &Block,
1151 until: &Expr,
1152 fixup: &Option<Box<Block>>,
1153) -> fmt::Result {
1154 write!(indent, "Repeat:")?;
1155 indent = set_indentation(indent, 1);
1156 write!(indent, "\n{repeat}")?;
1157 write!(indent, "\n{until}")?;
1158 match fixup {
1159 Some(b) => write!(indent, "\n{b}")?,
1160 None => write!(indent, "\n<no fixup>")?,
1161 }
1162 Ok(())
1163}
1164
1165fn display_struct(
1166 mut indent: Indented<Formatter>,
1167 name: &PathKind,
1168 copy: &Option<Box<Expr>>,
1169 fields: &[Box<FieldAssign>],
1170) -> fmt::Result {
1171 write!(indent, "Struct ({name}):")?;
1172 if copy.is_none() && fields.is_empty() {
1173 write!(indent, " <empty>")?;
1174 return Ok(());
1175 }
1176 indent = set_indentation(indent, 1);
1177 if let Some(copy) = copy {
1178 write!(indent, "\nCopy: {copy}")?;
1179 }
1180 for field in fields {
1181 write!(indent, "\n{field}")?;
1182 }
1183 Ok(())
1184}
1185
1186fn display_tern_op(
1187 mut indent: Indented<Formatter>,
1188 op: TernOp,
1189 expr1: &Expr,
1190 expr2: &Expr,
1191 expr3: &Expr,
1192) -> fmt::Result {
1193 write!(indent, "TernOp ({op:?}):")?;
1194 indent = set_indentation(indent, 1);
1195 write!(indent, "\n{expr1}")?;
1196 write!(indent, "\n{expr2}")?;
1197 write!(indent, "\n{expr3}")?;
1198 Ok(())
1199}
1200
1201fn display_tuple(mut indent: Indented<Formatter>, exprs: &[Box<Expr>]) -> fmt::Result {
1202 if exprs.is_empty() {
1203 write!(indent, "Unit")?;
1204 } else {
1205 write!(indent, "Tuple:")?;
1206 indent = set_indentation(indent, 1);
1207 for e in exprs {
1208 write!(indent, "\n{e}")?;
1209 }
1210 }
1211 Ok(())
1212}
1213
1214fn display_un_op(mut indent: Indented<Formatter>, op: UnOp, expr: &Expr) -> fmt::Result {
1215 write!(indent, "UnOp ({op}):")?;
1216 indent = set_indentation(indent, 1);
1217 write!(indent, "\n{expr}")?;
1218 Ok(())
1219}
1220
1221fn display_while(mut indent: Indented<Formatter>, cond: &Expr, block: &Block) -> fmt::Result {
1222 write!(indent, "While:")?;
1223 indent = set_indentation(indent, 1);
1224 write!(indent, "\n{cond}")?;
1225 write!(indent, "\n{block}")?;
1226 Ok(())
1227}
1228
1229/// A field assignment in a struct constructor expression.
1230#[derive(Clone, Debug, Default, PartialEq)]
1231pub struct FieldAssign {
1232 /// The node ID.
1233 pub id: NodeId,
1234 /// The span.
1235 pub span: Span,
1236 /// The field to assign.
1237 pub field: Box<Ident>,
1238 /// The value to assign to the field.
1239 pub value: Box<Expr>,
1240}
1241
1242impl WithSpan for FieldAssign {
1243 fn with_span(self, span: Span) -> Self {
1244 Self { span, ..self }
1245 }
1246}
1247
1248impl Display for FieldAssign {
1249 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1250 write!(
1251 f,
1252 "FieldsAssign {} {}: ({}) {}",
1253 self.id, self.span, self.field, self.value
1254 )
1255 }
1256}
1257
1258/// An interpolated string component.
1259#[derive(Clone, Debug, PartialEq)]
1260pub enum StringComponent {
1261 /// An expression.
1262 Expr(Box<Expr>),
1263 /// A string literal.
1264 Lit(Rc<str>),
1265}
1266
1267/// A pattern.
1268#[derive(Clone, Debug, Eq, Hash, PartialEq, Default)]
1269pub struct Pat {
1270 /// The node ID.
1271 pub id: NodeId,
1272 /// The span.
1273 pub span: Span,
1274 /// The pattern kind.
1275 pub kind: Box<PatKind>,
1276}
1277
1278impl Display for Pat {
1279 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1280 write!(f, "Pat {} {}: {}", self.id, self.span, self.kind)
1281 }
1282}
1283
1284impl WithSpan for Pat {
1285 fn with_span(self, span: Span) -> Self {
1286 Self { span, ..self }
1287 }
1288}
1289
1290/// A pattern kind.
1291#[derive(Clone, Debug, Eq, Hash, PartialEq, Default)]
1292pub enum PatKind {
1293 /// A binding with an optional type annotation.
1294 Bind(Box<Ident>, Option<Box<Ty>>),
1295 /// A discarded binding, `_`, with an optional type annotation.
1296 Discard(Option<Box<Ty>>),
1297 /// An elided pattern, `...`, used by specializations.
1298 Elided,
1299 /// Parentheses: `(a)`.
1300 Paren(Box<Pat>),
1301 /// A tuple: `(a, b, c)`.
1302 Tuple(Box<[Box<Pat>]>),
1303 /// An invalid pattern.
1304 #[default]
1305 Err,
1306}
1307
1308impl Display for PatKind {
1309 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1310 let mut indent = set_indentation(indented(f), 0);
1311 match self {
1312 PatKind::Bind(id, ty) => {
1313 write!(indent, "Bind:")?;
1314 indent = set_indentation(indent, 1);
1315 write!(indent, "\n{id}")?;
1316 if let Some(t) = ty {
1317 write!(indent, "\n{t}")?;
1318 }
1319 }
1320 PatKind::Discard(d) => match d {
1321 Some(t) => {
1322 write!(indent, "Discard:")?;
1323 indent = set_indentation(indent, 1);
1324 write!(indent, "\n{t}")?;
1325 }
1326 None => write!(indent, "Discard")?,
1327 },
1328 PatKind::Elided => write!(indent, "Elided")?,
1329 PatKind::Paren(p) => {
1330 write!(indent, "Paren:")?;
1331 indent = set_indentation(indent, 1);
1332 write!(indent, "\n{p}")?;
1333 }
1334 PatKind::Tuple(ps) => {
1335 if ps.is_empty() {
1336 write!(indent, "Unit")?;
1337 } else {
1338 write!(indent, "Tuple:")?;
1339 indent = set_indentation(indent, 1);
1340 for p in ps {
1341 write!(indent, "\n{p}")?;
1342 }
1343 }
1344 }
1345 PatKind::Err => write!(indent, "Err")?,
1346 }
1347 Ok(())
1348 }
1349}
1350
1351/// A qubit initializer.
1352#[derive(Clone, Debug, PartialEq, Default)]
1353pub struct QubitInit {
1354 /// The node ID.
1355 pub id: NodeId,
1356 /// The span.
1357 pub span: Span,
1358 /// The qubit initializer kind.
1359 pub kind: Box<QubitInitKind>,
1360}
1361
1362impl Display for QubitInit {
1363 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1364 write!(f, "QubitInit {} {} {}", self.id, self.span, self.kind)
1365 }
1366}
1367
1368impl WithSpan for QubitInit {
1369 fn with_span(self, span: Span) -> Self {
1370 Self { span, ..self }
1371 }
1372}
1373
1374/// A qubit initializer kind.
1375#[derive(Clone, Debug, PartialEq, Default)]
1376pub enum QubitInitKind {
1377 /// An array of qubits: `Qubit[a]`.
1378 Array(Box<Expr>),
1379 /// A parenthesized initializer: `(a)`.
1380 Paren(Box<QubitInit>),
1381 /// A single qubit: `Qubit()`.
1382 Single,
1383 /// A tuple: `(a, b, c)`.
1384 Tuple(Box<[Box<QubitInit>]>),
1385 /// An invalid initializer.
1386 #[default]
1387 Err,
1388}
1389
1390impl Display for QubitInitKind {
1391 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1392 let mut indent = set_indentation(indented(f), 0);
1393 match self {
1394 QubitInitKind::Array(e) => {
1395 write!(indent, "Array:")?;
1396 indent = set_indentation(indent, 1);
1397 write!(indent, "\n{e}")?;
1398 }
1399 QubitInitKind::Paren(qi) => {
1400 write!(indent, "Parens:")?;
1401 indent = set_indentation(indent, 1);
1402 write!(indent, "\n{qi}")?;
1403 }
1404 QubitInitKind::Single => write!(indent, "Single")?,
1405 QubitInitKind::Tuple(qis) => {
1406 if qis.is_empty() {
1407 write!(indent, "Unit")?;
1408 } else {
1409 write!(indent, "Tuple:")?;
1410 indent = set_indentation(indent, 1);
1411 for qi in qis {
1412 write!(indent, "\n{qi}")?;
1413 }
1414 }
1415 }
1416 QubitInitKind::Err => write!(indent, "Err")?,
1417 }
1418 Ok(())
1419 }
1420}
1421
1422/// A path that may or may not have been successfully parsed.
1423#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1424pub enum PathKind {
1425 /// A successfully parsed path.
1426 Ok(Box<Path>),
1427
1428 /// An invalid path.
1429 Err(Option<Box<IncompletePath>>),
1430}
1431
1432impl Default for PathKind {
1433 fn default() -> Self {
1434 PathKind::Err(None)
1435 }
1436}
1437
1438/// A path that was successfully parsed up to a certain `.`,
1439/// but is missing its final identifier.
1440#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1441pub struct IncompletePath {
1442 /// The whole span of the incomplete path,
1443 /// including the final `.` and any whitespace or keyword
1444 /// that follows it.
1445 pub span: Span,
1446 /// Any segments that were successfully parsed before the final `.`.
1447 pub segments: Box<[Ident]>,
1448 /// Whether a keyword exists after the final `.`.
1449 /// This keyword can be presumed to be a partially typed identifier.
1450 pub keyword: bool,
1451}
1452
1453impl Display for PathKind {
1454 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1455 match self {
1456 PathKind::Ok(path) => write!(f, "{path}")?,
1457 PathKind::Err(Some(incomplete_path)) => {
1458 let mut indent = set_indentation(indented(f), 0);
1459 write!(indent, "Err IncompletePath {}:", incomplete_path.span)?;
1460 indent = set_indentation(indent, 1);
1461 for part in &incomplete_path.segments {
1462 write!(indent, "\n{part}")?;
1463 }
1464 }
1465 PathKind::Err(None) => write!(f, "Err",)?,
1466 }
1467 Ok(())
1468 }
1469}
1470
1471/// A path to a declaration or a field access expression,
1472/// to be disambiguated during name resolution.
1473#[derive(Clone, Debug, Eq, Hash, PartialEq)]
1474pub struct Path {
1475 /// The node ID.
1476 pub id: NodeId,
1477 /// The span.
1478 pub span: Span,
1479 /// The segments that make up the front of the path before the final `.`.
1480 pub segments: Option<Box<[Ident]>>,
1481 /// The declaration or field name.
1482 pub name: Box<Ident>,
1483}
1484
1485impl Display for Path {
1486 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1487 if self.segments.is_none() {
1488 write!(f, "Path {} {} ({})", self.id, self.span, self.name)?;
1489 } else {
1490 let mut indent = set_indentation(indented(f), 0);
1491 write!(indent, "Path {} {}:", self.id, self.span)?;
1492 indent = set_indentation(indent, 1);
1493 if let Some(parts) = &self.segments {
1494 for part in parts {
1495 write!(indent, "\n{part}")?;
1496 }
1497 }
1498 write!(indent, "\n{}", self.name)?;
1499 }
1500 Ok(())
1501 }
1502}
1503
1504impl WithSpan for Path {
1505 fn with_span(self, span: Span) -> Self {
1506 Self { span, ..self }
1507 }
1508}
1509
1510/// An identifier.
1511#[derive(Clone, Debug, Eq, Hash, PartialEq)]
1512pub struct Ident {
1513 /// The node ID.
1514 pub id: NodeId,
1515 /// The span.
1516 pub span: Span,
1517 /// The identifier name.
1518 pub name: Rc<str>,
1519}
1520
1521impl Default for Ident {
1522 fn default() -> Self {
1523 Ident {
1524 id: NodeId::default(),
1525 span: Span::default(),
1526 name: "".into(),
1527 }
1528 }
1529}
1530
1531impl WithSpan for Ident {
1532 fn with_span(self, span: Span) -> Self {
1533 Self { span, ..self }
1534 }
1535}
1536
1537impl Display for Ident {
1538 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1539 write!(f, "Ident {} {} \"{}\"", self.id, self.span, self.name)
1540 }
1541}
1542
1543/// Trait for working with dot-separated sequences of identifiers,
1544/// intended to unify the different representations that can appear
1545/// in the AST (`Path`s and `Ident` slices).
1546pub trait Idents {
1547 /// Iterates over the [`Ident`]s in this sequence.
1548 fn iter(&self) -> impl Iterator<Item = &Ident>;
1549
1550 /// The full dot-separated name represented by this [`Ident`] sequence.
1551 /// E.g. `a.b.c`
1552 fn full_name(&self) -> Rc<str> {
1553 let mut strs = self.rc_str_iter();
1554 let first = strs.next();
1555 let Some(first) = first else {
1556 // No parts, empty string
1557 return "".into();
1558 };
1559
1560 let next = strs.next();
1561 let Some(mut part) = next else {
1562 // Only one ident, return it directly
1563 return first.clone();
1564 };
1565
1566 // More than one ident, build up a dotted string
1567 let mut buf = String::new();
1568 buf.push_str(first);
1569 loop {
1570 buf.push('.');
1571 buf.push_str(part);
1572 part = match strs.next() {
1573 Some(part) => part,
1574 None => {
1575 break;
1576 }
1577 };
1578 }
1579 buf.into()
1580 }
1581
1582 /// Iterates over the identifier names as string slices.
1583 fn str_iter(&self) -> impl Iterator<Item = &str> {
1584 self.iter().map(|ident| ident.name.as_ref())
1585 }
1586
1587 /// Iterates over the identifier names as `Rc<str>`s.
1588 fn rc_str_iter(&self) -> impl Iterator<Item = &Rc<str>> {
1589 self.iter().map(|ident| &ident.name)
1590 }
1591
1592 /// Returns the conjoined span of all [`Ident`]s in this collection.
1593 #[must_use]
1594 fn full_span(&self) -> Span {
1595 let mut idents = self.iter().peekable();
1596 Span {
1597 lo: idents.peek().map(|i| i.span.lo).unwrap_or_default(),
1598 hi: idents.last().map(|i| i.span.hi).unwrap_or_default(),
1599 }
1600 }
1601}
1602
1603impl Idents for Box<[Ident]> {
1604 fn iter(&self) -> impl Iterator<Item = &Ident> {
1605 self.as_ref().iter() // invokes the slice iterator
1606 }
1607}
1608
1609impl Idents for &[Ident] {
1610 fn iter(&self) -> impl Iterator<Item = &Ident> {
1611 (*self).iter() // invokes the slice iterator
1612 }
1613}
1614
1615impl<T, U> Idents for (&T, &U)
1616where
1617 T: Idents,
1618 U: Idents,
1619{
1620 fn iter(&self) -> impl Iterator<Item = &Ident> {
1621 self.0.iter().chain(self.1.iter())
1622 }
1623}
1624
1625impl Idents for Ident {
1626 fn iter(&self) -> impl Iterator<Item = &Ident> {
1627 once(self)
1628 }
1629}
1630
1631impl Idents for Path {
1632 fn iter(&self) -> impl Iterator<Item = &Ident> {
1633 self.segments
1634 .iter()
1635 .flat_map(Idents::iter)
1636 .chain(once(self.name.as_ref()))
1637 }
1638}
1639
1640/// A callable kind.
1641#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1642pub enum CallableKind {
1643 /// A function.
1644 Function,
1645 /// An operation.
1646 Operation,
1647}
1648
1649/// The mutability of a binding.
1650#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1651pub enum Mutability {
1652 /// An immutable binding.
1653 Immutable,
1654 /// A mutable binding.
1655 Mutable,
1656}
1657
1658/// The source of an allocated qubit.
1659#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1660pub enum QubitSource {
1661 /// A qubit initialized to the zero state.
1662 Fresh,
1663 /// A qubit borrowed from another part of the program that may be in any state, and is expected
1664 /// to be returned to that state before being released.
1665 Dirty,
1666}
1667
1668/// A literal.
1669#[derive(Clone, Debug, PartialEq)]
1670pub enum Lit {
1671 /// A big integer literal.
1672 BigInt(Box<BigInt>),
1673 /// A boolean literal.
1674 Bool(bool),
1675 /// A floating-point literal.
1676 Double(f64),
1677 /// An integer literal.
1678 Int(i64),
1679 /// A Pauli operator literal.
1680 Pauli(Pauli),
1681 /// A measurement result literal.
1682 Result(Result),
1683 /// A string literal.
1684 String(Rc<str>),
1685}
1686
1687impl Display for Lit {
1688 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1689 match self {
1690 Lit::BigInt(val) => write!(f, "BigInt({val})")?,
1691 Lit::Bool(val) => write!(f, "Bool({val})")?,
1692 Lit::Double(val) => write!(f, "Double({val})")?,
1693 Lit::Int(val) => write!(f, "Int({val})")?,
1694 Lit::Pauli(val) => write!(f, "Pauli({val:?})")?,
1695 Lit::Result(val) => write!(f, "Result({val:?})")?,
1696 Lit::String(val) => write!(f, "String({val:?})")?,
1697 }
1698 Ok(())
1699 }
1700}
1701
1702/// A measurement result.
1703#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1704pub enum Result {
1705 /// The zero eigenvalue.
1706 Zero,
1707 /// The one eigenvalue.
1708 One,
1709}
1710
1711impl From<bool> for Result {
1712 fn from(b: bool) -> Self {
1713 if b {
1714 Result::One
1715 } else {
1716 Result::Zero
1717 }
1718 }
1719}
1720
1721/// A Pauli operator.
1722#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1723pub enum Pauli {
1724 /// The Pauli I operator.
1725 I,
1726 /// The Pauli X operator.
1727 X,
1728 /// The Pauli Y operator.
1729 Y,
1730 /// The Pauli Z operator.
1731 Z,
1732}
1733
1734/// A functor that may be applied to an operation.
1735#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1736pub enum Functor {
1737 /// The adjoint functor.
1738 Adj,
1739 /// The controlled functor.
1740 Ctl,
1741}
1742
1743/// A specialization that may be implemented for an operation.
1744#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1745pub enum Spec {
1746 /// The default specialization.
1747 Body,
1748 /// The adjoint specialization.
1749 Adj,
1750 /// The controlled specialization.
1751 Ctl,
1752 /// The controlled adjoint specialization.
1753 CtlAdj,
1754}
1755
1756impl Display for Spec {
1757 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1758 match self {
1759 Spec::Body => f.write_str("body"),
1760 Spec::Adj => f.write_str("adjoint"),
1761 Spec::Ctl => f.write_str("controlled"),
1762 Spec::CtlAdj => f.write_str("controlled adjoint"),
1763 }
1764 }
1765}
1766
1767/// A strategy for generating a specialization.
1768#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1769pub enum SpecGen {
1770 /// Choose a strategy automatically.
1771 Auto,
1772 /// Distributes controlled qubits.
1773 Distribute,
1774 /// A specialization implementation is not generated, but is instead left as an opaque
1775 /// declaration.
1776 Intrinsic,
1777 /// Inverts the order of operations.
1778 Invert,
1779 /// Uses the body specialization without modification.
1780 Slf,
1781}
1782
1783/// A unary operator.
1784#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1785pub enum UnOp {
1786 /// A functor application.
1787 Functor(Functor),
1788 /// Negation: `-`.
1789 Neg,
1790 /// Bitwise NOT: `~~~`.
1791 NotB,
1792 /// Logical NOT: `not`.
1793 NotL,
1794 /// A leading `+`.
1795 Pos,
1796 /// Unwrap a user-defined type: `!`.
1797 Unwrap,
1798}
1799
1800impl Display for UnOp {
1801 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1802 match self {
1803 UnOp::Functor(func) => write!(f, "Functor {func:?}")?,
1804 _ => fmt::Debug::fmt(self, f)?,
1805 }
1806 Ok(())
1807 }
1808}
1809
1810/// A binary operator.
1811#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1812pub enum BinOp {
1813 /// Addition: `+`.
1814 Add,
1815 /// Bitwise AND: `&&&`.
1816 AndB,
1817 /// Logical AND: `and`.
1818 AndL,
1819 /// Division: `/`.
1820 Div,
1821 /// Equality: `==`.
1822 Eq,
1823 /// Exponentiation: `^`.
1824 Exp,
1825 /// Greater than: `>`.
1826 Gt,
1827 /// Greater than or equal: `>=`.
1828 Gte,
1829 /// Less than: `<`.
1830 Lt,
1831 /// Less than or equal: `<=`.
1832 Lte,
1833 /// Modulus: `%`.
1834 Mod,
1835 /// Multiplication: `*`.
1836 Mul,
1837 /// Inequality: `!=`.
1838 Neq,
1839 /// Bitwise OR: `|||`.
1840 OrB,
1841 /// Logical OR: `or`.
1842 OrL,
1843 /// Shift left: `<<<`.
1844 Shl,
1845 /// Shift right: `>>>`.
1846 Shr,
1847 /// Subtraction: `-`.
1848 Sub,
1849 /// Bitwise XOR: `^^^`.
1850 XorB,
1851}
1852
1853/// A ternary operator.
1854#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1855pub enum TernOp {
1856 /// Conditional: `a ? b | c`.
1857 Cond,
1858 /// Aggregate update: `a w/ b <- c`.
1859 Update,
1860}
1861
1862/// A set operator.
1863#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1864pub enum SetOp {
1865 /// The set union.
1866 Union,
1867 /// The set intersection.
1868 Intersect,
1869}
1870
1871#[derive(Clone, Debug, Eq, PartialEq)]
1872/// Represents an export declaration.
1873pub struct ImportOrExportDecl {
1874 /// The span.
1875 pub span: Span,
1876 /// The items being exported from this namespace.
1877 pub items: Box<[ImportOrExportItem]>,
1878 /// Whether this is an export declaration or not. If `false`, then this is an `Import`.
1879 is_export: bool,
1880}
1881
1882impl Display for ImportOrExportDecl {
1883 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1884 let items_str = self
1885 .items
1886 .iter()
1887 .map(std::string::ToString::to_string)
1888 .collect::<Vec<_>>()
1889 .join(", ");
1890 write!(f, "ImportOrExportDecl {}: [{items_str}]", self.span)
1891 }
1892}
1893
1894impl ImportOrExportDecl {
1895 /// Creates a new `ImportOrExportDecl` with the given span, items, and export flag.
1896 #[must_use]
1897 pub fn new(span: Span, items: Box<[ImportOrExportItem]>, is_export: bool) -> Self {
1898 Self {
1899 span,
1900 items,
1901 is_export,
1902 }
1903 }
1904
1905 /// Returns true if this is an export declaration.
1906 #[must_use]
1907 pub fn is_export(&self) -> bool {
1908 self.is_export
1909 }
1910
1911 /// Returns true if this is an import declaration.
1912 #[must_use]
1913 pub fn is_import(&self) -> bool {
1914 !self.is_export
1915 }
1916
1917 /// Returns an iterator over the items being exported from this namespace.
1918 pub fn items(&self) -> impl Iterator<Item = &ImportOrExportItem> {
1919 self.items.iter()
1920 }
1921}
1922
1923/// An individual item within an [`ImportOrExportDecl`]. This can be a path or a path with an alias.
1924#[derive(Clone, Debug, Eq, PartialEq, Default)]
1925pub struct ImportOrExportItem {
1926 /// The span of the import path including the glob and alias, if any.
1927 pub span: Span,
1928 /// The path to the item being exported.
1929 pub path: PathKind,
1930 /// An optional alias for the item being exported.
1931 pub alias: Option<Ident>,
1932 /// Whether this is a glob import/export.
1933 pub is_glob: bool,
1934}
1935
1936impl Display for ImportOrExportItem {
1937 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1938 let ImportOrExportItem {
1939 span: _,
1940 ref path,
1941 ref alias,
1942 is_glob,
1943 } = self;
1944 let is_glob = if *is_glob { ".*" } else { "" };
1945 match alias {
1946 Some(alias) => write!(f, "{path}{is_glob} as {alias}",),
1947 None => write!(f, "{path}{is_glob}"),
1948 }
1949 }
1950}
1951
1952impl WithSpan for ImportOrExportItem {
1953 fn with_span(self, span: Span) -> Self {
1954 Self { span, ..self }
1955 }
1956}
1957
1958impl ImportOrExportItem {
1959 /// Returns the alias ident, if any, or the name from the path if no alias is present.
1960 /// Returns `None` if the path has an error.
1961 #[must_use]
1962 pub fn name(&self) -> Option<&Ident> {
1963 match &self.alias {
1964 Some(_) => self.alias.as_ref(),
1965 None => {
1966 if let PathKind::Ok(path) = &self.path {
1967 Some(&path.name)
1968 } else {
1969 None
1970 }
1971 }
1972 }
1973 }
1974}
1975
1976/// A [`TypeParameter`] is a generic type variable with optional bounds (constraints).
1977#[derive(Default, Debug, PartialEq, Eq, Clone, Hash)]
1978pub struct TypeParameter {
1979 /// Class constraints specified for this type parameter -- any type variable passed in
1980 /// as an argument to these parameters must satisfy these constraints.
1981 pub constraints: ClassConstraints,
1982 /// The name of the type parameter.
1983 pub ty: Ident,
1984 /// The span of the full type parameter, including its name and its constraints.
1985 pub span: Span,
1986}
1987
1988impl WithSpan for TypeParameter {
1989 fn with_span(self, span: Span) -> Self {
1990 Self { span, ..self }
1991 }
1992}
1993
1994impl TypeParameter {
1995 /// Instantiates a new `TypeParameter` with the given type name, constraints, and span.
1996 #[must_use]
1997 pub fn new(ty: Ident, bounds: ClassConstraints, span: Span) -> Self {
1998 Self {
1999 ty,
2000 constraints: bounds,
2001 span,
2002 }
2003 }
2004}
2005
2006impl std::fmt::Display for TypeParameter {
2007 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
2008 // 'A: Eq + Ord + Clone
2009 write!(
2010 f,
2011 "{}{}",
2012 self.ty.name,
2013 if self.constraints.0.is_empty() {
2014 Default::default()
2015 } else {
2016 format!(": {}", self.constraints)
2017 }
2018 )
2019 }
2020}
2021
2022/// A list of class constraints, used when constraining a type parameter.
2023#[derive(Default, Debug, PartialEq, Eq, Clone, Hash)]
2024pub struct ClassConstraints(pub Box<[ClassConstraint]>);
2025
2026/// An individual class constraint, used when constraining a type parameter.
2027/// To understand this concept, think of parameters in a function signature -- the potential arguments that can
2028/// be passed to them are constrained by what type is specified. Type-level parameters are no different, and
2029/// the type variables that are passed to a type parameter must satisfy the constraints specified in the type parameter.
2030#[derive(PartialEq, Eq, Clone, Hash, Debug)]
2031pub struct ClassConstraint {
2032 /// The name of the constraint.
2033 pub name: Ident,
2034 /// Parameters for a constraint. For example, `Iterator` has a parameter `T` in `Iterator<T>` -- this
2035 /// is the type of the item that is coming out of the iterator.
2036 pub parameters: Box<[ConstraintParameter]>,
2037}
2038
2039impl std::fmt::Display for ClassConstraint {
2040 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
2041 // Iterator<T>
2042 write!(
2043 f,
2044 "{}{}",
2045 self.name.name,
2046 if self.parameters.is_empty() {
2047 String::new()
2048 } else {
2049 format!(
2050 "[{}]",
2051 self.parameters
2052 .iter()
2053 .map(|x| x.ty.to_string())
2054 .collect::<Vec<_>>()
2055 .join(", ")
2056 )
2057 }
2058 )
2059 }
2060}
2061
2062/// An individual constraint parameter is a type that is passed to a constraint, such as `T` in `Iterator<T>`.
2063/// #[derive(Default, `PartialEq`, Eq, Clone, Hash, Debug)]
2064#[derive(Default, PartialEq, Eq, Clone, Hash, Debug)]
2065pub struct ConstraintParameter {
2066 /// The type variable being passed as a constraint parameter.
2067 pub ty: Ty,
2068}
2069
2070impl WithSpan for ConstraintParameter {
2071 fn with_span(self, span: Span) -> Self {
2072 Self {
2073 ty: self.ty.with_span(span),
2074 }
2075 }
2076}
2077
2078impl ClassConstraint {
2079 /// Getter for the `span` field of the `name` field (the name of the class constraint).
2080 #[must_use]
2081 pub fn span(&self) -> Span {
2082 self.name.span
2083 }
2084}
2085
2086impl ClassConstraints {
2087 /// The conjoined span of all of the bounds
2088 #[must_use]
2089 pub fn span(&self) -> Span {
2090 Span {
2091 lo: self.0.first().map(|i| i.span().lo).unwrap_or_default(),
2092 hi: self.0.last().map(|i| i.span().hi).unwrap_or_default(),
2093 }
2094 }
2095}
2096
2097impl std::fmt::Display for ClassConstraints {
2098 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
2099 // A + B + C + D
2100 write!(
2101 f,
2102 "{}",
2103 self.0
2104 .iter()
2105 .map(|x| format!("{}", x.name.name,))
2106 .collect::<Vec<_>>()
2107 .join(" + "),
2108 )
2109 }
2110}
2111