Skip to content

Commit

Permalink
temp
Browse files Browse the repository at this point in the history
  • Loading branch information
dalance committed May 1, 2024
1 parent 4fc45e0 commit bcb0cba
Show file tree
Hide file tree
Showing 38 changed files with 21,430 additions and 17,206 deletions.
26 changes: 24 additions & 2 deletions crates/analyzer/src/analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,20 @@ use crate::analyzer::resource_table::PathId;
use crate::analyzer_error::AnalyzerError;
use crate::assign::{AssignPath, AssignPosition, AssignPositionTree, AssignPositionType};
use crate::handlers::*;
use crate::namespace::Namespace;
use crate::namespace_table;
use crate::symbol::{
Direction, ParameterValue, Symbol, SymbolId, SymbolKind, TypeKind, VariableAffiniation,
Direction, DocComment, ParameterValue, Symbol, SymbolId, SymbolKind, TypeKind,
VariableAffiniation,
};
use crate::symbol_table::{self, SymbolPath};
use crate::symbol_path::SymbolPath;
use crate::symbol_table;
use itertools::Itertools;
use std::path::Path;
use veryl_metadata::{Lint, Metadata};
use veryl_parser::resource_table;
use veryl_parser::veryl_grammar_trait::*;
use veryl_parser::veryl_token::{Token, TokenSource};
use veryl_parser::veryl_walker::{Handler, VerylWalker};

pub struct AnalyzerPass1<'a> {
Expand Down Expand Up @@ -176,15 +180,33 @@ pub struct Analyzer {
lint_opt: Lint,
}

fn new_namespace(name: &str) -> (Token, Symbol) {
let token = Token::new(name, 0, 0, 0, 0, TokenSource::External);
let symbol = Symbol::new(
&token,
SymbolKind::Namespace,
&Namespace::new(),
false,
DocComment::default(),
);
(token, symbol)
}

