@@ -9,9 +9,13 @@ mod tests;
9
9
#[ cfg( test) ]
10
10
mod debugger_tests;
11
11
12
+ use std:: rc:: Rc ;
13
+
12
14
pub use qsc_eval:: {
13
15
debug:: Frame ,
14
16
output:: { self , GenericReceiver } ,
17
+ val:: Closure ,
18
+ val:: Range as ValueRange ,
15
19
val:: Result ,
16
20
val:: Value ,
17
21
StepAction , StepResult ,
@@ -37,9 +41,9 @@ use qsc_eval::{
37
41
debug:: { map_fir_package_to_hir, map_hir_package_to_fir} ,
38
42
output:: Receiver ,
39
43
val:: { self } ,
40
- Env , EvalId , State , VariableInfo ,
44
+ Env , State , VariableInfo ,
41
45
} ;
42
- use qsc_fir:: fir:: { self , Global , PackageStoreLookup } ;
46
+ use qsc_fir:: fir:: { self , ExecGraphNode , Global , PackageStoreLookup } ;
43
47
use qsc_fir:: {
44
48
fir:: { Block , BlockId , Expr , ExprId , Package , PackageId , Pat , PatId , Stmt , StmtId } ,
45
49
visit:: { self , Visitor } ,
@@ -173,11 +177,11 @@ impl Interpreter {
173
177
& mut self ,
174
178
receiver : & mut impl Receiver ,
175
179
) -> std:: result:: Result < Value , Vec < Error > > {
176
- let expr = self . get_entry_expr ( ) ?;
180
+ let graph = self . get_entry_exec_graph ( ) ?;
177
181
eval (
178
182
self . source_package ,
179
183
self . classical_seed ,
180
- expr . into ( ) ,
184
+ graph ,
181
185
self . compiler . package_store ( ) ,
182
186
& self . fir_store ,
183
187
& mut Env :: default ( ) ,
@@ -193,14 +197,14 @@ impl Interpreter {
193
197
sim : & mut impl Backend < ResultType = impl Into < val:: Result > > ,
194
198
receiver : & mut impl Receiver ,
195
199
) -> std:: result:: Result < Value , Vec < Error > > {
196
- let expr = self . get_entry_expr ( ) ?;
200
+ let graph = self . get_entry_exec_graph ( ) ?;
197
201
if self . quantum_seed . is_some ( ) {
198
202
sim. set_seed ( self . quantum_seed ) ;
199
203
}
200
204
eval (
201
205
self . source_package ,
202
206
self . classical_seed ,
203
- expr . into ( ) ,
207
+ graph ,
204
208
self . compiler . package_store ( ) ,
205
209
& self . fir_store ,
206
210
& mut Env :: default ( ) ,
@@ -209,10 +213,10 @@ impl Interpreter {
209
213
)
210
214
}
211
215
212
- fn get_entry_expr ( & self ) -> std:: result:: Result < ExprId , Vec < Error > > {
216
+ fn get_entry_exec_graph ( & self ) -> std:: result:: Result < Rc < [ ExecGraphNode ] > , Vec < Error > > {
213
217
let unit = self . fir_store . get ( self . source_package ) ;
214
- if let Some ( entry ) = unit. entry {
215
- return Ok ( entry ) ;
218
+ if unit. entry . is_some ( ) {
219
+ return Ok ( unit . entry_exec_graph . clone ( ) ) ;
216
220
} ;
217
221
Err ( vec ! [ Error :: NoEntryPoint ] )
218
222
}
@@ -233,7 +237,7 @@ impl Interpreter {
233
237
. compile_fragments_fail_fast ( & label, fragments)
234
238
. map_err ( into_errors) ?;
235
239
236
- let stmts = self . lower ( & increment) ;
240
+ let ( _ , graph ) = self . lower ( & increment) ;
237
241
238
242
// Updating the compiler state with the new AST/HIR nodes
239
243
// is not necessary for the interpreter to function, as all
@@ -243,22 +247,16 @@ impl Interpreter {
243
247
// here to keep the package stores consistent.
244
248
self . compiler . update ( increment) ;
245
249
246
- let mut result = Value :: unit ( ) ;
247
-
248
- for stmt_id in stmts {
249
- result = eval (
250
- self . package ,
251
- self . classical_seed ,
252
- stmt_id. into ( ) ,
253
- self . compiler . package_store ( ) ,
254
- & self . fir_store ,
255
- & mut self . env ,
256
- & mut self . sim ,
257
- receiver,
258
- ) ?;
259
- }
260
-
261
- Ok ( result)
250
+ eval (
251
+ self . package ,
252
+ self . classical_seed ,
253
+ graph. into ( ) ,
254
+ self . compiler . package_store ( ) ,
255
+ & self . fir_store ,
256
+ & mut self . env ,
257
+ & mut self . sim ,
258
+ receiver,
259
+ )
262
260
}
263
261
264
262
/// Runs the given entry expression on a new instance of the environment and simulator,
@@ -300,7 +298,7 @@ impl Interpreter {
300
298
receiver : & mut impl Receiver ,
301
299
expr : & str ,
302
300
) -> std:: result:: Result < InterpretResult , Vec < Error > > {
303
- let expr_id = self . compile_entry_expr ( expr) ?;
301
+ let graph = self . compile_entry_expr ( expr) ?;
304
302
305
303
if self . quantum_seed . is_some ( ) {
306
304
sim. set_seed ( self . quantum_seed ) ;
@@ -309,7 +307,7 @@ impl Interpreter {
309
307
Ok ( eval (
310
308
self . package ,
311
309
self . classical_seed ,
312
- expr_id . into ( ) ,
310
+ graph . into ( ) ,
313
311
self . compiler . package_store ( ) ,
314
312
& self . fir_store ,
315
313
& mut Env :: default ( ) ,
@@ -318,15 +316,18 @@ impl Interpreter {
318
316
) )
319
317
}
320
318
321
- fn compile_entry_expr ( & mut self , expr : & str ) -> std:: result:: Result < ExprId , Vec < Error > > {
319
+ fn compile_entry_expr (
320
+ & mut self ,
321
+ expr : & str ,
322
+ ) -> std:: result:: Result < Vec < ExecGraphNode > , Vec < Error > > {
322
323
let increment = self
323
324
. compiler
324
325
. compile_entry_expr ( expr)
325
326
. map_err ( into_errors) ?;
326
327
327
328
// `lower` will update the entry expression in the FIR store,
328
329
// and it will always return an empty list of statements.
329
- let _ = self . lower ( & increment) ;
330
+ let ( _ , graph ) = self . lower ( & increment) ;
330
331
331
332
// The AST and HIR packages in `increment` only contain an entry
332
333
// expression and no statements. The HIR *can* contain items if the entry
@@ -342,16 +343,19 @@ impl Interpreter {
342
343
// here to keep the package stores consistent.
343
344
self . compiler . update ( increment) ;
344
345
345
- let unit = self . fir_store . get ( self . package ) ;
346
- let entry = unit. entry . expect ( "package should have an entry expression" ) ;
347
-
348
- Ok ( entry)
346
+ Ok ( graph)
349
347
}
350
348
351
- fn lower ( & mut self , unit_addition : & qsc_frontend:: incremental:: Increment ) -> Vec < StmtId > {
349
+ fn lower (
350
+ & mut self ,
351
+ unit_addition : & qsc_frontend:: incremental:: Increment ,
352
+ ) -> ( Vec < StmtId > , Vec < ExecGraphNode > ) {
352
353
let fir_package = self . fir_store . get_mut ( self . package ) ;
353
- self . lowerer
354
- . lower_and_update_package ( fir_package, & unit_addition. hir )
354
+ (
355
+ self . lowerer
356
+ . lower_and_update_package ( fir_package, & unit_addition. hir ) ,
357
+ self . lowerer . take_exec_graph ( ) ,
358
+ )
355
359
}
356
360
357
361
fn next_line_label ( & mut self ) -> String {
@@ -387,24 +391,15 @@ impl Debugger {
387
391
language_features,
388
392
) ?;
389
393
let source_package_id = interpreter. source_package ;
394
+ let unit = interpreter. fir_store . get ( source_package_id) ;
395
+ let entry_exec_graph = unit. entry_exec_graph . clone ( ) ;
390
396
Ok ( Self {
391
397
interpreter,
392
398
position_encoding,
393
- state : State :: new ( source_package_id, None ) ,
399
+ state : State :: new ( source_package_id, entry_exec_graph , None ) ,
394
400
} )
395
401
}
396
402
397
- /// Loads the entry expression to the top of the evaluation stack.
398
- /// This is needed for debugging so that when begging to debug with
399
- /// a step action the system is already in the correct state.
400
- /// # Errors
401
- /// Returns a vector of errors if loading the entry point fails.
402
- pub fn set_entry ( & mut self ) -> std:: result:: Result < ( ) , Vec < Error > > {
403
- let expr = self . interpreter . get_entry_expr ( ) ?;
404
- qsc_eval:: eval_push_expr ( & mut self . state , expr) ;
405
- Ok ( ( ) )
406
- }
407
-
408
403
/// Resumes execution with specified `StepAction`.
409
404
/// # Errors
410
405
/// Returns a vector of errors if evaluating the entry point fails.
@@ -527,15 +522,23 @@ impl Debugger {
527
522
fn eval (
528
523
package : PackageId ,
529
524
classical_seed : Option < u64 > ,
530
- id : EvalId ,
525
+ exec_graph : Rc < [ ExecGraphNode ] > ,
531
526
package_store : & PackageStore ,
532
527
fir_store : & fir:: PackageStore ,
533
528
env : & mut Env ,
534
529
sim : & mut impl Backend < ResultType = impl Into < val:: Result > > ,
535
530
receiver : & mut impl Receiver ,
536
531
) -> InterpretResult {
537
- qsc_eval:: eval ( package, classical_seed, id, fir_store, env, sim, receiver)
538
- . map_err ( |( error, call_stack) | eval_error ( package_store, fir_store, call_stack, error) )
532
+ qsc_eval:: eval (
533
+ package,
534
+ classical_seed,
535
+ exec_graph,
536
+ fir_store,
537
+ env,
538
+ sim,
539
+ receiver,
540
+ )
541
+ . map_err ( |( error, call_stack) | eval_error ( package_store, fir_store, call_stack, error) )
539
542
}
540
543
541
544
/// Represents a stack frame for debugging.
0 commit comments