Skip to content

Commit 4e90a94

Browse files
committed
temp
1 parent b1fa0a3 commit 4e90a94

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+9081
-2540
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,12 @@ console = "0.16.1"
3939
futures = "0.3.31"
4040
fxhash = "0.2.1"
4141
handlebars = "6.3"
42+
itertools = "0.14.0"
4243
log = "0.4.28"
4344
mdbook = "0.4.51"
4445
miette = {version = "7.6"}
46+
num-bigint = "0.4.6"
47+
num-traits = "0.2.19"
4548
once_cell = "1.21"
4649
parol_runtime = "4.1"
4750
pulldown-cmark = "0.13.0"

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ install:
7777
gen_sv:
7878
cargo run --bin veryl -- build
7979

80+
gen_ir:
81+
cargo run --bin veryl -- dump --ir
82+
8083
fmt_veryl:
8184
cargo run --bin veryl -- fmt
8285

crates/analyzer/Cargo.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ edition.workspace = true
1616
bimap = "0.6.3"
1717
daggy = "0.9.0"
1818
fxhash = {workspace = true}
19-
itertools = "0.14.0"
19+
indent = "0.1.1"
20+
itertools = {workspace = true}
2021
log = {workspace = true}
21-
num-bigint = "0.4.6"
22-
num-traits = "0.2.19"
22+
num-bigint = {workspace = true}
23+
num-traits = {workspace = true}
2324
smallvec = {workspace = true}
2425
strnum_bitwidth = {workspace = true}
2526
thiserror = {workspace = true}

crates/analyzer/src/analyzer.rs

Lines changed: 34 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,24 @@ use crate::HashMap;
22
use crate::analyzer::resource_table::PathId;
33
use crate::analyzer_error::AnalyzerError;
44
use crate::attribute_table;
5-
use crate::handlers::check_expression::CheckExpression;
5+
use crate::conv::{Context, Conv};
66
use crate::handlers::*;
7-
use crate::instance_history;
7+
use crate::ir::Ir;
88
use crate::msb_table;
99
use crate::namespace::Namespace;
1010
use crate::namespace_table;
1111
use crate::reference_table;
12-
use crate::symbol::{
13-
Direction, DocComment, Symbol, SymbolId, SymbolKind, TypeKind, VariableAffiliation,
14-
};
12+
use crate::symbol::{Affiliation, Direction, DocComment, Symbol, SymbolId, SymbolKind, TypeKind};
1513
use crate::symbol_path::SymbolPathNamespace;
1614
use crate::symbol_table;
1715
use crate::type_dag;
1816
use crate::var_ref::{
19-
AssignPosition, AssignPositionTree, AssignPositionType, ExpressionTargetType, VarRef,
20-
VarRefAffiliation, VarRefPath, VarRefType,
17+
ExpressionTargetType, VarRef, VarRefAffiliation,
18+
VarRefPath, VarRefType,
2119
};
22-
use itertools::Itertools;
2320
use std::path::Path;
2421
use veryl_metadata::{Build, EnvVar, Lint, Metadata};
2522
use veryl_parser::resource_table::{self, StrId};
26-
use veryl_parser::token_range::TokenRange;
2723
use veryl_parser::veryl_grammar_trait::*;
2824
use veryl_parser::veryl_token::{Token, TokenSource};
2925
use veryl_parser::veryl_walker::{Handler, VerylWalker};
@@ -64,28 +60,6 @@ impl VerylWalker for AnalyzerPass2 {
6460
}
6561
}
6662

67-
pub struct AnalyzerPass2Expression {
68-
check_expression: CheckExpression,
69-
}
70-
71-
impl AnalyzerPass2Expression {
72-
pub fn new(inst_context: Vec<TokenRange>) -> Self {
73-
AnalyzerPass2Expression {
74-
check_expression: CheckExpression::new(inst_context),
75-
}
76-
}
77-
78-
pub fn get_errors(&mut self) -> Vec<AnalyzerError> {
79-
self.check_expression.errors.drain(0..).collect()
80-
}
81-
}
82-
83-
impl VerylWalker for AnalyzerPass2Expression {
84-
fn get_handlers(&mut self) -> Option<Vec<(bool, &mut dyn Handler)>> {
85-
Some(vec![(true, &mut self.check_expression as &mut dyn Handler)])
86-
}
87-
}
88-
8963
pub struct AnalyzerPass3 {
9064
path: PathId,
9165
}
@@ -156,26 +130,6 @@ impl AnalyzerPass3 {
156130
));
157131
}
158132
}
159-
160-
let full_path = path.full_path();
161-
let symbol = symbol_table::get(*full_path.first().unwrap()).unwrap();
162-
163-
if positions.len() > 1 {
164-
for comb in positions.iter().combinations(2) {
165-
ret.append(&mut check_multiple_assignment(&symbol, comb[0], comb[1]));
166-
}
167-
}
168-
169-
let non_state_variable = match &symbol.kind {
170-
SymbolKind::Port(_) => true,
171-
SymbolKind::Variable(x) => x.affiliation != VariableAffiliation::StatementBlock,
172-
_ => {
173-
unreachable!()
174-
}
175-
};
176-
if non_state_variable {
177-
ret.append(&mut check_assign_position_tree(&symbol, positions));
178-
}
179133
}
180134

181135
ret
@@ -377,22 +331,45 @@ impl Analyzer {
377331
ret
378332
}
379333