impl Analyzer {
pub fn new(metadata: &Metadata) -> Self {
for locks in metadata.lockfile.lock_table.values() {
for lock in locks {
let prj = resource_table::insert_str(&lock.name);
let (token, symbol) = new_namespace(&lock.name);
symbol_table::insert(&token, symbol);
for lock_dep in &lock.dependencies {
let from = resource_table::insert_str(&lock_dep.name);
let to = metadata.lockfile.lock_table.get(&lock_dep.url).unwrap();
let to = to.iter().find(|x| x.version == lock_dep.version).unwrap();

let (token, symbol) = new_namespace(&to.name);
symbol_table::insert(&token, symbol);

let to = resource_table::insert_str(&to.name);
symbol_table::add_project_local(prj, from, to);
}
Expand Down
3 changes: 2 additions & 1 deletion crates/analyzer/src/handlers/check_function.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::analyzer_error::AnalyzerError;
use crate::symbol::SymbolKind;
use crate::symbol_table::{self, SymbolPath};
use crate::symbol_path::SymbolPath;
use crate::symbol_table;
use veryl_parser::veryl_grammar_trait::*;
use veryl_parser::veryl_walker::{Handler, HandlerPoint};
use veryl_parser::ParolError;
Expand Down
1 change: 1 addition & 0 deletions crates/analyzer/src/handlers/check_instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ impl<'a> VerylGrammarTrait for CheckInstance<'a> {
}
SymbolKind::Interface(_) => (),
SymbolKind::SystemVerilog => (),
SymbolKind::GenericParameter => (),
_ => {
self.errors.push(AnalyzerError::mismatch_type(
name,
Expand Down
3 changes: 2 additions & 1 deletion crates/analyzer/src/handlers/check_msb_lsb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use crate::namespace::Namespace;
use crate::namespace_table;
use crate::symbol::Type as SymType;
use crate::symbol::{SymbolKind, TypeKind};
use crate::symbol_table::{self, SymbolPath, SymbolPathNamespace};
use crate::symbol_path::{SymbolPath, SymbolPathNamespace};
use crate::symbol_table;
use veryl_parser::veryl_grammar_trait::*;
use veryl_parser::veryl_walker::{Handler, HandlerPoint};
use veryl_parser::ParolError;
Expand Down
179 changes: 152 additions & 27 deletions crates/analyzer/src/handlers/create_reference.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
use crate::analyzer_error::AnalyzerError;
use crate::namespace::Namespace;
use crate::namespace_table;
use crate::symbol::SymbolKind;
use crate::symbol_table::{self, ResolveError, ResolveErrorCause, SymbolPath};
use crate::symbol::{
DocComment, GenericArguments, GenericInstanceProperty, GenericParameterItemProperty, Symbol,
SymbolId, SymbolKind,
};
use crate::symbol_path::{SymbolPath, SymbolPathNamespace};
use crate::symbol_table::{self, ResolveError, ResolveErrorCause};
use veryl_parser::resource_table::TokenId;
use veryl_parser::veryl_grammar_trait::*;
use veryl_parser::veryl_token::TokenRange;
use veryl_parser::veryl_token::{Token, TokenRange};
use veryl_parser::veryl_walker::{Handler, HandlerPoint};
use veryl_parser::ParolError;

Expand All @@ -17,7 +21,6 @@ pub struct CreateReference<'a> {
top_level: bool,
file_scope_imported_items: Vec<TokenId>,
file_scope_imported_packages: Vec<Namespace>,
in_expression_identifier: Vec<()>,
}

impl<'a> CreateReference<'a> {
Expand Down Expand Up @@ -60,6 +63,108 @@ impl<'a> Handler for CreateReference<'a> {
}
}

struct GenericPath {
pub namespace: Namespace,
pub mangled_path: SymbolPath,
pub base_path: SymbolPath,
pub tokens: Vec<Token>,
pub args: Vec<Option<GenericArguments>>,
}

impl GenericPath {
pub fn len(&self) -> usize {
self.tokens.len()
}

pub fn base_path(&self, i: usize) -> SymbolPathNamespace {
let ret = &[
&self.mangled_path.as_slice()[0..i],
&[self.base_path.as_slice()[i]],
]
.concat();
(&SymbolPath::new(ret), &self.namespace).into()
}

pub fn get_generic_instance(&self, i: usize, base: &Symbol) -> Option<(Token, Symbol)> {
let mangled_name = self.mangled_path.as_slice()[i];
let base_name = self.base_path.as_slice()[i];

if mangled_name != base_name {
let arguments = self.args[i].clone().unwrap();
let property = GenericInstanceProperty {
base: base.id,
arguments,
};
let kind = SymbolKind::GenericInstance(property);
let token = self.tokens[i];
let token = Token::new(
&mangled_name.to_string(),
token.line,
token.column,
token.length,
token.pos,
token.source,
);
let symbol = Symbol::new(&token, kind, &base.namespace, false, DocComment::default());
Some((token, symbol))
} else {
None
}
}

pub fn get_generic_parameter_item(&self, i: usize, parameter: SymbolId) -> (Token, Symbol) {
let mut namespace = self.namespace.clone();
for j in 0..i {
namespace.push(self.base_path.as_slice()[j]);
}

let property = GenericParameterItemProperty { parameter };
let kind = SymbolKind::GenericParameterItem(property);
let token = self.tokens[i];
let symbol = Symbol::new(&token, kind, &namespace, false, DocComment::default());
(token, symbol)
}
}

impl From<&ScopedIdentifier> for GenericPath {
fn from(value: &ScopedIdentifier) -> Self {
let namespace = namespace_table::get(value.identifier().token.id).unwrap();
let mangled_path: SymbolPath = value.into();
let mut base_path = SymbolPath::default();
let mut tokens = Vec::new();
let mut args = Vec::new();
match value.scoped_identifier_group.as_ref() {
ScopedIdentifierGroup::DollarIdentifier(x) => {
base_path.push(x.dollar_identifier.dollar_identifier_token.token.text);
tokens.push(x.dollar_identifier.dollar_identifier_token.token);
args.push(None);
}
ScopedIdentifierGroup::IdentifierScopedIdentifierOpt(x) => {
base_path.push(x.identifier.identifier_token.token.text);
tokens.push(x.identifier.identifier_token.token);
if let Some(ref x) = x.scoped_identifier_opt {
let arg: GenericArguments = x.with_generic_argument.as_ref().into();
args.push(Some(arg));
} else {
args.push(None);
}
}
}
for x in &value.scoped_identifier_list {
base_path.push(x.identifier.identifier_token.token.text);
tokens.push(x.identifier.identifier_token.token);
}

Self {
namespace,
mangled_path,
base_path,
tokens,
args,
}
}
}

impl<'a> VerylGrammarTrait for CreateReference<'a> {
fn hierarchical_identifier(&mut self, arg: &HierarchicalIdentifier) -> Result<(), ParolError> {
if let HandlerPoint::Before = self.point {
Expand All @@ -86,16 +191,43 @@ impl<'a> VerylGrammarTrait for CreateReference<'a> {

fn scoped_identifier(&mut self, arg: &ScopedIdentifier) -> Result<(), ParolError> {
if let HandlerPoint::Before = self.point {
if self.in_expression_identifier.is_empty() {
let ident = arg.identifier().token;
match symbol_table::resolve(arg) {
let ident = arg.identifier().token;
let path: GenericPath = arg.into();
let mut generic_parameter_symbol = None;

for i in 0..path.len() {
let base_path = path.base_path(i);

match symbol_table::resolve(&base_path) {
Ok(symbol) => {
for id in symbol.full_path {
symbol_table::add_reference(id, &ident);
symbol_table::add_reference(symbol.found.id, &ident);

if let Some((token, new_symbol)) =
path.get_generic_instance(i, &symbol.found)
{
if let Some(ref x) = symbol_table::insert(&token, new_symbol) {
symbol_table::add_generic_instance(symbol.found.id, *x);
}
}

if let SymbolKind::GenericParameter = symbol.found.kind {
generic_parameter_symbol = Some(symbol.found.id);
}
}
Err(err) => {
self.push_resolve_error(err, &arg.into());
if let Some(generic_parameter_symbol) = generic_parameter_symbol {
let (token, symbol) =
path.get_generic_parameter_item(i, generic_parameter_symbol);
symbol_table::insert(&token, symbol);
} else {
let is_single_identifier = SymbolPath::from(arg).as_slice().len() == 1;
let name = ident.to_string();
if name == "_" && is_single_identifier {
return Ok(());
}

self.push_resolve_error(err, &arg.into());
}
}
}
}
Expand All @@ -104,31 +236,24 @@ impl<'a> VerylGrammarTrait for CreateReference<'a> {
}

fn expression_identifier(&mut self, arg: &ExpressionIdentifier) -> Result<(), ParolError> {
match self.point {
HandlerPoint::Before => {
self.in_expression_identifier.push(());
// Should be executed after scoped_identifier to handle hierarchical access only
if let HandlerPoint::After = self.point {
let ident = arg.identifier().token;
let mut path: SymbolPath = arg.scoped_identifier.as_ref().into();
let namespace = namespace_table::get(ident.id).unwrap();

for x in &arg.expression_identifier_list0 {
path.push(x.identifier.identifier_token.token.text);

let ident = arg.identifier().token;
match symbol_table::resolve(arg) {
match symbol_table::resolve((&path, &namespace)) {
Ok(symbol) => {
for id in symbol.full_path {
symbol_table::add_reference(id, &ident);
}
symbol_table::add_reference(symbol.found.id, &ident);
}
Err(err) => {
let is_single_identifier = SymbolPath::from(arg).as_slice().len() == 1;
let name = ident.to_string();
if name == "_" && is_single_identifier {
return Ok(());
}

self.push_resolve_error(err, &arg.into());
}
}
}
HandlerPoint::After => {
self.in_expression_identifier.pop();
}
}
Ok(())
}
Expand Down
Loading

0 comments on commit bcb0cba

Please sign in to comment.