Skip to content

Commit

Permalink
Add enum member scope #66
Browse files Browse the repository at this point in the history
  • Loading branch information
dalance committed Jan 16, 2023
1 parent 6d266b6 commit 6852583
Show file tree
Hide file tree
Showing 18 changed files with 169 additions and 76 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* [Changed] modport separator from `.` to `::` [#65](https://github.com/dalance/veryl/issues/65)
* [Changed] `[package]` in Veryl.toml to `[project]` [#82](https://github.com/dalance/veryl/issues/82)
* [Added] type cast [#48](https://github.com/dalance/veryl/issues/48)
* [Changed] enum member scope [#66](https://github.com/dalance/veryl/issues/66)

## [v0.1.14](https://github.com/dalance/veryl/compare/v0.1.13...v0.1.14) - 2023-01-12

Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 8 additions & 11 deletions crates/analyzer/src/handlers/check_function_arity.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use crate::analyzer_error::AnalyzerError;
use crate::namespace_table;
use crate::symbol::SymbolKind;
use crate::symbol_table::{self, SymbolPath};
use veryl_parser::resource_table;
use veryl_parser::veryl_grammar_trait::*;
use veryl_parser::veryl_walker::{Handler, HandlerPoint};
use veryl_parser::ParolError;
Expand Down Expand Up @@ -38,13 +36,7 @@ impl<'a> VerylGrammarTrait for CheckFunctionArity<'a> {
return Ok(());
}

let path: SymbolPath = x.expression_identifier.as_ref().into();
let namespace = namespace_table::get(
x.expression_identifier.identifier.identifier_token.token.id,
)
.unwrap();
let symbol = symbol_table::get(&path, &namespace);

let symbol = symbol_table::resolve(x.expression_identifier.as_ref());
let arity = if let Some(symbol) = symbol {
if let SymbolKind::Function(x) = symbol.kind {
Some(x.ports.len())
Expand All @@ -65,8 +57,13 @@ impl<'a> VerylGrammarTrait for CheckFunctionArity<'a> {

if let Some(arity) = arity {
if arity != args {
let name = resource_table::get_str_value(*path.as_slice().last().unwrap())
.unwrap();
let name = format!(
"{}",
SymbolPath::from(x.expression_identifier.as_ref())
.as_slice()
.last()
.unwrap()
);
self.errors.push(AnalyzerError::mismatch_arity(
&name,
arity,
Expand Down
17 changes: 3 additions & 14 deletions crates/analyzer/src/handlers/check_instance.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::analyzer_error::AnalyzerError;
use crate::namespace_table;
use crate::symbol::SymbolKind;
use crate::symbol_table::{self, SymbolPath};
use crate::symbol_table;
use veryl_parser::resource_table;
use veryl_parser::veryl_grammar_trait::*;
use veryl_parser::veryl_walker::{Handler, HandlerPoint};
Expand Down Expand Up @@ -32,8 +31,6 @@ impl<'a> Handler for CheckInstance<'a> {
impl<'a> VerylGrammarTrait for CheckInstance<'a> {
fn inst_declaration(&mut self, arg: &InstDeclaration) -> Result<(), ParolError> {
if let HandlerPoint::Before = self.point {
let path = &SymbolPath::new(&[arg.identifier0.identifier_token.token.text]);

let mut connected_ports = Vec::new();
if let Some(ref x) = arg.inst_declaration_opt1 {
if let Some(ref x) = x.inst_declaration_opt2 {
Expand All @@ -46,16 +43,13 @@ impl<'a> VerylGrammarTrait for CheckInstance<'a> {
}
}

let namespace = namespace_table::get(arg.identifier.identifier_token.token.id).unwrap();
let symbol = symbol_table::get(path, &namespace);
let symbol = symbol_table::resolve(arg.identifier0.as_ref());
let name = arg.identifier0.identifier_token.text();
if let Some(symbol) = symbol {
match symbol.kind {
SymbolKind::Module(ref x) => {
for port in &x.ports {
if !connected_ports.contains(&port.name) {
let name =
resource_table::get_str_value(*path.as_slice().last().unwrap())
.unwrap();
let port = resource_table::get_str_value(port.name).unwrap();
self.errors.push(AnalyzerError::missing_port(
&name,
Expand All @@ -67,9 +61,6 @@ impl<'a> VerylGrammarTrait for CheckInstance<'a> {
}
for port in &connected_ports {
if !x.ports.iter().any(|x| &x.name == port) {
let name =
resource_table::get_str_value(*path.as_slice().last().unwrap())
.unwrap();
let port = resource_table::get_str_value(*port).unwrap();
self.errors.push(AnalyzerError::unknown_port(
&name,
Expand All @@ -82,8 +73,6 @@ impl<'a> VerylGrammarTrait for CheckInstance<'a> {
}
SymbolKind::Interface(_) => (),
_ => {
let name = resource_table::get_str_value(*path.as_slice().last().unwrap())
.unwrap();
self.errors.push(AnalyzerError::mismatch_type(
&name,
"module or interface",
Expand Down
29 changes: 8 additions & 21 deletions crates/analyzer/src/handlers/create_reference.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use crate::analyzer_error::AnalyzerError;
use crate::namespace_table;
use crate::symbol_table::{self, SymbolPath};
use veryl_parser::resource_table;
use veryl_parser::veryl_grammar_trait::*;
use veryl_parser::veryl_walker::{Handler, HandlerPoint};
use veryl_parser::ParolError;
Expand Down Expand Up @@ -31,19 +29,16 @@ impl<'a> Handler for CreateReference<'a> {
impl<'a> VerylGrammarTrait for CreateReference<'a> {
fn hierarchical_identifier(&mut self, arg: &HierarchicalIdentifier) -> Result<(), ParolError> {
if let HandlerPoint::Before = self.point {
let namespace = namespace_table::get(arg.identifier.identifier_token.token.id).unwrap();
let path = SymbolPath::from(arg);
let symbol = symbol_table::get(&path, &namespace);
let symbol = symbol_table::resolve(arg);
if let Some(symbol) = symbol {
symbol_table::add_reference(
symbol.token.id,
&arg.identifier.identifier_token.token,
);
} else {
let is_single_identifier = path.as_slice().len() == 1;
let is_single_identifier = SymbolPath::from(arg).as_slice().len() == 1;
if is_single_identifier {
let name =
resource_table::get_str_value(*path.as_slice().last().unwrap()).unwrap();
let name = arg.identifier.identifier_token.text();
self.errors.push(AnalyzerError::undefined_identifier(
&name,
self.text,
Expand All @@ -62,19 +57,16 @@ impl<'a> VerylGrammarTrait for CreateReference<'a> {
return Ok(());
}

let namespace = namespace_table::get(arg.identifier.identifier_token.token.id).unwrap();
let path = SymbolPath::from(arg);
let symbol = symbol_table::get(&path, &namespace);
let symbol = symbol_table::resolve(arg);
if let Some(symbol) = symbol {
symbol_table::add_reference(
symbol.token.id,
&arg.identifier.identifier_token.token,
);
} else {
let is_single_identifier = path.as_slice().len() == 1;
let is_single_identifier = SymbolPath::from(arg).as_slice().len() == 1;
if is_single_identifier {
let name =
resource_table::get_str_value(*path.as_slice().last().unwrap()).unwrap();
let name = arg.identifier.identifier_token.text();
self.errors.push(AnalyzerError::undefined_identifier(
&name,
self.text,
Expand All @@ -88,9 +80,7 @@ impl<'a> VerylGrammarTrait for CreateReference<'a> {

fn modport_item(&mut self, arg: &ModportItem) -> Result<(), ParolError> {
if let HandlerPoint::Before = self.point {
let namespace = namespace_table::get(arg.identifier.identifier_token.token.id).unwrap();
let path = SymbolPath::from(arg.identifier.as_ref());
let symbol = symbol_table::get(&path, &namespace);
let symbol = symbol_table::resolve(arg.identifier.as_ref());
if let Some(symbol) = symbol {
symbol_table::add_reference(
symbol.token.id,
Expand All @@ -103,10 +93,7 @@ impl<'a> VerylGrammarTrait for CreateReference<'a> {

fn inst_declaration(&mut self, arg: &InstDeclaration) -> Result<(), ParolError> {
if let HandlerPoint::Before = self.point {
let namespace =
namespace_table::get(arg.identifier0.identifier_token.token.id).unwrap();
let path = SymbolPath::from(arg.identifier0.as_ref());
let symbol = symbol_table::get(&path, &namespace);
let symbol = symbol_table::resolve(arg.identifier0.as_ref());
if let Some(symbol) = symbol {
symbol_table::add_reference(
symbol.token.id,
Expand Down
16 changes: 11 additions & 5 deletions crates/analyzer/src/handlers/create_symbol_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,17 @@ impl<'a> VerylGrammarTrait for CreateSymbolTable<'a> {
}

fn enum_declaration(&mut self, arg: &EnumDeclaration) -> Result<(), ParolError> {
if let HandlerPoint::Before = self.point {
let r#type = arg.r#type.as_ref().into();
let property = EnumProperty { r#type };
let kind = SymbolKind::Enum(property);
self.insert_symbol(&arg.identifier.identifier_token, kind);
match self.point {
HandlerPoint::Before => {
let r#type = arg.r#type.as_ref().into();
let property = EnumProperty { r#type };
let kind = SymbolKind::Enum(property);
self.insert_symbol(&arg.identifier.identifier_token, kind);

let name = arg.identifier.identifier_token.token.text;
self.namespace.push(name)
}
HandlerPoint::After => self.namespace.pop(),
}
Ok(())
}
Expand Down
4 changes: 0 additions & 4 deletions crates/analyzer/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,6 @@ pub enum TypeKind {
F32,
F64,
UserDefined(Vec<StrId>),
Modport(StrId, StrId),
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -220,9 +219,6 @@ impl fmt::Display for Type {
text.push_str(&format!("::{}", path));
}
}
TypeKind::Modport(interface, modport) => {
text.push_str(&format!("{}.{}", interface, modport));
}
}
if !self.width.is_empty() {
text.push(' ');
Expand Down
39 changes: 39 additions & 0 deletions crates/analyzer/src/symbol_table.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::namespace::Namespace;
use crate::namespace_table;
use crate::symbol::{Symbol, SymbolKind};
use std::cell::RefCell;
use std::collections::HashMap;
Expand Down Expand Up @@ -87,6 +88,36 @@ impl From<&syntax_tree::ExpressionIdentifier> for SymbolPath {
}
}

pub struct SymbolPathNamespace(SymbolPath, Namespace);

impl From<&syntax_tree::Identifier> for SymbolPathNamespace {
fn from(value: &syntax_tree::Identifier) -> Self {
let namespace = namespace_table::get(value.identifier_token.token.id).unwrap();
SymbolPathNamespace(value.into(), namespace)
}
}

impl From<&syntax_tree::HierarchicalIdentifier> for SymbolPathNamespace {
fn from(value: &syntax_tree::HierarchicalIdentifier) -> Self {
let namespace = namespace_table::get(value.identifier.identifier_token.token.id).unwrap();
SymbolPathNamespace(value.into(), namespace)
}
}

impl From<&syntax_tree::ScopedIdentifier> for SymbolPathNamespace {
fn from(value: &syntax_tree::ScopedIdentifier) -> Self {
let namespace = namespace_table::get(value.identifier.identifier_token.token.id).unwrap();
SymbolPathNamespace(value.into(), namespace)
}
}

impl From<&syntax_tree::ExpressionIdentifier> for SymbolPathNamespace {
fn from(value: &syntax_tree::ExpressionIdentifier) -> Self {
let namespace = namespace_table::get(value.identifier.identifier_token.token.id).unwrap();
SymbolPathNamespace(value.into(), namespace)
}
}

#[derive(Clone, Default, Debug)]
pub struct SymbolTable {
table: HashMap<StrId, Vec<Symbol>>,
Expand Down Expand Up @@ -130,6 +161,9 @@ impl SymbolTable {
namespace = Namespace::default();
namespace.push(ret.token.text);
}
SymbolKind::Enum(_) => {
namespace.push(ret.token.text);
}
SymbolKind::Instance(ref x) => {
namespace = Namespace::default();
namespace.push(x.type_name);
Expand Down Expand Up @@ -224,6 +258,11 @@ pub fn get(path: &SymbolPath, namespace: &Namespace) -> Option<Symbol> {
SYMBOL_TABLE.with(|f| f.borrow().get(path, namespace).cloned())
}

pub fn resolve<T: Into<SymbolPathNamespace>>(path: T) -> Option<Symbol> {
let SymbolPathNamespace(path, namespace) = path.into();
SYMBOL_TABLE.with(|f| f.borrow().get(&path, &namespace).cloned())
}

pub fn get_all() -> Vec<Symbol> {
SYMBOL_TABLE.with(|f| f.borrow().get_all())
}
Expand Down
1 change: 1 addition & 0 deletions crates/emitter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ edition = "2021"

[dependencies]
serde = {workspace = true}
veryl-analyzer = {version = "0.1.14", path = "../analyzer"}
veryl-metadata = {version = "0.1.14", path = "../metadata"}
veryl-parser = {version = "0.1.14", path = "../parser"}
49 changes: 49 additions & 0 deletions crates/emitter/src/emitter.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::aligner::{Aligner, Location};
use veryl_analyzer::symbol::SymbolKind;
use veryl_analyzer::symbol_table;
use veryl_metadata::{ClockType, Metadata, ResetType};
use veryl_parser::resource_table;
use veryl_parser::veryl_grammar_trait::*;
Expand All @@ -25,6 +27,7 @@ pub struct Emitter {
in_direction_modport: bool,
reset_signal: Option<String>,
default_block: Option<String>,
enum_name: Option<String>,
}

impl Default for Emitter {
Expand All @@ -48,6 +51,7 @@ impl Default for Emitter {
in_direction_modport: false,
reset_signal: None,
default_block: None,
enum_name: None,
}
}
}
Expand Down Expand Up @@ -287,6 +291,48 @@ impl VerylWalker for Emitter {
}
}

/// Semantic action for non-terminal 'ExpressionIdentifier'
fn expression_identifier(&mut self, arg: &ExpressionIdentifier) {
if let Some(ref x) = arg.expression_identifier_opt {
self.dollar(&x.dollar);
}

self.identifier(&arg.identifier);
let symbol = symbol_table::resolve(arg);
let is_enum_member = if let Some(ref symbol) = symbol {
matches!(symbol.kind, SymbolKind::EnumMember(_))
} else {
false
};

match &*arg.expression_identifier_group {
ExpressionIdentifierGroup::ColonColonIdentifierExpressionIdentifierGroupList(x) => {
if is_enum_member {
self.str("_");
} else {
self.colon_colon(&x.colon_colon);
}
self.identifier(&x.identifier);
for x in &x.expression_identifier_group_list {
self.colon_colon(&x.colon_colon);
self.identifier(&x.identifier);
}
}
ExpressionIdentifierGroup::ExpressionIdentifierGroupList0ExpressionIdentifierGroupList1(x) => {
for x in &x.expression_identifier_group_list0 {
self.range(&x.range);
}
for x in &x.expression_identifier_group_list1 {
self.dot(&x.dot);
self.identifier(&x.identifier);
for x in &x.expression_identifier_group_list1_list {
self.range(&x.range);
}
}
}
}
}

/// Semantic action for non-terminal 'Expression'
fn expression(&mut self, arg: &Expression) {
self.expression01(&arg.expression01);
Expand Down Expand Up @@ -1011,6 +1057,7 @@ impl VerylWalker for Emitter {

/// Semantic action for non-terminal 'EnumDeclaration'
fn enum_declaration(&mut self, arg: &EnumDeclaration) {
self.enum_name = Some(arg.identifier.identifier_token.text());
self.str("typedef");
self.space(1);
self.r#enum(&arg.r#enum);
Expand Down Expand Up @@ -1044,6 +1091,8 @@ impl VerylWalker for Emitter {

/// Semantic action for non-terminal 'EnumItem'
fn enum_item(&mut self, arg: &EnumItem) {
self.str(&self.enum_name.clone().unwrap());
self.str("_");
self.identifier(&arg.identifier);
if let Some(ref x) = arg.enum_item_opt {
self.space(1);
Expand Down
Loading

0 comments on commit 6852583

Please sign in to comment.