microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
280b0da953f54bd2ea9e48c78f03518ef4e75bae

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc_ast/src/ast.rs

2122lines · 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.as_deref())?,
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) => {
948 display_range(indent, start.as_deref(), step.as_deref(), end.as_deref())?;
949 }
950 ExprKind::Repeat(repeat, until, fixup) => {
951 display_repeat(indent, repeat, until, fixup.as_deref())?;
952 }
953 ExprKind::Return(e) => write!(indent, "Return: {e}")?,
954 ExprKind::Struct(name, copy, fields) => {
955 display_struct(indent, name, copy.as_deref(), fields)?;
956 }
957 ExprKind::TernOp(op, expr1, expr2, expr3) => {
958 display_tern_op(indent, *op, expr1, expr2, expr3)?;
959 }
960 ExprKind::Tuple(exprs) => display_tuple(indent, exprs)?,
961 ExprKind::UnOp(op, expr) => display_un_op(indent, *op, expr)?,
962 ExprKind::While(cond, block) => display_while(indent, cond, block)?,
963 }
964 Ok(())
965 }
966}
967
968fn display_array(mut indent: Indented<Formatter>, exprs: &[Box<Expr>]) -> fmt::Result {
969 write!(indent, "Array:")?;
970 indent = set_indentation(indent, 1);
971 for e in exprs {
972 write!(indent, "\n{e}")?;
973 }
974 Ok(())
975}
976
977fn display_array_repeat(mut indent: Indented<Formatter>, val: &Expr, size: &Expr) -> fmt::Result {
978 write!(indent, "ArrayRepeat:")?;
979 indent = set_indentation(indent, 1);
980 write!(indent, "\n{val}")?;
981 write!(indent, "\n{size}")?;
982 Ok(())
983}
984
985fn display_assign(mut indent: Indented<Formatter>, lhs: &Expr, rhs: &Expr) -> fmt::Result {
986 write!(indent, "Assign:")?;
987 indent = set_indentation(indent, 1);
988 write!(indent, "\n{lhs}")?;
989 write!(indent, "\n{rhs}")?;
990 Ok(())
991}
992
993fn display_assign_op(
994 mut indent: Indented<Formatter>,
995 op: BinOp,
996 lhs: &Expr,
997 rhs: &Expr,
998) -> fmt::Result {
999 write!(indent, "AssignOp ({op:?}):")?;
1000 indent = set_indentation(indent, 1);
1001 write!(indent, "\n{lhs}")?;
1002 write!(indent, "\n{rhs}")?;
1003 Ok(())
1004}
1005
1006fn display_assign_update(
1007 mut indent: Indented<Formatter>,
1008 container: &Expr,
1009 item: &Expr,
1010 val: &Expr,
1011) -> fmt::Result {
1012 write!(indent, "AssignUpdate:")?;
1013 indent = set_indentation(indent, 1);
1014 write!(indent, "\n{container}")?;
1015 write!(indent, "\n{item}")?;
1016 write!(indent, "\n{val}")?;
1017 Ok(())
1018}
1019
1020fn display_bin_op(
1021 mut indent: Indented<Formatter>,
1022 op: BinOp,
1023 lhs: &Expr,
1024 rhs: &Expr,
1025) -> fmt::Result {
1026 write!(indent, "BinOp ({op:?}):")?;
1027 indent = set_indentation(indent, 1);
1028 write!(indent, "\n{lhs}")?;
1029 write!(indent, "\n{rhs}")?;
1030 Ok(())
1031}
1032
1033fn display_call(mut indent: Indented<Formatter>, callable: &Expr, arg: &Expr) -> fmt::Result {
1034 write!(indent, "Call:")?;
1035 indent = set_indentation(indent, 1);
1036 write!(indent, "\n{callable}")?;
1037 write!(indent, "\n{arg}")?;
1038 Ok(())
1039}
1040
1041fn display_conjugate(
1042 mut indent: Indented<Formatter>,
1043 within: &Block,
1044 apply: &Block,
1045) -> fmt::Result {
1046 write!(indent, "Conjugate:")?;
1047 indent = set_indentation(indent, 1);
1048 write!(indent, "\n{within}")?;
1049 write!(indent, "\n{apply}")?;
1050 Ok(())
1051}
1052
1053fn display_field(mut indent: Indented<Formatter>, expr: &Expr, field: &FieldAccess) -> fmt::Result {
1054 write!(indent, "Field:")?;
1055 indent = set_indentation(indent, 1);
1056 write!(indent, "\n{expr}")?;
1057 match field {
1058 FieldAccess::Ok(i) => write!(indent, "\n{i}")?,
1059 FieldAccess::Err => write!(indent, "\nErr")?,
1060 }
1061 Ok(())
1062}
1063
1064fn display_for(
1065 mut indent: Indented<Formatter>,
1066 iter: &Pat,
1067 iterable: &Expr,
1068 body: &Block,
1069) -> fmt::Result {
1070 write!(indent, "For:")?;
1071 indent = set_indentation(indent, 1);
1072 write!(indent, "\n{iter}")?;
1073 write!(indent, "\n{iterable}")?;
1074 write!(indent, "\n{body}")?;
1075 Ok(())
1076}
1077
1078fn display_if(
1079 mut indent: Indented<Formatter>,
1080 cond: &Expr,
1081 body: &Block,
1082 els: Option<&Expr>,
1083) -> fmt::Result {
1084 write!(indent, "If:")?;
1085 indent = set_indentation(indent, 1);
1086 write!(indent, "\n{cond}")?;
1087 write!(indent, "\n{body}")?;
1088 if let Some(e) = els {
1089 write!(indent, "\n{e}")?;
1090 }
1091 Ok(())
1092}
1093
1094fn display_index(mut indent: Indented<Formatter>, array: &Expr, index: &Expr) -> fmt::Result {
1095 write!(indent, "Index:")?;
1096 indent = set_indentation(indent, 1);
1097 write!(indent, "\n{array}")?;
1098 write!(indent, "\n{index}")?;
1099 Ok(())
1100}
1101
1102fn display_interpolate(
1103 mut indent: Indented<Formatter>,
1104 components: &[StringComponent],
1105) -> fmt::Result {
1106 write!(indent, "Interpolate:")?;
1107 indent = set_indentation(indent, 1);
1108 for component in components {
1109 match component {
1110 StringComponent::Expr(expr) => write!(indent, "\nExpr: {expr}")?,
1111 StringComponent::Lit(str) => write!(indent, "\nLit: {str:?}")?,
1112 }
1113 }
1114
1115 Ok(())
1116}
1117
1118fn display_lambda(
1119 mut indent: Indented<Formatter>,
1120 kind: CallableKind,
1121 param: &Pat,
1122 expr: &Expr,
1123) -> fmt::Result {
1124 write!(indent, "Lambda ({kind:?}):")?;
1125 indent = set_indentation(indent, 1);
1126 write!(indent, "\n{param}")?;
1127 write!(indent, "\n{expr}")?;
1128 Ok(())
1129}
1130
1131fn display_range(
1132 mut indent: Indented<Formatter>,
1133 start: Option<&Expr>,
1134 step: Option<&Expr>,
1135 end: Option<&Expr>,
1136) -> fmt::Result {
1137 write!(indent, "Range:")?;
1138 indent = set_indentation(indent, 1);
1139 match start {
1140 Some(e) => write!(indent, "\n{e}")?,
1141 None => write!(indent, "\n<no start>")?,
1142 }
1143 match step {
1144 Some(e) => write!(indent, "\n{e}")?,
1145 None => write!(indent, "\n<no step>")?,
1146 }
1147 match end {
1148 Some(e) => write!(indent, "\n{e}")?,
1149 None => write!(indent, "\n<no end>")?,
1150 }
1151 Ok(())
1152}
1153
1154fn display_repeat(
1155 mut indent: Indented<Formatter>,
1156 repeat: &Block,
1157 until: &Expr,
1158 fixup: Option<&Block>,
1159) -> fmt::Result {
1160 write!(indent, "Repeat:")?;
1161 indent = set_indentation(indent, 1);
1162 write!(indent, "\n{repeat}")?;
1163 write!(indent, "\n{until}")?;
1164 match fixup {
1165 Some(b) => write!(indent, "\n{b}")?,
1166 None => write!(indent, "\n<no fixup>")?,
1167 }
1168 Ok(())
1169}
1170
1171fn display_struct(
1172 mut indent: Indented<Formatter>,
1173 name: &PathKind,
1174 copy: Option<&Expr>,
1175 fields: &[Box<FieldAssign>],
1176) -> fmt::Result {
1177 write!(indent, "Struct ({name}):")?;
1178 if copy.is_none() && fields.is_empty() {
1179 write!(indent, " <empty>")?;
1180 return Ok(());
1181 }
1182 indent = set_indentation(indent, 1);
1183 if let Some(copy) = copy {
1184 write!(indent, "\nCopy: {copy}")?;
1185 }
1186 for field in fields {
1187 write!(indent, "\n{field}")?;
1188 }
1189 Ok(())
1190}
1191
1192fn display_tern_op(
1193 mut indent: Indented<Formatter>,
1194 op: TernOp,
1195 expr1: &Expr,
1196 expr2: &Expr,
1197 expr3: &Expr,
1198) -> fmt::Result {
1199 write!(indent, "TernOp ({op:?}):")?;
1200 indent = set_indentation(indent, 1);
1201 write!(indent, "\n{expr1}")?;
1202 write!(indent, "\n{expr2}")?;
1203 write!(indent, "\n{expr3}")?;
1204 Ok(())
1205}
1206
1207fn display_tuple(mut indent: Indented<Formatter>, exprs: &[Box<Expr>]) -> fmt::Result {
1208 if exprs.is_empty() {
1209 write!(indent, "Unit")?;
1210 } else {
1211 write!(indent, "Tuple:")?;
1212 indent = set_indentation(indent, 1);
1213 for e in exprs {
1214 write!(indent, "\n{e}")?;
1215 }
1216 }
1217 Ok(())
1218}
1219
1220fn display_un_op(mut indent: Indented<Formatter>, op: UnOp, expr: &Expr) -> fmt::Result {
1221 write!(indent, "UnOp ({op}):")?;
1222 indent = set_indentation(indent, 1);
1223 write!(indent, "\n{expr}")?;
1224 Ok(())
1225}
1226
1227fn display_while(mut indent: Indented<Formatter>, cond: &Expr, block: &Block) -> fmt::Result {
1228 write!(indent, "While:")?;
1229 indent = set_indentation(indent, 1);
1230 write!(indent, "\n{cond}")?;
1231 write!(indent, "\n{block}")?;
1232 Ok(())
1233}
1234
1235/// A field assignment in a struct constructor expression.
1236#[derive(Clone, Debug, Default, PartialEq)]
1237pub struct FieldAssign {
1238 /// The node ID.
1239 pub id: NodeId,
1240 /// The span.
1241 pub span: Span,
1242 /// The field to assign.
1243 pub field: Box<Ident>,
1244 /// The value to assign to the field.
1245 pub value: Box<Expr>,
1246}
1247
1248impl WithSpan for FieldAssign {
1249 fn with_span(self, span: Span) -> Self {
1250 Self { span, ..self }
1251 }
1252}
1253
1254impl Display for FieldAssign {
1255 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1256 write!(
1257 f,
1258 "FieldsAssign {} {}: ({}) {}",
1259 self.id, self.span, self.field, self.value
1260 )
1261 }
1262}
1263
1264/// An interpolated string component.
1265#[derive(Clone, Debug, PartialEq)]
1266pub enum StringComponent {
1267 /// An expression.
1268 Expr(Box<Expr>),
1269 /// A string literal.
1270 Lit(Rc<str>),
1271}
1272
1273/// A pattern.
1274#[derive(Clone, Debug, Eq, Hash, PartialEq, Default)]
1275pub struct Pat {
1276 /// The node ID.
1277 pub id: NodeId,
1278 /// The span.
1279 pub span: Span,
1280 /// The pattern kind.
1281 pub kind: Box<PatKind>,
1282}
1283
1284impl Display for Pat {
1285 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1286 write!(f, "Pat {} {}: {}", self.id, self.span, self.kind)
1287 }
1288}
1289
1290impl WithSpan for Pat {
1291 fn with_span(self, span: Span) -> Self {
1292 Self { span, ..self }
1293 }
1294}
1295
1296/// A pattern kind.
1297#[derive(Clone, Debug, Eq, Hash, PartialEq, Default)]
1298pub enum PatKind {
1299 /// A binding with an optional type annotation.
1300 Bind(Box<Ident>, Option<Box<Ty>>),
1301 /// A discarded binding, `_`, with an optional type annotation.
1302 Discard(Option<Box<Ty>>),
1303 /// An elided pattern, `...`, used by specializations.
1304 Elided,
1305 /// Parentheses: `(a)`.
1306 Paren(Box<Pat>),
1307 /// A tuple: `(a, b, c)`.
1308 Tuple(Box<[Box<Pat>]>),
1309 /// An invalid pattern.
1310 #[default]
1311 Err,
1312}
1313
1314impl Display for PatKind {
1315 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1316 let mut indent = set_indentation(indented(f), 0);
1317 match self {
1318 PatKind::Bind(id, ty) => {
1319 write!(indent, "Bind:")?;
1320 indent = set_indentation(indent, 1);
1321 write!(indent, "\n{id}")?;
1322 if let Some(t) = ty {
1323 write!(indent, "\n{t}")?;
1324 }
1325 }
1326 PatKind::Discard(d) => match d {
1327 Some(t) => {
1328 write!(indent, "Discard:")?;
1329 indent = set_indentation(indent, 1);
1330 write!(indent, "\n{t}")?;
1331 }
1332 None => write!(indent, "Discard")?,
1333 },
1334 PatKind::Elided => write!(indent, "Elided")?,
1335 PatKind::Paren(p) => {
1336 write!(indent, "Paren:")?;
1337 indent = set_indentation(indent, 1);
1338 write!(indent, "\n{p}")?;
1339 }
1340 PatKind::Tuple(ps) => {
1341 if ps.is_empty() {
1342 write!(indent, "Unit")?;
1343 } else {
1344 write!(indent, "Tuple:")?;
1345 indent = set_indentation(indent, 1);
1346 for p in ps {
1347 write!(indent, "\n{p}")?;
1348 }
1349 }
1350 }
1351 PatKind::Err => write!(indent, "Err")?,
1352 }
1353 Ok(())
1354 }
1355}
1356
1357/// A qubit initializer.
1358#[derive(Clone, Debug, PartialEq, Default)]
1359pub struct QubitInit {
1360 /// The node ID.
1361 pub id: NodeId,
1362 /// The span.
1363 pub span: Span,
1364 /// The qubit initializer kind.
1365 pub kind: Box<QubitInitKind>,
1366}
1367
1368impl Display for QubitInit {
1369 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1370 write!(f, "QubitInit {} {} {}", self.id, self.span, self.kind)
1371 }
1372}
1373
1374impl WithSpan for QubitInit {
1375 fn with_span(self, span: Span) -> Self {
1376 Self { span, ..self }
1377 }
1378}
1379
1380/// A qubit initializer kind.
1381#[derive(Clone, Debug, PartialEq, Default)]
1382pub enum QubitInitKind {
1383 /// An array of qubits: `Qubit[a]`.
1384 Array(Box<Expr>),
1385 /// A parenthesized initializer: `(a)`.
1386 Paren(Box<QubitInit>),
1387 /// A single qubit: `Qubit()`.
1388 Single,
1389 /// A tuple: `(a, b, c)`.
1390 Tuple(Box<[Box<QubitInit>]>),
1391 /// An invalid initializer.
1392 #[default]
1393 Err,
1394}
1395
1396impl Display for QubitInitKind {
1397 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1398 let mut indent = set_indentation(indented(f), 0);
1399 match self {
1400 QubitInitKind::Array(e) => {
1401 write!(indent, "Array:")?;
1402 indent = set_indentation(indent, 1);
1403 write!(indent, "\n{e}")?;
1404 }
1405 QubitInitKind::Paren(qi) => {
1406 write!(indent, "Parens:")?;
1407 indent = set_indentation(indent, 1);
1408 write!(indent, "\n{qi}")?;
1409 }
1410 QubitInitKind::Single => write!(indent, "Single")?,
1411 QubitInitKind::Tuple(qis) => {
1412 if qis.is_empty() {
1413 write!(indent, "Unit")?;
1414 } else {
1415 write!(indent, "Tuple:")?;
1416 indent = set_indentation(indent, 1);
1417 for qi in qis {
1418 write!(indent, "\n{qi}")?;
1419 }
1420 }
1421 }
1422 QubitInitKind::Err => write!(indent, "Err")?,
1423 }
1424 Ok(())
1425 }
1426}
1427
1428/// A path that may or may not have been successfully parsed.
1429#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1430pub enum PathKind {
1431 /// A successfully parsed path.
1432 Ok(Box<Path>),
1433
1434 /// An invalid path.
1435 Err(Option<Box<IncompletePath>>),
1436}
1437
1438impl Default for PathKind {
1439 fn default() -> Self {
1440 PathKind::Err(None)
1441 }
1442}
1443
1444/// A path that was successfully parsed up to a certain `.`,
1445/// but is missing its final identifier.
1446#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1447pub struct IncompletePath {
1448 /// The whole span of the incomplete path,
1449 /// including the final `.` and any whitespace or keyword
1450 /// that follows it.
1451 pub span: Span,
1452 /// Any segments that were successfully parsed before the final `.`.
1453 pub segments: Box<[Ident]>,
1454 /// Whether a keyword exists after the final `.`.
1455 /// This keyword can be presumed to be a partially typed identifier.
1456 pub keyword: bool,
1457}
1458
1459impl Display for PathKind {
1460 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1461 match self {
1462 PathKind::Ok(path) => write!(f, "{path}")?,
1463 PathKind::Err(Some(incomplete_path)) => {
1464 let mut indent = set_indentation(indented(f), 0);
1465 write!(indent, "Err IncompletePath {}:", incomplete_path.span)?;
1466 indent = set_indentation(indent, 1);
1467 for part in &incomplete_path.segments {
1468 write!(indent, "\n{part}")?;
1469 }
1470 }
1471 PathKind::Err(None) => write!(f, "Err",)?,
1472 }
1473 Ok(())
1474 }
1475}
1476
1477/// A path to a declaration or a field access expression,
1478/// to be disambiguated during name resolution.
1479#[derive(Clone, Debug, Eq, Hash, PartialEq)]
1480pub struct Path {
1481 /// The node ID.
1482 pub id: NodeId,
1483 /// The span.
1484 pub span: Span,
1485 /// The segments that make up the front of the path before the final `.`.
1486 pub segments: Option<Box<[Ident]>>,
1487 /// The declaration or field name.
1488 pub name: Box<Ident>,
1489}
1490
1491impl Display for Path {
1492 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1493 if self.segments.is_none() {
1494 write!(f, "Path {} {} ({})", self.id, self.span, self.name)?;
1495 } else {
1496 let mut indent = set_indentation(indented(f), 0);
1497 write!(indent, "Path {} {}:", self.id, self.span)?;
1498 indent = set_indentation(indent, 1);
1499 if let Some(parts) = &self.segments {
1500 for part in parts {
1501 write!(indent, "\n{part}")?;
1502 }
1503 }
1504 write!(indent, "\n{}", self.name)?;
1505 }
1506 Ok(())
1507 }
1508}
1509
1510impl WithSpan for Path {
1511 fn with_span(self, span: Span) -> Self {
1512 Self { span, ..self }
1513 }
1514}
1515
1516/// An identifier.
1517#[derive(Clone, Debug, Eq, Hash, PartialEq)]
1518pub struct Ident {
1519 /// The node ID.
1520 pub id: NodeId,
1521 /// The span.
1522 pub span: Span,
1523 /// The identifier name.
1524 pub name: Rc<str>,
1525}
1526
1527impl Default for Ident {
1528 fn default() -> Self {
1529 Ident {
1530 id: NodeId::default(),
1531 span: Span::default(),
1532 name: "".into(),
1533 }
1534 }
1535}
1536
1537impl WithSpan for Ident {
1538 fn with_span(self, span: Span) -> Self {
1539 Self { span, ..self }
1540 }
1541}
1542
1543impl Display for Ident {
1544 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1545 write!(f, "Ident {} {} \"{}\"", self.id, self.span, self.name)
1546 }
1547}
1548
1549/// Trait for working with dot-separated sequences of identifiers,
1550/// intended to unify the different representations that can appear
1551/// in the AST (`Path`s and `Ident` slices).
1552pub trait Idents {
1553 /// Iterates over the [`Ident`]s in this sequence.
1554 fn iter(&self) -> impl Iterator<Item = &Ident>;
1555
1556 /// The full dot-separated name represented by this [`Ident`] sequence.
1557 /// E.g. `a.b.c`
1558 fn full_name(&self) -> Rc<str> {
1559 let mut strs = self.rc_str_iter();
1560 let first = strs.next();
1561 let Some(first) = first else {
1562 // No parts, empty string
1563 return "".into();
1564 };
1565
1566 let next = strs.next();
1567 let Some(mut part) = next else {
1568 // Only one ident, return it directly
1569 return first.clone();
1570 };
1571
1572 // More than one ident, build up a dotted string
1573 let mut buf = String::new();
1574 buf.push_str(first);
1575 loop {
1576 buf.push('.');
1577 buf.push_str(part);
1578 part = match strs.next() {
1579 Some(part) => part,
1580 None => {
1581 break;
1582 }
1583 };
1584 }
1585 buf.into()
1586 }
1587
1588 /// Iterates over the identifier names as string slices.
1589 fn str_iter(&self) -> impl Iterator<Item = &str> {
1590 self.iter().map(|ident| ident.name.as_ref())
1591 }
1592
1593 /// Iterates over the identifier names as `Rc<str>`s.
1594 fn rc_str_iter(&self) -> impl Iterator<Item = &Rc<str>> {
1595 self.iter().map(|ident| &ident.name)
1596 }
1597
1598 /// Returns the conjoined span of all [`Ident`]s in this collection.
1599 #[must_use]
1600 fn full_span(&self) -> Span {
1601 let mut idents = self.iter().peekable();
1602 Span {
1603 lo: idents.peek().map(|i| i.span.lo).unwrap_or_default(),
1604 hi: idents.last().map(|i| i.span.hi).unwrap_or_default(),
1605 }
1606 }
1607}
1608
1609impl Idents for Box<[Ident]> {
1610 fn iter(&self) -> impl Iterator<Item = &Ident> {
1611 self.as_ref().iter() // invokes the slice iterator
1612 }
1613}
1614
1615impl Idents for &[Ident] {
1616 fn iter(&self) -> impl Iterator<Item = &Ident> {
1617 (*self).iter() // invokes the slice iterator
1618 }
1619}
1620
1621impl<T, U> Idents for (T, U)
1622where
1623 T: Idents,
1624 U: Idents,
1625{
1626 fn iter(&self) -> impl Iterator<Item = &Ident> {
1627 self.0.iter().chain(self.1.iter())
1628 }
1629}
1630
1631impl Idents for Ident {
1632 fn iter(&self) -> impl Iterator<Item = &Ident> {
1633 once(self)
1634 }
1635}
1636
1637impl Idents for &Ident {
1638 fn iter(&self) -> impl Iterator<Item = &Ident> {
1639 once(*self)
1640 }
1641}
1642
1643impl Idents for Path {
1644 fn iter(&self) -> impl Iterator<Item = &Ident> {
1645 self.segments
1646 .iter()
1647 .flat_map(Idents::iter)
1648 .chain(once(self.name.as_ref()))
1649 }
1650}
1651
1652/// A callable kind.
1653#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1654pub enum CallableKind {
1655 /// A function.
1656 Function,
1657 /// An operation.
1658 Operation,
1659}
1660
1661/// The mutability of a binding.
1662#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1663pub enum Mutability {
1664 /// An immutable binding.
1665 Immutable,
1666 /// A mutable binding.
1667 Mutable,
1668}
1669
1670/// The source of an allocated qubit.
1671#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1672pub enum QubitSource {
1673 /// A qubit initialized to the zero state.
1674 Fresh,
1675 /// A qubit borrowed from another part of the program that may be in any state, and is expected
1676 /// to be returned to that state before being released.
1677 Dirty,
1678}
1679
1680/// A literal.
1681#[derive(Clone, Debug, PartialEq)]
1682pub enum Lit {
1683 /// A big integer literal.
1684 BigInt(Box<BigInt>),
1685 /// A boolean literal.
1686 Bool(bool),
1687 /// A floating-point literal.
1688 Double(f64),
1689 /// An integer literal.
1690 Int(i64),
1691 /// A Pauli operator literal.
1692 Pauli(Pauli),
1693 /// A measurement result literal.
1694 Result(Result),
1695 /// A string literal.
1696 String(Rc<str>),
1697}
1698
1699impl Display for Lit {
1700 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1701 match self {
1702 Lit::BigInt(val) => write!(f, "BigInt({val})")?,
1703 Lit::Bool(val) => write!(f, "Bool({val})")?,
1704 Lit::Double(val) => write!(f, "Double({val})")?,
1705 Lit::Int(val) => write!(f, "Int({val})")?,
1706 Lit::Pauli(val) => write!(f, "Pauli({val:?})")?,
1707 Lit::Result(val) => write!(f, "Result({val:?})")?,
1708 Lit::String(val) => write!(f, "String({val:?})")?,
1709 }
1710 Ok(())
1711 }
1712}
1713
1714/// A measurement result.
1715#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1716pub enum Result {
1717 /// The zero eigenvalue.
1718 Zero,
1719 /// The one eigenvalue.
1720 One,
1721}
1722
1723impl From<bool> for Result {
1724 fn from(b: bool) -> Self {
1725 if b {
1726 Result::One
1727 } else {
1728 Result::Zero
1729 }
1730 }
1731}
1732
1733/// A Pauli operator.
1734#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1735pub enum Pauli {
1736 /// The Pauli I operator.
1737 I,
1738 /// The Pauli X operator.
1739 X,
1740 /// The Pauli Y operator.
1741 Y,
1742 /// The Pauli Z operator.
1743 Z,
1744}
1745
1746/// A functor that may be applied to an operation.
1747#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1748pub enum Functor {
1749 /// The adjoint functor.
1750 Adj,
1751 /// The controlled functor.
1752 Ctl,
1753}
1754
1755/// A specialization that may be implemented for an operation.
1756#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1757pub enum Spec {
1758 /// The default specialization.
1759 Body,
1760 /// The adjoint specialization.
1761 Adj,
1762 /// The controlled specialization.
1763 Ctl,
1764 /// The controlled adjoint specialization.
1765 CtlAdj,
1766}
1767
1768impl Display for Spec {
1769 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1770 match self {
1771 Spec::Body => f.write_str("body"),
1772 Spec::Adj => f.write_str("adjoint"),
1773 Spec::Ctl => f.write_str("controlled"),
1774 Spec::CtlAdj => f.write_str("controlled adjoint"),
1775 }
1776 }
1777}
1778
1779/// A strategy for generating a specialization.
1780#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1781pub enum SpecGen {
1782 /// Choose a strategy automatically.
1783 Auto,
1784 /// Distributes controlled qubits.
1785 Distribute,
1786 /// A specialization implementation is not generated, but is instead left as an opaque
1787 /// declaration.
1788 Intrinsic,
1789 /// Inverts the order of operations.
1790 Invert,
1791 /// Uses the body specialization without modification.
1792 Slf,
1793}
1794
1795/// A unary operator.
1796#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1797pub enum UnOp {
1798 /// A functor application.
1799 Functor(Functor),
1800 /// Negation: `-`.
1801 Neg,
1802 /// Bitwise NOT: `~~~`.
1803 NotB,
1804 /// Logical NOT: `not`.
1805 NotL,
1806 /// A leading `+`.
1807 Pos,
1808 /// Unwrap a user-defined type: `!`.
1809 Unwrap,
1810}
1811
1812impl Display for UnOp {
1813 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1814 match self {
1815 UnOp::Functor(func) => write!(f, "Functor {func:?}")?,
1816 _ => fmt::Debug::fmt(self, f)?,
1817 }
1818 Ok(())
1819 }
1820}
1821
1822/// A binary operator.
1823#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1824pub enum BinOp {
1825 /// Addition: `+`.
1826 Add,
1827 /// Bitwise AND: `&&&`.
1828 AndB,
1829 /// Logical AND: `and`.
1830 AndL,
1831 /// Division: `/`.
1832 Div,
1833 /// Equality: `==`.
1834 Eq,
1835 /// Exponentiation: `^`.
1836 Exp,
1837 /// Greater than: `>`.
1838 Gt,
1839 /// Greater than or equal: `>=`.
1840 Gte,
1841 /// Less than: `<`.
1842 Lt,
1843 /// Less than or equal: `<=`.
1844 Lte,
1845 /// Modulus: `%`.
1846 Mod,
1847 /// Multiplication: `*`.
1848 Mul,
1849 /// Inequality: `!=`.
1850 Neq,
1851 /// Bitwise OR: `|||`.
1852 OrB,
1853 /// Logical OR: `or`.
1854 OrL,
1855 /// Shift left: `<<<`.
1856 Shl,
1857 /// Shift right: `>>>`.
1858 Shr,
1859 /// Subtraction: `-`.
1860 Sub,
1861 /// Bitwise XOR: `^^^`.
1862 XorB,
1863}
1864
1865/// A ternary operator.
1866#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1867pub enum TernOp {
1868 /// Conditional: `a ? b | c`.
1869 Cond,
1870 /// Aggregate update: `a w/ b <- c`.
1871 Update,
1872}
1873
1874/// A set operator.
1875#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
1876pub enum SetOp {
1877 /// The set union.
1878 Union,
1879 /// The set intersection.
1880 Intersect,
1881}
1882
1883#[derive(Clone, Debug, Eq, PartialEq)]
1884/// Represents an export declaration.
1885pub struct ImportOrExportDecl {
1886 /// The span.
1887 pub span: Span,
1888 /// The items being exported from this namespace.
1889 pub items: Box<[ImportOrExportItem]>,
1890 /// Whether this is an export declaration or not. If `false`, then this is an `Import`.
1891 is_export: bool,
1892}
1893
1894impl Display for ImportOrExportDecl {
1895 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1896 let items_str = self
1897 .items
1898 .iter()
1899 .map(std::string::ToString::to_string)
1900 .collect::<Vec<_>>()
1901 .join(", ");
1902 write!(f, "ImportOrExportDecl {}: [{items_str}]", self.span)
1903 }
1904}
1905
1906impl ImportOrExportDecl {
1907 /// Creates a new `ImportOrExportDecl` with the given span, items, and export flag.
1908 #[must_use]
1909 pub fn new(span: Span, items: Box<[ImportOrExportItem]>, is_export: bool) -> Self {
1910 Self {
1911 span,
1912 items,
1913 is_export,
1914 }
1915 }
1916
1917 /// Returns true if this is an export declaration.
1918 #[must_use]
1919 pub fn is_export(&self) -> bool {
1920 self.is_export
1921 }
1922
1923 /// Returns true if this is an import declaration.
1924 #[must_use]
1925 pub fn is_import(&self) -> bool {
1926 !self.is_export
1927 }
1928
1929 /// Returns an iterator over the items being exported from this namespace.
1930 pub fn items(&self) -> impl Iterator<Item = &ImportOrExportItem> {
1931 self.items.iter()
1932 }
1933}
1934
1935/// An individual item within an [`ImportOrExportDecl`]. This can be a path or a path with an alias.
1936#[derive(Clone, Debug, Eq, PartialEq, Default)]
1937pub struct ImportOrExportItem {
1938 /// The span of the import path including the glob and alias, if any.
1939 pub span: Span,
1940 /// The path to the item being exported.
1941 pub path: PathKind,
1942 /// An optional alias for the item being exported.
1943 pub alias: Option<Ident>,
1944 /// Whether this is a glob import/export.
1945 pub is_glob: bool,
1946}
1947
1948impl Display for ImportOrExportItem {
1949 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1950 let ImportOrExportItem {
1951 span: _,
1952 ref path,
1953 ref alias,
1954 is_glob,
1955 } = self;
1956 let is_glob = if *is_glob { ".*" } else { "" };
1957 match alias {
1958 Some(alias) => write!(f, "{path}{is_glob} as {alias}",),
1959 None => write!(f, "{path}{is_glob}"),
1960 }
1961 }
1962}
1963
1964impl WithSpan for ImportOrExportItem {
1965 fn with_span(self, span: Span) -> Self {
1966 Self { span, ..self }
1967 }
1968}
1969
1970impl ImportOrExportItem {
1971 /// Returns the alias ident, if any, or the name from the path if no alias is present.
1972 /// Returns `None` if the path has an error.
1973 #[must_use]
1974 pub fn name(&self) -> Option<&Ident> {
1975 match &self.alias {
1976 Some(_) => self.alias.as_ref(),
1977 None => {
1978 if let PathKind::Ok(path) = &self.path {
1979 Some(&path.name)
1980 } else {
1981 None
1982 }
1983 }
1984 }
1985 }
1986}
1987
1988/// A [`TypeParameter`] is a generic type variable with optional bounds (constraints).
1989#[derive(Default, Debug, PartialEq, Eq, Clone, Hash)]
1990pub struct TypeParameter {
1991 /// Class constraints specified for this type parameter -- any type variable passed in
1992 /// as an argument to these parameters must satisfy these constraints.
1993 pub constraints: ClassConstraints,
1994 /// The name of the type parameter.
1995 pub ty: Ident,
1996 /// The span of the full type parameter, including its name and its constraints.
1997 pub span: Span,
1998}
1999
2000impl WithSpan for TypeParameter {
2001 fn with_span(self, span: Span) -> Self {
2002 Self { span, ..self }
2003 }
2004}
2005
2006impl TypeParameter {
2007 /// Instantiates a new `TypeParameter` with the given type name, constraints, and span.
2008 #[must_use]
2009 pub fn new(ty: Ident, bounds: ClassConstraints, span: Span) -> Self {
2010 Self {
2011 ty,
2012 constraints: bounds,
2013 span,
2014 }
2015 }
2016}
2017
2018impl std::fmt::Display for TypeParameter {
2019 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
2020 // 'A: Eq + Ord + Clone
2021 write!(
2022 f,
2023 "{}{}",
2024 self.ty.name,
2025 if self.constraints.0.is_empty() {
2026 Default::default()
2027 } else {
2028 format!(": {}", self.constraints)
2029 }
2030 )
2031 }
2032}
2033
2034/// A list of class constraints, used when constraining a type parameter.
2035#[derive(Default, Debug, PartialEq, Eq, Clone, Hash)]
2036pub struct ClassConstraints(pub Box<[ClassConstraint]>);
2037
2038/// An individual class constraint, used when constraining a type parameter.
2039/// To understand this concept, think of parameters in a function signature -- the potential arguments that can
2040/// be passed to them are constrained by what type is specified. Type-level parameters are no different, and
2041/// the type variables that are passed to a type parameter must satisfy the constraints specified in the type parameter.
2042#[derive(PartialEq, Eq, Clone, Hash, Debug)]
2043pub struct ClassConstraint {
2044 /// The name of the constraint.
2045 pub name: Ident,
2046 /// Parameters for a constraint. For example, `Iterator` has a parameter `T` in `Iterator<T>` -- this
2047 /// is the type of the item that is coming out of the iterator.
2048 pub parameters: Box<[ConstraintParameter]>,
2049}
2050
2051impl std::fmt::Display for ClassConstraint {
2052 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
2053 // Iterator<T>
2054 write!(
2055 f,
2056 "{}{}",
2057 self.name.name,
2058 if self.parameters.is_empty() {
2059 String::new()
2060 } else {
2061 format!(
2062 "[{}]",
2063 self.parameters
2064 .iter()
2065 .map(|x| x.ty.to_string())
2066 .collect::<Vec<_>>()
2067 .join(", ")
2068 )
2069 }
2070 )
2071 }
2072}
2073
2074/// An individual constraint parameter is a type that is passed to a constraint, such as `T` in `Iterator<T>`.
2075/// #[derive(Default, `PartialEq`, Eq, Clone, Hash, Debug)]
2076#[derive(Default, PartialEq, Eq, Clone, Hash, Debug)]
2077pub struct ConstraintParameter {
2078 /// The type variable being passed as a constraint parameter.
2079 pub ty: Ty,
2080}
2081
2082impl WithSpan for ConstraintParameter {
2083 fn with_span(self, span: Span) -> Self {
2084 Self {
2085 ty: self.ty.with_span(span),
2086 }
2087 }
2088}
2089
2090impl ClassConstraint {
2091 /// Getter for the `span` field of the `name` field (the name of the class constraint).
2092 #[must_use]
2093 pub fn span(&self) -> Span {
2094 self.name.span
2095 }
2096}
2097
2098impl ClassConstraints {
2099 /// The conjoined span of all of the bounds
2100 #[must_use]
2101 pub fn span(&self) -> Span {
2102 Span {
2103 lo: self.0.first().map(|i| i.span().lo).unwrap_or_default(),
2104 hi: self.0.last().map(|i| i.span().hi).unwrap_or_default(),
2105 }
2106 }
2107}
2108
2109impl std::fmt::Display for ClassConstraints {
2110 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
2111 // A + B + C + D
2112 write!(
2113 f,
2114 "{}",
2115 self.0
2116 .iter()
2117 .map(|x| format!("{}", x.name.name,))
2118 .collect::<Vec<_>>()
2119 .join(" + "),
2120 )
2121 }
2122}
2123