@@ -2,28 +2,21 @@ use crate::HashMap;
22use crate :: analyzer:: resource_table:: PathId ;
33use crate :: analyzer_error:: AnalyzerError ;
44use crate :: attribute_table;
5- use crate :: handlers :: check_expression :: CheckExpression ;
5+ use crate :: conv :: { Context , Conv } ;
66use crate :: handlers:: * ;
7- use crate :: instance_history ;
7+ use crate :: ir :: Ir ;
88use crate :: msb_table;
99use crate :: namespace:: Namespace ;
1010use crate :: namespace_table;
1111use 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 } ;
1513use crate :: symbol_path:: SymbolPathNamespace ;
1614use crate :: symbol_table;
1715use crate :: type_dag;
18- use crate :: var_ref:: {
19- AssignPosition , AssignPositionTree , AssignPositionType , ExpressionTargetType , VarRef ,
20- VarRefAffiliation , VarRefPath , VarRefType ,
21- } ;
22- use itertools:: Itertools ;
16+ use crate :: var_ref:: { ExpressionTargetType , VarRef , VarRefAffiliation , VarRefPath , VarRefType } ;
2317use std:: path:: Path ;
2418use veryl_metadata:: { Build , EnvVar , Lint , Metadata } ;
2519use veryl_parser:: resource_table:: { self , StrId } ;
26- use veryl_parser:: token_range:: TokenRange ;
2720use veryl_parser:: veryl_grammar_trait:: * ;
2821use veryl_parser:: veryl_token:: { Token , TokenSource } ;
2922use veryl_parser:: veryl_walker:: { Handler , VerylWalker } ;
@@ -64,28 +57,6 @@ impl VerylWalker for AnalyzerPass2 {
6457 }
6558}
6659
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-
8960pub struct AnalyzerPass3 {
9061 path : PathId ,
9162}
@@ -163,26 +134,6 @@ impl AnalyzerPass3 {
163134 ) ) ;
164135 }
165136 }
166-
167- let full_path = path. full_path ( ) ;
168- let symbol = symbol_table:: get ( * full_path. first ( ) . unwrap ( ) ) . unwrap ( ) ;
169-
170- if positions. len ( ) > 1 {
171- for comb in positions. iter ( ) . combinations ( 2 ) {
172- ret. append ( & mut check_multiple_assignment ( & symbol, comb[ 0 ] , comb[ 1 ] ) ) ;
173- }
174- }
175-
176- let non_state_variable = match & symbol. kind {
177- SymbolKind :: Port ( _) => true ,
178- SymbolKind :: Variable ( x) => x. affiliation != VariableAffiliation :: StatementBlock ,
179- _ => {
180- unreachable ! ( )
181- }
182- } ;
183- if non_state_variable {
184- ret. append ( & mut check_assign_position_tree ( & symbol, positions) ) ;
185- }
186137 }
187138
188139 ret
@@ -384,22 +335,45 @@ impl Analyzer {
384335 ret
385336 }
386337
338+ fn create_ir ( input : & Veryl , build_opt : & Build ) -> ( Ir , Vec < AnalyzerError > ) {
339+ let mut context = Context :: default ( ) ;
340+ context. instance_history . depth_limit = build_opt. instance_depth_limit ;
341+ context. instance_history . total_limit = build_opt. instance_total_limit ;
342+ let ir: Ir = Conv :: conv ( & mut context, input) ;
343+ ir. eval_assign ( & mut context) ;
344+ let errors = context. drain_errors ( ) ;
345+ ( ir, errors)
346+ }
347+
387348 pub fn analyze_pass2 < T : AsRef < Path > > (
388349 & self ,
389350 project_name : & str ,
390351 _path : T ,
391352 input : & Veryl ,
353+ ir : Option < & mut Ir > ,
392354 ) -> Vec < AnalyzerError > {
393355 let mut ret = Vec :: new ( ) ;
394356
395357 namespace_table:: set_default ( & [ project_name. into ( ) ] ) ;
396- instance_history:: clear ( ) ;
397- instance_history:: set_depth_limit ( self . build_opt . instance_depth_limit ) ;
398- instance_history:: set_total_limit ( self . build_opt . instance_total_limit ) ;
399358 let mut pass2 = AnalyzerPass2 :: new ( & self . build_opt , & self . lint_opt , & self . env_var ) ;
400359 pass2. veryl ( input) ;
401360 ret. append ( & mut pass2. handlers . get_errors ( ) ) ;
402361
362+ // some pass2 errors are generated in create_ir
363+ // The actual implementation is under crate/analyzer/src/ir/conv
364+ let mut ir_result = Self :: create_ir ( input, & self . build_opt ) ;
365+ if let Some ( x) = ir {
366+ x. append ( & mut ir_result. 0 ) ;
367+ ret. append ( & mut ir_result. 1 ) ;
368+ } else {
369+ // If IR is not used for successor stages, UnsupportedByIr should be ignored
370+ for error in ir_result. 1 {
371+ if !matches ! ( error, AnalyzerError :: UnsupportedByIr { .. } ) {
372+ ret. push ( error) ;
373+ }
374+ }
375+ }
376+
403377 ret
404378 }
405379
@@ -579,9 +553,9 @@ fn traverse_assignable_symbol(id: SymbolId, path: &VarRefPath) -> Vec<VarRefPath
579553 }
580554 }
581555 SymbolKind :: Variable ( x)
582- if x. affiliation == VariableAffiliation :: Module
583- || x. affiliation == VariableAffiliation :: Function
584- || x. affiliation == VariableAffiliation :: StatementBlock =>
556+ if x. affiliation == Affiliation :: Module
557+ || x. affiliation == Affiliation :: Function
558+ || x. affiliation == Affiliation :: StatementBlock =>
585559 {
586560 if let TypeKind :: UserDefined ( ref x) = x. r#type . kind {
587561 if let Some ( id) = x. symbol {
@@ -597,98 +571,3 @@ fn traverse_assignable_symbol(id: SymbolId, path: &VarRefPath) -> Vec<VarRefPath
597571
598572 vec ! [ ]
599573}
600-
601- fn check_multiple_assignment (
602- symbol : & Symbol ,
603- x : & ( AssignPosition , bool ) ,
604- y : & ( AssignPosition , bool ) ,
605- ) -> Vec < AnalyzerError > {
606- let x_pos = & x. 0 ;
607- let y_pos = & y. 0 ;
608- let x_partial = & x. 1 ;
609- let y_partial = & y. 1 ;
610- let mut ret = Vec :: new ( ) ;
611- let len = x_pos. 0 . len ( ) . min ( y_pos. 0 . len ( ) ) ;
612-
613- let x_maybe = x_pos. 0 . last ( ) . unwrap ( ) . is_maybe ( ) ;
614- let y_maybe = y_pos. 0 . last ( ) . unwrap ( ) . is_maybe ( ) ;
615- if x_maybe || y_maybe {
616- return vec ! [ ] ;
617- }
618-
619- let x_define = x_pos. 0 . last ( ) . unwrap ( ) . define_context ( ) ;
620- let y_define = y_pos. 0 . last ( ) . unwrap ( ) . define_context ( ) ;
621-
622- // If x and y is in exclusive define context, they are not conflict.
623- if x_define. exclusive ( y_define) {
624- return vec ! [ ] ;
625- }
626-
627- // Earyl return to avoid calling AnalyzerError constructor
628- for i in 0 ..len {
629- let x_type = & x_pos. 0 [ i] ;
630- let y_type = & y_pos. 0 [ i] ;
631- if x_type != y_type {
632- match x_type {
633- AssignPositionType :: DeclarationBranch { .. }
634- | AssignPositionType :: Declaration { .. } => ( ) ,
635- _ => return vec ! [ ] ,
636- }
637- }
638- }
639-
640- for i in 0 ..len {
641- let x_type = & x_pos. 0 [ i] ;
642- let y_type = & y_pos. 0 [ i] ;
643- if x_type != y_type {
644- match x_type {
645- AssignPositionType :: DeclarationBranch { .. }
646- | AssignPositionType :: Declaration { .. } => {
647- if !x_partial | !y_partial {
648- ret. push ( AnalyzerError :: multiple_assignment (
649- & symbol. token . to_string ( ) ,
650- & symbol. token . into ( ) ,
651- & x_pos. 0 . last ( ) . unwrap ( ) . token ( ) . into ( ) ,
652- & y_pos. 0 . last ( ) . unwrap ( ) . token ( ) . into ( ) ,
653- ) ) ;
654- }
655- }
656- _ => ( ) ,
657- }
658- }
659- }
660-
661- ret
662- }
663-
664- fn check_assign_position_tree (
665- symbol : & Symbol ,
666- positions : & [ ( AssignPosition , bool ) ] ,
667- ) -> Vec < AnalyzerError > {
668- let mut ret = Vec :: new ( ) ;
669-
670- let mut tree = AssignPositionTree :: default ( ) ;
671- for x in positions {
672- let pos = & x. 0 ;
673-
674- tree. add ( pos. clone ( ) ) ;
675- }
676-
677- if let Some ( token) = tree. check_always_comb_uncovered ( ) {
678- ret. push ( AnalyzerError :: uncovered_branch (
679- & symbol. token . to_string ( ) ,
680- & symbol. token . into ( ) ,
681- & token. into ( ) ,
682- ) ) ;
683- }
684-
685- if let Some ( token) = tree. check_always_ff_missing_reset ( ) {
686- ret. push ( AnalyzerError :: missing_reset_statement (
687- & symbol. token . to_string ( ) ,
688- & symbol. token . into ( ) ,
689- & token. into ( ) ,
690- ) ) ;
691- }
692-
693- ret
694- }
0 commit comments