1use itertools::Itertools;
2use num::{BigInt, BigUint, Signed, Zero};
3use serde::{Deserialize, Serialize};
4use spade_common::{
5 location_info::{Loc, WithLocation},
6 name::{Identifier, Path, Visibility},
7 namespace::ModuleNamespace,
8 num_ext::InfallibleToBigInt,
9};
10use spade_diagnostics::Diagnostic;
11use std::{fmt::Display, path::PathBuf, rc::Rc};
12
13pub use crate::token::TokenKind;
14
15pub mod testutil;
16pub mod token;
17
18#[derive(PartialEq, Debug, Clone)]
19pub struct ParseCtx {
20 pub file_id: usize,
21 pub working_dir: Option<PathBuf>,
22}
23
24#[derive(PartialEq, Debug, Clone)]
25pub enum TypeExpression {
26 TypeSpec(Box<Loc<TypeSpec>>),
27 Bool(bool),
28 Integer(BigInt),
29 String(String),
30 ConstGeneric(Box<Loc<Expression>>),
31}
32
33impl std::fmt::Display for TypeExpression {
34 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35 match self {
36 TypeExpression::TypeSpec(inner) => write!(f, "{inner}"),
37 TypeExpression::Bool(inner) => write!(f, "{inner}"),
38 TypeExpression::Integer(inner) => write!(f, "{inner}"),
39 TypeExpression::String(inner) => write!(f, "{inner:?}"),
40 TypeExpression::ConstGeneric(_) => write!(f, "{{...}}"),
41 }
42 }
43}
44
45#[derive(PartialEq, Debug, Clone)]
46pub enum NamedTurbofish {
47 Short(Loc<Identifier>),
48 Full(Loc<Identifier>, Loc<TypeExpression>),
49}
50
51#[derive(PartialEq, Debug, Clone)]
52pub enum TurbofishInner {
53 Named(Vec<Loc<NamedTurbofish>>),
54 Positional(Vec<Loc<TypeExpression>>),
55}
56
57#[derive(PartialEq, Debug, Clone)]
60pub enum TypeSpec {
61 Tuple(Vec<Loc<TypeExpression>>),
62 Array {
63 inner: Box<Loc<TypeExpression>>,
64 size: Box<Loc<TypeExpression>>,
65 },
66 Named(Loc<Path>, Option<Loc<Vec<Loc<TypeExpression>>>>),
67 Inverted(Box<Loc<TypeExpression>>),
73 CopyView(Box<Loc<TypeExpression>>),
74 Impl(Vec<Loc<TraitSpec>>),
75 Wildcard,
76}
77
78impl TypeSpec {
79 pub fn is_tuple(&self) -> bool {
80 match self {
81 TypeSpec::Tuple(_) => true,
82 TypeSpec::Array { .. }
83 | TypeSpec::Named(_, _)
84 | TypeSpec::Inverted(_)
85 | TypeSpec::CopyView(_)
86 | TypeSpec::Impl(_)
87 | TypeSpec::Wildcard => false,
88 }
89 }
90
91 pub fn is_empty_tuple(&self) -> bool {
92 match self {
93 TypeSpec::Tuple(ts) => ts.is_empty(),
94 TypeSpec::Array { .. }
95 | TypeSpec::Named(_, _)
96 | TypeSpec::Inverted(_)
97 | TypeSpec::CopyView(_)
98 | TypeSpec::Impl(_)
99 | TypeSpec::Wildcard => false,
100 }
101 }
102}
103
104impl std::fmt::Display for TypeSpec {
105 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
106 match self {
107 TypeSpec::Tuple(inner) => {
108 write!(f, "({})", inner.iter().map(|i| format!("{i}")).join(", "))
109 }
110 TypeSpec::Array { inner, size } => write!(f, "[{inner}; {size}]"),
111 TypeSpec::Named(name, args) => {
112 let args = match args {
113 Some(a) => format!("<{}>", a.iter().map(|a| format!("{a}")).join(", ")),
114 None => String::new(),
115 };
116 write!(f, "{name}{args}")
117 }
118 TypeSpec::Inverted(inner) => write!(f, "inv {inner}"),
119 TypeSpec::CopyView(inner) => write!(f, "&{inner}"),
120 TypeSpec::Impl(trait_specs) => write!(
121 f,
122 "impl {}",
123 trait_specs.iter().map(|s| format!("{s}")).join(" + ")
124 ),
125 TypeSpec::Wildcard => write!(f, "_"),
126 }
127 }
128}
129
130#[derive(PartialEq, Debug, Clone)]
131pub enum ArgumentPattern {
132 Named(Vec<(Loc<Identifier>, Option<Loc<Pattern>>)>),
133 Positional(Vec<Loc<Pattern>>),
134}
135
136#[derive(PartialEq, Debug, Clone)]
137pub enum Pattern {
138 Integer(IntLiteral),
139 Bool(bool),
140 Bound(Loc<Identifier>, Box<Loc<Pattern>>),
141 Path {
142 wire: Option<Loc<()>>,
143 path: Loc<Path>,
144 },
145 Tuple(Vec<Loc<Pattern>>),
146 Array(Vec<Loc<Pattern>>),
147 Type(Loc<Path>, Loc<ArgumentPattern>),
148}
149
150impl Pattern {
152 pub fn integer(val: i32) -> Self {
153 Pattern::Integer(IntLiteral::Unsized(val.to_bigint()))
154 }
155 pub fn name(name: &str) -> Loc<Self> {
156 Pattern::Path {
157 wire: None,
158 path: Path::from_strs(&[name]).nowhere(),
159 }
160 .nowhere()
161 }
162}
163
164#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
165pub enum MacroFragment {
166 Block,
167 Expr,
168 Ident,
169 Item,
170 Literal,
171 Pattern,
172 Path,
173 Statement,
174 Tokens,
175 Type,
176 Visibility,
177}
178
179#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
180pub enum MacroRepetitions {
181 Optional,
182 Many0,
183 Many1,
184}
185
186#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
187pub enum MacroPattern {
188 Token(Loc<TokenKind>),
189 RepeatedSubpattern {
190 parts: Vec<Loc<MacroPattern>>,
191 delim: Option<Loc<TokenKind>>,
192 reps: Loc<MacroRepetitions>,
193 },
194 EnclosedSubpattern {
195 parts: Vec<Loc<MacroPattern>>,
196 open_delim: Loc<TokenKind>,
197 close_delim: Loc<TokenKind>,
198 },
199 Fragment {
200 name: Loc<Identifier>,
201 kind: Loc<Identifier>,
202 },
203}
204
205#[derive(PartialEq, Debug, Clone)]
206pub enum NamedArgument {
207 Full(Loc<Identifier>, Loc<Expression>),
208 Short(Loc<Identifier>),
210}
211
212#[derive(PartialEq, Debug, Clone)]
213pub enum ArgumentList {
214 Positional(Vec<Loc<Expression>>),
215 Named(Vec<NamedArgument>),
216}
217
218#[derive(PartialEq, Debug, Clone)]
219pub enum Inequality {
220 Eq,
221 Neq,
222 Lt,
223 Leq,
224 Gt,
225 Geq,
226}
227
228#[derive(PartialEq, Debug, Clone)]
229pub enum WhereClause {
230 GenericInt {
231 target: Loc<Path>,
232 kind: Inequality,
233 expression: Loc<Expression>,
234 if_unsatisfied: Option<String>,
235 },
236 TraitBounds {
237 target: Loc<Path>,
238 traits: Vec<Loc<TraitSpec>>,
239 },
240}
241impl WhereClause {
242 pub fn target(&self) -> &Loc<Path> {
243 match self {
244 WhereClause::GenericInt {
245 target,
246 kind: _,
247 expression: _,
248 if_unsatisfied: _,
249 } => target,
250 WhereClause::TraitBounds { target, traits: _ } => target,
251 }
252 }
253}
254
255#[derive(PartialEq, Debug, Clone)]
256pub struct AssocType {
257 pub name: Loc<Identifier>,
258 pub type_params: Option<Loc<Vec<Loc<TypeParam>>>>,
259}
260
261#[derive(PartialEq, Debug, Clone)]
262pub enum BinaryOperator {
263 Add,
264 Sub,
265 Mul,
266 Div,
267 Mod,
268 Eq,
269 Neq,
270 Lt,
271 Gt,
272 Le,
273 Ge,
274 LogicalAnd,
275 LogicalOr,
276 LogicalXor,
277 LeftShift,
278 RightShift,
279 ArithmeticRightShift,
280 BitwiseAnd,
281 BitwiseOr,
282 BitwiseXor,
283 WrappingAdd,
284 WrappingSub,
285 WrappingMul,
286 WrappingLeftShift,
287 WrappingRightShift,
288}
289
290impl std::fmt::Display for BinaryOperator {
291 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
292 match self {
293 BinaryOperator::Add => write!(f, "+"),
294 BinaryOperator::Sub => write!(f, "-"),
295 BinaryOperator::Mul => write!(f, "*"),
296 BinaryOperator::Div => write!(f, "/"),
297 BinaryOperator::Mod => write!(f, "%"),
298 BinaryOperator::Eq => write!(f, "=="),
299 BinaryOperator::Neq => write!(f, "!="),
300 BinaryOperator::Lt => write!(f, "<"),
301 BinaryOperator::Gt => write!(f, ">"),
302 BinaryOperator::Le => write!(f, "<="),
303 BinaryOperator::Ge => write!(f, ">="),
304 BinaryOperator::LogicalAnd => write!(f, "&"),
305 BinaryOperator::LogicalOr => write!(f, "|"),
306 BinaryOperator::LogicalXor => write!(f, "^"),
307 BinaryOperator::LeftShift => write!(f, "<<"),
308 BinaryOperator::RightShift => write!(f, ">>"),
309 BinaryOperator::ArithmeticRightShift => write!(f, ">>>"),
310 BinaryOperator::BitwiseAnd => write!(f, "&&"),
311 BinaryOperator::BitwiseOr => write!(f, "||"),
312 BinaryOperator::BitwiseXor => write!(f, "^^"),
313 BinaryOperator::WrappingAdd => write!(f, "+."),
314 BinaryOperator::WrappingSub => write!(f, "-."),
315 BinaryOperator::WrappingMul => write!(f, "*."),
316 BinaryOperator::WrappingLeftShift => write!(f, "<<."),
317 BinaryOperator::WrappingRightShift => write!(f, ">>."),
318 }
319 }
320}
321
322#[derive(PartialEq, Debug, Clone)]
323pub enum UnaryOperator {
324 Sub,
325 Not,
326 BitwiseNot,
327 WrappingSub,
328 Dereference,
329 Reference,
330}
331
332impl std::fmt::Display for UnaryOperator {
333 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
334 match self {
335 UnaryOperator::Sub => write!(f, "-"),
336 UnaryOperator::Not => write!(f, "!"),
337 UnaryOperator::BitwiseNot => write!(f, "~"),
338 UnaryOperator::WrappingSub => write!(f, "-."),
339 UnaryOperator::Dereference => write!(f, "*"),
340 UnaryOperator::Reference => write!(f, "&"),
341 }
342 }
343}
344
345#[derive(PartialEq, Debug, Clone)]
346pub enum PipelineStageReference {
347 Relative(Loc<TypeExpression>),
348 Absolute(Loc<Identifier>),
349}
350
351#[derive(PartialEq, Debug, Clone)]
352pub enum CallKind {
353 Function,
354 Entity(Loc<()>),
355 Pipeline(Loc<()>, Loc<TypeExpression>),
356}
357
358#[derive(PartialEq, Debug, Clone)]
359pub enum BitLiteral {
360 Low,
361 High,
362 HighImp,
363}
364
365#[derive(PartialEq, Debug, Clone)]
366pub enum IncompleteExpression {
367 IncompleteDot {
368 base: Box<Loc<Expression>>,
369 has_inst: bool,
370 has_depth: bool,
371 },
372}
373
374#[derive(PartialEq, Debug, Clone)]
375pub enum Expression {
376 Identifier(Loc<Path>),
377 IntLiteral(Loc<IntLiteral>),
378 BoolLiteral(Loc<bool>),
379 StrLiteral(Loc<String>),
380 TriLiteral(Loc<BitLiteral>),
381 ArrayLiteral(Vec<(Option<Loc<Identifier>>, Loc<Expression>)>),
383 ArrayShorthandLiteral(Box<Loc<Expression>>, Box<Loc<Expression>>),
386 Index(Box<Loc<Expression>>, Box<Loc<Expression>>),
387 RangeIndex {
388 target: Box<Loc<Expression>>,
389 start: Option<Box<Loc<Expression>>>,
391 end: Option<Box<Loc<Expression>>>,
392 },
393 Parenthesized(Box<Loc<Expression>>),
394 TupleLiteral(Vec<Loc<Expression>>),
395 TupleIndex {
396 target: Box<Loc<Expression>>,
397 index: Loc<u128>,
398 deprecated_syntax: bool,
399 },
400 FieldAccess(Box<Loc<Expression>>, Loc<Identifier>),
401 TypeCast(Box<Loc<Expression>>, Loc<TypeExpression>),
402 Lambda {
403 unit_kind: Loc<UnitKind>,
404 args: Loc<Vec<Loc<Pattern>>>,
405 body: Box<Loc<Block>>,
406 },
407 Call {
409 kind: CallKind,
410 callee: Loc<Path>,
411 args: Loc<ArgumentList>,
412 turbofish: Option<Loc<TurbofishInner>>,
413 },
414 MethodCall {
415 target: Box<Loc<Expression>>,
416 name: Loc<Identifier>,
417 args: Loc<ArgumentList>,
418 kind: CallKind,
419 turbofish: Option<Loc<TurbofishInner>>,
420 },
421 MacroCall {
422 callee: Loc<Path>,
423 tokens: Vec<Loc<TokenKind>>,
424 parse_ctx: Rc<ParseCtx>,
425 },
426 If {
427 cond: Box<Loc<Expression>>,
428 on_true: Box<Loc<Expression>>,
429 on_false: Box<Loc<Expression>>,
430 },
431 TypeLevelIf {
432 cond: Box<Loc<Expression>>,
433 on_true: Box<Loc<Expression>>,
434 on_false: Box<Loc<Expression>>,
435 },
436 Match {
437 expression: Box<Loc<Expression>>,
438 branches: Loc<Vec<(Loc<Pattern>, Option<Loc<Expression>>, Loc<Expression>)>>,
439 if_let: bool,
440 },
441 UnaryOperator(Loc<UnaryOperator>, Box<Loc<Expression>>),
442 BinaryOperator(
443 Box<Loc<Expression>>,
444 Loc<BinaryOperator>,
445 Box<Loc<Expression>>,
446 ),
447 Block(Box<Block>),
448 Unsafe(Box<Loc<Block>>),
449 PipelineReference {
451 stage_kw_and_reference_loc: Loc<()>,
456 stage: PipelineStageReference,
461 name: Loc<Identifier>,
466 },
467 LabelAccess {
468 label: Loc<Path>,
469 field: Loc<Identifier>,
470 },
471 StageValid,
472 StageReady,
473 StaticUnreachable(Loc<String>),
474 Incomplete(Diagnostic, IncompleteExpression),
479}
480
481impl Expression {
482 pub fn int_literal_signed(val: i32) -> Self {
483 Self::IntLiteral(IntLiteral::unsized_(val).nowhere())
484 }
485
486 pub fn bool_literal(val: bool) -> Self {
487 Self::BoolLiteral(val.nowhere())
488 }
489
490 pub fn as_int_literal(self) -> Option<IntLiteral> {
491 match self {
492 Expression::IntLiteral(lit) => Some(lit.inner),
493 _ => None,
494 }
495 }
496
497 pub fn assume_block(&self) -> &Block {
498 if let Expression::Block(inner) = self {
499 inner
500 } else {
501 panic!("Expected block")
502 }
503 }
504
505 pub fn variant_str(&self) -> &'static str {
506 match self {
507 Expression::Identifier(_) => "identifier",
508 Expression::IntLiteral(_) => "int literal",
509 Expression::BoolLiteral(_) => "bool literal",
510 Expression::StrLiteral(_) => "str literal",
511 Expression::TriLiteral(_) => "tri-state literal",
512 Expression::ArrayLiteral(_) => "array literal",
513 Expression::ArrayShorthandLiteral(_, _) => "array shorthand literal",
514 Expression::Index(_, _) => "index",
515 Expression::RangeIndex { .. } => "range index",
516 Expression::Parenthesized(_) => "parenthesized",
517 Expression::TupleLiteral(_) => "tuple literal",
518 Expression::TupleIndex { .. } => "tuple index",
519 Expression::FieldAccess(_, _) => "field access",
520 Expression::Incomplete { .. } => "incomplete",
521 Expression::TypeCast(_, _) => "type cast",
522 Expression::If { .. } => "if",
523 Expression::TypeLevelIf { .. } => "type level if",
524 Expression::Match { if_let: false, .. } => "match",
525 Expression::Match { if_let: true, .. } => "if let",
526 Expression::Lambda { .. } => "lambda",
527 Expression::Call { .. } => "call",
528 Expression::MethodCall { .. } => "method call",
529 Expression::MacroCall { .. } => "macro call",
530 Expression::UnaryOperator(_, _) => "unary operator",
531 Expression::BinaryOperator(_, _, _) => "binary operator",
532 Expression::Block(_) => "block",
533 Expression::Unsafe(_) => "unsafe",
534 Expression::PipelineReference { .. } => "pipeline reference",
535 Expression::LabelAccess { .. } => "label access",
536 Expression::StageValid => "stage.valid",
537 Expression::StageReady => "stage.ready",
538 Expression::StaticUnreachable(_) => "static_unreachable",
539 }
540 }
541}
542
543#[derive(PartialEq, Debug, Clone)]
546pub enum IntLiteral {
547 Unsized(BigInt),
548 Signed { val: BigInt, size: Option<BigUint> },
549 Unsigned { val: BigUint, size: Option<BigUint> },
550}
551
552impl IntLiteral {
553 pub fn unsized_(val: i32) -> IntLiteral {
554 IntLiteral::Unsized(val.to_bigint())
555 }
556
557 pub fn as_signed(self) -> BigInt {
560 match self {
561 IntLiteral::Signed { val, size: _ } => val,
562 IntLiteral::Unsigned { val, size: _ } => val.to_bigint(),
563 IntLiteral::Unsized(val) => val,
564 }
565 }
566
567 pub fn as_unsigned(self) -> Option<BigUint> {
570 match self {
571 IntLiteral::Signed { val, size: _ } | IntLiteral::Unsized(val) => {
572 if val >= BigInt::zero() {
573 Some(val.to_biguint().unwrap())
574 } else {
575 None
576 }
577 }
578 IntLiteral::Unsigned { val, size: _ } => Some(val),
579 }
580 }
581
582 pub fn is_negative(&self) -> bool {
583 match self {
584 IntLiteral::Unsized(val) | IntLiteral::Signed { val, size: _ } => val.is_negative(),
585 IntLiteral::Unsigned { .. } => false,
586 }
587 }
588}
589
590impl Display for IntLiteral {
591 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
592 match self {
593 IntLiteral::Unsized(val) | IntLiteral::Signed { val, .. } => write!(f, "{}", val),
595 IntLiteral::Unsigned { val, .. } => write!(f, "{}", val),
596 }
597 }
598}
599
600#[derive(PartialEq, Debug, Clone, Default)]
601pub struct Block {
602 pub statements: Vec<Loc<Statement>>,
603 pub result: Option<Loc<Expression>>,
604}
605
606#[derive(PartialEq, Debug, Clone)]
607pub struct Binding {
608 pub pattern: Loc<Pattern>,
609 pub ty: Option<Loc<TypeSpec>>,
610 pub value: Loc<Expression>,
611 pub attrs: AttributeList,
612}
613
614#[derive(PartialEq, Debug, Clone)]
615pub enum Statement {
616 Label(Loc<Identifier>),
617 Declaration(Vec<Loc<Identifier>>),
618 Binding(Binding),
619 Expression(Loc<Expression>, AttributeList),
620 PipelineRegMarker(Option<Loc<TypeExpression>>, Option<Loc<Expression>>),
621 Register(Loc<Register>),
622 Set {
625 target: Loc<Expression>,
626 value: Loc<Expression>,
627 },
628 Assert(Loc<Expression>),
629 Type(Loc<TypeDeclaration>),
630}
631
632impl Statement {
633 pub fn binding(
635 pattern: Loc<Pattern>,
636 ty: Option<Loc<TypeSpec>>,
637 value: Loc<Expression>,
638 ) -> Self {
639 Self::Binding(Binding {
640 pattern,
641 ty,
642 value,
643 attrs: AttributeList::empty(),
644 })
645 }
646}
647
648#[derive(PartialEq, Debug, Clone)]
650pub enum TypeParam {
651 TypeName {
652 name: Loc<Identifier>,
653 traits: Vec<Loc<TraitSpec>>,
654 default: Option<Loc<TypeExpression>>,
655 },
656 TypeWithMeta {
657 meta: Loc<Identifier>,
658 name: Loc<Identifier>,
659 default: Option<Loc<TypeExpression>>,
660 },
661}
662impl TypeParam {
663 pub fn name(&self) -> &Loc<Identifier> {
664 match self {
665 TypeParam::TypeName {
666 name,
667 traits: _,
668 default: _,
669 } => name,
670 TypeParam::TypeWithMeta {
671 meta: _,
672 name,
673 default: _,
674 } => name,
675 }
676 }
677
678 pub fn default(&self) -> &Option<Loc<TypeExpression>> {
679 match self {
680 TypeParam::TypeName {
681 name: _,
682 traits: _,
683 default,
684 } => default,
685 TypeParam::TypeWithMeta {
686 meta: _,
687 name: _,
688 default,
689 } => default,
690 }
691 }
692}
693
694#[derive(PartialEq, Debug, Clone)]
695pub enum GenericBound {
696 IntegerConstraint(Loc<Path>, Loc<Expression>),
697 TypeConstraint(Loc<Path>, Vec<Loc<Identifier>>),
698}
699
700impl GenericBound {
701 pub fn path(&self) -> &Loc<Path> {
702 match self {
703 GenericBound::IntegerConstraint(path, _) => path,
704 GenericBound::TypeConstraint(path, _) => path,
705 }
706 }
707}
708
709#[derive(PartialEq, Debug, Clone)]
710pub enum Attribute {
711 SpadecParenSugar,
712 VerilogAttrs {
713 entries: Vec<(Loc<Identifier>, Option<Loc<String>>)>,
714 },
715 Optimize {
716 passes: Vec<Loc<String>>,
717 },
718 Deprecated {
719 since: Option<Loc<String>>,
720 note: Option<Loc<String>>,
721 },
722 NoMangle {
723 all: bool,
724 },
725 Fsm {
726 state: Option<Loc<Identifier>>,
727 },
728 Documentation {
729 content: String,
730 },
731 SurferTranslator(String),
732 Inline,
733}
734
735impl Attribute {
736 pub fn name(&self) -> &str {
737 match self {
738 Attribute::SpadecParenSugar => "spadec_paren_sugar",
739 Attribute::VerilogAttrs { .. } => "verilog_attrs",
740 Attribute::Optimize { passes: _ } => "optimize",
741 Attribute::Deprecated { .. } => "deprecated",
742 Attribute::NoMangle { .. } => "no_mangle",
743 Attribute::Fsm { .. } => "fsm",
744 Attribute::Documentation { .. } => "doc",
745 Attribute::SurferTranslator(_) => "surfer_translator",
746 Attribute::Inline => "inline",
747 }
748 }
749}
750
751#[derive(PartialEq, Debug, Clone)]
752pub struct AttributeList(pub Vec<Loc<Attribute>>);
753impl AttributeList {
754 pub fn empty() -> Self {
755 Self(vec![])
756 }
757
758 pub fn is_empty(&self) -> bool {
759 self.0.is_empty()
760 }
761
762 pub fn from_vec(attrs: Vec<Loc<Attribute>>) -> Self {
763 Self(attrs)
764 }
765
766 pub fn merge_docs(&self) -> String {
767 self.0
768 .iter()
769 .filter_map(|attr| {
770 if let Attribute::Documentation { content } = &attr.inner {
771 Some(content)
772 } else {
773 None
774 }
775 })
776 .join("\n")
777 }
778}
779
780#[derive(PartialEq, Debug, Clone, Copy)]
781pub struct WireMarker {}
782
783#[derive(PartialEq, Debug, Clone)]
784pub struct ParameterList {
785 pub self_: Option<(Loc<AttributeList>, Option<Loc<WireMarker>>, Option<Loc<()>>)>,
786 pub args: Vec<(
787 AttributeList,
788 Option<Loc<WireMarker>>,
789 Loc<Identifier>,
790 Loc<TypeSpec>,
791 )>,
792}
793
794impl ParameterList {
795 pub fn without_self(
796 args: Vec<(
797 AttributeList,
798 Option<Loc<WireMarker>>,
799 Loc<Identifier>,
800 Loc<TypeSpec>,
801 )>,
802 ) -> Self {
803 Self { self_: None, args }
804 }
805}
806
807#[derive(PartialEq, Debug, Clone)]
808pub enum UnitKind {
809 Function,
810 Entity,
811 Pipeline(Loc<TypeExpression>),
812}
813
814impl UnitKind {
815 pub fn is_pipeline(&self) -> bool {
816 match self {
817 UnitKind::Function => false,
818 UnitKind::Entity => false,
819 UnitKind::Pipeline(_) => true,
820 }
821 }
822}
823
824impl std::fmt::Display for UnitKind {
825 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
826 match self {
827 UnitKind::Function => write!(f, "fn"),
828 UnitKind::Entity => write!(f, "entity"),
829 UnitKind::Pipeline(_) => write!(f, "pipeline"),
830 }
831 }
832}
833
834#[derive(PartialEq, Debug, Clone)]
835pub struct UnitHead {
836 pub visibility: Loc<Visibility>,
837 pub unsafe_token: Option<Loc<()>>,
838 pub extern_token: Option<Loc<()>>,
839 pub attributes: AttributeList,
840 pub unit_kind: Loc<UnitKind>,
841 pub name: Loc<Identifier>,
842 pub inputs: Loc<ParameterList>,
843 pub output_type: Option<(Loc<()>, Loc<TypeSpec>)>,
844 pub type_params: Option<Loc<Vec<Loc<TypeParam>>>>,
845 pub where_clauses: Vec<WhereClause>,
846}
847
848#[derive(PartialEq, Debug, Clone)]
849pub struct Unit {
850 pub head: UnitHead,
851 pub body: Option<Loc<Expression>>,
854}
855
856#[derive(PartialEq, Debug, Clone)]
857pub struct Register {
858 pub keyword: Loc<()>,
859 pub pattern: Loc<Pattern>,
860 pub clock: Loc<Expression>,
861 pub reset: Option<(Loc<Expression>, Loc<Expression>)>,
862 pub initial: Option<Loc<Expression>>,
863 pub value: Loc<Expression>,
864 pub value_type: Option<Loc<TypeSpec>>,
865 pub attributes: AttributeList,
866}
867
868pub type MacroRules = Vec<(Loc<MacroPattern>, Vec<Loc<TokenKind>>)>;
869
870#[derive(PartialEq, Debug, Clone)]
872pub struct MacroDef {
873 pub visibility: Loc<Visibility>,
874 pub name: Loc<Identifier>,
875 pub rules: MacroRules,
876 pub attributes: AttributeList,
877}
878
879#[derive(PartialEq, Debug, Clone)]
881pub struct TraitDef {
882 pub visibility: Loc<Visibility>,
883 pub name: Loc<Identifier>,
884 pub type_params: Option<Loc<Vec<Loc<TypeParam>>>>,
885 pub subtraits: Vec<Loc<TraitSpec>>,
886 pub where_clauses: Vec<WhereClause>,
887 pub attributes: AttributeList,
888 pub assoc_types: Vec<Loc<AssocType>>,
889 pub methods: Vec<Loc<UnitHead>>,
890}
891
892#[derive(PartialEq, Debug, Clone)]
894pub struct TraitSpec {
895 pub path: Loc<Path>,
896 pub type_params: Option<Loc<Vec<Loc<TypeExpression>>>>,
897 pub paren_syntax: bool,
898}
899
900impl std::fmt::Display for TraitSpec {
901 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
902 let Self {
903 path,
904 type_params,
905 paren_syntax,
906 } = self;
907
908 if *paren_syntax {
909 let mut type_params = type_params.clone().unwrap();
910 let return_type = type_params.pop().unwrap();
911 let param_tuple = type_params.pop().unwrap();
912
913 let type_params_string = match type_params.as_slice() {
914 [] => String::new(),
915 params => format!("<{}>", params.iter().map(|p| format!("{p}")).join(", ")),
916 };
917
918 let return_type_string = match return_type.inner {
919 TypeExpression::TypeSpec(ts) if ts.is_empty_tuple() => String::new(),
920 ty => format!(" -> {ty}"),
921 };
922
923 write!(
924 f,
925 "{path}{type_params_string}{param_tuple}{return_type_string}",
926 )
927 } else {
928 write!(
929 f,
930 "{path}{}",
931 type_params
932 .as_ref()
933 .map(|tp| { format!("<{}>", tp.iter().map(|e| format!("{e}")).join(", ")) })
934 .unwrap_or(String::new())
935 )
936 }
937 }
938}
939
940#[derive(PartialEq, Debug, Clone)]
941pub struct ImplBlock {
942 pub r#trait: Option<Loc<TraitSpec>>,
943 pub type_params: Option<Loc<Vec<Loc<TypeParam>>>>,
944 pub where_clauses: Vec<WhereClause>,
945 pub target: Loc<TypeSpec>,
946 pub assoc_types: Vec<Loc<TypeDeclaration>>,
947 pub units: Vec<Loc<Unit>>,
948}
949
950#[derive(PartialEq, Debug, Clone)]
952pub struct Enum {
953 pub attributes: AttributeList,
954 pub name: Loc<Identifier>,
955 pub variants: Vec<EnumVariant>,
956}
957
958#[derive(PartialEq, Debug, Clone)]
959pub struct EnumVariant {
960 pub attributes: AttributeList,
961 pub name: Loc<Identifier>,
962 pub args: Option<Loc<ParameterList>>,
963}
964
965#[derive(PartialEq, Debug, Clone)]
966pub struct Struct {
967 pub attributes: AttributeList,
968 pub name: Loc<Identifier>,
969 pub members: Loc<ParameterList>,
970}
971
972#[derive(PartialEq, Debug, Clone)]
973pub struct TypeAlias {
974 pub attributes: AttributeList,
975 pub name: Loc<Identifier>,
976 pub type_spec: Loc<TypeSpec>,
977}
978
979#[derive(PartialEq, Debug, Clone)]
980pub enum TypeDeclKind {
981 Enum(Loc<Enum>),
982 Struct(Loc<Struct>),
983 Alias(Loc<TypeAlias>),
984}
985
986#[derive(PartialEq, Debug, Clone)]
988pub struct TypeDeclaration {
989 pub visibility: Loc<Visibility>,
990 pub name: Loc<Identifier>,
991 pub kind: TypeDeclKind,
992 pub generic_args: Option<Loc<Vec<Loc<TypeParam>>>>,
993}
994
995#[derive(PartialEq, Debug, Clone)]
996pub struct UseStatement {
997 pub visibility: Loc<Visibility>,
998 pub path: Loc<Path>,
999 pub alias: Option<Loc<Identifier>>,
1000}
1001
1002#[derive(PartialEq, Debug, Clone)]
1005pub enum Item {
1006 Unit(Loc<Unit>),
1007 MacroDef(Loc<MacroDef>),
1008 TraitDef(Loc<TraitDef>),
1009 Type(Loc<TypeDeclaration>),
1010 ExternalMod(Loc<ExternalMod>),
1011 Module(Loc<Module>),
1012 Use(AttributeList, Loc<Vec<UseStatement>>),
1013 ImplBlock(Loc<ImplBlock>),
1014}
1015
1016impl Item {
1017 pub fn name(&self) -> Option<&Identifier> {
1018 match self {
1019 Item::Unit(u) => Some(&u.head.name.inner),
1020 Item::MacroDef(m) => Some(&m.name.inner),
1021 Item::TraitDef(t) => Some(&t.name.inner),
1022 Item::Type(t) => Some(&t.name.inner),
1023 Item::Module(m) => Some(&m.name.inner),
1024 Item::ExternalMod(m) => Some(&m.name.inner),
1025 Item::Use(_, _) => None,
1026 Item::ImplBlock(_) => None,
1027 }
1028 }
1029
1030 pub fn variant_str(&self) -> &'static str {
1031 match self {
1032 Item::Unit(_) => "unit",
1033 Item::MacroDef(_) => "macro definition",
1034 Item::TraitDef(_) => "trait definition",
1035 Item::Type(_) => "type",
1036 Item::Module(_) => "module",
1037 Item::ExternalMod(_) => "module",
1038 Item::Use(_, _) => "use",
1039 Item::ImplBlock(_) => "impl",
1040 }
1041 }
1042}
1043
1044#[derive(PartialEq, Debug, Clone)]
1045pub struct ExternalMod {
1046 pub visibility: Loc<Visibility>,
1047 pub name: Loc<Identifier>,
1048 pub attributes: AttributeList,
1049}
1050
1051#[derive(PartialEq, Debug, Clone)]
1052pub struct Module {
1053 pub visibility: Loc<Visibility>,
1054 pub name: Loc<Identifier>,
1055 pub body: Loc<ModuleBody>,
1056 pub attributes: AttributeList,
1057}
1058
1059#[derive(PartialEq, Debug, Clone)]
1060pub struct ModuleBody {
1061 pub members: Vec<Item>,
1062 pub documentation: Vec<String>,
1063}
1064
1065#[derive(Clone, Default, Serialize, Deserialize)]
1080pub struct FloatingNodes {
1081 pub paths: Vec<Loc<Path>>,
1082 pub namespaces: Vec<Loc<ModuleNamespace>>,
1097}
1098
1099impl FloatingNodes {
1100 pub fn add_path(&mut self, path: Loc<Path>) {
1101 self.paths.push(path)
1102 }
1103
1104 pub fn merge(&mut self, other: FloatingNodes) {
1105 let FloatingNodes { paths, namespaces } = other;
1106 self.paths.extend(paths);
1107 self.namespaces.extend(namespaces);
1108 }
1109}