microsoft/qdk

Public

mirrored fromhttps://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
iadavis/pipeline-issue-debugging

Branches

Tags

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

Clone

HTTPS

Download ZIP

source/compiler/qsc/src/codegen.rs

211lines · 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::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(&fir_store, capabilities, Some(compute_properties), &entry)
107 .map_err(|e| {
108 let source_package_id = match e.span() {
109 Some(span) => span.package,
110 None => package_id,
111 };
112 let source_package = package_store
113 .get(source_package_id)
114 .expect("package should be in store");
115 vec![Error::PartialEvaluation(WithSource::from_map(
116 &source_package.sources,
117 e,
118 ))]
119 })?;
120 Ok(vec![raw.to_string(), ssa.to_string()])
121 }
122
123 pub fn get_qir(
124 sources: SourceMap,
125 language_features: LanguageFeatures,
126 capabilities: TargetCapabilityFlags,
127 mut package_store: PackageStore,
128 dependencies: &Dependencies,
129 ) -> Result<String, Vec<Error>> {
130 let (package_id, fir_store, entry, compute_properties) = compile_to_fir(
131 sources,
132 language_features,
133 capabilities,
134 &mut package_store,
135 dependencies,
136 )?;
137
138 fir_to_qir(&fir_store, capabilities, Some(compute_properties), &entry).map_err(|e| {
139 let source_package_id = match e.span() {
140 Some(span) => span.package,
141 None => package_id,
142 };
143 let source_package = package_store
144 .get(source_package_id)
145 .expect("package should be in store");
146 vec![Error::PartialEvaluation(WithSource::from_map(
147 &source_package.sources,
148 e,
149 ))]
150 })
151 }
152
153 fn compile_to_fir(
154 sources: SourceMap,
155 language_features: LanguageFeatures,
156 capabilities: TargetCapabilityFlags,
157 package_store: &mut PackageStore,
158 dependencies: &[(qsc_hir::hir::PackageId, Option<std::sync::Arc<str>>)],
159 ) -> Result<
160 (
161 qsc_hir::hir::PackageId,
162 qsc_fir::fir::PackageStore,
163 ProgramEntry,
164 qsc_rca::PackageStoreComputeProperties,
165 ),
166 Vec<Error>,
167 > {
168 if capabilities == TargetCapabilityFlags::all() {
169 return Err(vec![Error::UnsupportedRuntimeCapabilities]);
170 }
171 let (unit, errors) = crate::compile::compile(
172 package_store,
173 dependencies,
174 sources,
175 PackageType::Exe,
176 capabilities,
177 language_features,
178 );
179 if !errors.is_empty() {
180 return Err(errors.iter().map(|e| Error::Compile(e.clone())).collect());
181 }
182 let package_id = package_store.insert(unit);
183 let (fir_store, fir_package_id) = qsc_passes::lower_hir_to_fir(package_store, package_id);
184 let package = fir_store.get(fir_package_id);
185 let entry = ProgramEntry {
186 exec_graph: package.entry_exec_graph.clone(),
187 expr: (
188 fir_package_id,
189 package
190 .entry
191 .expect("package must have an entry expression"),
192 )
193 .into(),
194 };
195 let compute_properties = PassContext::run_fir_passes_on_fir(
196 &fir_store,
197 fir_package_id,
198 capabilities,
199 )
200 .map_err(|errors| {
201 let source_package = package_store
202 .get(package_id)
203 .expect("package should be in store");
204 errors
205 .iter()
206 .map(|e| Error::Pass(WithSource::from_map(&source_package.sources, e.clone())))
207 .collect::<Vec<_>>()
208 })?;
209 Ok((package_id, fir_store, entry, compute_properties))
210 }
211}
212