microsoft/qdk

Public

mirrored from https://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
fc18cc36fceb28438976110616dfee7b8b01bd85

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

source/compiler/qsc/src/codegen.rs

219lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4#[cfg(test)]
5mod tests;
6
7pub mod qsharp {
8 pub use qsc_codegen::qsharp::write_package_string;
9 pub use qsc_codegen::qsharp::write_stmt_string;
10}
11
12pub mod qir {
13 use qsc_codegen::qir::{fir_to_qir, fir_to_rir};
14
15 use qsc_data_structures::{
16 error::WithSource, language_features::LanguageFeatures, source::SourceMap,
17 target::TargetCapabilityFlags,
18 };
19 use qsc_frontend::compile::{Dependencies, PackageStore};
20 use qsc_partial_eval::{PartialEvalConfig, ProgramEntry};
21 use qsc_passes::{PackageType, PassContext};
22
23 use crate::interpret::Error;
24 pub fn get_qir_from_ast(
25 store: &mut PackageStore,
26 dependencies: &Dependencies,
27 ast_package: qsc_ast::ast::Package,
28 sources: SourceMap,
29 capabilities: TargetCapabilityFlags,
30 ) -> Result<String, Vec<Error>> {
31 if capabilities == TargetCapabilityFlags::all() {
32 return Err(vec![Error::UnsupportedRuntimeCapabilities]);
33 }
34
35 let (unit, errors) = crate::compile::compile_ast(
36 store,
37 dependencies,
38 ast_package,
39 sources,
40 PackageType::Exe,
41 capabilities,
42 );
43
44 // Ensure it compiles before trying to add it to the store.
45 if !errors.is_empty() {
46 return Err(errors.iter().map(|e| Error::Compile(e.clone())).collect());
47 }
48
49 let package_id = store.insert(unit);
50 let (fir_store, fir_package_id) = qsc_passes::lower_hir_to_fir(store, package_id);
51 let package = fir_store.get(fir_package_id);
52 let entry = ProgramEntry {
53 exec_graph: package.entry_exec_graph.clone(),
54 expr: (
55 fir_package_id,
56 package
57 .entry
58 .expect("package must have an entry expression"),
59 )
60 .into(),
61 };
62
63 let compute_properties = PassContext::run_fir_passes_on_fir(
64 &fir_store,
65 fir_package_id,
66 capabilities,
67 )
68 .map_err(|errors| {
69 let source_package = store.get(package_id).expect("package should be in store");
70 errors
71 .iter()
72 .map(|e| Error::Pass(WithSource::from_map(&source_package.sources, e.clone())))
73 .collect::<Vec<_>>()
74 })?;
75
76 fir_to_qir(&fir_store, capabilities, Some(compute_properties), &entry).map_err(|e| {
77 let source_package_id = match e.span() {
78 Some(span) => span.package,
79 None => package_id,
80 };
81 let source_package = store
82 .get(source_package_id)
83 .expect("package should be in store");
84 vec![Error::PartialEvaluation(WithSource::from_map(
85 &source_package.sources,
86 e,
87 ))]
88 })
89 }
90
91 pub fn get_rir(
92 sources: SourceMap,
93 language_features: LanguageFeatures,
94 capabilities: TargetCapabilityFlags,
95 mut package_store: PackageStore,
96 dependencies: &Dependencies,
97 ) -> Result<Vec<String>, Vec<Error>> {
98 let (package_id, fir_store, entry, compute_properties) = compile_to_fir(
99 sources,
100 language_features,
101 capabilities,
102 &mut package_store,
103 dependencies,
104 )?;
105
106 let (raw, ssa) = fir_to_rir(
107 &fir_store,
108 capabilities,
109 Some(compute_properties),
110 &entry,
111 PartialEvalConfig {
112 generate_debug_metadata: true,
113 },
114 )
115 .map_err(|e| {
116 let source_package_id = match e.span() {
117 Some(span) => span.package,
118 None => package_id,
119 };
120 let source_package = package_store
121 .get(source_package_id)
122 .expect("package should be in store");
123 vec![Error::PartialEvaluation(WithSource::from_map(
124 &source_package.sources,
125 e,
126 ))]
127 })?;
128 Ok(vec![raw.to_string(), ssa.to_string()])
129 }
130
131 pub fn get_qir(
132 sources: SourceMap,
133 language_features: LanguageFeatures,
134 capabilities: TargetCapabilityFlags,
135 mut package_store: PackageStore,
136 dependencies: &Dependencies,
137 ) -> Result<String, Vec<Error>> {
138 let (package_id, fir_store, entry, compute_properties) = compile_to_fir(
139 sources,
140 language_features,
141 capabilities,
142 &mut package_store,
143 dependencies,
144 )?;
145
146 fir_to_qir(&fir_store, capabilities, Some(compute_properties), &entry).map_err(|e| {
147 let source_package_id = match e.span() {
148 Some(span) => span.package,
149 None => package_id,
150 };
151 let source_package = package_store
152 .get(source_package_id)
153 .expect("package should be in store");
154 vec![Error::PartialEvaluation(WithSource::from_map(
155 &source_package.sources,
156 e,
157 ))]
158 })
159 }
160
161 fn compile_to_fir(
162 sources: SourceMap,
163 language_features: LanguageFeatures,
164 capabilities: TargetCapabilityFlags,
165 package_store: &mut PackageStore,
166 dependencies: &[(qsc_hir::hir::PackageId, Option<std::sync::Arc<str>>)],
167 ) -> Result<
168 (
169 qsc_hir::hir::PackageId,
170 qsc_fir::fir::PackageStore,
171 ProgramEntry,
172 qsc_rca::PackageStoreComputeProperties,
173 ),
174 Vec<Error>,
175 > {
176 if capabilities == TargetCapabilityFlags::all() {
177 return Err(vec![Error::UnsupportedRuntimeCapabilities]);
178 }
179 let (unit, errors) = crate::compile::compile(
180 package_store,
181 dependencies,
182 sources,
183 PackageType::Exe,
184 capabilities,
185 language_features,
186 );
187 if !errors.is_empty() {
188 return Err(errors.iter().map(|e| Error::Compile(e.clone())).collect());
189 }
190 let package_id = package_store.insert(unit);
191 let (fir_store, fir_package_id) = qsc_passes::lower_hir_to_fir(package_store, package_id);
192 let package = fir_store.get(fir_package_id);
193 let entry = ProgramEntry {
194 exec_graph: package.entry_exec_graph.clone(),
195 expr: (
196 fir_package_id,
197 package
198 .entry
199 .expect("package must have an entry expression"),
200 )
201 .into(),
202 };
203 let compute_properties = PassContext::run_fir_passes_on_fir(
204 &fir_store,
205 fir_package_id,
206 capabilities,
207 )
208 .map_err(|errors| {
209 let source_package = package_store
210 .get(package_id)
211 .expect("package should be in store");
212 errors
213 .iter()
214 .map(|e| Error::Pass(WithSource::from_map(&source_package.sources, e.clone())))
215 .collect::<Vec<_>>()
216 })?;
217 Ok((package_id, fir_store, entry, compute_properties))
218 }
219}
220