about summary refs log blame commit diff stats
path: root/arc/trace.arc.t
blob: 6dcebe0afad27e4af9b6ce29a666b23f87e705b2 (plain) (tree)
1
2
3
4
5
6
7
8
9
                                       
                    
                              
                                                     

                       
 
        
                         


                                                                        












                                                                   

                                                                                   




                                                                                                                        













                                                                                      
        
                                               


                                                                        












                                                                   

                                                                                   







                                                                                                                            











                                                                                      
                                                                  













                                                                                      
        
                                      


                                                                        












                                                                   

                                                                                  















                                                                                                                                 












                                                                                      
                                                 

                                                                        
                         



                                                            


                                                                                           



















                                                                                      


                                                                                           


                                                            
                                                                   
















                                                                                      



                                                                                           


















                                                                                      



                                                                                           













                                                                                      
        
                                


                                                                        












                                                                   

                                                                                  








                                                                                                                                 

















                                                                                      

                                                                                           












                                                                                      
                                                                       















                                                                                      
                                                                                   
 
        
                                        


                                                                        












                                                                   

                                                                                  














                                                                                                                                 














                                                                                      
 
        
                                  


                                                                        



                                                      
                          








                                                                   

                                                                                  
















                                                                                                                                 














                                                                                      
                                                                                 

                                                                        
                         



                                                            
                                                                                           

















                                                                                      
                                                                               

                                                                        
                         



                                                            
                                                                                           















                                                                                      
                                                                                             




                                                                        






                                                                                           
                                                                    
                                                                                           















                                                                                      
                                                                                                              
 

                       
        
                            


                                                                        





                   

        





                 
                

                                                                                   




                                                                                                                             








                                                                                
 




                                                                        



                                                                                           
   


                                 






                                                       









                                                            
 


                                                                        

                                                            

                                                        

                                                                                           
   


                                 







                                                                        










                                                            
 


                                                                        

                                                            

                                                        

                                                                                           
   


                                 






                                                                        
              
 









                                                                                           


                                 






                                                            
              
 







                                                                                           


                                 





                                                                            
 






                                                                                           


                                 





                                                                            
 


                                                                        
                               

                                                                                           
   


                                 
                                     
                                    


                               
                                 
                                                                    
 










                                                                                           


                                 







                                                        
 







                                                                                           


                                 
                                               


                                    
                               


                                                         
 






                                                                                           


                                 







                                                                                           
              
 






                                                                                           


                                 






                                                 
 










































                                                                                           
 















                                         


                                                                                 
                                                         

















                                                                   






















                                                                                 


                                                                                 
                                                         






                                                             
                          











                                                                                           
              
 


















                                                                                 
                                                         






                                                            











                                                                                           
 































































                                                                                           
 




























































































































































































































                                                                                           
              























































                                                                                                                             














































                                                                                           
                





















                                                                                           
















                                                                                           









                                                            
              



















                                                                                                                           
 















































































































                                                                                                                             








































                                                                                           
 

                                                                        
                                                                                 
                






































                                                                                           





























                                                                                           
        
                     
(selective-load "mu.arc" section-level)
(test-only-settings)
(add-code:readfile "trace.mu")
(ero "running tests in trace.arc.t (takes ~10 mins)")
(freeze function*)
(load-system-functions)

(reset2)
(new-trace "print-trace")
(run-code main
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (x:string-address <- new
"schedule: main
run: main 0: (((1 integer)) <- ((copy)) ((1 literal)))
run: main 0: 1 => ((1 integer))
mem: ((1 integer)): 1 <= 1
run: main 1: (((2 integer)) <- ((copy)) ((3 literal)))
run: main 1: 3 => ((2 integer))
mem: ((2 integer)): 2 <= 3
run: main 2: (((3 integer)) <- ((add)) ((1 integer)) ((2 integer)))
mem: ((1 integer)) => 1
mem: ((2 integer)) => 3
run: main 2: 4 => ((3 integer))
mem: ((3 integer)): 3 <= 4
schedule:  done with routine")
  (s:stream-address <- init-stream x:string-address)
  (traces:instruction-trace-address-array-address <- parse-traces s:stream-address)
  (screen:terminal-address <- init-fake-terminal 70:literal 15:literal)
  (browser-state:space-address <- browser-state traces:instruction-trace-address-array-address 30:literal/screen-height)
  (print-traces-collapsed browser-state:space-address screen:terminal-address)
  (1:string-address/raw <- get screen:terminal-address/deref data:offset)
)
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
;? (prn memory*.1)
(when (~screen-contains memory*.1 70
         (+ "+ main/ 0 : (((1 integer)) <- ((copy)) ((1 literal)))                 "
            "+ main/ 0 : 1 => ((1 integer))                                        "
            "+ main/ 1 : (((2 integer)) <- ((copy)) ((3 literal)))                 "
            "+ main/ 1 : 3 => ((2 integer))                                        "
            "+ main/ 2 : (((3 integer)) <- ((add)) ((1 integer)) ((2 integer)))    "
            "+ main/ 2 : 4 => ((3 integer))                                        "))
  (prn "F - print-traces-collapsed works"))
;? (quit) ;? 1

(reset2)
(new-trace "print-trace-from-middle-of-screen")
(run-code main
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (x:string-address <- new
"schedule: main
run: main 0: (((1 integer)) <- ((copy)) ((1 literal)))
run: main 0: 1 => ((1 integer))
mem: ((1 integer)): 1 <= 1
run: main 1: (((2 integer)) <- ((copy)) ((3 literal)))
run: main 1: 3 => ((2 integer))
mem: ((2 integer)): 2 <= 3
run: main 2: (((3 integer)) <- ((add)) ((1 integer)) ((2 integer)))
mem: ((1 integer)) => 1
mem: ((2 integer)) => 3
run: main 2: 4 => ((3 integer))
mem: ((3 integer)): 3 <= 4
schedule:  done with routine")
  (s:stream-address <- init-stream x:string-address)
  (traces:instruction-trace-address-array-address <- parse-traces s:stream-address)
  (1:terminal-address/raw <- init-fake-terminal 70:literal 15:literal)
  ; position the cursor away from top of screen
  (cursor-down 1:terminal-address/raw)
  (cursor-down 1:terminal-address/raw)
  (browser-state:space-address <- browser-state traces:instruction-trace-address-array-address 30:literal/screen-height)
  (print-traces-collapsed browser-state:space-address 1:terminal-address/raw traces:instruction-trace-address-array-address)
  (2:string-address/raw <- get 1:terminal-address/raw/deref data:offset)
)
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.2 70
         (+ "                                                                      "
            "                                                                      "
            "+ main/ 0 : (((1 integer)) <- ((copy)) ((1 literal)))                 "
            "+ main/ 0 : 1 => ((1 integer))                                        "
            "+ main/ 1 : (((2 integer)) <- ((copy)) ((3 literal)))                 "
            "+ main/ 1 : 3 => ((2 integer))                                        "
            "+ main/ 2 : (((3 integer)) <- ((add)) ((1 integer)) ((2 integer)))    "
            "+ main/ 2 : 4 => ((3 integer))                                        "))
  (prn "F - print-traces-collapsed works anywhere on the screen"))
