mod display;
mod util;
#[macro_use]
mod any_design_unit;
#[macro_use]
pub mod search;
mod ast_span;
pub mod token_range;
pub(crate) use self::util::*;
use crate::ast::token_range::*;
use crate::data::*;
use crate::named_entity::{EntityId, Reference};
use crate::syntax::{Token, TokenAccess, TokenId};
use crate::TokenSpan;
pub(crate) use any_design_unit::*;
use vhdl_lang::HasTokenSpan;
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub enum BaseSpecifier {
B,
O,
X,
UB,
UO,
UX,
SB,
SO,
SX,
D,
}
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
pub enum Operator {
And,
Or,
Nand,
Nor,
Xor,
Xnor,
Abs,
Not,
Minus,
Plus,
QueQue, EQ,
NE,
LT,
LTE,
GT,
GTE,
QueEQ,
QueNE,
QueLT,
QueLTE,
QueGT,
QueGTE,
SLL,
SRL,
SLA,
SRA,
ROL,
ROR,
Concat,
Times,
Div,
Mod,
Rem,
Pow,
}
#[derive(PartialEq, Debug, Clone)]
pub struct AttributeName {
pub name: WithTokenSpan<Name>,
pub signature: Option<WithTokenSpan<Signature>>,
pub attr: WithToken<AttributeDesignator>,
pub expr: Option<Box<WithTokenSpan<Expression>>>,
}
#[derive(PartialEq, Debug, Copy, Clone, Eq)]
pub enum TypeAttribute {
Subtype,
Element,
}
#[derive(PartialEq, Debug, Copy, Clone, Eq)]
pub enum RangeAttribute {
Range,
ReverseRange,
}
#[derive(PartialEq, Debug, Clone, Eq)]
pub enum AttributeDesignator {
Type(TypeAttribute),
Range(RangeAttribute),
Ident(WithRef<Symbol>),
Ascending,
Left,
Right,
High,
Low,
Length,
Image,
Value,
Pos,
Val,
Succ,
Pred,
LeftOf,
RightOf,
Signal(SignalAttribute),
SimpleName,
InstanceName,
PathName,
Converse,
}
#[derive(PartialEq, Debug, Copy, Clone, Eq)]
pub enum SignalAttribute {
Delayed,
Stable,
Quiet,
Transaction,
Event,
Active,
LastEvent,
LastActive,
LastValue,
Driving,
DrivingValue,
}
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
pub enum ExternalObjectClass {
Constant,
Signal,
Variable,
}
impl From<ExternalObjectClass> for ObjectClass {
fn from(object: ExternalObjectClass) -> ObjectClass {
match object {
ExternalObjectClass::Constant => ObjectClass::Constant,
ExternalObjectClass::Variable => ObjectClass::Variable,
ExternalObjectClass::Signal => ObjectClass::Signal,
}
}
}
#[derive(PartialEq, Debug, Clone)]
pub enum ExternalPath {
Package(WithTokenSpan<Name>),
Absolute(WithTokenSpan<Name>),
Relative(WithTokenSpan<Name>, usize),
}
#[derive(PartialEq, Debug, Clone)]
pub struct ExternalName {
pub class: ExternalObjectClass,
pub path: WithTokenSpan<ExternalPath>,
pub colon_token: TokenId,
pub subtype: SubtypeIndication,
}
#[derive(PartialEq, Debug, Clone)]
pub enum Name {
Designator(WithRef<Designator>),
Selected(Box<WithTokenSpan<Name>>, WithToken<WithRef<Designator>>),
SelectedAll(Box<WithTokenSpan<Name>>),
Slice(Box<WithTokenSpan<Name>>, Box<DiscreteRange>),
Attribute(Box<AttributeName>),
CallOrIndexed(Box<CallOrIndexed>),
External(Box<ExternalName>),
}
#[derive(PartialEq, Debug, Clone)]
pub struct CallOrIndexed {
pub name: WithTokenSpan<Name>,
pub parameters: SeparatedList<AssociationElement>,
}
#[derive(PartialEq, Debug, Clone)]
pub enum Choice {
Expression(Expression),
DiscreteRange(DiscreteRange),
Others,
}
#[derive(PartialEq, Debug, Clone)]
pub enum ElementAssociation {
Positional(WithTokenSpan<Expression>),
Named(Vec<WithTokenSpan<Choice>>, WithTokenSpan<Expression>),
}
#[derive(PartialEq, Debug, Clone)]
pub enum ActualPart {
Expression(Expression),
Open,
}
#[derive(PartialEq, Debug, Clone)]
pub struct AssociationElement {
pub formal: Option<WithTokenSpan<Name>>,
pub actual: WithTokenSpan<ActualPart>,
}
#[derive(PartialEq, Debug, Clone, Copy)]
pub enum AbstractLiteral {
Integer(u64),
Real(f64),
}
#[derive(PartialEq, Eq, Debug, Clone)]
pub struct BitString {
pub length: Option<u32>,
pub base: BaseSpecifier,
pub value: Latin1String,
}
#[derive(PartialEq, Debug, Clone)]
pub struct PhysicalLiteral {
pub value: AbstractLiteral,
pub unit: WithRef<Ident>,
}
#[derive(PartialEq, Debug, Clone)]
pub enum Literal {
String(Latin1String),
BitString(BitString),
Character(u8),
AbstractLiteral(AbstractLiteral),
Physical(PhysicalLiteral),
Null,
}
#[derive(PartialEq, Debug, Clone)]
pub enum Allocator {
Qualified(QualifiedExpression),
Subtype(SubtypeIndication),
}
#[derive(PartialEq, Debug, Clone)]
pub struct QualifiedExpression {
pub type_mark: WithTokenSpan<Name>,
pub expr: WithTokenSpan<Expression>,
}
#[derive(PartialEq, Debug, Clone)]
pub enum Expression {
Binary(
WithToken<WithRef<Operator>>,
Box<WithTokenSpan<Expression>>,
Box<WithTokenSpan<Expression>>,
),
Unary(WithToken<WithRef<Operator>>, Box<WithTokenSpan<Expression>>),
Aggregate(Vec<WithTokenSpan<ElementAssociation>>),
Qualified(Box<QualifiedExpression>),
Name(Box<Name>),
Literal(Literal),
New(Box<WithTokenSpan<Allocator>>),
Parenthesized(Box<WithTokenSpan<Expression>>),
}
pub type Ident = WithToken<Symbol>;
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
pub enum Direction {
Ascending,
Descending,
}
#[derive(PartialEq, Debug, Clone)]
pub enum DiscreteRange {
Discrete(WithTokenSpan<Name>, Option<Range>),
Range(Range),
}
#[derive(PartialEq, Debug, Clone)]
pub struct RangeConstraint {
pub direction: Direction,
pub left_expr: Box<WithTokenSpan<Expression>>,
pub right_expr: Box<WithTokenSpan<Expression>>,
}
impl RangeConstraint {
pub fn direction_token(&self) -> TokenId {
self.left_expr.span.end_token + 1
}
}
#[derive(PartialEq, Debug, Clone)]
pub enum Range {
Range(RangeConstraint),
Attribute(Box<AttributeName>),
}
#[derive(PartialEq, Debug, Clone)]
pub struct ElementConstraint {
pub ident: Ident,
pub constraint: Box<WithTokenSpan<SubtypeConstraint>>,
}
#[derive(PartialEq, Debug, Clone)]
pub enum SubtypeConstraint {
Range(Range),
Array(
Vec<WithTokenSpan<DiscreteRange>>,
Option<Box<WithTokenSpan<SubtypeConstraint>>>,
),
Record(Vec<ElementConstraint>),
}
#[derive(PartialEq, Debug, Clone)]
pub struct RecordElementResolution {
pub ident: Ident,
pub resolution: Box<ResolutionIndication>,
}
#[derive(PartialEq, Debug, Clone)]
pub enum ResolutionIndication {
FunctionName(WithTokenSpan<Name>),
ArrayElement(WithTokenSpan<Name>),
Record(WithTokenSpan<Vec<RecordElementResolution>>),
}
impl HasTokenSpan for ResolutionIndication {
fn get_start_token(&self) -> TokenId {
match self {
ResolutionIndication::FunctionName(name) => name.get_start_token(),
ResolutionIndication::ArrayElement(name) => name.get_start_token() - 1,
ResolutionIndication::Record(record) => record.get_start_token(),
}
}
fn get_end_token(&self) -> TokenId {
match self {
ResolutionIndication::FunctionName(name) => name.get_end_token(),
ResolutionIndication::ArrayElement(name) => name.get_end_token() + 1,
ResolutionIndication::Record(record) => record.get_end_token(),
}
}
}
#[derive(PartialEq, Debug, Clone)]
pub struct SubtypeIndication {
pub resolution: Option<ResolutionIndication>,
pub type_mark: WithTokenSpan<Name>,
pub constraint: Option<WithTokenSpan<SubtypeConstraint>>,
}
#[derive(PartialEq, Debug, Clone, TokenSpan)]
pub enum ArrayIndex {
IndexSubtypeDefintion(WithTokenSpan<Name>),
Discrete(WithTokenSpan<DiscreteRange>),
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct ElementDeclaration {
pub idents: Vec<WithDecl<Ident>>,
pub colon_token: TokenId,
pub subtype: SubtypeIndication,
}
#[derive(PartialEq, Debug, Clone)]
pub enum ProtectedTypeDeclarativeItem {
Subprogram(SubprogramDeclaration),
}
#[derive(PartialEq, Eq, Hash, Debug, Clone)]
pub enum Designator {
Identifier(Symbol),
OperatorSymbol(Operator),
Character(u8),
Anonymous(usize),
}
#[derive(PartialEq, Eq, Debug, Clone)]
pub struct WithRef<T> {
pub item: T,
pub reference: Reference,
}
impl<T> WithRef<T> {
pub fn new(item: T) -> WithRef<T> {
WithRef {
item,
reference: Reference::undefined(),
}
}
}
#[derive(PartialEq, Debug, Clone)]
pub struct WithDecl<T> {
pub tree: T,
pub decl: Reference,
}
impl<T> WithDecl<T> {
pub fn new(tree: T) -> WithDecl<T> {
WithDecl {
tree,
decl: Reference::undefined(),
}
}
}
impl<T> WithDecl<WithToken<T>> {
pub fn pos<'a>(&'a self, ctx: &'a dyn TokenAccess) -> &SrcPos {
self.tree.pos(ctx)
}
}
impl<T> From<T> for WithDecl<T> {
fn from(value: T) -> Self {
WithDecl::new(value)
}
}
impl<T: AsRef<SrcPos>> AsRef<SrcPos> for WithDecl<T> {
fn as_ref(&self) -> &SrcPos {
self.tree.as_ref()
}
}
impl HasDesignator for WithToken<WithRef<Designator>> {
fn designator(&self) -> &Designator {
self.item.designator()
}
}
#[derive(PartialEq, Debug, Clone)]
pub struct AliasDeclaration {
pub designator: WithDecl<WithToken<Designator>>,
pub subtype_indication: Option<SubtypeIndication>,
pub is_token: TokenId,
pub name: WithTokenSpan<Name>,
pub signature: Option<WithTokenSpan<Signature>>,
}
#[derive(PartialEq, Debug, Clone)]
pub struct AttributeDeclaration {
pub ident: WithDecl<Ident>,
pub type_mark: WithTokenSpan<Name>,
}
#[derive(PartialEq, Debug, Clone)]
pub struct EntityTag {
pub designator: WithToken<WithRef<Designator>>,
pub signature: Option<WithTokenSpan<Signature>>,
}
#[derive(PartialEq, Debug, Clone)]
pub enum EntityName {
Name(EntityTag),
All,
Others,
}
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
pub enum EntityClass {
Entity,
Architecture,
Configuration,
Procedure,
Function,
Package,
Type,
Subtype,
Constant,
Signal,
Variable,
Component,
Label,
Literal,
Units,
File,
}
#[derive(PartialEq, Debug, Clone)]
pub struct AttributeSpecification {
pub ident: WithRef<Ident>,
pub entity_name: EntityName,
pub colon_token: TokenId,
pub entity_class: EntityClass,
pub expr: WithTokenSpan<Expression>,
}
#[derive(PartialEq, Debug, Clone)]
pub enum Attribute {
Specification(AttributeSpecification),
Declaration(AttributeDeclaration),
}
#[derive(PartialEq, Debug, Clone)]
pub struct ProtectedTypeDeclaration {
pub items: Vec<ProtectedTypeDeclarativeItem>,
}
#[derive(PartialEq, Debug, Clone)]
pub struct ProtectedTypeBody {
pub decl: Vec<WithTokenSpan<Declaration>>,
}
#[derive(PartialEq, Debug, Clone)]
pub struct PhysicalTypeDeclaration {
pub range: Range,
pub units_token: TokenId,
pub primary_unit: WithDecl<Ident>,
pub secondary_units: Vec<(WithDecl<Ident>, WithTokenSpan<PhysicalLiteral>)>,
}
#[derive(PartialEq, Eq, Debug, Clone)]
pub enum EnumerationLiteral {
Identifier(Symbol),
Character(u8),
}
#[derive(PartialEq, Debug, Clone)]
pub enum TypeDefinition {
Enumeration(Vec<WithDecl<WithToken<EnumerationLiteral>>>),
Numeric(Range),
Physical(PhysicalTypeDeclaration),
Array(Vec<ArrayIndex>, TokenId, SubtypeIndication),
Record(Vec<ElementDeclaration>),
Access(SubtypeIndication),
Incomplete(Reference),
File(WithTokenSpan<Name>),
Protected(ProtectedTypeDeclaration),
ProtectedBody(ProtectedTypeBody),
Subtype(SubtypeIndication),
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct TypeDeclaration {
pub ident: WithDecl<Ident>,
pub def: TypeDefinition,
pub end_ident_pos: Option<TokenId>,
}
impl TypeDeclaration {
pub fn is_token(&self) -> Option<TokenId> {
if matches!(self.def, TypeDefinition::Incomplete(_)) {
None
} else {
Some(self.ident.tree.token + 1)
}
}
}
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
pub enum ObjectClass {
Signal,
Constant,
Variable,
SharedVariable,
}
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
pub enum InterfaceType {
Port,
Generic,
Parameter,
}
#[derive(PartialEq, Debug, Clone)]
pub struct ObjectDeclaration {
pub class: ObjectClass,
pub colon_token: TokenId,
pub idents: Vec<WithDecl<Ident>>,
pub subtype_indication: SubtypeIndication,
pub expression: Option<WithTokenSpan<Expression>>,
}
#[derive(PartialEq, Debug, Clone)]
pub struct FileDeclaration {
pub idents: Vec<WithDecl<Ident>>,
pub colon_token: TokenId,
pub subtype_indication: SubtypeIndication,
pub open_info: Option<(TokenId, WithTokenSpan<Expression>)>,
pub file_name: Option<(TokenId, WithTokenSpan<Expression>)>,
}
#[derive(PartialEq, Eq, Debug, Clone)]
pub enum SubprogramDesignator {
Identifier(Symbol),
OperatorSymbol(Operator),
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct InterfaceList {
pub interface_type: InterfaceType,
pub items: Vec<InterfaceDeclaration>,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct ProcedureSpecification {
pub designator: WithDecl<WithToken<SubprogramDesignator>>,
pub header: Option<SubprogramHeader>,
pub parameter_list: Option<InterfaceList>,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct FunctionSpecification {
pub pure: bool,
pub designator: WithDecl<WithToken<SubprogramDesignator>>,
pub header: Option<SubprogramHeader>,
pub parameter_list: Option<InterfaceList>,
pub return_type: WithTokenSpan<Name>,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct SubprogramBody {
pub specification: SubprogramSpecification,
pub declarations: Vec<WithTokenSpan<Declaration>>,
pub begin_token: TokenId,
pub statements: Vec<LabeledSequentialStatement>,
pub end_token: TokenId,
pub end_ident_pos: Option<TokenId>,
}
#[derive(PartialEq, Debug, Clone)]
pub struct SubprogramHeader {
pub generic_list: InterfaceList,
pub map_aspect: Option<MapAspect>,
}
#[derive(PartialEq, Debug, Clone, Copy)]
pub enum SubprogramKind {
Function,
Procedure,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct SubprogramInstantiation {
pub kind: SubprogramKind,
pub ident: WithDecl<Ident>,
pub subprogram_name: WithTokenSpan<Name>,
pub signature: Option<WithTokenSpan<Signature>>,
pub generic_map: Option<MapAspect>,
}
#[derive(PartialEq, Debug, Clone)]
pub enum Signature {
Function(Vec<WithTokenSpan<Name>>, WithTokenSpan<Name>),
Procedure(Vec<WithTokenSpan<Name>>),
}
#[derive(PartialEq, Debug, Clone, TokenSpan)]
pub enum SubprogramSpecification {
Procedure(ProcedureSpecification),
Function(FunctionSpecification),
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct SubprogramDeclaration {
pub specification: SubprogramSpecification,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct InterfaceFileDeclaration {
pub idents: Vec<WithDecl<Ident>>,
pub colon_token: TokenId,
pub subtype_indication: SubtypeIndication,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct InterfaceObjectDeclaration {
pub list_type: InterfaceType,
pub colon_token: TokenId,
pub idents: Vec<WithDecl<Ident>>,
pub mode: ModeIndication,
}
#[derive(PartialEq, Debug, Clone)]
pub enum ModeIndication {
Simple(SimpleModeIndication),
View(ModeViewIndication),
}
#[derive(PartialEq, Debug, Clone)]
pub struct SimpleModeIndication {
pub mode: Option<WithToken<Mode>>,
pub class: ObjectClass,
pub subtype_indication: SubtypeIndication,
pub bus: bool,
pub expression: Option<WithTokenSpan<Expression>>,
}
#[derive(PartialEq, Debug, Clone, Copy)]
pub enum ModeViewIndicationKind {
Array,
Record,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct ModeViewIndication {
pub kind: ModeViewIndicationKind,
pub name: WithTokenSpan<Name>,
pub subtype_indication: Option<(TokenId, SubtypeIndication)>,
}
#[derive(PartialEq, Debug, Clone)]
pub enum InterfacePackageGenericMapAspect {
Map(SeparatedList<AssociationElement>),
Box,
Default,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct InterfacePackageDeclaration {
pub ident: WithDecl<Ident>,
pub package_name: WithTokenSpan<Name>,
pub generic_map: WithTokenSpan<InterfacePackageGenericMapAspect>,
}
#[derive(PartialEq, Debug, Clone)]
pub enum SubprogramDefault {
Name(WithTokenSpan<Name>),
Box,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct InterfaceSubprogramDeclaration {
pub specification: SubprogramSpecification,
pub default: Option<SubprogramDefault>,
}
#[derive(PartialEq, Debug, Clone, TokenSpan)]
pub enum InterfaceDeclaration {
Object(InterfaceObjectDeclaration),
File(InterfaceFileDeclaration),
Type(WithDecl<Ident>),
Subprogram(InterfaceSubprogramDeclaration),
Package(InterfacePackageDeclaration),
}
#[derive(PartialEq, Eq, Debug, Clone, Copy, Default)]
pub enum Mode {
#[default]
In,
Out,
InOut,
Buffer,
Linkage,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct ComponentDeclaration {
pub ident: WithDecl<Ident>,
pub is_token: Option<TokenId>,
pub generic_list: Option<InterfaceList>,
pub port_list: Option<InterfaceList>,
pub end_token: TokenId,
pub end_ident_pos: Option<TokenId>,
}
#[derive(PartialEq, Debug, Clone)]
pub enum Declaration {
Object(ObjectDeclaration),
File(FileDeclaration),
Type(TypeDeclaration),
Component(ComponentDeclaration),
Attribute(Attribute),
Alias(AliasDeclaration),
SubprogramDeclaration(SubprogramDeclaration),
SubprogramInstantiation(SubprogramInstantiation),
SubprogramBody(SubprogramBody),
Use(UseClause),
Package(PackageInstantiation),
Configuration(ConfigurationSpecification),
View(ModeViewDeclaration),
}
impl Declaration {
pub fn declarations(&self) -> Vec<EntityId> {
match self {
Declaration::Object(ObjectDeclaration { idents, .. })
| Declaration::File(FileDeclaration { idents, .. }) => {
idents.iter().flat_map(|ident| ident.decl.get()).collect()
}
Declaration::Type(TypeDeclaration { ident, .. })
| Declaration::Component(ComponentDeclaration { ident, .. })
| Declaration::View(ModeViewDeclaration { ident, .. })
| Declaration::Package(PackageInstantiation { ident, .. })
| Declaration::SubprogramInstantiation(SubprogramInstantiation { ident, .. })
| Declaration::Attribute(Attribute::Declaration(AttributeDeclaration {
ident, ..
})) => ident.decl.get().into_iter().collect(),
Declaration::Alias(alias) => alias.designator.decl.get().into_iter().collect(),
Declaration::SubprogramDeclaration(SubprogramDeclaration { specification, .. })
| Declaration::SubprogramBody(SubprogramBody { specification, .. }) => {
let designator = match specification {
SubprogramSpecification::Procedure(procedure) => &procedure.designator,
SubprogramSpecification::Function(function) => &function.designator,
};
designator.decl.get().into_iter().collect()
}
_ => vec![],
}
}
}
#[derive(PartialEq, Debug, Clone)]
pub struct WaitStatement {
pub sensitivity_clause: Option<Vec<WithTokenSpan<Name>>>,
pub condition_clause: Option<WithTokenSpan<Expression>>,
pub timeout_clause: Option<WithTokenSpan<Expression>>,
}
#[derive(PartialEq, Debug, Clone)]
pub struct AssertStatement {
pub condition: WithTokenSpan<Expression>,
pub report: Option<WithTokenSpan<Expression>>,
pub severity: Option<WithTokenSpan<Expression>>,
}
#[derive(PartialEq, Debug, Clone)]
pub struct ReportStatement {
pub report: WithTokenSpan<Expression>,
pub severity: Option<WithTokenSpan<Expression>>,
}
#[derive(PartialEq, Debug, Clone)]
pub enum Target {
Name(Name),
Aggregate(Vec<WithTokenSpan<ElementAssociation>>),
}
#[derive(PartialEq, Debug, Clone)]
pub struct WaveformElement {
pub value: WithTokenSpan<Expression>,
pub after: Option<WithTokenSpan<Expression>>,
}
impl HasTokenSpan for WaveformElement {
fn get_start_token(&self) -> TokenId {
self.value.get_start_token()
}
fn get_end_token(&self) -> TokenId {
self.after
.as_ref()
.map(|expr| expr.get_end_token())
.unwrap_or(self.value.get_end_token())
}
}
#[derive(PartialEq, Debug, Clone)]
pub enum Waveform {
Elements(Vec<WaveformElement>),
Unaffected(TokenId),
}
#[derive(PartialEq, Debug, Clone)]
pub enum DelayMechanism {
Transport,
Inertial {
reject: Option<WithTokenSpan<Expression>>,
},
}
#[derive(PartialEq, Debug, Clone)]
pub struct SignalAssignment {
pub target: WithTokenSpan<Target>,
pub delay_mechanism: Option<WithTokenSpan<DelayMechanism>>,
pub rhs: AssignmentRightHand<Waveform>,
}
#[derive(PartialEq, Eq, Debug, Clone)]
pub enum ForceMode {
In,
Out,
}
#[derive(PartialEq, Debug, Clone)]
pub struct SignalForceAssignment {
pub target: WithTokenSpan<Target>,
pub force_mode: Option<ForceMode>,
pub rhs: AssignmentRightHand<WithTokenSpan<Expression>>,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct SignalReleaseAssignment {
pub target: WithTokenSpan<Target>,
pub force_mode: Option<ForceMode>,
}
#[derive(PartialEq, Debug, Clone)]
pub struct VariableAssignment {
pub target: WithTokenSpan<Target>,
pub rhs: AssignmentRightHand<WithTokenSpan<Expression>>,
}
#[derive(PartialEq, Debug, Clone)]
pub enum AssignmentRightHand<T> {
Simple(T),
Conditional(Conditionals<T>),
Selected(Selection<T>),
}
#[derive(PartialEq, Debug, Clone)]
pub struct Conditional<T> {
pub condition: WithTokenSpan<Expression>,
pub item: T,
}
#[derive(PartialEq, Debug, Clone)]
pub struct Conditionals<T> {
pub conditionals: Vec<Conditional<T>>,
pub else_item: Option<(T, TokenId)>,
}
#[derive(PartialEq, Debug, Clone)]
pub struct IfStatement {
pub conds: Conditionals<Vec<LabeledSequentialStatement>>,
pub end_label_pos: Option<SrcPos>,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct Alternative<T> {
pub choices: Vec<WithTokenSpan<Choice>>,
pub item: T,
}
#[derive(PartialEq, Debug, Clone)]
pub struct Selection<T> {
pub expression: WithTokenSpan<Expression>,
pub alternatives: Vec<Alternative<T>>,
}
#[derive(PartialEq, Debug, Clone)]
pub struct CaseStatement {
pub is_matching: bool,
pub expression: WithTokenSpan<Expression>,
pub alternatives: Vec<Alternative<Vec<LabeledSequentialStatement>>>,
pub end_token: TokenId,
pub end_label_pos: Option<SrcPos>,
}
#[derive(PartialEq, Debug, Clone)]
pub enum IterationScheme {
While(WithTokenSpan<Expression>),
For(WithDecl<Ident>, DiscreteRange),
}
#[derive(PartialEq, Debug, Clone)]
pub struct LoopStatement {
pub iteration_scheme: Option<IterationScheme>,
pub loop_token: TokenId,
pub statements: Vec<LabeledSequentialStatement>,
pub end_token: TokenId,
pub end_label_pos: Option<SrcPos>,
}
#[derive(PartialEq, Debug, Clone)]
pub struct NextStatement {
pub loop_label: Option<WithRef<Ident>>,
pub condition: Option<WithTokenSpan<Expression>>,
}
#[derive(PartialEq, Debug, Clone)]
pub struct ExitStatement {
pub loop_label: Option<WithRef<Ident>>,
pub condition: Option<WithTokenSpan<Expression>>,
}
#[derive(PartialEq, Debug, Clone)]
pub struct ReturnStatement {
pub expression: Option<WithTokenSpan<Expression>>,
}
#[derive(PartialEq, Debug, Clone)]
pub enum SequentialStatement {
Wait(WaitStatement),
Assert(AssertStatement),
Report(ReportStatement),
VariableAssignment(VariableAssignment),
SignalAssignment(SignalAssignment),
SignalForceAssignment(SignalForceAssignment),
SignalReleaseAssignment(SignalReleaseAssignment),
ProcedureCall(WithTokenSpan<CallOrIndexed>),
If(IfStatement),
Case(CaseStatement),
Loop(LoopStatement),
Next(NextStatement),
Exit(ExitStatement),
Return(ReturnStatement),
Null,
}
#[derive(PartialEq, Debug, Clone)]
pub struct LabeledSequentialStatement {
pub label: WithDecl<Option<Ident>>,
pub statement: WithTokenSpan<SequentialStatement>,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct BlockStatement {
pub guard_condition: Option<WithTokenSpan<Expression>>,
pub header: BlockHeader,
pub is_token: Option<TokenId>,
pub decl: Vec<WithTokenSpan<Declaration>>,
pub begin_token: TokenId,
pub statements: Vec<LabeledConcurrentStatement>,
pub end_token: TokenId,
pub end_label_pos: Option<SrcPos>,
}
#[derive(PartialEq, Debug, Clone)]
pub struct BlockHeader {
pub generic_clause: Option<InterfaceList>,
pub generic_map: Option<MapAspect>,
pub port_clause: Option<InterfaceList>,
pub port_map: Option<MapAspect>,
}
#[derive(PartialEq, Debug, Clone)]
pub enum SensitivityList {
Names(Vec<WithTokenSpan<Name>>),
All,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct ProcessStatement {
pub postponed: bool,
pub sensitivity_list: Option<WithTokenSpan<SensitivityList>>,
pub is_token: Option<TokenId>,
pub decl: Vec<WithTokenSpan<Declaration>>,
pub begin_token: TokenId,
pub statements: Vec<LabeledSequentialStatement>,
pub end_token: TokenId,
pub end_label_pos: Option<SrcPos>,
}
#[derive(PartialEq, Debug, Clone)]
pub struct ConcurrentProcedureCall {
pub postponed: bool,
pub call: WithTokenSpan<CallOrIndexed>,
}
#[derive(PartialEq, Debug, Clone)]
pub struct ConcurrentAssertStatement {
pub postponed: bool,
pub statement: AssertStatement,
}
#[derive(PartialEq, Debug, Clone)]
pub struct ConcurrentSignalAssignment {
pub postponed: bool,
pub guarded: bool,
pub assignment: SignalAssignment,
}
#[derive(PartialEq, Debug, Clone)]
pub enum InstantiatedUnit {
Component(WithTokenSpan<Name>),
Entity(WithTokenSpan<Name>, Option<WithRef<Ident>>),
Configuration(WithTokenSpan<Name>),
}
impl InstantiatedUnit {
pub fn entity_reference(&self) -> Option<EntityId> {
match &self {
InstantiatedUnit::Entity(name, _) => name.item.get_suffix_reference(),
InstantiatedUnit::Configuration(name) => name.item.get_suffix_reference(),
InstantiatedUnit::Component(name) => name.item.get_suffix_reference(),
}
}
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct MapAspect {
pub list: SeparatedList<AssociationElement>,
}
impl MapAspect {
pub fn formals(&self) -> impl Iterator<Item = Option<EntityId>> + '_ {
self.list.formals()
}
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct InstantiationStatement {
pub unit: InstantiatedUnit,
pub generic_map: Option<MapAspect>,
pub port_map: Option<MapAspect>,
}
impl InstantiationStatement {
pub fn entity_reference(&self) -> Option<EntityId> {
self.unit.entity_reference()
}
}
#[derive(PartialEq, Debug, Clone)]
pub struct GenerateBody {
pub alternative_label: Option<WithDecl<Ident>>,
pub decl: Option<(Vec<WithTokenSpan<Declaration>>, TokenId)>,
pub statements: Vec<LabeledConcurrentStatement>,
pub end_token: Option<TokenId>,
pub end_label: Option<TokenId>,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct ForGenerateStatement {
pub index_name: WithDecl<Ident>,
pub discrete_range: DiscreteRange,
pub generate_token: TokenId,
pub body: GenerateBody,
pub end_token: TokenId,
pub end_label_pos: Option<SrcPos>,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct IfGenerateStatement {
pub conds: Conditionals<GenerateBody>,
pub end_label_pos: Option<SrcPos>,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct CaseGenerateStatement {
pub sels: Selection<GenerateBody>,
pub end_token: TokenId,
pub end_label_pos: Option<SrcPos>,
}
#[derive(PartialEq, Debug, Clone)]
pub struct ModeViewDeclaration {
pub ident: WithDecl<Ident>,
pub typ: SubtypeIndication,
pub is_token: TokenId,
pub elements: Vec<ModeViewElement>,
pub end_token: TokenId,
pub end_ident_pos: Option<TokenId>,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct ModeViewElement {
pub names: Vec<WithDecl<Ident>>,
pub colon_token: TokenId,
pub mode: ElementMode,
}
#[derive(PartialEq, Debug, Clone)]
pub enum ElementMode {
Simple(WithToken<Mode>),
Record(WithTokenSpan<Name>),
Array(WithTokenSpan<Name>),
}
#[derive(PartialEq, Debug, Clone)]
pub enum ConcurrentStatement {
ProcedureCall(ConcurrentProcedureCall),
Block(BlockStatement),
Process(ProcessStatement),
Assert(ConcurrentAssertStatement),
Assignment(ConcurrentSignalAssignment),
Instance(InstantiationStatement),
ForGenerate(ForGenerateStatement),
IfGenerate(IfGenerateStatement),
CaseGenerate(CaseGenerateStatement),
}
#[derive(PartialEq, Debug, Clone)]
pub struct LabeledConcurrentStatement {
pub label: WithDecl<Option<Ident>>,
pub statement: WithTokenSpan<ConcurrentStatement>,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct LibraryClause {
pub name_list: Vec<WithRef<Ident>>,
}
#[derive(PartialEq, Debug, Clone)]
pub struct SeparatedList<T> {
pub items: Vec<T>,
pub tokens: Vec<TokenId>,
}
impl<T> Default for SeparatedList<T> {
fn default() -> Self {
SeparatedList {
items: Vec::default(),
tokens: Vec::default(),
}
}
}
impl SeparatedList<AssociationElement> {
pub fn formals(&self) -> impl Iterator<Item = Option<EntityId>> + '_ {
self.items.iter().filter_map(|el| match &el.formal {
None => None,
Some(name) => match &name.item {
Name::Designator(desi) => Some(desi.reference.get()),
_ => None,
},
})
}
}
impl<T> SeparatedList<T> {
pub fn single(item: T) -> SeparatedList<T> {
SeparatedList {
items: vec![item],
tokens: vec![],
}
}
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct UseClause {
pub name_list: Vec<WithTokenSpan<Name>>,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct ContextReference {
pub name_list: Vec<WithTokenSpan<Name>>,
}
#[derive(PartialEq, Debug, Clone, TokenSpan)]
pub enum ContextItem {
Use(UseClause),
Library(LibraryClause),
Context(ContextReference),
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct ContextDeclaration {
pub ident: WithDecl<Ident>,
pub items: ContextClause,
pub end_token: TokenId,
pub end_ident_pos: Option<TokenId>,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct PackageInstantiation {
pub context_clause: ContextClause,
pub ident: WithDecl<Ident>,
pub package_name: WithTokenSpan<Name>,
pub generic_map: Option<MapAspect>,
}
#[derive(PartialEq, Eq, Debug, Clone)]
pub enum InstantiationList {
Labels(Vec<Ident>),
Others,
All,
}
#[derive(PartialEq, Debug, Clone)]
pub enum EntityAspect {
Entity(WithTokenSpan<Name>, Option<Ident>),
Configuration(WithTokenSpan<Name>),
Open,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct BindingIndication {
pub entity_aspect: Option<EntityAspect>,
pub generic_map: Option<MapAspect>,
pub port_map: Option<MapAspect>,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct ComponentSpecification {
pub instantiation_list: InstantiationList,
pub colon_token: TokenId,
pub component_name: WithTokenSpan<Name>,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct VUnitBindingIndication {
pub vunit_list: Vec<WithTokenSpan<Name>>,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct ConfigurationSpecification {
pub spec: ComponentSpecification,
pub bind_ind: BindingIndication,
pub vunit_bind_inds: Vec<VUnitBindingIndication>,
pub end_token: Option<TokenId>,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct ComponentConfiguration {
pub spec: ComponentSpecification,
pub bind_ind: Option<BindingIndication>,
pub vunit_bind_inds: Vec<VUnitBindingIndication>,
pub block_config: Option<BlockConfiguration>,
}
#[derive(PartialEq, Debug, Clone)]
pub enum ConfigurationItem {
Block(BlockConfiguration),
Component(ComponentConfiguration),
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct BlockConfiguration {
pub block_spec: WithTokenSpan<Name>,
pub use_clauses: Vec<UseClause>,
pub items: Vec<ConfigurationItem>,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct ConfigurationDeclaration {
pub context_clause: ContextClause,
pub ident: WithDecl<Ident>,
pub entity_name: WithTokenSpan<Name>,
pub decl: Vec<WithTokenSpan<Declaration>>,
pub vunit_bind_inds: Vec<VUnitBindingIndication>,
pub block_config: BlockConfiguration,
pub end_token: TokenId,
pub end_ident_pos: Option<TokenId>,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct EntityDeclaration {
pub context_clause: ContextClause,
pub ident: WithDecl<Ident>,
pub generic_clause: Option<InterfaceList>,
pub port_clause: Option<InterfaceList>,
pub decl: Vec<WithTokenSpan<Declaration>>,
pub begin_token: Option<TokenId>,
pub statements: Vec<LabeledConcurrentStatement>,
pub end_token: TokenId,
pub end_ident_pos: Option<TokenId>,
}
impl EntityDeclaration {
pub fn is_token(&self) -> TokenId {
self.span.start_token + 2
}
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct ArchitectureBody {
pub context_clause: ContextClause,
pub ident: WithDecl<Ident>,
pub entity_name: WithRef<Ident>,
pub begin_token: TokenId,
pub decl: Vec<WithTokenSpan<Declaration>>,
pub statements: Vec<LabeledConcurrentStatement>,
pub end_token: TokenId,
pub end_ident_pos: Option<TokenId>,
}
impl ArchitectureBody {
pub fn is_token(&self) -> TokenId {
self.span.start_token + 4
}
pub fn statement_span(&self) -> TokenSpan {
TokenSpan::new(self.begin_token, self.end_token)
}
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct PackageDeclaration {
pub context_clause: ContextClause,
pub ident: WithDecl<Ident>,
pub generic_clause: Option<InterfaceList>,
pub decl: Vec<WithTokenSpan<Declaration>>,
pub end_token: TokenId,
pub end_ident_pos: Option<TokenId>,
}
#[with_token_span]
#[derive(PartialEq, Debug, Clone)]
pub struct PackageBody {
pub context_clause: ContextClause,
pub ident: WithDecl<Ident>,
pub decl: Vec<WithTokenSpan<Declaration>>,
pub end_token: TokenId,
pub end_ident_pos: Option<TokenId>,
}
#[derive(PartialEq, Debug, Clone, TokenSpan)]
pub enum AnyPrimaryUnit {
Entity(EntityDeclaration),
Configuration(ConfigurationDeclaration),
Package(PackageDeclaration),
PackageInstance(PackageInstantiation),
Context(ContextDeclaration),
}
#[derive(PartialEq, Debug, Clone, TokenSpan)]
pub enum AnySecondaryUnit {
Architecture(ArchitectureBody),
PackageBody(PackageBody),
}
pub type ContextClause = Vec<ContextItem>;
#[derive(PartialEq, Debug, Clone, TokenSpan)]
pub enum AnyDesignUnit {
Primary(AnyPrimaryUnit),
Secondary(AnySecondaryUnit),
}
impl AnyDesignUnit {
pub fn is_entity(&self) -> bool {
matches!(self, AnyDesignUnit::Primary(AnyPrimaryUnit::Entity(_)))
}
}
#[derive(PartialEq, Debug, Clone, Default)]
pub struct DesignFile {
pub design_units: Vec<(Vec<Token>, AnyDesignUnit)>,
}