1
1
use crate :: CompilerOptions ;
2
2
use ast:: token:: TokenKind ;
3
3
use codegen:: { context:: context:: CodeGenContext , options:: OutputKind } ;
4
- use diagcentral:: display_single_cusotm_diag ;
4
+ use diagcentral:: { display_single_custom_diag , reporter :: DiagReporter } ;
5
5
use lexer:: Lexer ;
6
6
use parser:: Parser ;
7
7
use resolver:: { Resolver , Visiting , generate_module_id, moduleloader:: ModuleLoaderOptions } ;
8
- use std:: { cell:: RefCell , env, mem, process:: exit, rc:: Rc } ;
9
- use typed_ast:: TypedProgramTree ;
10
-
11
- fn get_program_trees ( options : & CompilerOptions , file_path : String ) -> Vec < ( String , Rc < RefCell < TypedProgramTree > > ) > {
8
+ use static_analyzer:: context:: AnalysisContext ;
9
+ use std:: { cell:: RefCell , env, process:: exit, rc:: Rc } ;
10
+ use typed_ast:: { ModuleID , TypedProgramTree } ;
11
+
12
+ fn get_program_trees (
13
+ options : & CompilerOptions ,
14
+ file_path : String ,
15
+ ) -> ( Vec < ( String , ModuleID , Rc < RefCell < TypedProgramTree > > ) > , Rc < Resolver > ) {
12
16
let file_content = utils:: fs:: read_file ( file_path. clone ( ) ) . 0 ;
13
17
let mut lexer = Lexer :: new ( file_content, file_path. clone ( ) ) ;
14
18
let mut parser = Parser :: new ( lexer. tokenize ( ) , file_path. clone ( ) ) ;
@@ -37,24 +41,36 @@ fn get_program_trees(options: &CompilerOptions, file_path: String) -> Vec<(Strin
37
41
exit ( 1 ) ;
38
42
}
39
43
40
- let final_program_trees: Vec < ( String , Rc < RefCell < TypedProgramTree > > ) > ;
44
+ let final_program_trees: Vec < ( String , ModuleID , Rc < RefCell < TypedProgramTree > > ) > ;
41
45
let program_trees = resolver. program_trees . lock ( ) . unwrap ( ) ;
46
+
47
+ {
48
+ for ( _, _, typed_program_tree) in program_trees. iter ( ) {
49
+ let mut typed_program_tree_borrowed = typed_program_tree. borrow_mut ( ) ;
50
+ let mut analyzer = AnalysisContext :: new ( & resolver, module_id, & mut typed_program_tree_borrowed) ;
51
+ analyzer. analyze ( ) ;
52
+ if analyzer. reporter . has_errors ( ) {
53
+ DiagReporter :: display ( & analyzer. reporter ) ;
54
+ exit ( 1 ) ;
55
+ }
56
+ }
57
+ }
42
58
final_program_trees = program_trees. clone ( ) ;
43
59
drop ( program_trees) ;
44
60
45
- final_program_trees
61
+ ( final_program_trees, Rc :: new ( resolver ) )
46
62
}
47
63
48
64
pub ( crate ) fn command_run ( options : CompilerOptions , file_path : Option < String > ) {
49
- let context = CodeGenContext :: new ( options. to_compiler_options ( ) , OutputKind :: None ) ;
65
+ let ( program_trees, resolver_rc) = get_program_trees ( & options, file_path. unwrap ( ) ) ;
66
+
67
+ let context = CodeGenContext :: new ( options. to_compiler_options ( ) , OutputKind :: None , resolver_rc) ;
68
+ context. compile_modules ( program_trees) ;
50
69
51
70
let mut temp = env:: temp_dir ( ) ;
52
71
temp. push ( "path" ) ;
53
72
let temp_file_path = temp. to_str ( ) . unwrap ( ) . to_string ( ) ;
54
73
55
- let program_trees = get_program_trees ( & options, file_path. unwrap ( ) ) ;
56
- context. compile_modules ( program_trees) ;
57
-
58
74
context. emit_exec ( temp_file_path. clone ( ) ) ;
59
75
if temp. exists ( ) {
60
76
std:: fs:: remove_file ( temp_file_path) . unwrap ( ) ;
@@ -63,12 +79,16 @@ pub(crate) fn command_run(options: CompilerOptions, file_path: Option<String>) {
63
79
64
80
pub ( crate ) fn command_emit_llvm ( options : CompilerOptions , file_path : Option < String > , output_path : Option < String > ) {
65
81
let output_path = output_path. unwrap_or_else ( || {
66
- display_single_cusotm_diag ! ( "Output directory must be specified to generate llvm-ir." . to_string( ) ) ;
82
+ display_single_custom_diag ! ( "Output directory must be specified to generate llvm-ir." . to_string( ) ) ;
67
83
} ) ;
68
84
69
- let context = CodeGenContext :: new ( options. to_compiler_options ( ) , OutputKind :: LlvmIr ( output_path ) ) ;
85
+ let ( program_trees , resolver_rc ) = get_program_trees ( & options, file_path . unwrap ( ) ) ;
70
86
71
- let program_trees = get_program_trees ( & options, file_path. unwrap ( ) ) ;
87
+ let context = CodeGenContext :: new (
88
+ options. to_compiler_options ( ) ,
89
+ OutputKind :: LlvmIr ( output_path) ,
90
+ resolver_rc,
91
+ ) ;
72
92
context. compile_modules ( program_trees) ;
73
93
}
74
94
0 commit comments