use moore_common::source::*;
use moore_common::name::*;
use moore_common::util::HasSpan;
use score::*;
use typed_arena::Arena;
use syntax::ast;
use konst::*;
pub use syntax::ast::Dir;
make_arenas!(
pub struct Arenas {
lib: Lib,
entity: Entity,
arch: Arch,
intf_sig: IntfSignal,
subtype_ind: SubtypeInd,
package: Package,
package_body: PackageBody,
package_inst: PackageInst,
type_decl: TypeDecl,
subtype_decl: SubtypeDecl,
expr: Expr,
aggregate: Aggregate,
const_decl: Decl<ConstDecl>,
signal_decl: Decl<SignalDecl>,
variable_decl: Decl<VarDecl>,
file_decl: Decl<FileDecl>,
process_stmt: ProcessStmt,
sig_assign_stmt: SigAssignStmt,
array_type_index: Spanned<ArrayTypeIndex>,
subprog: Subprog,
subprog_body: SubprogBody,
subprog_inst: SubprogInst,
type_mark: TypeMarkRef,
wait_stmt: Stmt<WaitStmt>,
assert_stmt: Stmt<AssertStmt>,
report_stmt: Stmt<ReportStmt>,
var_assign_stmt: Stmt<VarAssignStmt>,
call_stmt: Stmt<CallStmt>,
if_stmt: Stmt<IfStmt>,
case_stmt: Stmt<CaseStmt>,
loop_stmt: Stmt<LoopStmt>,
nexit_stmt: Stmt<NexitStmt>,
return_stmt: Stmt<ReturnStmt>,
null_stmt: Stmt<NullStmt>,
}
);
impl Arenas {
pub fn new() -> Arenas {
Default::default()
}
}
#[derive(Debug)]
pub struct Lib {
pub entities: Vec<EntityRef>,
pub cfgs: Vec<CfgRef>,
pub pkg_decls: Vec<PkgDeclRef>,
pub pkg_insts: Vec<PkgInstRef>,
pub ctxs: Vec<CtxRef>,
pub archs: Vec<ArchRef>,
pub pkg_bodies: Vec<PkgBodyRef>,
}
impl Lib {
pub fn new() -> Lib {
Lib {
entities: Vec::new(),
cfgs: Vec::new(),
pkg_decls: Vec::new(),
pkg_insts: Vec::new(),
ctxs: Vec::new(),
archs: Vec::new(),
pkg_bodies: Vec::new(),
}
}
}
#[derive(Debug)]
pub struct Entity {
pub ctx_items: CtxItemsRef,
pub lib: LibRef,
pub name: Spanned<Name>,
pub generics: Vec<GenericRef>,
pub ports: Vec<IntfSignalRef>,
}
#[derive(Debug)]
pub struct Arch {
pub ctx_items: CtxItemsRef,
pub entity: EntityRef,
pub name: Spanned<Name>,
pub decls: Vec<DeclInBlockRef>,
pub stmts: Vec<ConcStmtRef>,
}
#[derive(Debug)]
pub struct IntfSignal {
pub name: Spanned<Name>,
pub mode: IntfSignalMode,
pub ty: SubtypeIndRef,
pub bus: bool,
pub init: Option<ExprRef>,
}
#[derive(Debug, Clone, Copy)]
pub enum IntfSignalMode {
In,
Out,
Inout,
Buffer,
Linkage,
}
#[derive(Debug)]
pub struct SubtypeInd {
pub span: Span,
pub type_mark: Spanned<TypeMarkRef>,
pub constraint: Option<Spanned<Constraint>>,
}
#[derive(Debug)]
pub enum Constraint {
Range(Range),
Array(ArrayConstraint),
Record(RecordConstraint),
}
impl From<ArrayConstraint> for Constraint {
fn from(value: ArrayConstraint) -> Constraint {
Constraint::Array(value)
}
}
impl From<RecordConstraint> for Constraint {
fn from(value: RecordConstraint) -> Constraint {
Constraint::Record(value)
}
}
#[derive(Debug)]
pub enum ElementConstraint {
Array(ArrayConstraint),
Record(RecordConstraint),
}
impl HasSpan for ElementConstraint {
fn span(&self) -> Span {
match *self {
ElementConstraint::Array(ref n) => n.span(),
ElementConstraint::Record(ref n) => n.span(),
}
}
}
impl From<ArrayConstraint> for ElementConstraint {
fn from(value: ArrayConstraint) -> ElementConstraint {
ElementConstraint::Array(value)
}
}
impl From<RecordConstraint> for ElementConstraint {
fn from(value: RecordConstraint) -> ElementConstraint {
ElementConstraint::Record(value)
}
}
#[derive(Debug)]
pub struct ArrayConstraint {
pub span: Span,
pub index: Vec<Spanned<DiscreteRange>>,
pub elem: Option<Box<Spanned<ElementConstraint>>>,
}
impl HasSpan for ArrayConstraint {
fn span(&self) -> Span {
self.span
}
}
#[derive(Debug)]
pub enum DiscreteRange {
Subtype(SubtypeIndRef),
Range(Range),
}
impl From<SubtypeIndRef> for DiscreteRange {
fn from(value: SubtypeIndRef) -> DiscreteRange {
DiscreteRange::Subtype(value)
}
}
impl From<Range> for DiscreteRange {
fn from(value: Range) -> DiscreteRange {
DiscreteRange::Range(value)
}
}
#[derive(Debug)]
pub enum Range {
Immediate(Dir, ExprRef, ExprRef),
}
#[derive(Debug)]
pub struct RecordConstraint {
pub span: Span,
pub elems: Vec<(Spanned<Name>, Box<Spanned<ElementConstraint>>)>,
}
impl HasSpan for RecordConstraint {
fn span(&self) -> Span {
self.span
}
}
#[derive(Debug)]
pub struct Package {
pub parent: ScopeRef,
pub name: Spanned<Name>,
pub generics: Vec<GenericRef>,
pub decls: Vec<DeclInPkgRef>,
}
#[derive(Debug)]
pub struct PackageBody {
pub parent: ScopeRef,
pub name: Spanned<Name>,
pub pkg: Spanned<LatentPkgRef>,
pub decls: Vec<DeclInPkgBodyRef>,
}
#[derive(Debug)]
pub struct PackageInst {
pub parent: ScopeRef,
pub name: Spanned<Name>,
pub pkg: Spanned<LatentPkgRef>,
pub generic_map: Vec<()>,
}
#[derive(Debug)]
pub struct TypeDecl {
pub parent: ScopeRef,
pub name: Spanned<Name>,
pub data: Option<Spanned<TypeData>>,
}
#[derive(Debug)]
pub enum TypeData {
Enum(Vec<EnumLit>),
Range(Dir, ExprRef, ExprRef),
Access(SubtypeIndRef),
Array(Vec<ArrayTypeIndexRef>, SubtypeIndRef),
File(TypeMarkRef),
Record(Vec<(Spanned<Name>, SubtypeIndRef)>),
}
#[derive(Debug)]
pub enum EnumLit {
Ident(Spanned<Name>),
Char(Spanned<char>),
}
#[derive(Debug)]
pub enum ArrayTypeIndex {
Unbounded(Spanned<TypeMarkRef>),
Subtype(SubtypeIndRef),
Range(Dir, ExprRef, ExprRef),
}
#[derive(Debug)]
pub struct SubtypeDecl {
pub parent: ScopeRef,
pub name: Spanned<Name>,
pub subty: SubtypeIndRef,
}
#[derive(Debug)]
pub struct Expr {
pub parent: ScopeRef,
pub span: Span,
pub data: ExprData,
}
#[derive(Debug)]
pub enum ExprData {
Name(Def, Span),
ConstName(ConstDeclRef),
SignalName(SignalRef),
VarName(VarDeclRef),
FileName(FileDeclRef),
EnumName(Vec<Spanned<EnumRef>>),
#[deprecated]
OverloadedName(Vec<Spanned<Def>>),
Select(ExprRef, Spanned<ResolvableName>),
Attr(ExprRef, Spanned<ResolvableName>),
StringLiteral(Name),
IntegerLiteral(ConstInt),
FloatLiteral(ConstFloat),
Unary(Spanned<UnaryOp>, ExprRef),
Binary(Operator, ExprRef, ExprRef),
Range(Dir, ExprRef, ExprRef),
Aggregate(AggregateRef),
Qualified(Spanned<TypeMarkRef>, ExprRef),
Allocator(Spanned<TypeMarkRef>, Option<ExprRef>),
Cast(Spanned<TypeMarkRef>, ExprRef),
Call(ExprRef, Spanned<AssocList>),
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum UnaryOp {
Not,
Abs,
Pos,
Neg,
Logical(ast::LogicalOp),
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum BinaryOp {
Logical(ast::LogicalOp),
Rel(ast::RelationalOp),
Match(ast::RelationalOp),
Shift(ast::ShiftOp),
Add,
Sub,
Concat,
Mul,
Div,
Mod,
Rem,
Pow,
}
#[derive(Debug)]
pub struct Decl<T> {
pub parent: ScopeRef,
pub span: Span,
pub name: Spanned<Name>,
pub decl: T,
}
#[derive(Debug)]
pub struct ConstDecl {
pub ty: SubtypeIndRef,
pub init: Option<ExprRef>,
}
#[derive(Debug)]
pub struct SignalDecl {
pub ty: SubtypeIndRef,
pub kind: SignalKind,
pub init: Option<ExprRef>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SignalKind {
Normal,
Register,
Bus,
}
#[derive(Debug)]
pub struct VarDecl {
pub shared: bool,
pub ty: SubtypeIndRef,
pub init: Option<ExprRef>,
}
#[derive(Debug)]
pub struct FileDecl {
pub ty: SubtypeIndRef,
pub filename: Option<ExprRef>,
pub mode: Option<ExprRef>,
}
#[derive(Debug)]
pub struct ProcessStmt {
pub parent: ScopeRef,
pub label: Option<Spanned<Name>>,
pub postponed: bool,
pub sensitivity: ProcessSensitivity,
pub decls: Vec<DeclInProcRef>,
pub stmts: Vec<SeqStmtRef>,
}
#[derive(Debug)]
pub enum ProcessSensitivity {
None,
All,
List(Vec<Def>),
}
#[derive(Debug)]
pub struct SigAssignStmt {
pub parent: ScopeRef,
pub span: Span,
pub label: Option<Spanned<Name>>,
pub target: SigAssignTarget,
pub target_span: Span,
pub kind: SigAssignKind,
pub kind_span: Span,
}
#[derive(Debug)]
pub enum SigAssignTarget {
Name(SignalRef),
Aggregate,
}
#[derive(Debug)]
pub enum SigAssignKind {
SimpleWave(DelayMechanism, Waveform),
SimpleForce(ForceMode, ExprRef),
SimpleRelease(ForceMode),
CondWave(DelayMechanism, Cond<Waveform>),
CondForce(ForceMode, Cond<ExprRef>),
SelWave(DelayMechanism, Sel<Waveform>),
SelForce(ForceMode, Sel<ExprRef>),
}
#[derive(Debug)]
pub struct Cond<T> {
pub when: Vec<(T, ExprRef)>,
pub other: Option<T>,
}
#[derive(Debug)]
pub struct Sel<T> {
pub matching: bool,
pub disc: ExprRef,
pub when: Vec<(T, Spanned<Choices>)>,
}
#[derive(Copy, Clone, Debug)]
pub enum ForceMode {
In,
Out,
}
#[derive(Copy, Clone, Debug)]
pub enum DelayMechanism {
Transport,
Inertial,
RejectInertial(ExprRef),
}
pub type Waveform = Vec<WaveElem>;
#[derive(Debug)]
pub struct WaveElem {
pub value: Option<ExprRef>,
pub after: Option<ExprRef>,
}
#[derive(Clone, Debug)]
pub struct Subprog {
pub parent: ScopeRef,
pub spec: SubprogSpec,
}
#[derive(Clone, Debug)]
pub struct SubprogBody {
pub parent: ScopeRef,
pub spec: SubprogSpec,
pub subprog: Spanned<LatentSubprogRef>,
pub decls: Vec<DeclInSubprogRef>,
pub stmts: Vec<SeqStmtRef>,
}
#[derive(Clone, Debug)]
pub struct SubprogInst {
pub parent: ScopeRef,
pub kind: SubprogKind,
pub name: Spanned<ResolvableName>,
pub subprog: Spanned<LatentSubprogRef>,
pub generic_map: Vec<()>,
}
#[derive(Clone, Debug)]
pub struct SubprogSpec {
pub name: Spanned<ResolvableName>,
pub kind: SubprogKind,
pub generics: Vec<GenericRef>,
pub generic_map: Vec<()>,
pub params: Vec<IntfObjRef>,
pub return_type: Option<Spanned<LatentTypeMarkRef>>,
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub enum SubprogKind {
Proc,
PureFunc,
ImpureFunc,
}
#[derive(Debug)]
pub struct Stmt<T> {
pub parent: ScopeRef,
pub span: Span,
pub label: Option<Spanned<Name>>,
pub stmt: T,
}
#[derive(Debug)]
pub struct WaitStmt {
pub sens: Option<Spanned<SensitivityList>>,
pub cond: Option<ExprRef>,
pub timeout: Option<ExprRef>,
}
#[derive(Debug)]
pub struct AssertStmt {
pub cond: ExprRef,
pub report: Option<ExprRef>,
pub severity: Option<ExprRef>,
}
#[derive(Debug)]
pub struct ReportStmt {
pub report: ExprRef,
pub severity: Option<ExprRef>,
}
#[derive(Debug)]
pub struct VarAssignStmt {
pub target: Spanned<Target>,
pub kind: VarAssignKind,
}
#[derive(Debug)]
pub enum VarAssignKind {
Simple(ExprRef),
Cond(Cond<ExprRef>),
Sel(Sel<ExprRef>),
}
#[derive(Debug)]
pub struct CallStmt {
pub subprog: SubprogRef,
pub params: (),
}
#[derive(Debug)]
pub struct IfStmt {
pub branches: Vec<(ExprRef, Vec<SeqStmtRef>)>,
pub otherwise: Option<Vec<SeqStmtRef>>,
}
#[derive(Debug)]
pub struct CaseStmt {
pub matching: bool,
pub switch: ExprRef,
pub cases: Vec<(Spanned<Choices>, Vec<SeqStmtRef>)>,
}
#[derive(Debug)]
pub struct LoopStmt {
pub scheme: LoopScheme,
pub stmts: Vec<SeqStmtRef>,
}
#[derive(Debug)]
pub enum LoopScheme {
Loop,
While(ExprRef),
For(Spanned<Name>, Spanned<DiscreteRange>),
}
#[derive(Debug)]
pub struct NexitStmt {
pub mode: NexitMode,
pub target: Option<Spanned<LoopStmtRef>>,
pub cond: Option<ExprRef>,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum NexitMode {
Next,
Exit,
}
#[derive(Debug)]
pub struct ReturnStmt {
pub expr: Option<ExprRef>,
}
#[derive(Debug)]
pub struct NullStmt;
pub type SensitivityList = Vec<Spanned<SignalRef>>;
#[derive(Debug)]
pub enum Target {
Name(ExprRef),
Aggregate(AggregateRef),
}
#[derive(Debug)]
pub struct Aggregate {
pub parent: ScopeRef,
pub span: Span,
pub positional: Vec<Spanned<ExprRef>>,
pub named: AggregateKind,
pub others: Option<Spanned<ExprRef>>,
}
pub type Choices = Vec<Spanned<Choice>>;
#[derive(Debug)]
pub enum Choice {
Expr(ExprRef),
DiscreteRange(DiscreteRange),
Element(Name),
Others
}
impl Choice {
pub fn is_others(&self) -> bool {
match *self {
Choice::Others => true,
_ => false,
}
}
pub fn is_element(&self) -> bool {
match *self {
Choice::Element(_) => true,
_ => false,
}
}
}
pub type RecordChoices = Vec<Spanned<Name>>;
pub type ArrayChoices = Vec<Spanned<ArrayChoice>>;
#[derive(Debug)]
pub enum ArrayChoice {
Expr(ExprRef),
DiscreteRange(DiscreteRange),
}
#[derive(Debug)]
pub enum AggregateKind {
Both,
Record(Vec<Spanned<(RecordChoices, Spanned<ExprRef>)>>),
Array(Vec<Spanned<(ArrayChoices, Spanned<ExprRef>)>>),
}
impl AggregateKind {
pub fn get(&self, index: usize) -> Spanned<ExprRef> {
match *self {
AggregateKind::Both => panic!("get() called on `AggregateKind::Both`"),
AggregateKind::Record(ref fields) => fields[index].value.1,
AggregateKind::Array(ref fields) => fields[index].value.1,
}
}
}
pub type AssocList = Vec<AssocElement>;
#[derive(Debug)]
pub struct AssocElement {
pub span: Span,
pub formal: Option<Spanned<ExprRef>>,
pub actual: Spanned<AssocActual>,
}
#[derive(Debug)]
pub enum AssocActual {
Expr(ExprRef),
InertialExpr(ExprRef),
Subtype(SubtypeIndRef),
Open,
}