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