#![allow(clippy::only_used_in_recursion)]
use super::analyze::*;
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<'_>,
target: &mut WithPos<Target>,
assignment_type: AssignmentType,
rhs: &mut AssignmentRightHand<WithPos<Expression>>,
diagnostics: &mut dyn DiagnosticHandler,
) -> FatalNullResult {
let ttyp = self.resolve_target(scope, target, assignment_type, diagnostics)?;
match rhs {
AssignmentRightHand::Simple(expr) => {
self.analyze_expression_for_target(scope, ttyp.as_ref(), 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.as_ref(), item, diagnostics)?;
self.analyze_expression(scope, condition, diagnostics)?;
}
if let Some(expr) = else_item {
self.analyze_expression_for_target(scope, ttyp.as_ref(), 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.as_ref(), item, diagnostics)?;
self.analyze_choices(scope, choices, diagnostics)?;
}
}
}
Ok(())
}
pub fn analyze_waveform_assignment(
&self,
scope: &Scope<'_>,
target: &mut WithPos<Target>,
assignment_type: AssignmentType,
rhs: &mut AssignmentRightHand<Waveform>,
diagnostics: &mut dyn DiagnosticHandler,
) -> FatalNullResult {
let ttyp = self.resolve_target(scope, target, assignment_type, diagnostics)?;
match rhs {
AssignmentRightHand::Simple(wavf) => {
self.analyze_waveform(scope, ttyp.as_ref(), 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.as_ref(), item, diagnostics)?;
self.analyze_expression(scope, condition, diagnostics)?;
}
if let Some(wavf) = else_item {
self.analyze_waveform(scope, ttyp.as_ref(), 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.as_ref(), item, diagnostics)?;
self.analyze_choices(scope, choices, diagnostics)?;
}
}
}
Ok(())
}
fn analyze_waveform(
&self,
scope: &Scope<'_>,
ttyp: Option<&TypeEnt>,
wavf: &mut Waveform,
diagnostics: &mut dyn DiagnosticHandler,
) -> FatalNullResult {
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.analyze_expression_with_target_type(
scope,
&standard.time(),
&expr.pos,
&mut expr.item,
diagnostics,
)?;
}
}
}
Waveform::Unaffected => {}
}
Ok(())
}
pub fn analyze_expression_for_target(
&self,
scope: &Scope<'_>,
ttyp: Option<&TypeEnt>,
expr: &mut WithPos<Expression>,
diagnostics: &mut dyn DiagnosticHandler,
) -> FatalNullResult {
if let Some(ttyp) = ttyp {
self.analyze_expression_with_target_type(
scope,
ttyp,
&expr.pos,
&mut expr.item,
diagnostics,
)?;
} else {
self.analyze_expression_pos(scope, &expr.pos, &mut expr.item, diagnostics)?;
}
Ok(())
}
}