diff --git a/crates/analyzer/src/analyzer_error.rs b/crates/analyzer/src/analyzer_error.rs index bed46575..6b0be519 100644 --- a/crates/analyzer/src/analyzer_error.rs +++ b/crates/analyzer/src/analyzer_error.rs @@ -614,6 +614,21 @@ pub enum AnalyzerError { error_location: SourceSpan, }, + #[diagnostic( + severity(Error), + code(unevaluatable_enum_variant_value), + help(""), + url("") + )] + #[error("The implicit value of enum variant {identifier} cannot be evaluated")] + UnevaluatableEnumVariant { + identifier: String, + #[source_code] + input: NamedSource, + #[label("Error location")] + error_location: SourceSpan, + }, + #[diagnostic( severity(Error), code(too_large_number), @@ -1334,6 +1349,14 @@ impl AnalyzerError { } } + pub fn unevaluatable_enum_variant(identifier: &str, source: &str, token: &TokenRange) -> Self { + AnalyzerError::UnevaluatableEnumVariant { + identifier: identifier.to_string(), + input: AnalyzerError::named_source(source, token), + error_location: token.into(), + } + } + pub fn too_large_number(width: usize, source: &str, token: &TokenRange) -> Self { AnalyzerError::TooLargeNumber { width, diff --git a/crates/analyzer/src/handlers/create_symbol_table.rs b/crates/analyzer/src/handlers/create_symbol_table.rs index 0339fd58..2b973778 100644 --- a/crates/analyzer/src/handlers/create_symbol_table.rs +++ b/crates/analyzer/src/handlers/create_symbol_table.rs @@ -630,7 +630,13 @@ impl<'a> VerylGrammarTrait for CreateSymbolTable<'a> { if let Some(value) = evaluated { value } else { - todo!("report error") + let name = arg.identifier.identifier_token.to_string(); + self.errors.push(AnalyzerError::unevaluatable_enum_variant( + &name, + self.text, + &arg.identifier.as_ref().into(), + )); + return Ok(()); } } EnumMemberValue::ImplicitValue(value) => value, diff --git a/crates/analyzer/src/tests.rs b/crates/analyzer/src/tests.rs index 7da8326a..78c9d89d 100644 --- a/crates/analyzer/src/tests.rs +++ b/crates/analyzer/src/tests.rs @@ -1388,6 +1388,36 @@ fn too_much_enum_variant() { )); } +#[test] +fn unevaluatable_enum_variant() { + let code = r#" + module ModuleA { + enum EnumA: logic<2> { + A = 2'b0x, + B = 2'b10, + } + } + "#; + + let errors = analyze(code); + assert!(errors.is_empty()); + + let code = r#" + module ModuleB { + enum EnumA: logic<2> { + A = 2'b0x, + B, + } + } + "#; + + let errors = analyze(code); + assert!(matches!( + errors[0], + AnalyzerError::UnevaluatableEnumVariant { .. } + )) +} + #[test] fn undefined_identifier() { let code = r#"