about summary refs log blame commit diff stats
path: root/apps/tile/value.mu
blob: 8dfe4bcc13219d53b0742c6060328011dba7545c (plain) (tree)























































                                                                           









                                                                

























































































































                                                                                           









                                                                 





























                                                                             
## Rendering values

fn render-value screen: (addr screen), _val: (addr value), max-width: int {
$render-value:body: {
  var val/esi: (addr value) <- copy _val
  var val-type/ecx: (addr int) <- get val, type
  # per-type rendering logic goes here
  compare *val-type, 1  # string
  {
    break-if-!=
    var val-ah/eax: (addr handle array byte) <- get val, text-data
    var val-string/eax: (addr array byte) <- lookup *val-ah
    compare val-string, 0
    break-if-=
    var orig-len/ecx: int <- length val-string
    var truncated: (handle array byte)
    var truncated-ah/esi: (addr handle array byte) <- address truncated
    substring val-string, 0, 0xc, truncated-ah
    var truncated-string/eax: (addr array byte) <- lookup *truncated-ah
#?     {
#?       var foo/eax: int <- copy truncated-string
#?       print-int32-hex 0, foo
#?       print-string 0, "\n"
#?     }
    var len/edx: int <- length truncated-string
    start-color screen, 0xf2, 7
    print-code-point screen, 0x275d  # open-quote
    print-string screen, truncated-string
    compare len, orig-len
    {
      break-if-=
      print-code-point screen, 0x2026  # ellipses
    }
    print-code-point screen, 0x275e  # close-quote
    reset-formatting screen
    break $render-value:body
  }
  compare *val-type, 2  # array
  {
    break-if-!=
    var val-ah/eax: (addr handle array value) <- get val, array-data
    var val-array/eax: (addr array value) <- lookup *val-ah
    render-array screen, val-array
    break $render-value:body
  }
  compare *val-type, 3  # file
  {
    break-if-!=
    var val-ah/eax: (addr handle buffered-file) <- get val, file-data
    var val-file/eax: (addr buffered-file) <- lookup *val-ah
    start-color screen, 0, 7
    # TODO
    print-string screen, " FILE "
    break $render-value:body
  }
  compare *val-type, 4  # file
  {
    break-if-!=
    var val-ah/eax: (addr handle screen) <- get val, screen-data
    var val-screen/eax: (addr screen) <- lookup *val-ah
    start-color screen, 0, 7
    # TODO
    print-string screen, " SCREEN "
    break $render-value:body
  }
  # render ints by default for now
  var val-int/eax: (addr int) <- get val, int-data
  render-integer screen, *val-int, max-width
}
}

# synaesthesia
fn render-integer screen: (addr screen), val: int, max-width: int {
$render-integer:body: {
  # if max-width is 0, we're inside an array. No coloring.
  compare max-width, 0
  {
    break-if-!=
    print-int32-decimal screen, val
    break $render-integer:body
  }
  var bg/eax: int <- hash-color val
  var fg/ecx: int <- copy 7
  {
    compare bg, 2
    break-if-!=
    fg <- copy 0
  }
  {
    compare bg, 3
    break-if-!=
    fg <- copy 0
  }
  {
    compare bg, 6
    break-if-!=
    fg <- copy 0
  }
  start-color screen, fg, bg
  print-grapheme screen, 0x20  # space
  print-int32-decimal-right-justified screen, val, max-width
  print-grapheme screen, 0x20  # space
}
}

fn render-array screen: (addr screen), _a: (addr array value) {
  start-color screen, 0xf2, 7
  # don't surround in spaces
  print-grapheme screen, 0x5b  # '['
  var a/esi: (addr array value) <- copy _a
  var max/ecx: int <- length a
  var i/eax: int <- copy 0
  {
    compare i, max
    break-if->=
    {
      compare i, 0
      break-if-=
      print-string screen, " "
    }
    var off/ecx: (offset value) <- compute-offset a, i
    var x/ecx: (addr value) <- index a, off
    render-value screen, x, 0
    i <- increment
    loop
  }
  print-grapheme screen, 0x5d  # ']'
}

fn hash-color val: int -> _/eax: int {
  var result/eax: int <- try-modulo val, 7  # assumes that 7 is always the background color
  return result
}

fn value-width _v: (addr value), top-level: boolean -> _/eax: int {
  var v/esi: (addr value) <- copy _v
  var type/eax: (addr int) <- get v, type
  {
    compare *type, 0  # int
    break-if-!=
    var v-int/edx: (addr int) <- get v, int-data
    var result/eax: int <- decimal-size *v-int
    return result
  }
  {
    compare *type, 1  # string
    break-if-!=
    var s-ah/eax: (addr handle array byte) <- get v, text-data
    var s/eax: (addr array byte) <- lookup *s-ah
    compare s, 0
    break-if-=
    var result/eax: int <- length s
    compare result, 0xd  # max string size
    {
      break-if-<=
      result <- copy 0xd
    }
    # if it's a nested string, include space for quotes
    # we don't do this for the top-level, where the quotes will overflow
    # into surrounding padding.
    compare top-level, 0  # false
    {
      break-if-!=
      result <- add 2
    }
    return result
  }
  {
    compare *type, 2  # array
    break-if-!=
    var a-ah/eax: (addr handle array value) <- get v, array-data
    var a/eax: (addr array value) <- lookup *a-ah
    compare a, 0
    break-if-=
    var result/eax: int <- array-width a
    return result
  }
  {
    compare *type, 3  # file handle
    break-if-!=
    var f-ah/eax: (addr handle buffered-file) <- get v, file-data
    var f/eax: (addr buffered-file) <- lookup *f-ah
    compare f, 0
    break-if-=
    # TODO: visualizing file handles
    return 4
  }
  {
    compare *type, 4  # screen
    break-if-!=
    var screen-ah/eax: (addr handle screen) <- get v, screen-data
    var screen/eax: (addr screen) <- lookup *screen-ah
    compare screen, 0
    break-if-=
    # TODO: visualizing screen
    return 6
  }
  return 0
}

# keep sync'd with render-array
fn array-width _a: (addr array value) -> _/eax: int {
  var a/esi: (addr array value) <- copy _a
  var max/ecx: int <- length a
  var i/eax: int <- copy 0
  var result/edi: int <- copy 0
  {
    compare i, max
    break-if->=
    {
      compare i, 0
      break-if-=
      result <- increment  # for space
    }
    var off/ecx: (offset value) <- compute-offset a, i
    var x/ecx: (addr value) <- index a, off
    {
      var w/eax: int <- value-width x, 0
      result <- add w
    }
    i <- increment
    loop
  }
  # we won't add 2 for surrounding brackets since we don't surround arrays in
  # spaces like other value types
  return result
}