@@ -2,28 +2,24 @@ 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;
1816use crate :: var_ref:: {
19- AssignPosition , AssignPositionTree , AssignPositionType , ExpressionTargetType , VarRef ,
20- VarRefAffiliation , VarRefPath , VarRefType ,
17+ AssignPosition , AssignPositionTree , ExpressionTargetType , VarRef , VarRefAffiliation ,
18+ VarRefPath , VarRefType ,
2119} ;
22- use itertools:: Itertools ;
2320use std:: path:: Path ;
2421use veryl_metadata:: { Build , EnvVar , Lint , Metadata } ;
2522use veryl_parser:: resource_table:: { self , StrId } ;
26- use veryl_parser:: token_range:: TokenRange ;
2723use veryl_parser:: veryl_grammar_trait:: * ;
2824use veryl_parser:: veryl_token:: { Token , TokenSource } ;
2925use 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-
8963pub struct AnalyzerPass3 {
9064 path : PathId ,
9165}
@@ -160,15 +134,9 @@ impl AnalyzerPass3 {
160134 let full_path = path. full_path ( ) ;
161135 let symbol = symbol_table:: get ( * full_path. first ( ) . unwrap ( ) ) . unwrap ( ) ;
162136
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-
169137 let non_state_variable = match & symbol. kind {
170138 SymbolKind :: Port ( _) => true ,
171- SymbolKind :: Variable ( x) => x. affiliation != VariableAffiliation :: StatementBlock ,
139+ SymbolKind :: Variable ( x) => x. affiliation != Affiliation :: StatementBlock ,
172140 _ => {
173141 unreachable ! ( )
174142 }
@@ -377,22 +345,45 @@ impl Analyzer {
377345 ret
378346 }
379347
348+ fn create_ir ( input : & Veryl , build_opt : & Build ) -> ( Ir , Vec < AnalyzerError > ) {
349+ let mut context = Context :: default ( ) ;
350+ context. instance_history . depth_limit = build_opt. instance_depth_limit ;
351+ context. instance_history . total_limit = build_opt. instance_total_limit ;
352+ let ir: Ir = Conv :: conv ( & mut context, input) ;
353+ ir. eval_assign ( & mut context) ;
354+ let errors = context. drain_errors ( ) ;
355+ ( ir, errors)
356+ }
357+
380358 pub fn analyze_pass2 < T : AsRef < Path > > (
381359 & self ,
382360 project_name : & str ,
383361 _path : T ,
384362 input : & Veryl ,
363+ ir : Option < & mut Ir > ,
385364 ) -> Vec < AnalyzerError > {
386365 let mut ret = Vec :: new ( ) ;
387366
388367 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 ) ;
392368 let mut pass2 = AnalyzerPass2 :: new ( & self . build_opt , & self . lint_opt , & self . env_var ) ;
393369 pass2. veryl ( input) ;
394370 ret. append ( & mut pass2. handlers . get_errors ( ) ) ;
395371
372+ // some pass2 errors are generated in create_ir
373+ // The actual implementation is under crate/analyzer/src/ir/conv
374+ let mut ir_result = Self :: create_ir ( input, & self . build_opt ) ;
375+ if let Some ( x) = ir {
376+ x. append ( & mut ir_result. 0 ) ;
377+ ret. append ( & mut ir_result. 1 ) ;
378+ } else {
379+ // If IR is not used for successor stages, UnsupportedByIr should be ignored
380+ for error in ir_result. 1 {
381+ if !matches ! ( error, AnalyzerError :: UnsupportedByIr { .. } ) {
382+ ret. push ( error) ;
383+ }
384+ }
385+ }
386+
396387 ret
397388 }
398389
@@ -572,9 +563,9 @@ fn traverse_assignable_symbol(id: SymbolId, path: &VarRefPath) -> Vec<VarRefPath
572563 }
573564 }
574565 SymbolKind :: Variable ( x)
575- if x. affiliation == VariableAffiliation :: Module
576- || x. affiliation == VariableAffiliation :: Function
577- || x. affiliation == VariableAffiliation :: StatementBlock =>
566+ if x. affiliation == Affiliation :: Module
567+ || x. affiliation == Affiliation :: Function
568+ || x. affiliation == Affiliation :: StatementBlock =>
578569 {
579570 if let TypeKind :: UserDefined ( ref x) = x. r#type . kind {
580571 if let Some ( id) = x. symbol {
@@ -591,69 +582,6 @@ fn traverse_assignable_symbol(id: SymbolId, path: &VarRefPath) -> Vec<VarRefPath
591582 vec ! [ ]
592583}
593584
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-
657585fn check_assign_position_tree (
658586 symbol : & Symbol ,
659587 positions : & [ ( AssignPosition , bool ) ] ,
@@ -667,14 +595,6 @@ fn check_assign_position_tree(
667595 tree. add ( pos. clone ( ) ) ;
668596 }
669597
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-
678598 if let Some ( token) = tree. check_always_ff_missing_reset ( ) {
679599 ret. push ( AnalyzerError :: missing_reset_statement (
680600 & symbol. token . to_string ( ) ,
0 commit comments