rukalang/driver/
passes.rs1use std::convert::Infallible;
4use std::path::Path;
5
6use crate::check::{self, CheckedProgram};
7use crate::codegen;
8use crate::elab;
9use crate::hir::{self, HirProgram};
10use crate::meta;
11use crate::mir::{self, MirProgram};
12use crate::pass::{Pass, PassContext, PassTiming};
13use crate::source_index::build_function_line_map;
14use crate::syntax::ast::Program;
15
16pub(super) struct ExpandProgramPass<'a> {
26 pub(super) program: &'a Program,
28}
29
30impl<'a> Pass for ExpandProgramPass<'a> {
31 type In = ();
32 type Out = Program;
33 type Error = meta::MetaEvalError;
34
35 const NAME: &'static str = "meta.expand_program";
36
37 fn run(&mut self, _input: Self::In, _cx: &mut PassContext) -> Result<Self::Out, Self::Error> {
38 meta::expand_program(self.program)
39 }
40}
41
42pub(super) struct ElaborateProgramPass<'a> {
51 pub(super) program: &'a Program,
53 pub(super) subpass_timings: Vec<PassTiming>,
55}
56
57impl<'a> Pass for ElaborateProgramPass<'a> {
58 type In = ();
59 type Out = Program;
60 type Error = elab::ElabError;
61
62 const NAME: &'static str = "elab.elaborate_program";
63
64 fn run(&mut self, _input: Self::In, _cx: &mut PassContext) -> Result<Self::Out, Self::Error> {
65 let (program, timings) = elab::elaborate_program_with_timings(self.program)?;
66 self.subpass_timings = timings;
67 Ok(program)
68 }
69}
70
71impl<'a> ElaborateProgramPass<'a> {
72 pub(super) fn take_subpass_timings(&mut self) -> Vec<PassTiming> {
74 std::mem::take(&mut self.subpass_timings)
75 }
76}
77
78pub(super) struct LowerHirPass<'a> {
87 pub(super) program: &'a Program,
89}
90
91impl<'a> Pass for LowerHirPass<'a> {
92 type In = ();
93 type Out = HirProgram;
94 type Error = Infallible;
95
96 const NAME: &'static str = "hir.lower_program";
97
98 fn run(&mut self, _input: Self::In, _cx: &mut PassContext) -> Result<Self::Out, Self::Error> {
99 Ok(hir::lower::lower_program(self.program))
100 }
101}
102
103pub(super) struct CheckProgramPass<'a> {
112 pub(super) program: &'a HirProgram,
114}
115
116impl<'a> Pass for CheckProgramPass<'a> {
117 type In = ();
118 type Out = CheckedProgram;
119 type Error = check::CheckError;
120
121 const NAME: &'static str = "check.check_program";
122
123 fn run(&mut self, _input: Self::In, _cx: &mut PassContext) -> Result<Self::Out, Self::Error> {
124 check::check_program(self.program)
125 }
126}
127
128pub(super) struct LowerMirPass<'a> {
137 pub(super) hir: &'a HirProgram,
139 pub(super) checked: &'a CheckedProgram,
141}
142
143impl<'a> Pass for LowerMirPass<'a> {
144 type In = ();
145 type Out = MirProgram;
146 type Error = mir::lower::LowerError;
147
148 const NAME: &'static str = "mir.lower_program";
149
150 fn run(&mut self, _input: Self::In, _cx: &mut PassContext) -> Result<Self::Out, Self::Error> {
151 mir::lower::lower_program(self.hir, self.checked)
152 }
153}
154
155pub(super) struct EmitRustPass<'a> {
164 pub(super) mir: &'a MirProgram,
166 pub(super) source_file: &'a Path,
168 pub(super) source_text: &'a str,
170}
171
172impl<'a> Pass for EmitRustPass<'a> {
173 type In = ();
174 type Out = String;
175 type Error = codegen::rust::CodegenError;
176
177 const NAME: &'static str = "codegen.rust.emit_program";
178
179 fn run(&mut self, _input: Self::In, _cx: &mut PassContext) -> Result<Self::Out, Self::Error> {
180 let function_lines = build_function_line_map(self.source_text);
181 codegen::rust::emit_program_with_function_lines(self.mir, self.source_file, &function_lines)
182 }
183}
184
185pub(super) struct EmitWasmPass<'a> {
194 pub(super) mir: &'a MirProgram,
196 pub(super) source_text: &'a str,
198}
199
200impl<'a> Pass for EmitWasmPass<'a> {
201 type In = ();
202 type Out = codegen::wasm::WasmArtifacts;
203 type Error = Infallible;
204
205 const NAME: &'static str = "codegen.wasm.emit_program";
206
207 fn run(&mut self, _input: Self::In, _cx: &mut PassContext) -> Result<Self::Out, Self::Error> {
208 let function_lines = build_function_line_map(self.source_text);
209 Ok(codegen::wasm::emit_program_best_effort_with_options(
210 self.mir,
211 codegen::wasm::EmitOptions {
212 assert_no_leaks_at_run_main: true,
213 function_lines,
214 },
215 ))
216 }
217}