(run-code main2
  (print-character 1:terminal-address/raw ((#\* literal))))
(when (~screen-contains memory*.2 70
         (+ "                                                                      "
            "                                                                      "
            "+ main/ 0 : (((1 integer)) <- ((copy)) ((1 literal)))                 "
            "+ main/ 0 : 1 => ((1 integer))                                        "
            "+ main/ 1 : (((2 integer)) <- ((copy)) ((3 literal)))                 "
            "+ main/ 1 : 3 => ((2 integer))                                        "
            "+ main/ 2 : (((3 integer)) <- ((add)) ((1 integer)) ((2 integer)))    "
            "+ main/ 2 : 4 => ((3 integer))                                        "
            "*                                                                     "))
  (prn "F - print-traces-collapsed leaves cursor at next line"))

(reset2)
(new-trace "process-key-move-up-down")
(run-code main
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (x:string-address <- new
"schedule: main
run: main 0: (((1 integer)) <- ((copy)) ((1 literal)))
run: main 0: 1 => ((1 integer))
mem: ((1 integer)): 1 <= 1
run: main 1: (((2 integer)) <- ((copy)) ((3 literal)))
run: main 1: 3 => ((2 integer))
mem: ((2 integer)): 2 <= 3
run: main 2: (((3 integer)) <- ((add)) ((1 integer)) ((2 integer)))
mem: ((1 integer)) => 1
mem: ((2 integer)) => 3
run: main 2: 4 => ((3 integer))
mem: ((3 integer)): 3 <= 4
schedule:  done with routine")
  (s:stream-address <- init-stream x:string-address)
  (1:instruction-trace-address-array-address/raw <- parse-traces s:stream-address)
  (2:terminal-address/raw <- init-fake-terminal 70:literal 15:literal)
  ; position the cursor away from top of screen
  (cursor-down 2:terminal-address/raw)
  (cursor-down 2:terminal-address/raw)
  (3:space-address/raw <- browser-state 1:instruction-trace-address-array-address/raw 30:literal/screen-height)
  ; draw trace
  (print-traces-collapsed 3:space-address/raw/browser-state 2:terminal-address/raw 1:instruction-trace-address-array-address/raw)
  ; move cursor up
  ; we have no way yet to test special keys like up-arrow
  (s:string-address <- new "k")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  ; draw cursor
  (replace-character 2:terminal-address/raw ((#\* literal)))
  (4:string-address/raw <- get 2:terminal-address/raw/deref data:offset)
)
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 70
         (+ "                                                                      "
            "                                                                      "
            "+ main/ 0 : (((1 integer)) <- ((copy)) ((1 literal)))                 "
            "+ main/ 0 : 1 => ((1 integer))                                        "
            "+ main/ 1 : (((2 integer)) <- ((copy)) ((3 literal)))                 "
            "+ main/ 1 : 3 => ((2 integer))                                        "
            "+ main/ 2 : (((3 integer)) <- ((add)) ((1 integer)) ((2 integer)))    "
            "* main/ 2 : 4 => ((3 integer))                                        "))
            ;^cursor
  (prn "F - process-key can move up the cursor"))
(run-code main2
  (default-space:space-address <- new space:literal 30:literal/capacity)
  ; reset previous cursor
  (replace-character 2:terminal-address/raw ((#\+ literal)))
  ; move cursor up 3 more lines
  (s:string-address <- new "kkk")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (replace-character 2:terminal-address/raw ((#\* literal)))
  )
; cursor is now at line 3
(when (~screen-contains memory*.4 70
         (+ "                                                                      "
            "                                                                      "
            "+ main/ 0 : (((1 integer)) <- ((copy)) ((1 literal)))                 "
            "+ main/ 0 : 1 => ((1 integer))                                        "
            "* main/ 1 : (((2 integer)) <- ((copy)) ((3 literal)))                 "
            ;^cursor
            "+ main/ 1 : 3 => ((2 integer))                                        "
            "+ main/ 2 : (((3 integer)) <- ((add)) ((1 integer)) ((2 integer)))    "
            "+ main/ 2 : 4 => ((3 integer))                                        "))
  (prn "F - process-key can move up multiple times"))
; try to move cursor up thrice more
(run-code main3
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (replace-character 2:terminal-address/raw ((#\+ literal)))
  (s:string-address <- new "kkk")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (replace-character 2:terminal-address/raw ((#\* literal)))
  )
; cursor doesn't go beyond the first line printed
; stuff on screen before browser-state was initialized is inviolate
(when (~screen-contains memory*.4 70
         (+ "                                                                      "
            "                                                                      "
            "* main/ 0 : (((1 integer)) <- ((copy)) ((1 literal)))                 "
            ;^cursor
            "+ main/ 0 : 1 => ((1 integer))                                        "
            "+ main/ 1 : (((2 integer)) <- ((copy)) ((3 literal)))                 "
            "+ main/ 1 : 3 => ((2 integer))                                        "
            "+ main/ 2 : (((3 integer)) <- ((add)) ((1 integer)) ((2 integer)))    "
            "+ main/ 2 : 4 => ((3 integer))                                        "))
  (prn "F - process-key doesn't move above bounds"))
; now move cursor down 4 times
(run-code main4
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (replace-character 2:terminal-address/raw ((#\+ literal)))
  (s:string-address <- new "jjjj")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (replace-character 2:terminal-address/raw ((#\* literal)))
  )
(when (~screen-contains memory*.4 70
         (+ "                                                                      "
            "                                                                      "
            "+ main/ 0 : (((1 integer)) <- ((copy)) ((1 literal)))                 "
            "+ main/ 0 : 1 => ((1 integer))                                        "
            "+ main/ 1 : (((2 integer)) <- ((copy)) ((3 literal)))                 "
            "+ main/ 1 : 3 => ((2 integer))                                        "
            "* main/ 2 : (((3 integer)) <- ((add)) ((1 integer)) ((2 integer)))    "
            ;^cursor
            "+ main/ 2 : 4 => ((3 integer))                                        "))
  (prn "F - process-key can move down multiple times"))
; try to move cursor down 4 more times
(run-code main5
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (replace-character 2:terminal-address/raw ((#\+ literal)))
  (s:string-address <- new "jjjj")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (replace-character 2:terminal-address/raw ((#\* literal)))
  )
(when (~screen-contains memory*.4 70
         (+ "                                                                      "
            "                                                                      "
            "+ main/ 0 : (((1 integer)) <- ((copy)) ((1 literal)))                 "
            "+ main/ 0 : 1 => ((1 integer))                                        "
            "+ main/ 1 : (((2 integer)) <- ((copy)) ((3 literal)))                 "
            "+ main/ 1 : 3 => ((2 integer))                                        "
            "+ main/ 2 : (((3 integer)) <- ((add)) ((1 integer)) ((2 integer)))    "
            "+ main/ 2 : 4 => ((3 integer))                                        "
            "*                                                                     "))
  (prn "F - process-key doesn't move below bounds"))

(reset2)
(new-trace "process-key-expand")
(run-code main
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (x:string-address <- new
"schedule: main
run: main 0: (((1 integer)) <- ((copy)) ((1 literal)))
run: main 0: 1 => ((1 integer))
mem: ((1 integer)): 1 <= 1
run: main 1: (((2 integer)) <- ((copy)) ((3 literal)))
run: main 1: 3 => ((2 integer))
mem: ((2 integer)): 2 <= 3
run: main 2: (((3 integer)) <- ((add)) ((1 integer)) ((2 integer)))
mem: ((1 integer)) => 1
mem: ((2 integer)) => 3
run: main 2: 4 => ((3 integer))
mem: ((3 integer)): 3 <= 4
schedule:  done with routine")
  (s:stream-address <- init-stream x:string-address)
  (1:instruction-trace-address-array-address/raw <- parse-traces s:stream-address)
  (2:terminal-address/raw <- init-fake-terminal 70:literal 15:literal)
  ; position the cursor away from top of screen
  (cursor-down 2:terminal-address/raw)
  (cursor-down 2:terminal-address/raw)
  (3:space-address/raw <- browser-state 1:instruction-trace-address-array-address/raw 30:literal/screen-height)
  ; draw trace
  (print-traces-collapsed 3:space-address/raw/browser-state 2:terminal-address/raw 1:instruction-trace-address-array-address/raw)
  (4:string-address/raw <- get 2:terminal-address/raw/deref data:offset)
)
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 70
         (+ "                                                                      "
            "                                                                      "
            "+ main/ 0 : (((1 integer)) <- ((copy)) ((1 literal)))                 "
            "+ main/ 0 : 1 => ((1 integer))                                        "
            "+ main/ 1 : (((2 integer)) <- ((copy)) ((3 literal)))                 "
            "+ main/ 1 : 3 => ((2 integer))                                        "
            "+ main/ 2 : (((3 integer)) <- ((add)) ((1 integer)) ((2 integer)))    "
            "+ main/ 2 : 4 => ((3 integer))                                        "))
  (prn "F - process-key: before expand"))
(run-code main2
  (default-space:space-address <- new space:literal 30:literal/capacity)
  ; move cursor to final line and expand
  (s:string-address <- new "k\n")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
; final line is expanded
(when (~screen-contains memory*.4 70
         (+ "                                                                      "
            "                                                                      "
            "+ main/ 0 : (((1 integer)) <- ((copy)) ((1 literal)))                 "
            "+ main/ 0 : 1 => ((1 integer))                                        "
            "+ main/ 1 : (((2 integer)) <- ((copy)) ((3 literal)))                 "
            "+ main/ 1 : 3 => ((2 integer))                                        "
            "+ main/ 2 : (((3 integer)) <- ((add)) ((1 integer)) ((2 integer)))    "
            "- main/ 2 : 4 => ((3 integer))                                        "
            "   mem : ((3 integer)): 3 <= 4                                        "
            "   schedule :  done with routine                                      "))
  (prn "F - process-key expands the trace index at cursor on <enter>"))
; and cursor should remain on the top-level line
(run-code main3
  (replace-character 2:terminal-address/raw ((#\* literal)))
  )
(when (~screen-contains memory*.4 70
         (+ "                                                                      "
            "                                                                      "
            "+ main/ 0 : (((1 integer)) <- ((copy)) ((1 literal)))                 "
            "+ main/ 0 : 1 => ((1 integer))                                        "
            "+ main/ 1 : (((2 integer)) <- ((copy)) ((3 literal)))                 "
            "+ main/ 1 : 3 => ((2 integer))                                        "
            "+ main/ 2 : (((3 integer)) <- ((add)) ((1 integer)) ((2 integer)))    "
            "* main/ 2 : 4 => ((3 integer))                                        "
            ;^cursor
            "   mem : ((3 integer)): 3 <= 4                                        "
            "   schedule :  done with routine                                      "))
  (prn "F - process-key positions cursor at start of trace index after expanding"))

(reset2)
(new-trace "process-key-expand-nonlast")
(run-code main
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (x:string-address <- new
"schedule: main
run: main 0: (((1 integer)) <- ((copy)) ((1 literal)))
run: main 0: 1 => ((1 integer))
mem: ((1 integer)): 1 <= 1
run: main 1: (((2 integer)) <- ((copy)) ((3 literal)))
run: main 1: 3 => ((2 integer))
mem: ((2 integer)): 2 <= 3
run: main 2: (((3 integer)) <- ((add)) ((1 integer)) ((2 integer)))
mem: ((1 integer)) => 1
mem: ((2 integer)) => 3
run: main 2: 4 => ((3 integer))
mem: ((3 integer)): 3 <= 4
schedule:  done with routine")
  (s:stream-address <- init-stream x:string-address)
  (1:instruction-trace-address-array-address/raw <- parse-traces s:stream-address)
  (2:terminal-address/raw <- init-fake-terminal 70:literal 15:literal)
  ; position the cursor away from top of screen
  (cursor-down 2:terminal-address/raw)
  (cursor-down 2:terminal-address/raw)
  (3:space-address/raw <- browser-state 1:instruction-trace-address-array-address/raw 30:literal/screen-height)
  ; draw trace
  (print-traces-collapsed 3:space-address/raw/browser-state 2:terminal-address/raw 1:instruction-trace-address-array-address/raw)
  ; expand penultimate line
  (s:string-address <- new "kk\n")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (4:string-address/raw <- get 2:terminal-address/raw/deref data:offset)
)
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 70
         (+ "                                                                      "
            "                                                                      "
            "+ main/ 0 : (((1 integer)) <- ((copy)) ((1 literal)))                 "
            "+ main/ 0 : 1 => ((1 integer))                                        "
            "+ main/ 1 : (((2 integer)) <- ((copy)) ((3 literal)))                 "
            "+ main/ 1 : 3 => ((2 integer))                                        "
            "- main/ 2 : (((3 integer)) <- ((add)) ((1 integer)) ((2 integer)))    "
            "   mem : ((1 integer)) => 1                                           "
            "   mem : ((2 integer)) => 3                                           "
            "+ main/ 2 : 4 => ((3 integer))                                        "))
  (prn "F - process-key: expanding a line continues to print lines after it"))

(reset2)
(new-trace "process-key-expanded")
(run-code main
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (x:string-address <- new
"schedule: main
run: main 0: (((1 integer)) <- ((copy)) ((1 literal)))
run: main 0: 1 => ((1 integer))
mem: ((1 integer)): 1 <= 1
mem: ((1 integer)): 1 <= 1
run: main 1: (((2 integer)) <- ((copy)) ((3 literal)))
run: main 1: 3 => ((2 integer))
mem: ((2 integer)): 2 <= 3
run: main 2: (((3 integer)) <- ((add)) ((1 integer)) ((2 integer)))
mem: ((1 integer)) => 1
mem: ((2 integer)) => 3
run: main 2: 4 => ((3 integer))
mem: ((3 integer)): 3 <= 4
schedule:  done with routine")
  (s:stream-address <- init-stream x:string-address)
  (1:instruction-trace-address-array-address/raw <- parse-traces s:stream-address)
  (2:terminal-address/raw <- init-fake-terminal 70:literal 15:literal)
  ; position the cursor away from top of screen
  (cursor-down 2:terminal-address/raw)
  (cursor-down 2:terminal-address/raw)
  (3:space-address/raw <- browser-state 1:instruction-trace-address-array-address/raw 30:literal/screen-height)
  ; draw trace
  (print-traces-collapsed 3:space-address/raw/browser-state 2:terminal-address/raw 1:instruction-trace-address-array-address/raw)
  ; expand penultimate line, then move one line down and draw cursor
  (s:string-address <- new "kk\nj")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (replace-character 2:terminal-address/raw ((#\* literal)))
  (4:string-address/raw <- get 2:terminal-address/raw/deref data:offset)
)
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
; cursor should be at next top-level 'run' line
(when (~screen-contains memory*.4 70
         (+ "                                                                      "
            "                                                                      "
            "+ main/ 0 : (((1 integer)) <- ((copy)) ((1 literal)))                 "
            "+ main/ 0 : 1 => ((1 integer))                                        "
            "+ main/ 1 : (((2 integer)) <- ((copy)) ((3 literal)))                 "
            "+ main/ 1 : 3 => ((2 integer))                                        "
            "- main/ 2 : (((3 integer)) <- ((add)) ((1 integer)) ((2 integer)))    "
            "   mem : ((1 integer)) => 1                                           "
            "   mem : ((2 integer)) => 3                                           "
            "* main/ 2 : 4 => ((3 integer))                                        "))
  (prn "F - process-key: navigation moves between top-level trace indices only"))
(run-code main2
  (default-space:space-address <- new space:literal 30:literal/capacity)
  ; reset previous cursor
  (replace-character 2:terminal-address/raw ((#\+ literal)))
  ; move cursor back up one line
  (s:string-address <- new "k")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  ; show cursor
  (replace-character 2:terminal-address/raw ((#\* literal)))
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
; cursor should be back at the top of the expanded line
(when (~screen-contains memory*.4 70
         (+ "                                                                      "
            "                                                                      "
            "+ main/ 0 : (((1 integer)) <- ((copy)) ((1 literal)))                 "
            "+ main/ 0 : 1 => ((1 integer))                                        "
            "+ main/ 1 : (((2 integer)) <- ((copy)) ((3 literal)))                 "
            "+ main/ 1 : 3 => ((2 integer))                                        "
            "* main/ 2 : (((3 integer)) <- ((add)) ((1 integer)) ((2 integer)))    "
            "   mem : ((1 integer)) => 1                                           "
            "   mem : ((2 integer)) => 3                                           "
            "+ main/ 2 : 4 => ((3 integer))                                        "))
  (prn "F - process-key: navigation moves between top-level indices only - 2"))
(run-code main3
  (default-space:space-address <- new space:literal 30:literal/capacity)
  ; reset previous cursor
  (replace-character 2:terminal-address/raw ((#\+ literal)))
  ; press enter
  (s:string-address <- new "\n")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
; expanded trace should now be collapsed
(when (~screen-contains memory*.4 70
         (+ "                                                                      "
            "                                                                      "
            "+ main/ 0 : (((1 integer)) <- ((copy)) ((1 literal)))                 "
            "+ main/ 0 : 1 => ((1 integer))                                        "
            "+ main/ 1 : (((2 integer)) <- ((copy)) ((3 literal)))                 "
            "+ main/ 1 : 3 => ((2 integer))                                        "
            "+ main/ 2 : (((3 integer)) <- ((add)) ((1 integer)) ((2 integer)))    "
            "+ main/ 2 : 4 => ((3 integer))                                        "
            "                                                                      "
            "                                                                      "))
  (prn "F - process-key: process-key collapses trace indices correctly after moving around"))
(run-code main4
  (default-space:space-address <- new space:literal 30:literal/capacity)
  ; move up a few lines, expand, then move down and expand again
  (s:string-address <- new "kkk\njjj\n")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
;?   (replace-character 2:terminal-address/raw ((#\* literal))) ;? 1
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
; first expand should have no effect
(when (~screen-contains memory*.4 70
         (+ "                                                                      "
            "                                                                      "
            "+ main/ 0 : (((1 integer)) <- ((copy)) ((1 literal)))                 "
            "+ main/ 0 : 1 => ((1 integer))                                        "
            "+ main/ 1 : (((2 integer)) <- ((copy)) ((3 literal)))                 "
            "+ main/ 1 : 3 => ((2 integer))                                        "
            "- main/ 2 : (((3 integer)) <- ((add)) ((1 integer)) ((2 integer)))    "
            "   mem : ((1 integer)) => 1                                           "
            "   mem : ((2 integer)) => 3                                           "
            "+ main/ 2 : 4 => ((3 integer))                                        "))
  (prn "F - process-key: process-key collapses the previously expanded trace index when expanding elsewhere"))

;; manage screen height

(reset2)
(new-trace "trace-paginate")
(run-code main
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (x:string-address <- new
"run: main 0: a b c
mem: 0 a
run: main 1: d e f
mem: 1 a
mem: 1 b
mem: 1 c
mem: 1 d
mem: 1 e
run: main 2: g hi
run: main 3: j
mem: 3 a
run: main 4: k
run: main 5: l
run: main 6: m
run: main 7: n")
  (s:stream-address <- init-stream x:string-address)
  (traces:instruction-trace-address-array-address <- parse-traces s:stream-address)
  (2:terminal-address/raw <- init-fake-terminal 17:literal 15:literal)
  (3:space-address/raw/browser-state <- browser-state traces:instruction-trace-address-array-address 3:literal/screen-height)
  (print-traces-collapsed 3:space-address/raw/browser-state 2:terminal-address/raw)
  (4:string-address/raw <- get 2:terminal-address/raw/deref data:offset)
)
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
; screen shows a subset of collapsed trace lines
(when (~screen-contains memory*.4 17
         (+ "+ main/ 0 : a b c"
            "+ main/ 1 : d e f"
            "+ main/ 2 : g hi "))
  (prn "F - print-traces-collapsed can show just one 'page' of a larger trace"))

; expand top line
(run-code main2
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (s:string-address <- new "kkk\n")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
; screen shows just first trace line fully expanded
(when (~screen-contains memory*.4 17
         (+ "- main/ 0 : a b c"
            "   mem : 0 a     "
            "+ main/ 1 : d e f"
            "                 "))
  (prn "F - expanding doesn't print past end of page"))
(run-code main2-2
  (replace-character 2:terminal-address/raw ((#\* literal)))
  )
; screen shows part of the second trace line expanded
(when (~screen-contains memory*.4 17
         (+ "* main/ 0 : a b c"
            "   mem : 0 a     "
            "+ main/ 1 : d e f"
            "                 "))
  (prn "F - cursor at right place after expand"))

; expand line below without first collapsing previously expanded line
(run-code main3
  (default-space:space-address <- new space:literal 30:literal/capacity)
  ; reset previous cursor
  (replace-character 2:terminal-address/raw ((#\- literal)))
  (s:string-address <- new "j\n")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
; screen shows part of the second trace line expanded
(when (~screen-contains memory*.4 17
         (+ "+ main/ 0 : a b c"
            "- main/ 1 : d e f"
            "   mem : 1 a     "
            "                 "
            "                 "))
  (prn "F - expanding below expanded line respects screen/page height"))
(run-code main3-2
  (replace-character 2:terminal-address/raw ((#\* literal)))
  )
; screen shows part of the second trace line expanded
(when (~screen-contains memory*.4 17
         (+ "+ main/ 0 : a b c"
            "* main/ 1 : d e f"
            "   mem : 1 a     "
            "                 "
            "                 "))
  (prn "F - cursor at right place after expand below"))

; expand line *above* without first collapsing previously expanded line
(run-code main4
  (default-space:space-address <- new space:literal 30:literal/capacity)
  ; reset previous cursor
  (replace-character 2:terminal-address/raw ((#\- literal)))
  (s:string-address <- new "k\n")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
; screen again shows first trace line expanded
(when (~screen-contains memory*.4 17
         (+ "- main/ 0 : a b c"
            "   mem : 0 a     "
            "+ main/ 1 : d e f"
            "                 "))
  (prn "F - expanding above expanded line respects screen/page height"))
;? (quit) ;? 1

; collapse everything and hit page-down
; again, we can't yet check for special keys like 'page-down so we'll use
; upper-case J and K for moving a page down or up, respectively.
(run-code main5
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (s:string-address <- new "\nJ")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
; screen shows second page of traces
(when (~screen-contains memory*.4 17
         (+ "+ main/ 3 : j    "
            "+ main/ 4 : k    "
            "+ main/ 5 : l    "
            "                 "))
  (prn "F - 'page-down' skips to next page after this one"))
;? (quit) ;? 1

; move cursor down, then page-down
(run-code main6
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (s:string-address <- new "jJ")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
; page-down behaves the same regardless of where the cursor was
(when (~screen-contains memory*.4 17
         (+ "+ main/ 6 : m    "
            "+ main/ 7 : n    "
            "                 "))
  (prn "F - 'page-down' skips to same place regardless of cursor position"))

; try to page-down past end of trace
(run-code main7
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (s:string-address <- new "J")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
; no change
(when (~screen-contains memory*.4 17
         (+ "+ main/ 6 : m    "
            "+ main/ 7 : n    "
            "                 "))
  (prn "F - 'page-down' skips to same place regardless of cursor position"))

; now page-up
(run-code main8
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (s:string-address <- new "K")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
; precisely undoes previous page-down
(when (~screen-contains memory*.4 17
         (+ "+ main/ 3 : j    "
            "+ main/ 4 : k    "
            "+ main/ 5 : l    "
            "                 "))
  (prn "F - 'page-up' on partial page behaves as if page was full"))

;; back to page 1, expand a line
(run-code main9
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (s:string-address <- new "Kkk\n")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
;?   (print-character 2:terminal-address/raw ((#\* literal))) ;? 1
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
; now we have an expanded line
(when (~screen-contains memory*.4 17
         (+ "+ main/ 0 : a b c"
            "- main/ 1 : d e f"
            "   mem : 1 a     "
            "                 "
            "                 "))
  (prn "F - intermediate state after expanding a line"))

; next page
(run-code main10
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (s:string-address <- new "J")
  (k:keyboard-address <- init-keyboard s:string-address)
;?   ($start-tracing) ;? 1
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
; no lines skipped, page with just inner traces
(when (~screen-contains memory*.4 17
         (+ "   mem : 1 b     "
            "   mem : 1 c     "
            "   mem : 1 d     "
            "                 "
            "                 "))
  (prn "F - page down continues existing expanded line"))

; next page
(run-code main11
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (s:string-address <- new "J")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
; page with partial inner trace and more collapsed
(when (~screen-contains memory*.4 17
         (+ "   mem : 1 e     "
            "+ main/ 2 : g hi "
            "+ main/ 3 : j    "
            "                 "
            "                 "))
  (prn "F - page down shows collapsed lines after continued expanded line at top of page"))
;? (quit) ;? 1

; page-up through an expanded line
(run-code main12
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (s:string-address <- new "K")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 17
         (+ "   mem : 1 b     "
            "   mem : 1 c     "
            "   mem : 1 d     "
            "                 "
            "                 "))
  (prn "F - page up understands expanded lines"))

;; page up scenarios
; skip ones starting at top of trace for now
; page-up scenario 2
; + run: main 0: a b c
;   mem: 0 a
; + run: main 1: d e f  <- top of page
;   mem: 1 a
;   mem: 1 b
;   mem: 1 c
;   mem: 1 d
;   mem: 1 e
; + run: main 2: g hi
; + run: main 3: j      <- bottom of page
;   mem: 3 a
; + run: main 4: k
; + run: main 5: l
; + run: main 6: m
; + run: main 7: n
(run-code main13
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (0:space-address/names:browser-state <- copy 3:space-address/raw/browser-state)
;?   ($print first-index-on-page:integer/space:1) ;? 1
;?   ($print (("\n" literal))) ;? 1
  (first-index-on-page:integer/space:1 <- copy 1:literal)
;?   ($print first-index-on-page:integer/space:1) ;? 1
;?   ($print (("\n" literal))) ;? 1
  (first-subindex-on-page:integer/space:1 <- copy -2:literal)
  (last-index-on-page:integer/space:1 <- copy 3:literal)
  (last-subindex-on-page:integer/space:1 <- copy -2:literal)
  (expanded-index:integer/space:1 <- copy -1:literal)
  (expanded-children:integer/space:1 <- copy -1:literal)
  (s:string-address <- new "K")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 17
         (+ "+ main/ 0 : a b c"
            "+ main/ 1 : d e f"
            "+ main/ 2 : g hi "))
  (prn "F - page-up 2"))

; page-up scenario 3
; + run: main 0: a b c
;   mem: 0 a
; - run: main 1: d e f  <- top of page
;   mem: 1 a
;   mem: 1 b            <- bottom of page
;   mem: 1 c
;   mem: 1 d
;   mem: 1 e
; + run: main 2: g hi
; + run: main 3: j
;   mem: 3 a
; + run: main 4: k
; + run: main 5: l
; + run: main 6: m
; + run: main 7: n
(run-code main14pre
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (0:space-address/names:browser-state <- copy 3:space-address/raw/browser-state)
  (first-index-on-page:integer/space:1 <- copy 1:literal)
  (first-subindex-on-page:integer/space:1 <- copy -1:literal)
  (last-index-on-page:integer/space:1 <- copy 1:literal)
  (last-subindex-on-page:integer/space:1 <- copy 1:literal)
  (expanded-index:integer/space:1 <- copy 1:literal)
  (expanded-children:integer/space:1 <- copy 5:literal)
  (to-top 0:space-address/browser-state 2:terminal-address/raw)
  (print-page 0:space-address/browser-state 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 17
         (+ "- main/ 1 : d e f"
            "   mem : 1 a     "
            "   mem : 1 b     "
            "                 "
            "                 "))
  (prn "F - page-up 3: initial print-page state"))
(run-code main14post
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (0:space-address/names:browser-state <- copy 3:space-address/raw/browser-state)
  (first-index-on-page:integer/space:1 <- copy 0:literal)
  (first-subindex-on-page:integer/space:1 <- copy -2:literal)
  (last-index-on-page:integer/space:1 <- copy 1:literal)
  (last-subindex-on-page:integer/space:1 <- copy 0:literal)
  (expanded-index:integer/space:1 <- copy 1:literal)
  (expanded-children:integer/space:1 <- copy 5:literal)
  (to-top 0:space-address/browser-state 2:terminal-address/raw)
  (print-page 0:space-address/browser-state 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 17
         (+ "+ main/ 0 : a b c"
            "- main/ 1 : d e f"
            "   mem : 1 a     "
            "                 "
            "                 "))
  (prn "F - page-up 3: expected post page-up state"))
;? (quit) ;? 1
(run-code main14
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (0:space-address/names:browser-state <- copy 3:space-address/raw/browser-state)
  (first-index-on-page:integer/space:1 <- copy 1:literal)
  (first-subindex-on-page:integer/space:1 <- copy -1:literal)
  (last-index-on-page:integer/space:1 <- copy 1:literal)
  (last-subindex-on-page:integer/space:1 <- copy 1:literal)
  (expanded-index:integer/space:1 <- copy 1:literal)
  (expanded-children:integer/space:1 <- copy 5:literal)
  (s:string-address <- new "K")
  (k:keyboard-address <- init-keyboard s:string-address)
;?   ($start-tracing) ;? 1
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 17
         (+ "+ main/ 0 : a b c"
            "- main/ 1 : d e f"
            "   mem : 1 a     "
            "                 "
            "                 "))
  (prn "F - page-up 3"))
;? (quit) ;? 1

; page-up scenario 4
; + run: main 0: a b c
;   mem: 0 a
; - run: main 1: d e f
;   mem: 1 a
;   mem: 1 b
;   mem: 1 c            <- top of page
;   mem: 1 d
;   mem: 1 e            <- bottom of page
; + run: main 2: g hi
; + run: main 3: j
;   mem: 3 a
; + run: main 4: k
; + run: main 5: l
; + run: main 6: m
; + run: main 7: n
(run-code main15
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (0:space-address/names:browser-state <- copy 3:space-address/raw/browser-state)
  (first-index-on-page:integer/space:1 <- copy 1:literal)
  (first-subindex-on-page:integer/space:1 <- copy 2:literal)
  (last-index-on-page:integer/space:1 <- copy 1:literal)
  (last-subindex-on-page:integer/space:1 <- copy 4:literal)
  (expanded-index:integer/space:1 <- copy 1:literal)
  (expanded-children:integer/space:1 <- copy 5:literal)
  (s:string-address <- new "K")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 17
         (+ "- main/ 1 : d e f"
            "   mem : 1 a     "
            "   mem : 1 b     "
            "                 "
            "                 "))
  (prn "F - page-up 4"))

; page-up scenario 5
; + run: main 0: a b c
;   mem: 0 a
; - run: main 1: d e f
;   mem: 1 a            <- top of page
;   mem: 1 b
;   mem: 1 c            <- bottom of page
;   mem: 1 d
;   mem: 1 e
; + run: main 2: g hi
; + run: main 3: j
;   mem: 3 a
; + run: main 4: k
; + run: main 5: l
; + run: main 6: m
; + run: main 7: n
(run-code main16pre
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (0:space-address/names:browser-state <- copy 3:space-address/raw/browser-state)
  (first-index-on-page:integer/space:1 <- copy 1:literal)
  (first-subindex-on-page:integer/space:1 <- copy 0:literal)
  (last-index-on-page:integer/space:1 <- copy 1:literal)
  (last-subindex-on-page:integer/space:1 <- copy 2:literal)
  (expanded-index:integer/space:1 <- copy 1:literal)
  (expanded-children:integer/space:1 <- copy 5:literal)
;?   ($print cursor-row:integer/space:1) ;? 1
  (to-top 0:space-address/browser-state 2:terminal-address/raw)
;?   ($print cursor-row:integer/space:1) ;? 1
  (print-page 0:space-address/browser-state 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 17
         (+ "   mem : 1 a     "
            "   mem : 1 b     "
            "   mem : 1 c     "
            "                 "
            "                 "))
  (prn "F - page-up 5: initial print-page state"))
(run-code main16
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (0:space-address/names:browser-state <- copy 3:space-address/raw/browser-state)
  (first-index-on-page:integer/space:1 <- copy 1:literal)
  (first-subindex-on-page:integer/space:1 <- copy 0:literal)
  (last-index-on-page:integer/space:1 <- copy 1:literal)
  (last-subindex-on-page:integer/space:1 <- copy 2:literal)
  (expanded-index:integer/space:1 <- copy 1:literal)
  (expanded-children:integer/space:1 <- copy 5:literal)
  (s:string-address <- new "K")
  (k:keyboard-address <- init-keyboard s:string-address)
;?   ($dump-browser-state 3:space-address/raw/browser-state) ;? 1
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 17
         (+ "+ main/ 0 : a b c"
            "- main/ 1 : d e f"
            "   mem : 1 a     "
            "                 "
            "                 "))
  (prn "F - page-up 5"))

; page-up scenario 6
; + run: main 0: a b c
;   mem: 0 a
; - run: main 1: d e f
;   mem: 1 a
;   mem: 1 b            <- top of page
;   mem: 1 c
;   mem: 1 d            <- bottom of page
;   mem: 1 e
; + run: main 2: g hi
; + run: main 3: j
;   mem: 3 a
; + run: main 4: k
; + run: main 5: l
; + run: main 6: m
; + run: main 7: n
(run-code main17
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (0:space-address/names:browser-state <- copy 3:space-address/raw/browser-state)
  (first-index-on-page:integer/space:1 <- copy 1:literal)
  (first-subindex-on-page:integer/space:1 <- copy 1:literal)
  (last-index-on-page:integer/space:1 <- copy 1:literal)
  (last-subindex-on-page:integer/space:1 <- copy 3:literal)
  (expanded-index:integer/space:1 <- copy 1:literal)
  (expanded-children:integer/space:1 <- copy 5:literal)
  (s:string-address <- new "K")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 17
         (+ "+ main/ 0 : a b c"
            "- main/ 1 : d e f"
            "   mem : 1 a     "
            "                 "
            "                 "))
  (prn "F - page-up 6"))

; page-up scenario 7
; + run: main 0: a b c
;   mem: 0 a
; + run: main 1: d e f  <- top of page
;   mem: 1 a
;   mem: 1 b
;   mem: 1 c
;   mem: 1 d
;   mem: 1 e
; + run: main 2: g hi
; - run: main 3: j      <- bottom of page
;   mem: 3 a
; + run: main 4: k
; + run: main 5: l
; + run: main 6: m
; + run: main 7: n
(run-code main18
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (0:space-address/names:browser-state <- copy 3:space-address/raw/browser-state)
  (first-index-on-page:integer/space:1 <- copy 1:literal)
  (first-subindex-on-page:integer/space:1 <- copy -2:literal)
  (last-index-on-page:integer/space:1 <- copy 3:literal)
  (last-subindex-on-page:integer/space:1 <- copy -1:literal)
  (expanded-index:integer/space:1 <- copy 3:literal)
  (expanded-children:integer/space:1 <- copy 1:literal)
  (s:string-address <- new "K")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 17
         (+ "+ main/ 0 : a b c"
            "+ main/ 1 : d e f"
            "+ main/ 2 : g hi "
            "                 "))
  (prn "F - page-up 7 - expanded index starts below bottom"))
;? (quit) ;? 1

; page-up scenario 8
; + run: main 0: a b c
;   mem: 0 a
; + run: main 1: d e f  <- top of page
;   mem: 1 a
;   mem: 1 b
;   mem: 1 c
;   mem: 1 d
;   mem: 1 e
; + run: main 2: g hi
; + run: main 3: j      <- bottom of page
;   mem: 3 a
; - run: main 4: k
; + run: main 5: l
; + run: main 6: m
; + run: main 7: n
(run-code main19
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (0:space-address/names:browser-state <- copy 3:space-address/raw/browser-state)
  (first-index-on-page:integer/space:1 <- copy 1:literal)
  (first-subindex-on-page:integer/space:1 <- copy -2:literal)
  (last-index-on-page:integer/space:1 <- copy 3:literal)
  (last-subindex-on-page:integer/space:1 <- copy -1:literal)
  (expanded-index:integer/space:1 <- copy 4:literal)
  (expanded-children:integer/space:1 <- copy 0:literal)
  (s:string-address <- new "K")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 17
         (+ "+ main/ 0 : a b c"
            "+ main/ 1 : d e f"
            "+ main/ 2 : g hi "
            "                 "))
  (prn "F - page-up 8 - expanded index starts below top - 2"))

; page-up scenario 9
; - run: main 0: a b c
;   mem: 0 a
; + run: main 1: d e f
;   mem: 1 a
;   mem: 1 b
;   mem: 1 c
;   mem: 1 d
;   mem: 1 e
; + run: main 2: g hi
; + run: main 3: j      <- top of page
;   mem: 3 a
; + run: main 4: k
; + run: main 5: l      <- bottom of page
; + run: main 6: m
; + run: main 7: n
(run-code main20
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (0:space-address/names:browser-state <- copy 3:space-address/raw/browser-state)
  (first-index-on-page:integer/space:1 <- copy 3:literal)
  (first-subindex-on-page:integer/space:1 <- copy -2:literal)
  (last-index-on-page:integer/space:1 <- copy 5:literal)
  (last-subindex-on-page:integer/space:1 <- copy -2:literal)
  (expanded-index:integer/space:1 <- copy 0:literal)
  (expanded-children:integer/space:1 <- copy 1:literal)
  (s:string-address <- new "K")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 17
         (+ "   mem : 0 a     "
            "+ main/ 1 : d e f"
            "+ main/ 2 : g hi "
            "                 "))
  (prn "F - page-up 9 - expanded index overlaps target page"))

; page-up scenario 10
; - run: main 0: a b c
;   mem: 0 a
; + run: main 1: d e f
;   mem: 1 a
;   mem: 1 b
;   mem: 1 c
;   mem: 1 d
;   mem: 1 e
; + run: main 2: g hi   <- top of page
; + run: main 3: j
;   mem: 3 a
; + run: main 4: k      <- bottom of page
; + run: main 5: l
; + run: main 6: m
; + run: main 7: n
(run-code main21pre
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (0:space-address/names:browser-state <- copy 3:space-address/raw/browser-state)
  (first-index-on-page:integer/space:1 <- copy 2:literal)
  (first-subindex-on-page:integer/space:1 <- copy -2:literal)
  (last-index-on-page:integer/space:1 <- copy 4:literal)
  (last-subindex-on-page:integer/space:1 <- copy -2:literal)
  (expanded-index:integer/space:1 <- copy 0:literal)
  (expanded-children:integer/space:1 <- copy 1:literal)
  (to-top 0:space-address/browser-state 2:terminal-address/raw)
;?   ($start-tracing) ;? 2
  (print-page 0:space-address/browser-state 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 17
         (+ "+ main/ 2 : g hi "
            "+ main/ 3 : j    "
            "+ main/ 4 : k    "
            "                 "
            "                 "))
  (prn "F - page-up 10: initial print-page state"))
;? (quit) ;? 1
(run-code main21
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (0:space-address/names:browser-state <- copy 3:space-address/raw/browser-state)
  (first-index-on-page:integer/space:1 <- copy 2:literal)
  (first-subindex-on-page:integer/space:1 <- copy -2:literal)
  (last-index-on-page:integer/space:1 <- copy 4:literal)
  (last-subindex-on-page:integer/space:1 <- copy -2:literal)
  (expanded-index:integer/space:1 <- copy 0:literal)
  (expanded-children:integer/space:1 <- copy 1:literal)
  (s:string-address <- new "K")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 17
         (+ "- main/ 0 : a b c"
            "   mem : 0 a     "
            "+ main/ 1 : d e f"
            "                 "
            "                 "))
  (prn "F - page-up 10 - expanded index overlaps target page - 2"))
;? (quit) ;? 2

(reset2)
(new-trace "trace-paginate2")
; page-up scenario 11
; + run: main 0: a b c
;   mem: 0 a
; + run: main 1: d e f
; - run: main 2: g hi
;   mem: 2 a
; + run: main 3: j      <- top of page
;   mem: 3 a
; + run: main 4: k
; + run: main 5: l      <- bottom of page
; + run: main 6: m
; + run: main 7: n
(run-code main22
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (x:string-address <- new
"run: main 0: a b c
mem: 0 a
run: main 1: d e f
run: main 2: g hi
mem: 2 a
run: main 3: j
mem: 3 a
run: main 4: k
run: main 5: l
run: main 6: m
run: main 7: n")
  (s:stream-address <- init-stream x:string-address)
  (traces:instruction-trace-address-array-address <- parse-traces s:stream-address)
  (2:terminal-address/raw <- init-fake-terminal 17:literal 15:literal)
  (3:space-address/raw/browser-state <- browser-state traces:instruction-trace-address-array-address 3:literal/screen-height)
  (0:space-address/names:browser-state <- copy 3:space-address/raw/browser-state)
  (4:string-address/raw <- get 2:terminal-address/raw/deref data:offset)
  (first-index-on-page:integer/space:1 <- copy 3:literal)
  (first-subindex-on-page:integer/space:1 <- copy -2:literal)
  (last-index-on-page:integer/space:1 <- copy 5:literal)
  (last-subindex-on-page:integer/space:1 <- copy -2:literal)
  (expanded-index:integer/space:1 <- copy 2:literal)
  (expanded-children:integer/space:1 <- copy 1:literal)
  (s:string-address <- new "K")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 17
         (+ "+ main/ 1 : d e f"
            "- main/ 2 : g hi "
            "   mem : 2 a     "
            "                 "
            "                 "))
  (prn "F - page-up 11 - expanded index overlaps target page - 3"))

; page-up scenario 12
; + run: main 0: a b c
;   mem: 0 a
; + run: main 1: d e f
; - run: main 2: g hi
;   mem: 2 a
; + run: main 3: j
;   mem: 3 a
; + run: main 4: k      <- top of page
; + run: main 5: l
; + run: main 6: m      <- bottom of page
; + run: main 7: n
(run-code main23
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (0:space-address/names:browser-state <- copy 3:space-address/raw/browser-state)
  (first-index-on-page:integer/space:1 <- copy 4:literal)
  (first-subindex-on-page:integer/space:1 <- copy -2:literal)
  (last-index-on-page:integer/space:1 <- copy 6:literal)
  (last-subindex-on-page:integer/space:1 <- copy -2:literal)
  (expanded-index:integer/space:1 <- copy 2:literal)
  (expanded-children:integer/space:1 <- copy 1:literal)
  (s:string-address <- new "K")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 17
         (+ "- main/ 2 : g hi "
            "   mem : 2 a     "
            "+ main/ 3 : j    "
            "                 "))
  (prn "F - page-up 12 - expanded index overlaps target page - 4"))

; page-up scenario 13
; + run: main 0: a b c
;   mem: 0 a
; + run: main 1: d e f
; - run: main 2: g hi
;   mem: 2 a
; + run: main 3: j
;   mem: 3 a
; + run: main 4: k
; + run: main 5: l
; + run: main 6: m      <- top of page
; + run: main 7: n      <- bottom of page
(run-code main24
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (0:space-address/names:browser-state <- copy 3:space-address/raw/browser-state)
  (first-index-on-page:integer/space:1 <- copy 6:literal)
  (first-subindex-on-page:integer/space:1 <- copy -2:literal)
  (last-index-on-page:integer/space:1 <- copy 7:literal)
  (last-subindex-on-page:integer/space:1 <- copy -2:literal)
  (expanded-index:integer/space:1 <- copy 2:literal)
  (expanded-children:integer/space:1 <- copy 1:literal)
  (s:string-address <- new "K")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 17
         (+ "+ main/ 3 : j    "
            "+ main/ 4 : k    "
            "+ main/ 5 : l    "
            "                 "))
  (prn "F - page-up 13 - expanded index far above target page"))

(run-code main25
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (0:space-address/names:browser-state <- copy 3:space-address/raw/browser-state)
  (s:string-address <- new "kk\n")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 17
         (+ "+ main/ 3 : j    "
            "- main/ 4 : k    "
            "+ main/ 5 : l    "
            "                 "))
  (prn "F - process-key expands a trace index on any page"))
(run-code main26
  (replace-character 2:terminal-address/raw ((#\* literal)))
)
(when (~screen-contains memory*.4 17
         (+ "+ main/ 3 : j    "
            "* main/ 4 : k    "
            "+ main/ 5 : l    "
            "                 "))
  (prn "F - process-key resets the cursor after expand"))
;? (quit) ;? 1

(run-code main27
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (0:space-address/names:browser-state <- copy 3:space-address/raw/browser-state)
  ; reset previous cursor
  (replace-character 2:terminal-address/raw ((#\- literal)))
  (s:string-address <- new "j\n")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 17
         (+ "+ main/ 3 : j    "
            "+ main/ 4 : k    "
            "- main/ 5 : l    "
            "                 "))
  (prn "F - process-key expands a trace index on any page when there's an expanded trace index above it on the same page"))

; expand scenario
; + run: main 0: a b c
;   mem: 0 a
; + run: main 1: d e f
; - run: main 2: g hi
;   mem: 2 a              <- top of page
; + run: main 3: j
;   mem: 3 a
; + run: main 4: k        <- bottom of page
; + run: main 5: l
; + run: main 6: m
; + run: main 7: n
(run-code main28
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (0:space-address/names:browser-state <- copy 3:space-address/raw/browser-state)
  (first-index-on-page:integer/space:1 <- copy 2:literal)
  (first-subindex-on-page:integer/space:1 <- copy 0:literal)
  (last-index-on-page:integer/space:1 <- copy 4:literal)
  (last-subindex-on-page:integer/space:1 <- copy -2:literal)
  (expanded-index:integer/space:1 <- copy 2:literal)
  (expanded-children:integer/space:1 <- copy 1:literal)
  (to-top 0:space-address/browser-state 2:terminal-address/raw)
  (print-page 0:space-address/browser-state 2:terminal-address/raw)
  (s:string-address <- new "kk\n")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
;?   (replace-character 2:terminal-address/raw ((#\* literal))) ;? 2
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 17
;?          (+ "   mem : 2 a     "  ; after print-page
;?             "+ main/ 3 : j    "
;?             "+ main/ 4 : k    "
;?             "                 "))
         (+ "+ main/ 2 : g hi "
            "- main/ 3 : j    "
            "   mem : 3 a     "
            "                 "))
;?          (+ "- main/ 3 : j    "  ; alternative interpretation in case the above isn't intuitive
;?             "   mem : 3 a     "
;?          (+ "- main/ 4 : k    "
;?             "                 "))
  (prn "F - process-key expands trace index on a page that starts with a partial expanded trace"))

(reset2)
(new-trace "trace-paginate3")
; expand scenario
; + run: main 0: a b c
;   mem: 0 a
; + run: main 1: d e f
;   mem: 1 a
;   mem: 1 b              <- top of page
;   mem: 1 c
; + run: main 2: g hi     <- bottom of page
;   mem: 2 a
; + run: main 3: j
; + run: main 4: k
; + run: main 5: l
(run-code main29
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (x:string-address <- new
"run: main 0: a b c
mem: 0 a
run: main 1: d e f
mem: 1 a
mem: 1 b
mem: 1 c
run: main 2: g hi
mem: 2 a
run: main 3: j
run: main 4: k
run: main 5: l")
  (s:stream-address <- init-stream x:string-address)
  (traces:instruction-trace-address-array-address <- parse-traces s:stream-address)
  (2:terminal-address/raw <- init-fake-terminal 17:literal 15:literal)
  (3:space-address/raw/browser-state <- browser-state traces:instruction-trace-address-array-address 3:literal/screen-height)
  (0:space-address/names:browser-state <- copy 3:space-address/raw/browser-state)
  (4:string-address/raw <- get 2:terminal-address/raw/deref data:offset)
  (first-index-on-page:integer/space:1 <- copy 1:literal)
  (first-subindex-on-page:integer/space:1 <- copy 1:literal)
  (last-index-on-page:integer/space:1 <- copy 3:literal)
  (last-subindex-on-page:integer/space:1 <- copy -2:literal)
  (expanded-index:integer/space:1 <- copy 1:literal)
  (expanded-children:integer/space:1 <- copy 3:literal)
  (to-top 0:space-address/browser-state 2:terminal-address/raw)
  (print-page 0:space-address/browser-state 2:terminal-address/raw)
;?   (replace-character 2:terminal-address/raw ((#\* literal))) ;? 1
  (s:string-address <- new "k\n")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 17
;?          (+ "   mem : 1 b     "  ; after print-page
;?             "   mem : 1 c     "
;?             "+ main/ 2 : g hi "
;?             "*                "
;?             "                 "))
         (+ "+ main/ 1 : d e f"
            "- main/ 2 : g hi "
            "   mem : 2 a     "
            "                 "
            "                 "))
  (prn "F - process-key expands trace index on a page that starts with a partial expanded trace - 2"))

; expand scenario
; + run: main 0: a b c
;   mem: 0 a
; + run: main 1: d e f
;   mem: 1 a              <- top of page
;   mem: 1 b
;   mem: 1 c              <- bottom of page
; + run: main 2: g hi
;   mem: 2 a
; + run: main 3: j
; + run: main 4: k
; + run: main 5: l
(run-code main30
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (0:space-address/names:browser-state <- copy 3:space-address/raw/browser-state)
  (first-index-on-page:integer/space:1 <- copy 1:literal)
  (first-subindex-on-page:integer/space:1 <- copy 0:literal)
  (last-index-on-page:integer/space:1 <- copy 1:literal)
  (last-subindex-on-page:integer/space:1 <- copy 2:literal)
  (expanded-index:integer/space:1 <- copy 1:literal)
  (expanded-children:integer/space:1 <- copy 3:literal)
  (to-top 0:space-address/browser-state 2:terminal-address/raw)
  (print-page 0:space-address/browser-state 2:terminal-address/raw)
  (s:string-address <- new "k\n")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
;?   (replace-character 2:terminal-address/raw ((#\* literal))) ;? 1
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 17
;?          (+ "   mem : 1 a     "  ; after print-page
;?             "   mem : 1 b     "
;?             "   mem : 1 c     "
;?             "*                "))
         (+ "+ main/ 1 : d e f"
            "+ main/ 2 : g hi "
            "+ main/ 3 : j    "))
  (prn "F - process-key expands trace index on a page with only subindex lines"))

(run-code main31
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (0:space-address/names:browser-state <- copy 3:space-address/raw/browser-state)
  ; reinitialize
  (first-index-on-page:integer/space:1 <- copy 0:literal)
  (first-subindex-on-page:integer/space:1 <- copy -2:literal)
  (last-index-on-page:integer/space:1 <- copy 2:literal)
  (last-subindex-on-page:integer/space:1 <- copy -2:literal)
  (expanded-index:integer/space:1 <- copy -1:literal)
  (expanded-children:integer/space:1 <- copy -1:literal)
  (to-top 0:space-address/browser-state 2:terminal-address/raw)
  (print-page 0:space-address/browser-state 2:terminal-address/raw)
;?   (replace-character 2:terminal-address/raw ((#\* literal))) ;? 1
  (s:string-address <- new "Jjj\n")
  (k:keyboard-address <- init-keyboard s:string-address)
;?   ($print (("test: first subindex " literal))) ;? 1
;?   ($print first-subindex-on-page:integer/space:1) ;? 1
;?   ($print (("\n" literal))) ;? 1
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
;?   ($print (("test: first subindex 2 " literal))) ;? 1
;?   ($print first-subindex-on-page:integer/space:1) ;? 1
;?   ($print (("\n" literal))) ;? 1
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
;?   ($print (("test: first subindex 3 " literal))) ;? 1
;?   ($print first-subindex-on-page:integer/space:1) ;? 1
;?   ($print (("\n" literal))) ;? 1
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
;?   ($print (("test: first subindex 4 " literal))) ;? 1
;?   ($print first-subindex-on-page:integer/space:1) ;? 1
;?   ($print (("\n" literal))) ;? 1
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
(when (~screen-contains memory*.4 17
         (+ "+ main/ 3 : j    "
            "+ main/ 4 : k    "
            "- main/ 5 : l    "
            "                 "
            "                 "))
  (prn "F - process-key expands final index of trace at bottom of page"))

(run-code main32
  (default-space:space-address <- new space:literal 30:literal/capacity)
  (0:space-address/names:browser-state <- copy 3:space-address/raw/browser-state)
  ; reinitialize
  (first-index-on-page:integer/space:1 <- copy 0:literal)
  (first-subindex-on-page:integer/space:1 <- copy -2:literal)
  (last-index-on-page:integer/space:1 <- copy 2:literal)
  (last-subindex-on-page:integer/space:1 <- copy -2:literal)
  (expanded-index:integer/space:1 <- copy -1:literal)
  (expanded-children:integer/space:1 <- copy -1:literal)
  (to-top 0:space-address/browser-state 2:terminal-address/raw)
  (print-page 0:space-address/browser-state 2:terminal-address/raw)
;?   (replace-character 2:terminal-address/raw ((#\* literal))) ;? 1
  (s:string-address <- new "kk\nJjj")
  (k:keyboard-address <- init-keyboard s:string-address)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (process-key 3:space-address/raw/browser-state k:keyboard-address 2:terminal-address/raw)
  (5:integer-address/raw <- get-address 2:terminal-address/raw/deref cursor-row:offset)
  )
(each routine completed-routines*
  (awhen rep.routine!error
    (prn "error - " it)))
;? (prn (memory* memory*.5)) ;? 1
(when (~is 3 (memory* memory*.5))
  (prn "F - key movement stays within screen bounds, even when no next trace on page"))

(reset2)
;? (print-times) ;? 3
>> RUN: <span class="Delimiter">{</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span> <span class="Normal">case</span> RUN: <span class="Delimiter">{</span> assert<span class="Delimiter">(</span>Name[Next_recipe_ordinal]<span class="Delimiter">.</span>empty<span class="Delimiter">());</span> ostringstream tmp<span class="Delimiter">;</span> tmp &lt;&lt; <span class="Constant">&quot;recipe run_&quot;</span> &lt;&lt; Next_recipe_ordinal &lt;&lt; <span class="Constant">&quot; [ &quot;</span> &lt;&lt; current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot; ]&quot;</span><span class="Delimiter">;</span> vector&lt;recipe_ordinal&gt; tmp_recipe = load<span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>str<span class="Delimiter">());</span> mark_autogenerated<span class="Delimiter">(</span>tmp_recipe<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> bind_special_scenario_names<span class="Delimiter">(</span>tmp_recipe<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> transform_all<span class="Delimiter">();</span> <span class="Normal">if</span> <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">)</span> <span class="Delimiter">{</span> ++Trace_stream<span class="Delimiter">-&gt;</span>callstack_depth<span class="Delimiter">;</span> trace<span class="Delimiter">(</span><span class="Constant">9998</span><span class="Delimiter">,</span> <span class="Constant">&quot;trace&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;run: incrementing callstack depth to &quot;</span> &lt;&lt; Trace_stream<span class="Delimiter">-&gt;</span>callstack_depth &lt;&lt; end<span class="Delimiter">();</span> assert<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-&gt;</span>callstack_depth &lt; <span class="Constant">9000</span><span class="Delimiter">);</span> <span class="Comment">// 9998-101 plus cushion</span> <span class="Delimiter">}</span> Current_routine<span class="Delimiter">-&gt;</span>calls<span class="Delimiter">.</span>push_front<span class="Delimiter">(</span>call<span class="Delimiter">(</span>tmp_recipe<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)));</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Comment">// not done with caller; don't increment current_step_index()</span> <span class="Delimiter">}</span> <span class="Delimiter">:(before &quot;End maybe_make_raw&quot;)</span> <span class="Normal">if</span> <span class="Delimiter">(</span>starts_with<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">,</span> <span class="Constant">&quot;run_&quot;</span><span class="Delimiter">))</span> r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair&lt;string<span class="Delimiter">,</span> string_tree*&gt;<span class="Delimiter">(</span><span class="Constant">&quot;raw&quot;</span><span class="Delimiter">,</span> <span class="Constant">NULL</span><span class="Delimiter">));</span> <span class="Delimiter">:(scenario run_multiple)</span> def main [ run [ <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">13</span> ] run [ <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">13</span> ] ] <span class="traceContains">+mem: storing 13 in location 1</span> <span class="traceContains">+mem: storing 13 in location 2</span> <span class="Comment">//: 'memory-should-contain' raises errors if specific locations aren't as expected</span> <span class="Comment">//: Also includes some special support for checking strings.</span> <span class="Delimiter">:(before &quot;End Globals&quot;)</span> <span class="Normal">bool</span> Scenario_testing_scenario = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">:(before &quot;End Setup&quot;)</span> Scenario_testing_scenario = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">:(scenario memory_check)</span> <span class="Special">% Scenario_testing_scenario = true;</span> <span class="Special">% Hide_errors = true;</span> def main [ memory-should-contain [ <span class="Constant">1</span><span class="Special"> &lt;- </span><span class="Constant">13</span> ] ] <span class="traceContains">+run: checking location 1</span> <span class="traceContains">+error: expected location '1' to contain 13 but saw 0</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span> MEMORY_SHOULD_CONTAIN<span class="Delimiter">,</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span> put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;memory-should-contain&quot;</span><span class="Delimiter">,</span> MEMORY_SHOULD_CONTAIN<span class="Delimiter">);</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Checks&quot;)</span> <span class="Normal">case</span> MEMORY_SHOULD_CONTAIN: <span class="Delimiter">{</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span> <span class="Normal">case</span> MEMORY_SHOULD_CONTAIN: <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!Passed<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> check_memory<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">);</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> <span class="Normal">void</span> check_memory<span class="Delimiter">(</span><span class="Normal">const</span> string&amp; s<span class="Delimiter">)</span> <span class="Delimiter">{</span> istringstream in<span class="Delimiter">(</span>s<span class="Delimiter">);</span> in &gt;&gt; std::noskipws<span class="Delimiter">;</span> set&lt;<span class="Normal">int</span>&gt; locations_checked<span class="Delimiter">;</span> <span class="Normal">while</span> <span class="Delimiter">(</span><span class="Constant">true</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Identifier">break</span><span class="Delimiter">;</span> string lhs = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!is_integer<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Delimiter">{</span> check_type<span class="Delimiter">(</span>lhs<span class="Delimiter">,</span> in<span class="Delimiter">);</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">int</span> address = to_integer<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span> skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span> string _assign<span class="Delimiter">;</span> in &gt;&gt; _assign<span class="Delimiter">;</span> assert<span class="Delimiter">(</span>_assign == <span class="Constant">&quot;&lt;-&quot;</span><span class="Delimiter">);</span> skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span> string rhs = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!is_integer<span class="Delimiter">(</span>rhs<span class="Delimiter">)</span> &amp;&amp; !is_noninteger<span class="Delimiter">(</span>rhs<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>Current_scenario &amp;&amp; !Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Comment">// genuine test in a mu file</span> raise &lt;&lt; <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">F - &quot;</span> &lt;&lt; Current_scenario<span class="Delimiter">-&gt;</span>name &lt;&lt; <span class="Constant">&quot;: location '&quot;</span> &lt;&lt; address &lt;&lt; <span class="Constant">&quot;' can't contain non-number &quot;</span> &lt;&lt; rhs &lt;&lt; <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Normal">else</span> <span class="Comment">// just testing scenario support</span> raise &lt;&lt; <span class="Constant">&quot;location '&quot;</span> &lt;&lt; address &lt;&lt; <span class="Constant">&quot;' can't contain non-number &quot;</span> &lt;&lt; rhs &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!Scenario_testing_scenario<span class="Delimiter">)</span> Passed = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">double</span> value = to_double<span class="Delimiter">(</span>rhs<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>locations_checked<span class="Delimiter">,</span> address<span class="Delimiter">))</span> raise &lt;&lt; <span class="Constant">&quot;duplicate expectation for location '&quot;</span> &lt;&lt; address &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;checking location &quot;</span> &lt;&lt; address &lt;&lt; end<span class="Delimiter">();</span> <span class="Normal">if</span> <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address<span class="Delimiter">)</span> != value<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>Current_scenario &amp;&amp; !Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// genuine test in a mu file</span> raise &lt;&lt; <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">F - &quot;</span> &lt;&lt; Current_scenario<span class="Delimiter">-&gt;</span>name &lt;&lt; <span class="Constant">&quot;: expected location '&quot;</span> &lt;&lt; address &lt;&lt; <span class="Constant">&quot;' to contain &quot;</span> &lt;&lt; no_scientific<span class="Delimiter">(</span>value<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; but saw &quot;</span> &lt;&lt; no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address<span class="Delimiter">))</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Normal">else</span> <span class="Delimiter">{</span> <span class="Comment">// just testing scenario support</span> raise &lt;&lt; <span class="Constant">&quot;expected location '&quot;</span> &lt;&lt; address &lt;&lt; <span class="Constant">&quot;' to contain &quot;</span> &lt;&lt; no_scientific<span class="Delimiter">(</span>value<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; but saw &quot;</span> &lt;&lt; no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address<span class="Delimiter">))</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!Scenario_testing_scenario<span class="Delimiter">)</span> Passed = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> locations_checked<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>address<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Normal">void</span> check_type<span class="Delimiter">(</span><span class="Normal">const</span> string&amp; lhs<span class="Delimiter">,</span> istream&amp; in<span class="Delimiter">)</span> <span class="Delimiter">{</span> reagent x<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_array<span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span class="Delimiter">)</span> &amp;&amp; is_mu_character<span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>right<span class="Delimiter">))</span> <span class="Delimiter">{</span> x<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>to_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">));</span> skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span> string _assign = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span> assert<span class="Delimiter">(</span>_assign == <span class="Constant">&quot;&lt;-&quot;</span><span class="Delimiter">);</span> skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span> string literal = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span> <span class="Normal">int</span> address = x<span class="Delimiter">.</span>value<span class="Delimiter">;</span> <span class="Comment">// exclude quoting brackets</span> assert<span class="Delimiter">(</span>*literal<span class="Delimiter">.</span>begin<span class="Delimiter">()</span> == <span class="Constant">'['</span><span class="Delimiter">);</span> literal<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>literal<span class="Delimiter">.</span>begin<span class="Delimiter">());</span> assert<span class="Delimiter">(</span>*--literal<span class="Delimiter">.</span>end<span class="Delimiter">()</span> == <span class="Constant">']'</span><span class="Delimiter">);</span> literal<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>--literal<span class="Delimiter">.</span>end<span class="Delimiter">());</span> check_string<span class="Delimiter">(</span>address<span class="Delimiter">,</span> literal<span class="Delimiter">);</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Comment">// End Scenario Type Cases</span> raise &lt;&lt; <span class="Constant">&quot;don't know how to check memory for '&quot;</span> &lt;&lt; lhs &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Normal">void</span> check_string<span class="Delimiter">(</span><span class="Normal">int</span> address<span class="Delimiter">,</span> <span class="Normal">const</span> string&amp; literal<span class="Delimiter">)</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;checking string length at &quot;</span> &lt;&lt; address &lt;&lt; end<span class="Delimiter">();</span> <span class="Normal">if</span> <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address<span class="Delimiter">)</span> != SIZE<span class="Delimiter">(</span>literal<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>Current_scenario &amp;&amp; !Scenario_testing_scenario<span class="Delimiter">)</span> raise &lt;&lt; <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">F - &quot;</span> &lt;&lt; Current_scenario<span class="Delimiter">-&gt;</span>name &lt;&lt; <span class="Constant">&quot;: expected location '&quot;</span> &lt;&lt; address &lt;&lt; <span class="Constant">&quot;' to contain length &quot;</span> &lt;&lt; SIZE<span class="Delimiter">(</span>literal<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; of string [&quot;</span> &lt;&lt; literal &lt;&lt; <span class="Constant">&quot;] but saw &quot;</span> &lt;&lt; no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address<span class="Delimiter">))</span> &lt;&lt; <span class="Constant">&quot; (&quot;</span> &lt;&lt; read_mu_string<span class="Delimiter">(</span>address<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;)</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Normal">else</span> raise &lt;&lt; <span class="Constant">&quot;expected location '&quot;</span> &lt;&lt; address &lt;&lt; <span class="Constant">&quot;' to contain length &quot;</span> &lt;&lt; SIZE<span class="Delimiter">(</span>literal<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; of string [&quot;</span> &lt;&lt; literal &lt;&lt; <span class="Constant">&quot;] but saw &quot;</span> &lt;&lt; no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address<span class="Delimiter">))</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!Scenario_testing_scenario<span class="Delimiter">)</span> Passed = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> ++address<span class="Delimiter">;</span> <span class="Comment">// now skip length</span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>literal<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;checking location &quot;</span> &lt;&lt; address+i &lt;&lt; end<span class="Delimiter">();</span> <span class="Normal">if</span> <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address+i<span class="Delimiter">)</span> != literal<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>Current_scenario &amp;&amp; !Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// genuine test in a mu file</span> raise &lt;&lt; <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">F - &quot;</span> &lt;&lt; Current_scenario<span class="Delimiter">-&gt;</span>name &lt;&lt; <span class="Constant">&quot;: expected location &quot;</span> &lt;&lt; <span class="Delimiter">(</span>address+i<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; to contain &quot;</span> &lt;&lt; literal<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; but saw &quot;</span> &lt;&lt; no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address+i<span class="Delimiter">))</span> &lt;&lt; <span class="Constant">&quot; ('&quot;</span> &lt;&lt; <span class="Normal">static_cast</span>&lt;<span class="Normal">char</span>&gt;<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address+i<span class="Delimiter">))</span> &lt;&lt; <span class="Constant">&quot;')</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Normal">else</span> <span class="Delimiter">{</span> <span class="Comment">// just testing scenario support</span> raise &lt;&lt; <span class="Constant">&quot;expected location &quot;</span> &lt;&lt; <span class="Delimiter">(</span>address+i<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; to contain &quot;</span> &lt;&lt; literal<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; but saw &quot;</span> &lt;&lt; no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address+i<span class="Delimiter">))</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!Scenario_testing_scenario<span class="Delimiter">)</span> Passed = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Delimiter">:(scenario memory_check_multiple)</span> <span class="Special">% Scenario_testing_scenario = true;</span> <span class="Special">% Hide_errors = true;</span> def main [ memory-should-contain [ <span class="Constant">1</span><span class="Special"> &lt;- </span><span class="Constant">0</span> <span class="Constant">1</span><span class="Special"> &lt;- </span><span class="Constant">0</span> ] ] <span class="traceContains">+error: duplicate expectation for location '1'</span> <span class="Delimiter">:(scenario memory_check_string_length)</span> <span class="Special">% Scenario_testing_scenario = true;</span> <span class="Special">% Hide_errors = true;</span> def main [ <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">3</span> <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">97</span> <span class="Comment"># 'a'</span> <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">98</span> <span class="Comment"># 'b'</span> <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">99</span> <span class="Comment"># 'c'</span> memory-should-contain [ <span class="Constant">1</span>:array:character<span class="Special"> &lt;- </span>[ab] ] ] <span class="traceContains">+error: expected location '1' to contain length 2 of string [ab] but saw 3</span> <span class="Delimiter">:(scenario memory_check_string)</span> def main [ <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">3</span> <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">97</span> <span class="Comment"># 'a'</span> <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">98</span> <span class="Comment"># 'b'</span> <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">99</span> <span class="Comment"># 'c'</span> memory-should-contain [ <span class="Constant">1</span>:array:character<span class="Special"> &lt;- </span>[abc] ] ] <span class="traceContains">+run: checking string length at 1</span> <span class="traceContains">+run: checking location 2</span> <span class="traceContains">+run: checking location 3</span> <span class="traceContains">+run: checking location 4</span> <span class="Delimiter">:(scenario memory_invalid_string_check)</span> <span class="Special">% Scenario_testing_scenario = true;</span> <span class="Special">% Hide_errors = true;</span> def main [ memory-should-contain [ <span class="Constant">1</span><span class="Special"> &lt;- </span>[abc] ] ] <span class="traceContains">+error: location '1' can't contain non-number [abc]</span> <span class="Delimiter">:(scenario memory_check_with_comment)</span> <span class="Special">% Scenario_testing_scenario = true;</span> <span class="Special">% Hide_errors = true;</span> def main [ memory-should-contain [ <span class="Constant">1</span><span class="Special"> &lt;- </span><span class="Constant">34</span> <span class="Comment"># comment</span> ] ] <span class="traceAbsent">-error: location 1 can't contain non-number 34 # comment</span> <span class="Comment"># but there'll be an error signalled by memory-should-contain</span> <span class="Comment">//: 'trace-should-contain' is like the '+' lines in our scenarios so far</span> <span class="Comment">// Like runs of contiguous '+' lines, order is important. The trace checks</span> <span class="Comment">// that the lines are present *and* in the specified sequence. (There can be</span> <span class="Comment">// other lines in between.)</span> <span class="Delimiter">:(scenario trace_check_fails)</span> <span class="Special">% Scenario_testing_scenario = true;</span> <span class="Special">% Hide_errors = true;</span> def main [ trace-should-contain [ <span class="Normal">a</span>: b <span class="Normal">a</span>: d ] ] <span class="traceContains">+error: missing [b] in trace with label 'a'</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span> TRACE_SHOULD_CONTAIN<span class="Delimiter">,</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span> put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;trace-should-contain&quot;</span><span class="Delimiter">,</span> TRACE_SHOULD_CONTAIN<span class="Delimiter">);</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Checks&quot;)</span> <span class="Normal">case</span> TRACE_SHOULD_CONTAIN: <span class="Delimiter">{</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span> <span class="Normal">case</span> TRACE_SHOULD_CONTAIN: <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!Passed<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> check_trace<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">);</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> <span class="Comment">// simplified version of check_trace_contents() that emits errors rather</span> <span class="Comment">// than just printing to stderr</span> <span class="Normal">void</span> check_trace<span class="Delimiter">(</span><span class="Normal">const</span> string&amp; expected<span class="Delimiter">)</span> <span class="Delimiter">{</span> Trace_stream<span class="Delimiter">-&gt;</span>newline<span class="Delimiter">();</span> vector&lt;trace_line&gt; expected_lines = parse_trace<span class="Delimiter">(</span>expected<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>expected_lines<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Normal">int</span> curr_expected_line = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Normal">for</span> <span class="Delimiter">(</span>vector&lt;trace_line&gt;::iterator p = Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>label != p<span class="Delimiter">-&gt;</span>label<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>contents != trim<span class="Delimiter">(</span>p<span class="Delimiter">-&gt;</span>contents<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Comment">// match</span> ++curr_expected_line<span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>curr_expected_line == SIZE<span class="Delimiter">(</span>expected_lines<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>Current_scenario &amp;&amp; !Scenario_testing_scenario<span class="Delimiter">)</span> raise &lt;&lt; <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">F - &quot;</span> &lt;&lt; Current_scenario<span class="Delimiter">-&gt;</span>name &lt;&lt; <span class="Constant">&quot;: missing [&quot;</span> &lt;&lt; expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>contents &lt;&lt; <span class="Constant">&quot;] &quot;</span> &lt;&lt; <span class="Constant">&quot;in trace with label '&quot;</span> &lt;&lt; expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>label &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Normal">else</span> raise &lt;&lt; <span class="Constant">&quot;missing [&quot;</span> &lt;&lt; expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>contents &lt;&lt; <span class="Constant">&quot;] &quot;</span> &lt;&lt; <span class="Constant">&quot;in trace with label '&quot;</span> &lt;&lt; expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>label &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!Hide_errors<span class="Delimiter">)</span> DUMP<span class="Delimiter">(</span>expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>label<span class="Delimiter">);</span> Passed = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> vector&lt;trace_line&gt; parse_trace<span class="Delimiter">(</span><span class="Normal">const</span> string&amp; expected<span class="Delimiter">)</span> <span class="Delimiter">{</span> vector&lt;string&gt; buf = split<span class="Delimiter">(</span>expected<span class="Delimiter">,</span> <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="Delimiter">);</span> vector&lt;trace_line&gt; result<span class="Delimiter">;</span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>buf<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> buf<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> = trim<span class="Delimiter">(</span>buf<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> <span class="Normal">if</span> <span class="Delimiter">(</span>buf<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>empty<span class="Delimiter">())</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Normal">int</span> delim = buf<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>find<span class="Delimiter">(</span><span class="Constant">&quot;: &quot;</span><span class="Delimiter">);</span> result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>trace_line<span class="Delimiter">(</span>trim<span class="Delimiter">(</span>buf<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>substr<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">,</span> delim<span class="Delimiter">)),</span> trim<span class="Delimiter">(</span>buf<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>substr<span class="Delimiter">(</span>delim+<span class="Constant">2</span><span class="Delimiter">))));</span> <span class="Delimiter">}</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(scenario trace_check_fails_in_nonfirst_line)</span> <span class="Special">% Scenario_testing_scenario = true;</span> <span class="Special">% Hide_errors = true;</span> def main [ run [ trace <span class="Constant">1</span><span class="Delimiter">,</span> [a]<span class="Delimiter">,</span> [b] ] trace-should-contain [ <span class="Normal">a</span>: b <span class="Normal">a</span>: d ] ] <span class="traceContains">+error: missing [d] in trace with label 'a'</span> <span class="Delimiter">:(scenario trace_check_passes_silently)</span> <span class="Special">% Scenario_testing_scenario = true;</span> def main [ run [ trace <span class="Constant">1</span><span class="Delimiter">,</span> [a]<span class="Delimiter">,</span> [b] ] trace-should-contain [ <span class="Normal">a</span>: b ] ] <span class="traceAbsent">-error: missing [b] in trace with label 'a'</span> $error: <span class="Constant">0</span> <span class="Comment">//: 'trace-should-not-contain' is like the '-' lines in our scenarios so far</span> <span class="Comment">//: Each trace line is separately checked for absense. Order is *not*</span> <span class="Comment">//: important, so you can't say things like &quot;B should not exist after A.&quot;</span> <span class="Delimiter">:(scenario trace_negative_check_fails)</span> <span class="Special">% Scenario_testing_scenario = true;</span> <span class="Special">% Hide_errors = true;</span> def main [ run [ trace <span class="Constant">1</span><span class="Delimiter">,</span> [a]<span class="Delimiter">,</span> [b] ] trace-should-<span class="Normal">not</span>-contain [ <span class="Normal">a</span>: b ] ] <span class="traceContains">+error: unexpected [b] in trace with label 'a'</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span> TRACE_SHOULD_NOT_CONTAIN<span class="Delimiter">,</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span> put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;trace-should-not-contain&quot;</span><span class="Delimiter">,</span> TRACE_SHOULD_NOT_CONTAIN<span class="Delimiter">);</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Checks&quot;)</span> <span class="Normal">case</span> TRACE_SHOULD_NOT_CONTAIN: <span class="Delimiter">{</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span> <span class="Normal">case</span> TRACE_SHOULD_NOT_CONTAIN: <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!Passed<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> check_trace_missing<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">);</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> <span class="Comment">// simplified version of check_trace_contents() that emits errors rather</span> <span class="Comment">// than just printing to stderr</span> <span class="Normal">bool</span> check_trace_missing<span class="Delimiter">(</span><span class="Normal">const</span> string&amp; in<span class="Delimiter">)</span> <span class="Delimiter">{</span> Trace_stream<span class="Delimiter">-&gt;</span>newline<span class="Delimiter">();</span> vector&lt;trace_line&gt; lines = parse_trace<span class="Delimiter">(</span>in<span class="Delimiter">);</span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>lines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>trace_count<span class="Delimiter">(</span>lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>label<span class="Delimiter">,</span> lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>contents<span class="Delimiter">)</span> != <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise &lt;&lt; <span class="Constant">&quot;unexpected [&quot;</span> &lt;&lt; lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>contents &lt;&lt; <span class="Constant">&quot;] in trace with label '&quot;</span> &lt;&lt; lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>label &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> Passed = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(scenario trace_negative_check_passes_silently)</span> <span class="Special">% Scenario_testing_scenario = true;</span> def main [ trace-should-<span class="Normal">not</span>-contain [ <span class="Normal">a</span>: b ] ] <span class="traceAbsent">-error: unexpected [b] in trace with label 'a'</span> $error: <span class="Constant">0</span> <span class="Delimiter">:(scenario trace_negative_check_fails_on_any_unexpected_line)</span> <span class="Special">% Scenario_testing_scenario = true;</span> <span class="Special">% Hide_errors = true;</span> def main [ run [ trace <span class="Constant">1</span><span class="Delimiter">,</span> [a]<span class="Delimiter">,</span> [d] ] trace-should-<span class="Normal">not</span>-contain [ <span class="Normal">a</span>: b <span class="Normal">a</span>: d ] ] <span class="traceContains">+error: unexpected [d] in trace with label 'a'</span> <span class="Delimiter">:(scenario trace_count_check)</span> def main [ run [ trace <span class="Constant">1</span><span class="Delimiter">,</span> [a]<span class="Delimiter">,</span> [foo] ] check-trace-count-<span class="Normal">for</span>-label <span class="Constant">1</span><span class="Delimiter">,</span> [a] ] <span class="Comment"># checks are inside scenario</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span> CHECK_TRACE_COUNT_FOR_LABEL<span class="Delimiter">,</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span> put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;check-trace-count-for-label&quot;</span><span class="Delimiter">,</span> CHECK_TRACE_COUNT_FOR_LABEL<span class="Delimiter">);</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Checks&quot;)</span> <span class="Normal">case</span> CHECK_TRACE_COUNT_FOR_LABEL: <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'check-trace-count-for-label' requires exactly two ingredients, but got '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span> raise &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;first ingredient of 'check-trace-count-for-label' should be a number (count), but got '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!is_literal_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span> raise &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;second ingredient of 'check-trace-count-for-label' should be a literal string (label), but got '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>original_string &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span> <span class="Normal">case</span> CHECK_TRACE_COUNT_FOR_LABEL: <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!Passed<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Normal">int</span> expected_count = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> string label = current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">;</span> <span class="Normal">int</span> count = trace_count<span class="Delimiter">(</span>label<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>count != expected_count<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>Current_scenario &amp;&amp; !Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// genuine test in a mu file</span> raise &lt;&lt; <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">F - &quot;</span> &lt;&lt; Current_scenario<span class="Delimiter">-&gt;</span>name &lt;&lt; <span class="Constant">&quot;: &quot;</span> &lt;&lt; maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> &lt;&lt; <span class="Constant">&quot;expected &quot;</span> &lt;&lt; expected_count &lt;&lt; <span class="Constant">&quot; lines in trace with label '&quot;</span> &lt;&lt; label &lt;&lt; <span class="Constant">&quot;' in trace: &quot;</span> &lt;&lt; end<span class="Delimiter">();</span> DUMP<span class="Delimiter">(</span>label<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">else</span> <span class="Delimiter">{</span> <span class="Comment">// just testing scenario support</span> raise &lt;&lt; maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> &lt;&lt; <span class="Constant">&quot;expected &quot;</span> &lt;&lt; expected_count &lt;&lt; <span class="Constant">&quot; lines in trace with label '&quot;</span> &lt;&lt; label &lt;&lt; <span class="Constant">&quot;' in trace</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!Scenario_testing_scenario<span class="Delimiter">)</span> Passed = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(scenario trace_count_check_2)</span> <span class="Special">% Scenario_testing_scenario = true;</span> <span class="Special">% Hide_errors = true;</span> def main [ run [ trace <span class="Constant">1</span><span class="Delimiter">,</span> [a]<span class="Delimiter">,</span> [foo] ] check-trace-count-<span class="Normal">for</span>-label <span class="Constant">2</span><span class="Delimiter">,</span> [a] ] <span class="traceContains">+error: main: expected 2 lines in trace with label 'a' in trace</span> <span class="Comment">//: Minor detail: ignore 'system' calls in scenarios, since anything we do</span> <span class="Comment">//: with them is by definition impossible to test through mu.</span> <span class="Delimiter">:(after &quot;case _SYSTEM:&quot;)</span> <span class="Normal">if</span> <span class="Delimiter">(</span>Current_scenario<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="SalientComment">//:: Warn if people use '_' manually in function names. They're reserved for internal use.</span> <span class="Delimiter">:(scenario recipe_name_with_underscore)</span> <span class="Special">% Hide_errors = true;</span> def foo_bar [ ] <span class="traceContains">+error: foo_bar: don't create recipes with '_' in the name</span> <span class="Delimiter">:(before &quot;End recipe Fields&quot;)</span> <span class="Normal">bool</span> is_autogenerated<span class="Delimiter">;</span> <span class="Delimiter">:(before &quot;End recipe Constructor&quot;)</span> is_autogenerated = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">:(code)</span> <span class="Normal">void</span> mark_autogenerated<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>is_autogenerated = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(after &quot;void transform_all()&quot;)</span> <span class="Normal">for</span> <span class="Delimiter">(</span>map&lt;recipe_ordinal<span class="Delimiter">,</span> recipe&gt;::iterator p = Recipe<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Recipe<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">const</span> recipe&amp; r = p<span class="Delimiter">-&gt;</span>second<span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>r<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">'_'</span><span class="Delimiter">)</span> == string::npos<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>r<span class="Delimiter">.</span>is_autogenerated<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Comment">// created by previous call to transform_all()</span> raise &lt;&lt; r<span class="Delimiter">.</span>name &lt;&lt; <span class="Constant">&quot;: don't create recipes with '_' in the name</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="SalientComment">//:: Helpers</span> <span class="Delimiter">:(code)</span> <span class="Comment">// just for the scenarios running scenarios in C++ layers</span> <span class="Normal">void</span> run_mu_scenario<span class="Delimiter">(</span><span class="Normal">const</span> string&amp; form<span class="Delimiter">)</span> <span class="Delimiter">{</span> istringstream in<span class="Delimiter">(</span>form<span class="Delimiter">);</span> in &gt;&gt; std::noskipws<span class="Delimiter">;</span> skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span> string _scenario = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span> assert<span class="Delimiter">(</span>_scenario == <span class="Constant">&quot;scenario&quot;</span><span class="Delimiter">);</span> scenario s = parse_scenario<span class="Delimiter">(</span>in<span class="Delimiter">);</span> run_mu_scenario<span class="Delimiter">(</span>s<span class="Delimiter">);</span> <span class="Delimiter">}</span> </pre> </body> </html> <!-- vim: set foldmethod=manual : -->