334+
fn create_ir(input: &Veryl, build_opt: &Build) -> (Ir, Vec<AnalyzerError>) {
335+
let mut context = Context::default();
336+
context.instance_history.depth_limit = build_opt.instance_depth_limit;
337+
context.instance_history.total_limit = build_opt.instance_total_limit;
338+
let ir: Ir = Conv::conv(&mut context, input);
339+
ir.eval_assign(&mut context);
340+
let errors = context.drain_errors();
341+
(ir, errors)
342+
}
343+
380344
pub fn analyze_pass2<T: AsRef<Path>>(
381345
&self,
382346
project_name: &str,
383347
_path: T,
384348
input: &Veryl,
349+
ir: Option<&mut Ir>,
385350
) -> Vec<AnalyzerError> {
386351
let mut ret = Vec::new();
387352

388353
namespace_table::set_default(&[project_name.into()]);
389-
instance_history::clear();
390-
instance_history::set_depth_limit(self.build_opt.instance_depth_limit);
391-
instance_history::set_total_limit(self.build_opt.instance_total_limit);
392354
let mut pass2 = AnalyzerPass2::new(&self.build_opt, &self.lint_opt, &self.env_var);
393355
pass2.veryl(input);
394356
ret.append(&mut pass2.handlers.get_errors());
395357

358+
// some pass2 errors are generated in create_ir
359+
// The actual implementation is under crate/analyzer/src/ir/conv
360+
let mut ir_result = Self::create_ir(input, &self.build_opt);
361+
if let Some(x) = ir {
362+
x.append(&mut ir_result.0);
363+
ret.append(&mut ir_result.1);
364+
} else {
365+
// If IR is not used for successor stages, UnsupportedByIr should be ignored
366+
for error in ir_result.1 {
367+
if !matches!(error, AnalyzerError::UnsupportedByIr { .. }) {
368+
ret.push(error);
369+
}
370+
}
371+
}
372+
396373
ret
397374
}
398375

@@ -572,9 +549,9 @@ fn traverse_assignable_symbol(id: SymbolId, path: &VarRefPath) -> Vec<VarRefPath
572549
}
573550
}
574551
SymbolKind::Variable(x)
575-
if x.affiliation == VariableAffiliation::Module
576-
|| x.affiliation == VariableAffiliation::Function
577-
|| x.affiliation == VariableAffiliation::StatementBlock =>
552+
if x.affiliation == Affiliation::Module
553+
|| x.affiliation == Affiliation::Function
554+
|| x.affiliation == Affiliation::StatementBlock =>
578555
{
579556
if let TypeKind::UserDefined(ref x) = x.r#type.kind {
580557
if let Some(id) = x.symbol {
@@ -590,98 +567,3 @@ fn traverse_assignable_symbol(id: SymbolId, path: &VarRefPath) -> Vec<VarRefPath
590567

591568
vec![]
592569
}
593-
594-
fn check_multiple_assignment(
595-
symbol: &Symbol,
596-
x: &(AssignPosition, bool),
597-
y: &(AssignPosition, bool),
598-
) -> Vec<AnalyzerError> {
599-
let x_pos = &x.0;
600-
let y_pos = &y.0;
601-
let x_partial = &x.1;
602-
let y_partial = &y.1;
603-
let mut ret = Vec::new();
604-
let len = x_pos.0.len().min(y_pos.0.len());
605-
606-
let x_maybe = x_pos.0.last().unwrap().is_maybe();
607-
let y_maybe = y_pos.0.last().unwrap().is_maybe();
608-
if x_maybe || y_maybe {
609-
return vec![];
610-
}
611-
612-
let x_define = x_pos.0.last().unwrap().define_context();
613-
let y_define = y_pos.0.last().unwrap().define_context();
614-
615-
// If x and y is in exclusive define context, they are not conflict.
616-
if x_define.exclusive(y_define) {
617-
return vec![];
618-
}
619-
620-
// Earyl return to avoid calling AnalyzerError constructor
621-
for i in 0..len {
622-
let x_type = &x_pos.0[i];
623-
let y_type = &y_pos.0[i];
624-
if x_type != y_type {
625-
match x_type {
626-
AssignPositionType::DeclarationBranch { .. }
627-
| AssignPositionType::Declaration { .. } => (),
628-
_ => return vec![],
629-
}
630-
}
631-
}
632-
633-
for i in 0..len {
634-
let x_type = &x_pos.0[i];
635-
let y_type = &y_pos.0[i];
636-
if x_type != y_type {
637-
match x_type {
638-
AssignPositionType::DeclarationBranch { .. }
639-
| AssignPositionType::Declaration { .. } => {
640-
if !x_partial | !y_partial {
641-
ret.push(AnalyzerError::multiple_assignment(
642-
&symbol.token.to_string(),
643-
&symbol.token.into(),
644-
&x_pos.0.last().unwrap().token().into(),
645-
&y_pos.0.last().unwrap().token().into(),
646-
));
647-
}
648-
}
649-
_ => (),
650-
}
651-
}
652-
}
653-
654-
ret
655-
}
656-
657-
fn check_assign_position_tree(
658-
symbol: &Symbol,
659-
positions: &[(AssignPosition, bool)],
660-
) -> Vec<AnalyzerError> {
661-
let mut ret = Vec::new();
662-
663-
let mut tree = AssignPositionTree::default();
664-
for x in positions {
665-
let pos = &x.0;
666-
667-
tree.add(pos.clone());
668-
}
669-
670-
if let Some(token) = tree.check_always_comb_uncovered() {
671-
ret.push(AnalyzerError::uncovered_branch(
672-
&symbol.token.to_string(),
673-
&symbol.token.into(),
674-
&token.into(),
675-
));
676-
}
677-
678-
if let Some(token) = tree.check_always_ff_missing_reset() {
679-
ret.push(AnalyzerError::missing_reset_statement(
680-
&symbol.token.to_string(),
681-
&symbol.token.into(),
682-
&token.into(),
683-
));
684-
}
685-
686-
ret
687-
}

0 commit comments

Comments
 (0)