microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.8.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

compiler/qsc_ast/src/ast.rs

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