diff --git a/crates/analyzer/src/analyzer.rs b/crates/analyzer/src/analyzer.rs index da67add4..d6033c1d 100644 --- a/crates/analyzer/src/analyzer.rs +++ b/crates/analyzer/src/analyzer.rs @@ -392,6 +392,12 @@ fn check_multiple_assignment( let mut ret = Vec::new(); let len = x_pos.0.len().min(y_pos.0.len()); + let x_maybe = x_pos.0.last().unwrap().is_maybe(); + let y_maybe = y_pos.0.last().unwrap().is_maybe(); + if x_maybe || y_maybe { + return vec![]; + } + for i in 0..len { let x_type = &x_pos.0[i]; let y_type = &y_pos.0[i]; diff --git a/crates/analyzer/src/assign.rs b/crates/analyzer/src/assign.rs index 0120bfb2..e2e26ff7 100644 --- a/crates/analyzer/src/assign.rs +++ b/crates/analyzer/src/assign.rs @@ -115,17 +115,29 @@ pub enum AssignPositionType { token: Token, resettable: bool, }, + Connect { + token: Token, + maybe: bool, + }, } impl AssignPositionType { pub fn token(&self) -> &Token { match self { - AssignPositionType::DeclarationBranch { token: x, .. } => x, - AssignPositionType::DeclarationBranchItem { token: x, .. } => x, - AssignPositionType::Declaration { token: x, .. } => x, - AssignPositionType::StatementBranch { token: x, .. } => x, - AssignPositionType::StatementBranchItem { token: x, .. } => x, - AssignPositionType::Statement { token: x, .. } => x, + AssignPositionType::DeclarationBranch { token, .. } => token, + AssignPositionType::DeclarationBranchItem { token, .. } => token, + AssignPositionType::Declaration { token, .. } => token, + AssignPositionType::StatementBranch { token, .. } => token, + AssignPositionType::StatementBranchItem { token, .. } => token, + AssignPositionType::Statement { token, .. } => token, + AssignPositionType::Connect { token, .. } => token, + } + } + + pub fn is_maybe(&self) -> bool { + match self { + AssignPositionType::Connect { maybe, .. } => *maybe, + _ => false, } } } diff --git a/crates/analyzer/src/handlers/check_assignment.rs b/crates/analyzer/src/handlers/check_assignment.rs index c5d37123..24ee2f8b 100644 --- a/crates/analyzer/src/handlers/check_assignment.rs +++ b/crates/analyzer/src/handlers/check_assignment.rs @@ -423,9 +423,14 @@ impl<'a> VerylGrammarTrait for CheckAssignment<'a> { } } - for (name, target) in &x.connects { + self.assign_position.push(AssignPositionType::Declaration { + token: arg.inst.inst_token.token, + r#type: AssignDeclarationType::Inst, + }); + + for (token, target) in &x.connects { if !target.is_empty() { - let dir_output = if let Some(dir) = dirs.get(name) { + let dir_output = if let Some(dir) = dirs.get(&token.text) { matches!( dir, Direction::Ref | Direction::Inout | Direction::Output @@ -438,12 +443,10 @@ impl<'a> VerylGrammarTrait for CheckAssignment<'a> { if let Ok(x) = symbol_table::resolve((target, &symbol.namespace)) { - self.assign_position.push( - AssignPositionType::Declaration { - token: arg.inst.inst_token.token, - r#type: AssignDeclarationType::Inst, - }, - ); + self.assign_position.push(AssignPositionType::Connect { + token: *token, + maybe: dir_unknown, + }); symbol_table::add_assign( x.full_path, &self.assign_position, @@ -454,6 +457,8 @@ impl<'a> VerylGrammarTrait for CheckAssignment<'a> { } } } + + self.assign_position.pop(); } } } diff --git a/crates/analyzer/src/handlers/create_symbol_table.rs b/crates/analyzer/src/handlers/create_symbol_table.rs index 91558d03..0203bff8 100644 --- a/crates/analyzer/src/handlers/create_symbol_table.rs +++ b/crates/analyzer/src/handlers/create_symbol_table.rs @@ -35,7 +35,7 @@ pub struct CreateSymbolTable<'a> { struct_union_members: Vec>, affiniation: Vec, connect_targets: Vec>, - connects: HashMap>, + connects: HashMap>, } #[derive(Clone)] @@ -377,11 +377,11 @@ impl<'a> VerylGrammarTrait for CreateSymbolTable<'a> { match self.point { HandlerPoint::Before => self.connect_targets.clear(), HandlerPoint::After => { - let port = arg.identifier.identifier_token.token.text; + let port = arg.identifier.identifier_token.token; let targets = if arg.inst_port_item_opt.is_some() { self.connect_targets.drain(0..).collect() } else { - vec![vec![port]] + vec![vec![port.text]] }; for target in targets { self.connects.insert(port, target); diff --git a/crates/analyzer/src/symbol.rs b/crates/analyzer/src/symbol.rs index 0a849e22..797b4e63 100644 --- a/crates/analyzer/src/symbol.rs +++ b/crates/analyzer/src/symbol.rs @@ -623,7 +623,7 @@ pub struct FunctionProperty { #[derive(Debug, Clone)] pub struct InstanceProperty { pub type_name: Vec, - pub connects: HashMap>, + pub connects: HashMap>, } #[derive(Debug, Clone)] diff --git a/crates/parser/src/veryl_token.rs b/crates/parser/src/veryl_token.rs index fde2e14c..f4e8b904 100644 --- a/crates/parser/src/veryl_token.rs +++ b/crates/parser/src/veryl_token.rs @@ -6,7 +6,7 @@ use paste::paste; use regex::Regex; use std::fmt; -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum TokenSource { File(PathId), Builtin, @@ -33,7 +33,7 @@ impl PartialEq for TokenSource { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Token { pub id: TokenId, pub text: StrId,