1
+ use crate :: CompilerOptions ;
1
2
use ast:: token:: TokenKind ;
3
+ use codegen:: { context:: context:: CodeGenContext , options:: OutputKind } ;
4
+ use diagcentral:: display_single_cusotm_diag;
2
5
use lexer:: Lexer ;
6
+ use parser:: Parser ;
7
+ use resolver:: { Resolver , Visiting , generate_module_id, moduleloader:: ModuleLoaderOptions } ;
8
+ use std:: { 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 < TypedProgramTree > ) > {
12
+ let file_content = utils:: fs:: read_file ( file_path. clone ( ) ) . 0 ;
13
+ let mut lexer = Lexer :: new ( file_content, file_path. clone ( ) ) ;
14
+ let mut parser = Parser :: new ( lexer. tokenize ( ) , file_path. clone ( ) ) ;
15
+
16
+ let node = match parser. parse ( ) {
17
+ Ok ( node) => node,
18
+ Err ( errors) => {
19
+ parser. display_parser_errors ( errors. clone ( ) ) ;
20
+ exit ( 1 ) ;
21
+ }
22
+ } ;
23
+
24
+ let module_loader_opts = ModuleLoaderOptions {
25
+ stdlib_path : options. stdlib . clone ( ) ,
26
+ source_dirs : options. source_dirs . clone ( ) ,
27
+ } ;
28
+
29
+ let mut resolver = Resolver :: new ( module_loader_opts, file_path. clone ( ) ) ;
30
+ let module_id = generate_module_id ( ) ;
31
+ match resolver. resolve_module ( module_id, node. as_program ( ) , & mut Visiting :: new ( ) , true ) {
32
+ Some ( ..) => { }
33
+ None => unreachable ! ( ) ,
34
+ } ;
35
+ if resolver. reporter . has_errors ( ) {
36
+ resolver. reporter . display ( ) ;
37
+ exit ( 1 ) ;
38
+ }
3
39
4
- use crate :: CompilerOptions ;
40
+ let final_program_trees: Vec < ( String , Rc < TypedProgramTree > ) > ;
41
+ let mut program_trees = resolver. program_trees . lock ( ) . unwrap ( ) ;
42
+ final_program_trees = mem:: take ( & mut program_trees) ;
43
+ drop ( program_trees) ;
5
44
6
- pub ( crate ) fn command_run ( compiler_options : CompilerOptions , file_path : Option < String > ) {
7
- // let context = CodeGenContext::new(options, output_kind);
8
- todo ! ( )
45
+ final_program_trees
9
46
}
10
47
11
- pub ( crate ) fn command_emit_llvm (
12
- compiler_options : CompilerOptions ,
13
- file_path : Option < String > ,
14
- output_path : Option < String > ,
15
- ) {
16
- // let context = CodeGenContext::new(options, output_kind);
17
- todo ! ( )
48
+ pub ( crate ) fn command_run ( options : CompilerOptions , file_path : Option < String > ) {
49
+ let context = CodeGenContext :: new ( options. to_compiler_options ( ) , OutputKind :: None ) ;
50
+
51
+ let mut temp = env:: temp_dir ( ) ;
52
+ temp. push ( "path" ) ;
53
+ let temp_file_path = temp. to_str ( ) . unwrap ( ) . to_string ( ) ;
54
+
55
+ let program_trees = get_program_trees ( & options, file_path. unwrap ( ) ) ;
56
+ context. compile_modules ( program_trees) ;
57
+
58
+ context. emit_exec ( temp_file_path. clone ( ) ) ;
59
+ if temp. exists ( ) {
60
+ std:: fs:: remove_file ( temp_file_path) . unwrap ( ) ;
61
+ }
18
62
}
19
63
20
- pub ( crate ) fn command_emit_asm (
21
- compiler_options : CompilerOptions ,
22
- file_path : Option < String > ,
23
- output_path : Option < String > ,
24
- ) {
64
+ pub ( crate ) fn command_emit_llvm ( options : CompilerOptions , file_path : Option < String > , output_path : Option < String > ) {
65
+ let output_path = output_path. unwrap_or_else ( || {
66
+ display_single_cusotm_diag ! ( "Output directory must be specified to generate llvm-ir." . to_string( ) ) ;
67
+ } ) ;
68
+
69
+ let context = CodeGenContext :: new ( options. to_compiler_options ( ) , OutputKind :: LlvmIr ( output_path) ) ;
70
+
71
+ let program_trees = get_program_trees ( & options, file_path. unwrap ( ) ) ;
72
+ context. compile_modules ( program_trees) ;
73
+ }
74
+
75
+ pub ( crate ) fn command_emit_asm ( options : CompilerOptions , file_path : Option < String > , output_path : Option < String > ) {
25
76
// let context = CodeGenContext::new(options, output_kind);
26
77
todo ! ( )
27
78
}
28
79
29
- pub ( crate ) fn command_build ( compiler_options : CompilerOptions , file_path : Option < String > , output_path : Option < String > ) {
80
+ pub ( crate ) fn command_build ( options : CompilerOptions , file_path : Option < String > , output_path : Option < String > ) {
30
81
// let context = CodeGenContext::new(options, output_kind);
31
82
todo ! ( )
32
83
}
33
84
34
- pub ( crate ) fn command_object (
35
- compiler_options : CompilerOptions ,
36
- file_path : Option < String > ,
37
- output_path : Option < String > ,
38
- ) {
85
+ pub ( crate ) fn command_object ( options : CompilerOptions , file_path : Option < String > , output_path : Option < String > ) {
39
86
// let context = CodeGenContext::new(options, output_kind);
40
87
todo ! ( )
41
88
}
42
89
43
- pub ( crate ) fn command_dylib ( compiler_options : CompilerOptions , file_path : Option < String > , output_path : Option < String > ) {
90
+ pub ( crate ) fn command_dylib ( options : CompilerOptions , file_path : Option < String > , output_path : Option < String > ) {
44
91
// let context = CodeGenContext::new(options, output_kind);
45
92
todo ! ( )
46
93
}
@@ -62,17 +109,17 @@ pub(crate) fn command_lex_only(file_path: String) {
62
109
}
63
110
64
111
pub ( crate ) fn command_parse_only ( file_path : String ) {
65
- // let (file_content, file_name) = read_file(file_path.clone());
66
- // let mut lexer = Lexer::new(file_content, file_name);
67
-
68
- // match CyrusParser::new(&mut lexer).parse() {
69
- // Ok(result) => println!("{:#?}", result),
70
- // Err(errors ) => {
71
- // for err in errors {
72
- // err.print( );
73
- // }
74
- // }
75
- // }
112
+ let ( file_content, file_name) = utils :: fs :: read_file ( file_path. clone ( ) ) ;
113
+ let mut lexer = Lexer :: new ( file_content, file_name. clone ( ) ) ;
114
+ let mut parser = Parser :: new ( lexer . tokenize ( ) , file_name ) ;
115
+
116
+ match parser . parse ( ) {
117
+ Ok ( result ) => println ! ( "{:#?}" , result ) ,
118
+ Err ( errors) => {
119
+ parser . display_parser_errors ( errors . clone ( ) ) ;
120
+ exit ( 1 ) ;
121
+ }
122
+ }
76
123
}
77
124
78
125
pub ( crate ) fn command_syntactic_only ( file_path : String ) {
0 commit comments