#![allow(clippy::only_used_in_recursion)]
use super::analyze::*;
use super::named_entity::*;
use super::region::*;
use super::target::AssignmentType;
use crate::ast::*;
use crate::data::*;
impl<'a> AnalyzeContext<'a> {
pub fn analyze_expr_assignment(
&self,
scope: &Scope<'a>,
target: &mut WithPos<Target>,
assignment_type: AssignmentType,
rhs: &mut AssignmentRightHand<WithPos<Expression>>,
diagnostics: &mut dyn DiagnosticHandler,
) -> FatalResult {
let ttyp = self.resolve_target(scope, target, assignment_type, diagnostics)?;
match rhs {
AssignmentRightHand::Simple(expr) => {
self.analyze_expression_for_target(scope, ttyp, expr, diagnostics)?;
}
AssignmentRightHand::Conditional(conditionals) => {
let Conditionals {
conditionals,
else_item,
} = conditionals;
for conditional in conditionals {
let Conditional { condition, item } = conditional;
self.analyze_expression_for_target(scope, ttyp, item, diagnostics)?;
self.analyze_expression(scope, condition, diagnostics)?;
}
if let Some(expr) = else_item {
self.analyze_expression_for_target(scope, ttyp, expr, diagnostics)?;
}
}
AssignmentRightHand::Selected(selection) => {
let Selection {
expression,
alternatives,
} = selection;
self.analyze_expression(scope, expression, diagnostics)?;
for Alternative { choices, item } in alternatives.iter_mut() {
self.analyze_expression_for_target(scope, ttyp, item, diagnostics)?;
self.analyze_choices(scope, choices, diagnostics)?;
}
}
}
Ok(())
}
pub fn analyze_waveform_assignment(
&self,
scope: &Scope<'a>,
target: &mut WithPos<Target>,
assignment_type: AssignmentType,
rhs: &mut AssignmentRightHand<Waveform>,
diagnostics: &mut dyn DiagnosticHandler,
) -> FatalResult {
let ttyp = self.resolve_target(scope, target, assignment_type, diagnostics)?;
match rhs {
AssignmentRightHand::Simple(wavf) => {
self.analyze_waveform(scope, ttyp, wavf, diagnostics)?;
}
AssignmentRightHand::Conditional(conditionals) => {
let Conditionals {
conditionals,
else_item,
} = conditionals;
for conditional in conditionals {
let Conditional { condition, item } = conditional;
self.analyze_waveform(scope, ttyp, item, diagnostics)?;
self.analyze_expression(scope, condition, diagnostics)?;
}
if let Some(wavf) = else_item {
self.analyze_waveform(scope, ttyp, wavf, diagnostics)?;
}
}
AssignmentRightHand::Selected(selection) => {
let Selection {
expression,
alternatives,
} = selection;
self.analyze_expression(scope, expression, diagnostics)?;
for Alternative { choices, item } in alternatives.iter_mut() {
self.analyze_waveform(scope, ttyp, item, diagnostics)?;
self.analyze_choices(scope, choices, diagnostics)?;
}
}
}
Ok(())
}
fn analyze_waveform(
&self,
scope: &Scope<'a>,
ttyp: Option<TypeEnt<'a>>,
wavf: &mut Waveform,
diagnostics: &mut dyn DiagnosticHandler,
) -> FatalResult {
match wavf {
Waveform::Elements(ref mut elems) => {
for elem in elems.iter_mut() {
let WaveformElement { value, after } = elem;
self.analyze_expression_for_target(scope, ttyp, value, diagnostics)?;
if let Some(expr) = after {
let standard = self.standard_package().unwrap();
self.expr_with_ttyp(
scope,
standard.time(),
&expr.pos,
&mut expr.item,
diagnostics,
)?;
}
}
}
Waveform::Unaffected => {}
}
Ok(())
}
pub fn analyze_expression_for_target(
&self,
scope: &Scope<'a>,
ttyp: Option<TypeEnt<'a>>,
expr: &mut WithPos<Expression>,
diagnostics: &mut dyn DiagnosticHandler,
) -> FatalResult {
if let Some(ttyp) = ttyp {
self.expr_with_ttyp(scope, ttyp, &expr.pos, &mut expr.item, diagnostics)?;
} else {
self.analyze_expression_pos(scope, &expr.pos, &mut expr.item, diagnostics)?;
}
Ok(())
}
}