microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.25.1

Branches

Tags

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

Clone

HTTPS

Download ZIP

source/compiler/qsc_ast/src/ast.rs

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