https://github.com/akkartik/mu/blob/main/shell/sandbox.mu
   1 type sandbox {
   2   data: (handle gap-buffer)
   3   value: (handle stream byte)
   4   trace: (handle trace)
   5   screen-var: (handle cell)
   6   keyboard-var: (handle cell)
   7   cursor-in-data?: boolean
   8   cursor-in-trace?: boolean
   9   cursor-in-keyboard?: boolean
  10 }
  11 
  12 fn initialize-sandbox _self: (addr sandbox), fake-screen-width: int, fake-screen-height: int {
  13   var self/esi: (addr sandbox) <- copy _self
  14   var data-ah/eax: (addr handle gap-buffer) <- get self, data
  15   allocate data-ah
  16   var data/eax: (addr gap-buffer) <- lookup *data-ah
  17   initialize-gap-buffer data, 0x40000/default-gap-buffer-size=256KB
  18   #
  19   var value-ah/eax: (addr handle stream byte) <- get self, value
  20   populate-stream value-ah, 0x1000/4KB
  21   #
  22   {
  23     compare fake-screen-width, 0
  24     break-if-=
  25     var screen-ah/eax: (addr handle cell) <- get self, screen-var
  26     new-fake-screen screen-ah, fake-screen-width, fake-screen-height, 1/enable-pixel-graphics
  27     var keyboard-ah/eax: (addr handle cell) <- get self, keyboard-var
  28     new-fake-keyboard keyboard-ah, 0x10/keyboard-capacity
  29   }
  30   #
  31   var trace-ah/eax: (addr handle trace) <- get self, trace
  32   allocate trace-ah
  33   var trace/eax: (addr trace) <- lookup *trace-ah
  34   initialize-trace trace, 4/max-depth, 0x8000/lines, 0x80/visible
  35   var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data?
  36   copy-to *cursor-in-data?, 1/true
  37 }
  38 
  39 ## some helpers for tests
  40 
  41 fn initialize-sandbox-with _self: (addr sandbox), s: (addr array byte) {
  42   var self/esi: (addr sandbox) <- copy _self
  43   var data-ah/eax: (addr handle gap-buffer) <- get self, data
  44   allocate data-ah
  45   var data/eax: (addr gap-buffer) <- lookup *data-ah
  46   initialize-gap-buffer-with data, s
  47   var value-ah/eax: (addr handle stream byte) <- get self, value
  48   populate-stream value-ah, 0x1000/4KB
  49   var trace-ah/eax: (addr handle trace) <- get self, trace
  50   allocate trace-ah
  51   var trace/eax: (addr trace) <- lookup *trace-ah
  52   initialize-trace trace, 3/max-depth, 0x8000/lines, 0x80/visible
  53   var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data?
  54   copy-to *cursor-in-data?, 1/true
  55 }
  56 
  57 fn allocate-sandbox-with _out: (addr handle sandbox), s: (addr array byte) {
  58   var out/eax: (addr handle sandbox) <- copy _out
  59   allocate out
  60   var out-addr/eax: (addr sandbox) <- lookup *out
  61   initialize-sandbox-with out-addr, s
  62 }
  63 
  64 fn write-sandbox out: (addr stream byte), _self: (addr sandbox) {
  65   var self/eax: (addr sandbox) <- copy _self
  66   var data-ah/eax: (addr handle gap-buffer) <- get self, data
  67   var data/eax: (addr gap-buffer) <- lookup *data-ah
  68   {
  69     var len/eax: int <- gap-buffer-length data
  70     compare len, 0
  71     break-if-!=
  72     return
  73   }
  74   write out, "  (sandbox . ["
  75   append-gap-buffer data, out
  76   write out, "])\n"
  77 }
  78 
  79 ##
  80 
  81 fn render-sandbox screen: (addr screen), _self: (addr sandbox), xmin: int, ymin: int, xmax: int, ymax: int, show-cursor?: boolean {
  82   clear-rect screen, xmin, ymin, xmax, ymax, 0xc5/bg=blue-bg
  83   add-to xmin, 1/padding-left
  84   add-to ymin, 1/padding-top
  85   subtract-from xmax, 1/padding-right
  86   var self/esi: (addr sandbox) <- copy _self
  87   # data
  88   var data-ah/eax: (addr handle gap-buffer) <- get self, data
  89   var _data/eax: (addr gap-buffer) <- lookup *data-ah
  90   var data/edx: (addr gap-buffer) <- copy _data
  91   var x/eax: int <- copy xmin
  92   var y/ecx: int <- copy ymin
  93   y <- maybe-render-empty-screen screen, self, xmin, y
  94   y <- maybe-render-keyboard screen, self, xmin, y
  95   var cursor-in-editor?/ebx: boolean <- copy show-cursor?
  96   {
  97     compare cursor-in-editor?, 0/false
  98     break-if-=
  99     var cursor-in-data-a/eax: (addr boolean) <- get self, cursor-in-data?
 100     cursor-in-editor? <- copy *cursor-in-data-a
 101   }
 102   x, y <- render-gap-buffer-wrapping-right-then-down screen, data, x, y, xmax, ymax, cursor-in-editor?, 7/fg, 0xc5/bg=blue-bg
 103   y <- increment
 104   # trace
 105   var trace-ah/eax: (addr handle trace) <- get self, trace
 106   var _trace/eax: (addr trace) <- lookup *trace-ah
 107   var trace/edx: (addr trace) <- copy _trace
 108   var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace?
 109   y <- render-trace screen, trace, xmin, y, xmax, ymax, *cursor-in-trace?
 110   # value
 111   $render-sandbox:value: {
 112     compare y, ymax
 113     break-if->=
 114     var value-ah/eax: (addr handle stream byte) <- get self, value
 115     var _value/eax: (addr stream byte) <- lookup *value-ah
 116     var value/esi: (addr stream byte) <- copy _value
 117     rewind-stream value
 118     var done?/eax: boolean <- stream-empty? value
 119     compare done?, 0/false
 120     break-if-!=
 121     var x/eax: int <- copy 0
 122     x, y <- draw-text-wrapping-right-then-down screen, "=> ", xmin, y, xmax, ymax, xmin, y, 7/fg, 0xc5/bg=blue-bg
 123     var x2/edx: int <- copy x
 124     var dummy/eax: int <- draw-stream-rightward screen, value, x2, xmax, y, 7/fg=grey, 0xc5/bg=blue-bg
 125   }
 126   y <- add 2  # padding
 127   maybe-render-screen screen, self, xmin, y
 128 }
 129 
 130 fn render-sandbox-menu screen: (addr screen), _self: (addr sandbox) {
 131   var self/esi: (addr sandbox) <- copy _self
 132   var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data?
 133   compare *cursor-in-data?, 0/false
 134   {
 135     break-if-=
 136     render-sandbox-edit-menu screen, self
 137     return
 138   }
 139   var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace?
 140   compare *cursor-in-trace?, 0/false
 141   {
 142     break-if-=
 143     render-trace-menu screen
 144     return
 145   }
 146   var cursor-in-keyboard?/eax: (addr boolean) <- get self, cursor-in-keyboard?
 147   compare *cursor-in-keyboard?, 0/false
 148   {
 149     break-if-=
 150     render-keyboard-menu screen
 151     return
 152   }
 153 }
 154 
 155 fn clear-sandbox-output screen: (addr screen), _self: (addr sandbox), xmin: int, ymin: int, xmax: int, ymax: int {
 156   # render just enough of the sandbox to figure out what to erase
 157   var self/esi: (addr sandbox) <- copy _self
 158   var data-ah/eax: (addr handle gap-buffer) <- get self, data
 159   var _data/eax: (addr gap-buffer) <- lookup *data-ah
 160   var data/edx: (addr gap-buffer) <- copy _data
 161   var x/eax: int <- copy xmin
 162   var y/ecx: int <- copy ymin
 163   y <- maybe-render-empty-screen screen, self, xmin, y
 164   y <- maybe-render-keyboard screen, self, xmin, y
 165   var cursor-in-sandbox?/ebx: (addr boolean) <- get self, cursor-in-data?
 166   x, y <- render-gap-buffer-wrapping-right-then-down screen, data, x, y, xmax, ymax, *cursor-in-sandbox?, 3/fg, 0xc5/bg=blue-bg
 167   y <- increment
 168   clear-rect screen, xmin, y, xmax, ymax, 0xc5/bg=blue-bg
 169 }
 170 
 171 fn maybe-render-empty-screen screen: (addr screen), _self: (addr sandbox), xmin: int, ymin: int -> _/ecx: int {
 172   var self/esi: (addr sandbox) <- copy _self
 173   var screen-obj-cell-ah/eax: (addr handle cell) <- get self, screen-var
 174   var screen-obj-cell/eax: (addr cell) <- lookup *screen-obj-cell-ah
 175   compare screen-obj-cell, 0
 176   {
 177     break-if-!=
 178     return ymin
 179   }
 180   var screen-obj-cell-type/ecx: (addr int) <- get screen-obj-cell, type
 181   compare *screen-obj-cell-type, 5/screen
 182   {
 183     break-if-=
 184     return ymin  # silently give up on rendering the screen
 185   }
 186   var y/ecx: int <- copy ymin
 187   var screen-obj-ah/eax: (addr handle screen) <- get screen-obj-cell, screen-data
 188   var _screen-obj/eax: (addr screen) <- lookup *screen-obj-ah
 189   var screen-obj/edx: (addr screen) <- copy _screen-obj
 190   var x/eax: int <- draw-text-rightward screen, "screen:   ", xmin, 0x99/xmax, y, 0x17/fg, 0xc5/bg=blue-bg
 191   x <- copy xmin
 192   x <- add 2
 193   y <- increment
 194   y <- render-empty-screen screen, screen-obj, x, y
 195   return y
 196 }
 197 
 198 fn maybe-render-screen screen: (addr screen), _self: (addr sandbox), xmin: int, ymin: int {
 199   var self/esi: (addr sandbox) <- copy _self
 200   var screen-obj-cell-ah/eax: (addr handle cell) <- get self, screen-var
 201   var screen-obj-cell/eax: (addr cell) <- lookup *screen-obj-cell-ah
 202   compare screen-obj-cell, 0
 203   {
 204     break-if-!=
 205     return
 206   }
 207   var screen-obj-cell-type/ecx: (addr int) <- get screen-obj-cell, type
 208   compare *screen-obj-cell-type, 5/screen
 209   {
 210     break-if-=
 211     return  # silently give up on rendering the screen
 212   }
 213   var screen-obj-ah/eax: (addr handle screen) <- get screen-obj-cell, screen-data
 214   var _screen-obj/eax: (addr screen) <- lookup *screen-obj-ah
 215   var screen-obj/edx: (addr screen) <- copy _screen-obj
 216   {
 217     var screen-empty?/eax: boolean <- fake-screen-empty? screen-obj
 218     compare screen-empty?, 0/false
 219     break-if-=
 220     return
 221   }
 222   var x/eax: int <- draw-text-rightward screen, "screen:   ", xmin, 0x99/xmax, ymin, 0x17/fg, 0xc5/bg=blue-bg
 223   x <- copy xmin
 224   x <- add 2
 225   var y/ecx: int <- copy ymin
 226   y <- increment
 227   render-screen screen, screen-obj, x, y
 228 }
 229 
 230 fn render-empty-screen screen: (addr screen), _target-screen: (addr screen), xmin: int, ymin: int -> _/ecx: int {
 231   var target-screen/esi: (addr screen) <- copy _target-screen
 232   var screen-y/edi: int <- copy ymin
 233   # screen
 234   var height/edx: (addr int) <- get target-screen, height
 235   var y/ecx: int <- copy 0
 236   {
 237     compare y, *height
 238     break-if->=
 239     set-cursor-position screen, xmin, screen-y
 240     var width/edx: (addr int) <- get target-screen, width
 241     var x/ebx: int <- copy 0
 242     {
 243       compare x, *width
 244       break-if->=
 245       draw-code-point-at-cursor screen, 0x20/space, 0x18/fg, 0/bg
 246       move-cursor-right screen
 247       x <- increment
 248       loop
 249     }
 250     y <- increment
 251     screen-y <- increment
 252     loop
 253   }
 254   return screen-y
 255 }
 256 
 257 fn render-screen screen: (addr screen), _target-screen: (addr screen), xmin: int, ymin: int {
 258   var target-screen/esi: (addr screen) <- copy _target-screen
 259   convert-graphemes-to-pixels target-screen  # might overwrite existing pixel data with graphemes
 260                                              # overlapping the two is not supported
 261   # pixel data
 262   {
 263     # screen top left pixels x y width height
 264     var tmp/eax: int <- copy xmin
 265     tmp <- shift-left 3/log2-font-width
 266     var left: int
 267     copy-to left, tmp
 268     tmp <- copy ymin
 269     tmp <- shift-left 4/log2-font-height
 270     var top: int
 271     copy-to top, tmp
 272     var pixels-ah/eax: (addr handle array byte) <- get target-screen, pixels
 273     var _pixels/eax: (addr array byte) <- lookup *pixels-ah
 274     var pixels/edi: (addr array byte) <- copy _pixels
 275     compare pixels, 0
 276     break-if-=
 277     var y/ebx: int <- copy 0
 278     var height-addr/edx: (addr int) <- get target-screen, height
 279     var height/edx: int <- copy *height-addr
 280     height <- shift-left 4/log2-font-height
 281     {
 282       compare y, height
 283       break-if->=
 284       var width-addr/edx: (addr int) <- get target-screen, width
 285       var width/edx: int <- copy *width-addr
 286       width <- shift-left 3/log2-font-width
 287       var x/eax: int <- copy 0
 288       {
 289         compare x, width
 290         break-if->=
 291         {
 292           var idx/ecx: int <- pixel-index target-screen, x, y
 293           var color-addr/ecx: (addr byte) <- index pixels, idx
 294           var color/ecx: byte <- copy-byte *color-addr
 295           var color2/ecx: int <- copy color
 296           var x2/eax: int <- copy x
 297           x2 <- add left
 298           var y2/ebx: int <- copy y
 299           y2 <- add top
 300           pixel screen, x2, y2, color2
 301         }
 302         x <- increment
 303         loop
 304       }
 305       y <- increment
 306       loop
 307     }
 308   }
 309 }
 310 
 311 fn has-keyboard? _self: (addr sandbox) -> _/eax: boolean {
 312   var self/esi: (addr sandbox) <- copy _self
 313   var keyboard-obj-cell-ah/eax: (addr handle cell) <- get self, keyboard-var
 314   var keyboard-obj-cell/eax: (addr cell) <- lookup *keyboard-obj-cell-ah
 315   compare keyboard-obj-cell, 0
 316   {
 317     break-if-!=
 318     return 0/false
 319   }
 320   var keyboard-obj-cell-type/ecx: (addr int) <- get keyboard-obj-cell, type
 321   compare *keyboard-obj-cell-type, 6/keyboard
 322   {
 323     break-if-=
 324     return 0/false
 325   }
 326   var keyboard-obj-ah/eax: (addr handle gap-buffer) <- get keyboard-obj-cell, keyboard-data
 327   var _keyboard-obj/eax: (addr gap-buffer) <- lookup *keyboard-obj-ah
 328   var keyboard-obj/edx: (addr gap-buffer) <- copy _keyboard-obj
 329   compare keyboard-obj, 0
 330   {
 331     break-if-!=
 332     return 0/false
 333   }
 334   return 1/true
 335 }
 336 
 337 fn maybe-render-keyboard screen: (addr screen), _self: (addr sandbox), xmin: int, ymin: int -> _/ecx: int {
 338   var self/esi: (addr sandbox) <- copy _self
 339   var keyboard-obj-cell-ah/eax: (addr handle cell) <- get self, keyboard-var
 340   var keyboard-obj-cell/eax: (addr cell) <- lookup *keyboard-obj-cell-ah
 341   compare keyboard-obj-cell, 0
 342   {
 343     break-if-!=
 344     return ymin
 345   }
 346   var keyboard-obj-cell-type/ecx: (addr int) <- get keyboard-obj-cell, type
 347   compare *keyboard-obj-cell-type, 6/keyboard
 348   {
 349     break-if-=
 350     return ymin  # silently give up on rendering the keyboard
 351   }
 352   var keyboard-obj-ah/eax: (addr handle gap-buffer) <- get keyboard-obj-cell, keyboard-data
 353   var _keyboard-obj/eax: (addr gap-buffer) <- lookup *keyboard-obj-ah
 354   var keyboard-obj/edx: (addr gap-buffer) <- copy _keyboard-obj
 355   var y/ecx: int <- copy ymin
 356   y <- increment  # padding
 357   var x/eax: int <- draw-text-rightward screen, "keyboard: ", xmin, 0x99/xmax, y, 0x17/fg, 0xc5/bg=blue-bg
 358   var cursor-in-keyboard?/esi: (addr boolean) <- get self, cursor-in-keyboard?
 359   y <- render-keyboard screen, keyboard-obj, x, y, *cursor-in-keyboard?
 360   y <- increment  # padding
 361   return y
 362 }
 363 
 364 fn render-keyboard screen: (addr screen), _keyboard: (addr gap-buffer), xmin: int, ymin: int, render-cursor?: boolean -> _/ecx: int {
 365   var keyboard/esi: (addr gap-buffer) <- copy _keyboard
 366   var width/edx: int <- copy 0x10/keyboard-capacity
 367   var y/edi: int <- copy ymin
 368   # keyboard
 369   var x/eax: int <- copy xmin
 370   var xmax/ecx: int <- copy x
 371   xmax <- add 0x10
 372   var ymax/edx: int <- copy ymin
 373   ymax <- add 1
 374   clear-rect screen, x, y, xmax, ymax, 0/bg
 375   x <- render-gap-buffer screen, keyboard, x, y, render-cursor?, 3/fg, 0/bg
 376   y <- increment
 377   return y
 378 }
 379 
 380 fn print-screen-cell-of-fake-screen screen: (addr screen), _target: (addr screen), x: int, y: int {
 381   var target/ecx: (addr screen) <- copy _target
 382   var data-ah/eax: (addr handle array screen-cell) <- get target, data
 383   var data/eax: (addr array screen-cell) <- lookup *data-ah
 384   var index/ecx: int <- screen-cell-index target, x, y
 385   var offset/ecx: (offset screen-cell) <- compute-offset data, index
 386   var src-cell/esi: (addr screen-cell) <- index data, offset
 387   var src-grapheme/eax: (addr grapheme) <- get src-cell, data
 388   var src-color/ecx: (addr int) <- get src-cell, color
 389   var src-background-color/edx: (addr int) <- get src-cell, background-color
 390   draw-grapheme-at-cursor screen, *src-grapheme, *src-color, *src-background-color
 391 }
 392 
 393 fn render-sandbox-edit-menu screen: (addr screen), _self: (addr sandbox) {
 394   var _width/eax: int <- copy 0
 395   var height/ecx: int <- copy 0
 396   _width, height <- screen-size screen
 397   var width/edx: int <- copy _width
 398   var y/ecx: int <- copy height
 399   y <- decrement
 400   var height/ebx: int <- copy y
 401   height <- increment
 402   clear-rect screen, 0/x, y, width, height, 0xc5/bg=blue-bg
 403   set-cursor-position screen, 0/x, y
 404   draw-text-rightward-from-cursor screen, " ^r ", width, 0/fg, 0x5c/bg=menu-highlight
 405   draw-text-rightward-from-cursor screen, " run main  ", width, 7/fg, 0xc5/bg=blue-bg
 406   draw-text-rightward-from-cursor screen, " ^s ", width, 0/fg, 0x5c/bg=menu-highlight
 407   draw-text-rightward-from-cursor screen, " run sandbox  ", width, 7/fg, 0xc5/bg=blue-bg
 408   draw-text-rightward-from-cursor screen, " ^g ", width, 0/fg, 0x5c/bg=menu-highlight
 409   draw-text-rightward-from-cursor screen, " go to  ", width, 7/fg, 0xc5/bg=blue-bg
 410   $render-sandbox-edit-menu:render-ctrl-m: {
 411     var self/eax: (addr sandbox) <- copy _self
 412     var has-trace?/eax: boolean <- has-trace? self
 413     compare has-trace?, 0/false
 414     {
 415       break-if-=
 416       draw-text-rightward-from-cursor screen, " ^m ", width, 0/fg, 0x38/bg=trace
 417       draw-text-rightward-from-cursor screen, " to trace  ", width, 7/fg, 0xc5/bg=blue-bg
 418       break $render-sandbox-edit-menu:render-ctrl-m
 419     }
 420     draw-text-rightward-from-cursor screen, " ^m ", width, 0/fg, 3/bg=keyboard
 421     draw-text-rightward-from-cursor screen, " to keyboard  ", width, 7/fg, 0xc5/bg=blue-bg
 422   }
 423   draw-text-rightward-from-cursor screen, " ^a ", width, 0/fg, 0x5c/bg=menu-highlight
 424   draw-text-rightward-from-cursor screen, " <<  ", width, 7/fg, 0xc5/bg=blue-bg
 425   draw-text-rightward-from-cursor screen, " ^b ", width, 0/fg, 0x5c/bg=menu-highlight
 426   draw-text-rightward-from-cursor screen, " <word  ", width, 7/fg, 0xc5/bg=blue-bg
 427   draw-text-rightward-from-cursor screen, " ^f ", width, 0/fg, 0x5c/bg=menu-highlight
 428   draw-text-rightward-from-cursor screen, " word>  ", width, 7/fg, 0xc5/bg=blue-bg
 429   draw-text-rightward-from-cursor screen, " ^e ", width, 0/fg, 0x5c/bg=menu-highlight
 430   draw-text-rightward-from-cursor screen, " >>  ", width, 7/fg, 0xc5/bg=blue-bg
 431 }
 432 
 433 fn render-keyboard-menu screen: (addr screen) {
 434   var width/eax: int <- copy 0
 435   var height/ecx: int <- copy 0
 436   width, height <- screen-size screen
 437   var y/ecx: int <- copy height
 438   y <- decrement
 439   var height/edx: int <- copy y
 440   height <- increment
 441   clear-rect screen, 0/x, y, width, height, 0xc5/bg=blue-bg
 442   set-cursor-position screen, 0/x, y
 443   draw-text-rightward-from-cursor screen, " ^r ", width, 0/fg, 0x5c/bg=menu-highlight
 444   draw-text-rightward-from-cursor screen, " run main  ", width, 7/fg, 0xc5/bg=blue-bg
 445   draw-text-rightward-from-cursor screen, " ^s ", width, 0/fg, 0x5c/bg=menu-highlight
 446   draw-text-rightward-from-cursor screen, " run sandbox  ", width, 7/fg, 0xc5/bg=blue-bg
 447   draw-text-rightward-from-cursor screen, " ^g ", width, 0/fg, 0x5c/bg=menu-highlight
 448   draw-text-rightward-from-cursor screen, " go to  ", width, 7/fg, 0xc5/bg=blue-bg
 449   draw-text-rightward-from-cursor screen, " ^m ", width, 0/fg, 7/bg
 450   draw-text-rightward-from-cursor screen, " to sandbox  ", width, 7/fg, 0xc5/bg=blue-bg
 451 }
 452 
 453 fn edit-sandbox _self: (addr sandbox), key: grapheme, globals: (addr global-table), data-disk: (addr disk) {
 454   var self/esi: (addr sandbox) <- copy _self
 455   # ctrl-s
 456   {
 457     compare key, 0x13/ctrl-s
 458     break-if-!=
 459     # if cursor is in trace, skip
 460     var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace?
 461     compare *cursor-in-trace?, 0/false
 462     break-if-!=
 463     # minor gotcha here: any bindings created later in this iteration won't be
 464     # persisted until the next call to ctrl-s.
 465     store-state data-disk, self, globals
 466     #
 467 #?     turn-on-debug-print
 468     run-sandbox self, globals
 469     return
 470   }
 471   # ctrl-m
 472   {
 473     compare key, 0xd/ctrl-m
 474     break-if-!=
 475     # if cursor in data, switch to trace or fall through to keyboard
 476     {
 477       var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data?
 478       compare *cursor-in-data?, 0/false
 479       break-if-=
 480       var has-trace?/eax: boolean <- has-trace? self
 481       compare has-trace?, 0/false
 482       {
 483         break-if-=
 484         var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data?
 485         copy-to *cursor-in-data?, 0/false
 486         var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace?
 487         copy-to *cursor-in-trace?, 1/false
 488         return
 489       }
 490       var has-keyboard?/eax: boolean <- has-keyboard? self
 491       compare has-keyboard?, 0/false
 492       {
 493         break-if-=
 494         var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data?
 495         copy-to *cursor-in-data?, 0/false
 496         var cursor-in-keyboard?/eax: (addr boolean) <- get self, cursor-in-keyboard?
 497         copy-to *cursor-in-keyboard?, 1/false
 498         return
 499       }
 500       return
 501     }
 502     # if cursor in trace, switch to keyboard or fall through to data
 503     {
 504       var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace?
 505       compare *cursor-in-trace?, 0/false
 506       break-if-=
 507       copy-to *cursor-in-trace?, 0/false
 508       var cursor-target/ecx: (addr boolean) <- get self, cursor-in-keyboard?
 509       var has-keyboard?/eax: boolean <- has-keyboard? self
 510       compare has-keyboard?, 0/false
 511       {
 512         break-if-!=
 513         cursor-target <- get self, cursor-in-data?
 514       }
 515       copy-to *cursor-target, 1/true
 516       return
 517     }
 518     # otherwise if cursor in keyboard, switch to data
 519     {
 520       var cursor-in-keyboard?/eax: (addr boolean) <- get self, cursor-in-keyboard?
 521       compare *cursor-in-keyboard?, 0/false
 522       break-if-=
 523       copy-to *cursor-in-keyboard?, 0/false
 524       var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data?
 525       copy-to *cursor-in-data?, 1/true
 526       return
 527     }
 528     return
 529   }
 530   # if cursor in data, send key to data
 531   {
 532     var cursor-in-data?/eax: (addr boolean) <- get self, cursor-in-data?
 533     compare *cursor-in-data?, 0/false
 534     break-if-=
 535     var data-ah/eax: (addr handle gap-buffer) <- get self, data
 536     var data/eax: (addr gap-buffer) <- lookup *data-ah
 537     edit-gap-buffer data, key
 538     return
 539   }
 540   # if cursor in keyboard, send key to keyboard
 541   {
 542     var cursor-in-keyboard?/eax: (addr boolean) <- get self, cursor-in-keyboard?
 543     compare *cursor-in-keyboard?, 0/false
 544     break-if-=
 545     var inner-keyboard-var-ah/eax: (addr handle cell) <- get self, keyboard-var
 546     var inner-keyboard-var/eax: (addr cell) <- lookup *inner-keyboard-var-ah
 547     compare inner-keyboard-var, 0
 548     {
 549       break-if-!=
 550       return
 551     }
 552     var inner-keyboard-var-type/ecx: (addr int) <- get inner-keyboard-var, type
 553     compare *inner-keyboard-var-type, 6/keyboard
 554     {
 555       break-if-=
 556       return
 557     }
 558     var keyboard-ah/eax: (addr handle gap-buffer) <- get inner-keyboard-var, keyboard-data
 559     var keyboard/eax: (addr gap-buffer) <- lookup *keyboard-ah
 560     edit-gap-buffer keyboard, key
 561     return
 562   }
 563   # if cursor in trace, send key to trace
 564   {
 565     var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace?
 566     compare *cursor-in-trace?, 0/false
 567     break-if-=
 568     var trace-ah/eax: (addr handle trace) <- get self, trace
 569     var trace/eax: (addr trace) <- lookup *trace-ah
 570     # if expanding the trace, first check if we need to run the sandbox again with a deeper trace
 571     {
 572       compare key, 0xa/newline
 573       break-if-!=
 574       {
 575         var need-rerun?/eax: boolean <- cursor-too-deep? trace
 576         compare need-rerun?, 0/false
 577       }
 578       break-if-=
 579 #?       draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "rerun", 7/fg 0/bg
 580       # save trace lines at various cached indices
 581       var save: trace-index-stash
 582       var save-addr/ecx: (addr trace-index-stash) <- address save
 583       save-indices trace, save-addr
 584       # rerun at higher depth
 585       var max-depth-addr/ecx: (addr int) <- get trace, max-depth
 586       increment *max-depth-addr
 587       run-sandbox self, globals
 588       # recompute cached indices
 589       recompute-all-visible-lines trace
 590       var save-addr/ecx: (addr trace-index-stash) <- address save
 591       restore-indices trace, save-addr
 592     }
 593     edit-trace trace, key
 594     return
 595   }
 596 }
 597 
 598 fn run-sandbox _self: (addr sandbox), globals: (addr global-table) {
 599   var self/esi: (addr sandbox) <- copy _self
 600   var data-ah/ecx: (addr handle gap-buffer) <- get self, data
 601   var eval-result-h: (handle cell)
 602   var eval-result-ah/edi: (addr handle cell) <- address eval-result-h
 603   var definitions-created-storage: (stream int 0x10)
 604   var definitions-created/edx: (addr stream int) <- address definitions-created-storage
 605   var trace-ah/eax: (addr handle trace) <- get self, trace
 606   var _trace/eax: (addr trace) <- lookup *trace-ah
 607   var trace/ebx: (addr trace) <- copy _trace
 608   clear-trace trace
 609   var tmp/eax: (addr handle cell) <- get self, screen-var
 610   var inner-screen-var: (addr handle cell)
 611   copy-to inner-screen-var, tmp
 612   clear-screen-var inner-screen-var
 613   var inner-keyboard-var/eax: (addr handle cell) <- get self, keyboard-var
 614   rewind-keyboard-var inner-keyboard-var  # don't clear keys from before
 615   #
 616   read-and-evaluate-and-save-gap-buffer-to-globals data-ah, eval-result-ah, globals, definitions-created, trace, inner-screen-var, inner-keyboard-var
 617   var error?/eax: boolean <- has-errors? trace
 618   {
 619     compare error?, 0/false
 620     break-if-=
 621     return
 622   }
 623   # if necessary, initialize a new gap-buffer for sandbox
 624   {
 625     compare globals, 0
 626     break-if-=
 627     rewind-stream definitions-created
 628     var no-definitions?/eax: boolean <- stream-empty? definitions-created
 629     compare no-definitions?, 0/false
 630     break-if-!=
 631     # some definitions were created; clear the gap buffer
 632     var data/eax: (addr gap-buffer) <- lookup *data-ah
 633     var capacity/edx: int <- gap-buffer-capacity data
 634     allocate data-ah
 635     var new-data/eax: (addr gap-buffer) <- lookup *data-ah
 636     initialize-gap-buffer new-data, capacity
 637   }
 638   # print
 639   var value-ah/eax: (addr handle stream byte) <- get self, value
 640   var value/eax: (addr stream byte) <- lookup *value-ah
 641   clear-stream value
 642   print-cell eval-result-ah, value, trace
 643 }
 644 
 645 fn test-run-integer {
 646   var sandbox-storage: sandbox
 647   var sandbox/esi: (addr sandbox) <- address sandbox-storage
 648   initialize-sandbox-with sandbox, "1"
 649   # eval
 650   edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk
 651   # setup: screen
 652   var screen-on-stack: screen
 653   var screen/edi: (addr screen) <- address screen-on-stack
 654   initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics
 655   #
 656   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
 657   # skip one line of padding
 658   check-screen-row screen, 1/y, " 1    ", "F - test-run-integer/0"
 659   check-screen-row screen, 2/y, " ...  ", "F - test-run-integer/1"
 660   check-screen-row screen, 3/y, " => 1 ", "F - test-run-integer/2"
 661 }
 662 
 663 fn test-run-negative-integer {
 664   var sandbox-storage: sandbox
 665   var sandbox/esi: (addr sandbox) <- address sandbox-storage
 666   initialize-sandbox-with sandbox, "-1"
 667   # eval
 668   edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk
 669   # setup: screen
 670   var screen-on-stack: screen
 671   var screen/edi: (addr screen) <- address screen-on-stack
 672   initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics
 673   #
 674   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
 675   # skip one line of padding
 676   check-screen-row screen, 1/y, " -1    ", "F - test-run-negative-integer/0"
 677   check-screen-row screen, 2/y, " ...   ", "F - test-run-negative-integer/1"
 678   check-screen-row screen, 3/y, " => -1 ", "F - test-run-negative-integer/2"
 679 }
 680 
 681 fn test-run-error-invalid-integer {
 682   var sandbox-storage: sandbox
 683   var sandbox/esi: (addr sandbox) <- address sandbox-storage
 684   initialize-sandbox-with sandbox, "1a"
 685   # eval
 686   edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk
 687   # setup: screen
 688   var screen-on-stack: screen
 689   var screen/edi: (addr screen) <- address screen-on-stack
 690   initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics
 691   #
 692   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
 693   # skip one line of padding
 694   check-screen-row            screen,               1/y, " 1a                       ", "F - test-run-error-invalid-integer/0"
 695   check-screen-row            screen,               2/y, " ...                      ", "F - test-run-error-invalid-integer/1"
 696   check-screen-row-in-color   screen, 0xc/fg=error, 3/y, " unbound symbol: 1a       ", "F - test-run-error-invalid-integer/2"
 697 }
 698 
 699 fn test-run-error-unknown-symbol {
 700   var sandbox-storage: sandbox
 701   var sandbox/esi: (addr sandbox) <- address sandbox-storage
 702   initialize-sandbox-with sandbox, "a"
 703   # eval
 704   edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk
 705   # setup: screen
 706   var screen-on-stack: screen
 707   var screen/edi: (addr screen) <- address screen-on-stack
 708   initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics
 709   #
 710   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
 711   # skip one line of padding
 712   check-screen-row            screen,               1/y, " a                  ", "F - test-run-error-unknown-symbol/0"
 713   check-screen-row            screen,               2/y, " ...                ", "F - test-run-error-unknown-symbol/1"
 714   check-screen-row-in-color   screen, 0xc/fg=error, 3/y, " unbound symbol: a  ", "F - test-run-error-unknown-symbol/2"
 715 }
 716 
 717 fn test-run-with-spaces {
 718   var sandbox-storage: sandbox
 719   var sandbox/esi: (addr sandbox) <- address sandbox-storage
 720   initialize-sandbox-with sandbox, " 1 \n"
 721   # eval
 722   edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk
 723   # setup: screen
 724   var screen-on-stack: screen
 725   var screen/edi: (addr screen) <- address screen-on-stack
 726   initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics
 727   #
 728   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
 729   # skip one line of padding
 730   check-screen-row screen, 1/y, "  1   ", "F - test-run-with-spaces/0"
 731   check-screen-row screen, 2/y, "      ", "F - test-run-with-spaces/1"
 732   check-screen-row screen, 3/y, " ...  ", "F - test-run-with-spaces/2"
 733   check-screen-row screen, 4/y, " => 1 ", "F - test-run-with-spaces/3"
 734 }
 735 
 736 fn test-run-quote {
 737   var sandbox-storage: sandbox
 738   var sandbox/esi: (addr sandbox) <- address sandbox-storage
 739   initialize-sandbox-with sandbox, "'a"
 740   # eval
 741   edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk
 742   # setup: screen
 743   var screen-on-stack: screen
 744   var screen/edi: (addr screen) <- address screen-on-stack
 745   initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics
 746   #
 747   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
 748   # skip one line of padding
 749   check-screen-row screen, 1/y, " 'a   ", "F - test-run-quote/0"
 750   check-screen-row screen, 2/y, " ...  ", "F - test-run-quote/1"
 751   check-screen-row screen, 3/y, " => a ", "F - test-run-quote/2"
 752 }
 753 
 754 fn test-run-dotted-list {
 755   var sandbox-storage: sandbox
 756   var sandbox/esi: (addr sandbox) <- address sandbox-storage
 757   initialize-sandbox-with sandbox, "'(a . b)"
 758   # eval
 759   edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk
 760   # setup: screen
 761   var screen-on-stack: screen
 762   var screen/edi: (addr screen) <- address screen-on-stack
 763   initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics
 764   #
 765   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
 766   # skip one line of padding
 767   check-screen-row screen, 1/y, " '(a . b)   ", "F - test-run-dotted-list/0"
 768   check-screen-row screen, 2/y, " ...        ", "F - test-run-dotted-list/1"
 769   check-screen-row screen, 3/y, " => (a . b) ", "F - test-run-dotted-list/2"
 770 }
 771 
 772 fn test-run-dot-and-list {
 773   var sandbox-storage: sandbox
 774   var sandbox/esi: (addr sandbox) <- address sandbox-storage
 775   initialize-sandbox-with sandbox, "'(a . (b))"
 776   # eval
 777   edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk
 778   # setup: screen
 779   var screen-on-stack: screen
 780   var screen/edi: (addr screen) <- address screen-on-stack
 781   initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics
 782   #
 783   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
 784   # skip one line of padding
 785   check-screen-row screen, 1/y, " '(a . (b)) ", "F - test-run-dot-and-list/0"
 786   check-screen-row screen, 2/y, " ...        ", "F - test-run-dot-and-list/1"
 787   check-screen-row screen, 3/y, " => (a b)   ", "F - test-run-dot-and-list/2"
 788 }
 789 
 790 fn test-run-final-dot {
 791   var sandbox-storage: sandbox
 792   var sandbox/esi: (addr sandbox) <- address sandbox-storage
 793   initialize-sandbox-with sandbox, "'(a .)"
 794   # eval
 795   edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk
 796   # setup: screen
 797   var screen-on-stack: screen
 798   var screen/edi: (addr screen) <- address screen-on-stack
 799   initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics
 800   #
 801   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
 802   # skip one line of padding
 803   check-screen-row screen, 1/y, " '(a .)               ", "F - test-run-final-dot/0"
 804   check-screen-row screen, 2/y, " ...                  ", "F - test-run-final-dot/1"
 805   check-screen-row screen, 3/y, " '. )' makes no sense ", "F - test-run-final-dot/2"
 806   # further errors may occur
 807 }
 808 
 809 fn test-run-double-dot {
 810   var sandbox-storage: sandbox
 811   var sandbox/esi: (addr sandbox) <- address sandbox-storage
 812   initialize-sandbox-with sandbox, "'(a . .)"
 813   # eval
 814   edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk
 815   # setup: screen
 816   var screen-on-stack: screen
 817   var screen/edi: (addr screen) <- address screen-on-stack
 818   initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics
 819   #
 820   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
 821   # skip one line of padding
 822   check-screen-row screen, 1/y, " '(a . .)             ", "F - test-run-double-dot/0"
 823   check-screen-row screen, 2/y, " ...                  ", "F - test-run-double-dot/1"
 824   check-screen-row screen, 3/y, " '. .' makes no sense ", "F - test-run-double-dot/2"
 825   # further errors may occur
 826 }
 827 
 828 fn test-run-multiple-expressions-after-dot {
 829   var sandbox-storage: sandbox
 830   var sandbox/esi: (addr sandbox) <- address sandbox-storage
 831   initialize-sandbox-with sandbox, "'(a . b c)"
 832   # eval
 833   edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk
 834   # setup: screen
 835   var screen-on-stack: screen
 836   var screen/edi: (addr screen) <- address screen-on-stack
 837   initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics
 838   #
 839   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
 840   # skip one line of padding
 841   check-screen-row screen, 1/y, " '(a . b c)                                           ", "F - test-run-multiple-expressions-after-dot/0"
 842   check-screen-row screen, 2/y, " ...                                                  ", "F - test-run-multiple-expressions-after-dot/1"
 843   check-screen-row screen, 3/y, " cannot have multiple expressions between '.' and ')' ", "F - test-run-multiple-expressions-after-dot/2"
 844   # further errors may occur
 845 }
 846 
 847 fn test-run-stream {
 848   var sandbox-storage: sandbox
 849   var sandbox/esi: (addr sandbox) <- address sandbox-storage
 850   initialize-sandbox-with sandbox, "[a b]"
 851   # eval
 852   edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk
 853   # setup: screen
 854   var screen-on-stack: screen
 855   var screen/edi: (addr screen) <- address screen-on-stack
 856   initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics
 857   #
 858   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
 859   # skip one line of padding
 860   check-screen-row screen, 1/y, " [a b]    ", "F - test-run-stream/0"
 861   check-screen-row screen, 2/y, " ...      ", "F - test-run-stream/1"
 862   check-screen-row screen, 3/y, " => [a b] ", "F - test-run-stream/2"
 863 }
 864 
 865 fn test-run-move-cursor-into-trace {
 866   var sandbox-storage: sandbox
 867   var sandbox/esi: (addr sandbox) <- address sandbox-storage
 868   initialize-sandbox-with sandbox, "12"
 869   # eval
 870   edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk
 871   # setup: screen
 872   var screen-on-stack: screen
 873   var screen/edi: (addr screen) <- address screen-on-stack
 874   initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics
 875   #
 876   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
 877   # skip one line of padding
 878   check-screen-row screen,                                  1/y, " 12    ", "F - test-run-move-cursor-into-trace/pre-0"
 879   check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, "   |   ", "F - test-run-move-cursor-into-trace/pre-0/cursor"
 880   check-screen-row screen,                                  2/y, " ...   ", "F - test-run-move-cursor-into-trace/pre-1"
 881   check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, "       ", "F - test-run-move-cursor-into-trace/pre-1/cursor"
 882   check-screen-row screen,                                  3/y, " => 12 ", "F - test-run-move-cursor-into-trace/pre-2"
 883   check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, "       ", "F - test-run-move-cursor-into-trace/pre-2/cursor"
 884   # move cursor into trace
 885   edit-sandbox sandbox, 0xd/ctrl-m, 0/no-globals, 0/no-disk
 886   #
 887   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
 888   # skip one line of padding
 889   check-screen-row screen,                                  1/y, " 12    ", "F - test-run-move-cursor-into-trace/trace-0"
 890   check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, "       ", "F - test-run-move-cursor-into-trace/trace-0/cursor"
 891   check-screen-row screen,                                  2/y, " ...   ", "F - test-run-move-cursor-into-trace/trace-1"
 892   check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " |||   ", "F - test-run-move-cursor-into-trace/trace-1/cursor"
 893   check-screen-row screen,                                  3/y, " => 12 ", "F - test-run-move-cursor-into-trace/trace-2"
 894   check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, "       ", "F - test-run-move-cursor-into-trace/trace-2/cursor"
 895   # move cursor into input
 896   edit-sandbox sandbox, 0xd/ctrl-m, 0/no-globals, 0/no-disk
 897   #
 898   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
 899   # skip one line of padding
 900   check-screen-row screen,                                  1/y, " 12    ", "F - test-run-move-cursor-into-trace/input-0"
 901   check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, "   |   ", "F - test-run-move-cursor-into-trace/input-0/cursor"
 902   check-screen-row screen,                                  2/y, " ...   ", "F - test-run-move-cursor-into-trace/input-1"
 903   check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, "       ", "F - test-run-move-cursor-into-trace/input-1/cursor"
 904   check-screen-row screen,                                  3/y, " => 12 ", "F - test-run-move-cursor-into-trace/input-2"
 905   check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, "       ", "F - test-run-move-cursor-into-trace/input-2/cursor"
 906 }
 907 
 908 fn has-trace? _self: (addr sandbox) -> _/eax: boolean {
 909   var self/esi: (addr sandbox) <- copy _self
 910   var trace-ah/eax: (addr handle trace) <- get self, trace
 911   var _trace/eax: (addr trace) <- lookup *trace-ah
 912   var trace/edx: (addr trace) <- copy _trace
 913   compare trace, 0
 914   {
 915     break-if-!=
 916     abort "null trace"
 917   }
 918   var first-free/ebx: (addr int) <- get trace, first-free
 919   compare *first-free, 0
 920   {
 921     break-if->
 922     return 0/false
 923   }
 924   return 1/true
 925 }
 926 
 927 fn test-run-expand-trace {
 928   var sandbox-storage: sandbox
 929   var sandbox/esi: (addr sandbox) <- address sandbox-storage
 930   initialize-sandbox-with sandbox, "12"
 931   # eval
 932   edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk
 933   # setup: screen
 934   var screen-on-stack: screen
 935   var screen/edi: (addr screen) <- address screen-on-stack
 936   initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics
 937   #
 938   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
 939   # skip one line of padding
 940   check-screen-row screen,                                  1/y, " 12    ", "F - test-run-expand-trace/pre0-0"
 941   check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, "   |   ", "F - test-run-expand-trace/pre0-0/cursor"
 942   check-screen-row screen,                                  2/y, " ...   ", "F - test-run-expand-trace/pre0-1"
 943   check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, "       ", "F - test-run-expand-trace/pre0-1/cursor"
 944   check-screen-row screen,                                  3/y, " => 12 ", "F - test-run-expand-trace/pre0-2"
 945   check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, "       ", "F - test-run-expand-trace/pre0-2/cursor"
 946   # move cursor into trace
 947   edit-sandbox sandbox, 0xd/ctrl-m, 0/no-globals, 0/no-disk
 948   #
 949   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
 950   # skip one line of padding
 951   check-screen-row screen,                                  1/y, " 12    ", "F - test-run-expand-trace/pre1-0"
 952   check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, "       ", "F - test-run-expand-trace/pre1-0/cursor"
 953   check-screen-row screen,                                  2/y, " ...   ", "F - test-run-expand-trace/pre1-1"
 954   check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " |||   ", "F - test-run-expand-trace/pre1-1/cursor"
 955   check-screen-row screen,                                  3/y, " => 12 ", "F - test-run-expand-trace/pre1-2"
 956   check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, "       ", "F - test-run-expand-trace/pre1-2/cursor"
 957   # expand
 958   edit-sandbox sandbox, 0xa/newline, 0/no-globals, 0/no-disk
 959   #
 960   clear-screen screen
 961   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
 962   # skip one line of padding
 963   check-screen-row screen,                                  1/y, " 12    ", "F - test-run-expand-trace/expand-0"
 964   check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, "       ", "F - test-run-expand-trace/expand-0/cursor"
 965   check-screen-row screen,                                  2/y, " 1 toke", "F - test-run-expand-trace/expand-1"
 966   check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ||||||", "F - test-run-expand-trace/expand-1/cursor"
 967   check-screen-row screen,                                  3/y, " ...   ", "F - test-run-expand-trace/expand-2"
 968   check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, "       ", "F - test-run-expand-trace/expand-2/cursor"
 969   check-screen-row screen,                                  4/y, " 1 inse", "F - test-run-expand-trace/expand-3"
 970   check-background-color-in-screen-row screen, 7/bg=cursor, 4/y, "       ", "F - test-run-expand-trace/expand-3/cursor"
 971 }
 972 
 973 fn test-run-can-rerun-when-expanding-trace {
 974   var sandbox-storage: sandbox
 975   var sandbox/esi: (addr sandbox) <- address sandbox-storage
 976   # initialize sandbox with a max-depth of 3
 977   initialize-sandbox-with sandbox, "12"
 978   # eval
 979   edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk
 980   # setup: screen
 981   var screen-on-stack: screen
 982   var screen/edi: (addr screen) <- address screen-on-stack
 983   initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics
 984   #
 985   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
 986   # skip one line of padding
 987   check-screen-row screen,                                  1/y, " 12    ", "F - test-run-can-rerun-when-expanding-trace/pre0-0"
 988   check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, "   |   ", "F - test-run-can-rerun-when-expanding-trace/pre0-0/cursor"
 989   check-screen-row screen,                                  2/y, " ...   ", "F - test-run-can-rerun-when-expanding-trace/pre0-1"
 990   check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, "       ", "F - test-run-can-rerun-when-expanding-trace/pre0-1/cursor"
 991   check-screen-row screen,                                  3/y, " => 12 ", "F - test-run-can-rerun-when-expanding-trace/pre0-2"
 992   check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, "       ", "F - test-run-can-rerun-when-expanding-trace/pre0-2/cursor"
 993   # move cursor into trace
 994   edit-sandbox sandbox, 0xd/ctrl-m, 0/no-globals, 0/no-disk
 995   #
 996   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
 997   # skip one line of padding
 998   check-screen-row screen,                                  1/y, " 12    ", "F - test-run-can-rerun-when-expanding-trace/pre1-0"
 999   check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, "       ", "F - test-run-can-rerun-when-expanding-trace/pre1-0/cursor"
1000   check-screen-row screen,                                  2/y, " ...   ", "F - test-run-can-rerun-when-expanding-trace/pre1-1"
1001   check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " |||   ", "F - test-run-can-rerun-when-expanding-trace/pre1-1/cursor"
1002   check-screen-row screen,                                  3/y, " => 12 ", "F - test-run-can-rerun-when-expanding-trace/pre1-2"
1003   check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, "       ", "F - test-run-can-rerun-when-expanding-trace/pre1-2/cursor"
1004   # expand
1005   edit-sandbox sandbox, 0xa/newline, 0/no-globals, 0/no-disk
1006   #
1007   clear-screen screen
1008   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
1009   # skip one line of padding
1010   check-screen-row screen,                                  1/y, " 12    ", "F - test-run-can-rerun-when-expanding-trace/pre2-0"
1011   check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, "       ", "F - test-run-can-rerun-when-expanding-trace/pre2-0/cursor"
1012   check-screen-row screen,                                  2/y, " 1 toke", "F - test-run-can-rerun-when-expanding-trace/pre2-1"
1013   check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ||||||", "F - test-run-can-rerun-when-expanding-trace/pre2-1/cursor"
1014   check-screen-row screen,                                  3/y, " ...   ", "F - test-run-can-rerun-when-expanding-trace/pre2-2"
1015   check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, "       ", "F - test-run-can-rerun-when-expanding-trace/pre2-2/cursor"
1016   check-screen-row screen,                                  4/y, " 1 inse", "F - test-run-can-rerun-when-expanding-trace/pre2-2"
1017   check-background-color-in-screen-row screen, 7/bg=cursor, 4/y, "       ", "F - test-run-can-rerun-when-expanding-trace/pre2-2/cursor"
1018   # move cursor down and expand
1019   edit-sandbox sandbox, 0x6a/j, 0/no-globals, 0/no-disk
1020   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
1021   edit-sandbox sandbox, 0xa/newline, 0/no-globals, 0/no-disk
1022   #
1023   clear-screen screen
1024   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
1025   # screen looks same as if trace max-depth was really high
1026   check-screen-row screen,                                  1/y, " 12    ", "F - test-run-can-rerun-when-expanding-trace/expand-0"
1027   check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, "       ", "F - test-run-can-rerun-when-expanding-trace/expand-0/cursor"
1028   check-screen-row screen,                                  2/y, " 1 toke", "F - test-run-can-rerun-when-expanding-trace/expand-1"
1029   check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, "       ", "F - test-run-can-rerun-when-expanding-trace/expand-1/cursor"
1030   check-screen-row screen,                                  3/y, " 2 next", "F - test-run-can-rerun-when-expanding-trace/expand-2"
1031   check-background-color-in-screen-row screen, 7/bg=cursor, 3/y, " ||||||", "F - test-run-can-rerun-when-expanding-trace/expand-2/cursor"
1032   check-screen-row screen,                                  4/y, " ...   ", "F - test-run-can-rerun-when-expanding-trace/expand-3"
1033   check-background-color-in-screen-row screen, 7/bg=cursor, 4/y, "       ", "F - test-run-can-rerun-when-expanding-trace/expand-3/cursor"
1034   check-screen-row screen,                                  5/y, " 2 next", "F - test-run-can-rerun-when-expanding-trace/expand-4"
1035   check-background-color-in-screen-row screen, 7/bg=cursor, 5/y, "       ", "F - test-run-can-rerun-when-expanding-trace/expand-4/cursor"
1036   check-screen-row screen,                                  6/y, " ...   ", "F - test-run-can-rerun-when-expanding-trace/expand-5"
1037   check-background-color-in-screen-row screen, 7/bg=cursor, 6/y, "       ", "F - test-run-can-rerun-when-expanding-trace/expand-5/cursor"
1038   check-screen-row screen,                                  7/y, " 2 => 1", "F - test-run-can-rerun-when-expanding-trace/expand-6"
1039   check-background-color-in-screen-row screen, 7/bg=cursor, 7/y, "       ", "F - test-run-can-rerun-when-expanding-trace/expand-6/cursor"
1040 }
1041 
1042 fn test-run-preserves-trace-view-on-rerun {
1043   var sandbox-storage: sandbox
1044   var sandbox/esi: (addr sandbox) <- address sandbox-storage
1045   # initialize sandbox with a max-depth of 3
1046   initialize-sandbox-with sandbox, "7"
1047   # eval
1048   edit-sandbox sandbox, 0x13/ctrl-s, 0/no-globals, 0/no-disk
1049   # setup: screen
1050   var screen-on-stack: screen
1051   var screen/edi: (addr screen) <- address screen-on-stack
1052   initialize-screen screen, 0x80/width, 0x10/height, 0/no-pixel-graphics
1053   #
1054   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
1055   # skip one line of padding
1056   check-screen-row screen,                                    1/y, " 7                     ", "F - test-run-preserves-trace-view-on-rerun/pre0-0"
1057   check-background-color-in-screen-row screen, 7/bg=cursor,   1/y, "  |                    ", "F - test-run-preserves-trace-view-on-rerun/pre0-0/cursor"
1058   check-screen-row screen,                                    2/y, " ...                   ", "F - test-run-preserves-trace-view-on-rerun/pre0-1"
1059   check-background-color-in-screen-row screen, 7/bg=cursor,   2/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/pre0-1/cursor"
1060   check-screen-row screen,                                    3/y, " => 7                  ", "F - test-run-preserves-trace-view-on-rerun/pre0-2"
1061   check-background-color-in-screen-row screen, 7/bg=cursor,   3/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/pre0-2/cursor"
1062   # move cursor into trace
1063   edit-sandbox sandbox, 0xd/ctrl-m, 0/no-globals, 0/no-disk
1064   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
1065   #
1066   check-screen-row screen,                                    1/y, " 7                     ", "F - test-run-preserves-trace-view-on-rerun/pre1-0"
1067   check-background-color-in-screen-row screen, 7/bg=cursor,   1/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/pre1-0/cursor"
1068   check-screen-row screen,                                    2/y, " ...                   ", "F - test-run-preserves-trace-view-on-rerun/pre1-1"
1069   check-background-color-in-screen-row screen, 7/bg=cursor,   2/y, " |||                   ", "F - test-run-preserves-trace-view-on-rerun/pre1-1/cursor"
1070   check-screen-row screen,                                    3/y, " => 7                  ", "F - test-run-preserves-trace-view-on-rerun/pre1-2"
1071   check-background-color-in-screen-row screen, 7/bg=cursor,   3/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/pre1-2/cursor"
1072   # expand
1073   edit-sandbox sandbox, 0xa/newline, 0/no-globals, 0/no-disk
1074   clear-screen screen
1075   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
1076   #
1077   check-screen-row screen,                                    1/y, " 7                     ", "F - test-run-preserves-trace-view-on-rerun/pre2-0"
1078   check-background-color-in-screen-row screen, 7/bg=cursor,   1/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/pre2-0/cursor"
1079   check-screen-row screen,                                    2/y, " 1 tokenize            ", "F - test-run-preserves-trace-view-on-rerun/pre2-1"
1080   check-background-color-in-screen-row screen, 7/bg=cursor,   2/y, " ||||||||||            ", "F - test-run-preserves-trace-view-on-rerun/pre2-1/cursor"
1081   check-screen-row screen,                                    3/y, " ...                   ", "F - test-run-preserves-trace-view-on-rerun/pre2-2"
1082   check-background-color-in-screen-row screen, 7/bg=cursor,   3/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/pre2-2/cursor"
1083   check-screen-row screen,                                    4/y, " 1 insert parens       ", "F - test-run-preserves-trace-view-on-rerun/pre2-3"
1084   check-background-color-in-screen-row screen, 7/bg=cursor,   4/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/pre2-3/cursor"
1085   check-screen-row screen,                                    5/y, " 1 parse               ", "F - test-run-preserves-trace-view-on-rerun/pre2-4"
1086   check-background-color-in-screen-row screen, 7/bg=cursor,   5/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/pre2-4/cursor"
1087   check-screen-row screen,                                    6/y, " ...                   ", "F - test-run-preserves-trace-view-on-rerun/pre2-5"
1088   check-background-color-in-screen-row screen, 7/bg=cursor,   6/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/pre2-5/cursor"
1089   check-screen-row screen,                                    7/y, " 1 transform infix     ", "F - test-run-preserves-trace-view-on-rerun/pre2-6"
1090   check-background-color-in-screen-row screen, 7/bg=cursor,   7/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/pre2-6/cursor"
1091   check-screen-row screen,                                    8/y, " ...                   ", "F - test-run-preserves-trace-view-on-rerun/pre2-7"
1092   check-background-color-in-screen-row screen, 7/bg=cursor,   8/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/pre2-7/cursor"
1093   check-screen-row screen,                                    9/y, " 1 macroexpand 7       ", "F - test-run-preserves-trace-view-on-rerun/pre2-8"
1094   check-background-color-in-screen-row screen, 7/bg=cursor,   9/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/pre2-8/cursor"
1095   check-screen-row screen,                                  0xa/y, " ...                   ", "F - test-run-preserves-trace-view-on-rerun/pre2-9"
1096   check-background-color-in-screen-row screen, 7/bg=cursor, 0xa/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/pre2-9/cursor"
1097   check-screen-row screen,                                  0xb/y, " 1 => 7                ", "F - test-run-preserves-trace-view-on-rerun/pre2-10"
1098   check-background-color-in-screen-row screen, 7/bg=cursor, 0xb/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/pre2-10/cursor"
1099   # move cursor down below the macroexpand line and expand
1100   edit-sandbox sandbox, 0x6a/j, 0/no-globals, 0/no-disk
1101   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
1102   edit-sandbox sandbox, 0x6a/j, 0/no-globals, 0/no-disk
1103   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
1104   edit-sandbox sandbox, 0x6a/j, 0/no-globals, 0/no-disk
1105   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
1106   edit-sandbox sandbox, 0x6a/j, 0/no-globals, 0/no-disk
1107   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
1108   edit-sandbox sandbox, 0x6a/j, 0/no-globals, 0/no-disk
1109   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
1110   edit-sandbox sandbox, 0x6a/j, 0/no-globals, 0/no-disk
1111   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
1112   edit-sandbox sandbox, 0x6a/j, 0/no-globals, 0/no-disk
1113   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
1114   edit-sandbox sandbox, 0x6a/j, 0/no-globals, 0/no-disk
1115   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
1116   #
1117   check-screen-row screen,                                    1/y, " 7                     ", "F - test-run-preserves-trace-view-on-rerun/pre3-0"
1118   check-background-color-in-screen-row screen, 7/bg=cursor,   1/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/pre3-0/cursor"
1119   check-screen-row screen,                                    2/y, " 1 tokenize            ", "F - test-run-preserves-trace-view-on-rerun/pre3-1"
1120   check-background-color-in-screen-row screen, 7/bg=cursor,   2/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/pre3-1/cursor"
1121   check-screen-row screen,                                    3/y, " ...                   ", "F - test-run-preserves-trace-view-on-rerun/pre3-2"
1122   check-background-color-in-screen-row screen, 7/bg=cursor,   3/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/pre3-2/cursor"
1123   check-screen-row screen,                                    4/y, " 1 insert parens       ", "F - test-run-preserves-trace-view-on-rerun/pre3-3"
1124   check-background-color-in-screen-row screen, 7/bg=cursor,   4/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/pre3-3/cursor"
1125   check-screen-row screen,                                    5/y, " 1 parse               ", "F - test-run-preserves-trace-view-on-rerun/pre3-4"
1126   check-background-color-in-screen-row screen, 7/bg=cursor,   5/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/pre3-4/cursor"
1127   check-screen-row screen,                                    6/y, " ...                   ", "F - test-run-preserves-trace-view-on-rerun/pre3-5"
1128   check-background-color-in-screen-row screen, 7/bg=cursor,   6/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/pre3-5/cursor"
1129   check-screen-row screen,                                    7/y, " 1 transform infix     ", "F - test-run-preserves-trace-view-on-rerun/pre3-6"
1130   check-background-color-in-screen-row screen, 7/bg=cursor,   7/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/pre3-6/cursor"
1131   check-screen-row screen,                                    8/y, " ...                   ", "F - test-run-preserves-trace-view-on-rerun/pre3-7"
1132   check-background-color-in-screen-row screen, 7/bg=cursor,   8/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/pre3-7/cursor"
1133   check-screen-row screen,                                    9/y, " 1 macroexpand 7       ", "F - test-run-preserves-trace-view-on-rerun/pre3-8"
1134   check-background-color-in-screen-row screen, 7/bg=cursor,   9/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/pre3-8/cursor"
1135   check-screen-row screen,                                  0xa/y, " ...                   ", "F - test-run-preserves-trace-view-on-rerun/pre3-9"
1136   check-background-color-in-screen-row screen, 7/bg=cursor, 0xa/y, " |||                   ", "F - test-run-preserves-trace-view-on-rerun/pre3-9/cursor"
1137   check-screen-row screen,                                  0xb/y, " 1 => 7                ", "F - test-run-preserves-trace-view-on-rerun/pre3-10"
1138   check-background-color-in-screen-row screen, 7/bg=cursor, 0xb/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/pre3-10/cursor"
1139   # expand
1140   edit-sandbox sandbox, 0xa/newline, 0/no-globals, 0/no-disk
1141   clear-screen screen
1142   render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height, 1/show-cursor
1143   # cursor line is expanded
1144   check-screen-row screen,                                    1/y, " 7                     ", "F - test-run-preserves-trace-view-on-rerun/expand-0"
1145   check-background-color-in-screen-row screen, 7/bg=cursor,   1/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/expand-0/cursor"
1146   check-screen-row screen,                                    2/y, " 1 tokenize            ", "F - test-run-preserves-trace-view-on-rerun/expand-1"
1147   check-background-color-in-screen-row screen, 7/bg=cursor,   2/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/expand-1/cursor"
1148   check-screen-row screen,                                    3/y, " ...                   ", "F - test-run-preserves-trace-view-on-rerun/expand-2"
1149   check-background-color-in-screen-row screen, 7/bg=cursor,   3/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/expand-2/cursor"
1150   check-screen-row screen,                                    4/y, " 1 insert parens       ", "F - test-run-preserves-trace-view-on-rerun/expand-3"
1151   check-background-color-in-screen-row screen, 7/bg=cursor,   4/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/expand-3/cursor"
1152   check-screen-row screen,                                    5/y, " 1 parse               ", "F - test-run-preserves-trace-view-on-rerun/expand-4"
1153   check-background-color-in-screen-row screen, 7/bg=cursor,   5/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/expand-4/cursor"
1154   check-screen-row screen,                                    6/y, " ...                   ", "F - test-run-preserves-trace-view-on-rerun/expand-5"
1155   check-background-color-in-screen-row screen, 7/bg=cursor,   6/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/expand-5/cursor"
1156   check-screen-row screen,                                    7/y, " 1 transform infix     ", "F - test-run-preserves-trace-view-on-rerun/expand-6"
1157   check-background-color-in-screen-row screen, 7/bg=cursor,   7/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/expand-6/cursor"
1158   check-screen-row screen,                                    8/y, " ...                   ", "F - test-run-preserves-trace-view-on-rerun/expand-7"
1159   check-background-color-in-screen-row screen, 7/bg=cursor,   8/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/expand-7/cursor"
1160   check-screen-row screen,                                    9/y, " 1 macroexpand 7       ", "F - test-run-preserves-trace-view-on-rerun/expand-8"
1161   check-background-color-in-screen-row screen, 7/bg=cursor,   9/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/expand-8/cursor"
1162   check-screen-row screen,                                  0xa/y, " 2 macroexpand-iter 7  ", "F - test-run-preserves-trace-view-on-rerun/expand-9"
1163   check-background-color-in-screen-row screen, 7/bg=cursor, 0xa/y, " ||||||||||||||||||||  ", "F - test-run-preserves-trace-view-on-rerun/expand-9/cursor"
1164   check-screen-row screen,                                  0xb/y, " ...                   ", "F - test-run-preserves-trace-view-on-rerun/expand-10"
1165   check-background-color-in-screen-row screen, 7/bg=cursor, 0xb/y, "                       ", "F - test-run-preserves-trace-view-on-rerun/expand-10/cursor"
1166 }