image/svg+xml            R reload thisdirectory r :open_with ^R resetranger E edit e W show log w show back-ground tasks Q quit q close tab TAB prev. tab tab next tab ~ ` openbookmarks ! :shell 1 (1) ESC abort T t tag files Y y yank (3) U u undo ^U move uphalf page I i inspect file :rename(insert) O o sort P p paste (3) { [ move up inparent dir } traverse sub-directories ] move downin parent dir @ :shell %s 2 (1) # :shell -p 3 (1) $ 4 (1) % 5 (1) ^ 6 (1) & 7 (1) * 8 (1) ( 9 (1) ) 0 (1) _ - chmod (2) + chmod (2) = chmod (2) A :rename(append) a :rename (skipextension) S open shell s :shell D d cut (3) (4) move downhalf page ^D F f :find ^F move downone page G go to top g :cd ... H back inhistory h go up 1directory ^H togglehidden files J move downhalf page j move down K move uphalf page k move up L forward inhistory l enter dir/open file ^L redraw : console ; console ' openbookmarks " tag files withcustom tag CAPSLOCK SHIFT Z ZZ/ZQ = quit z toggleoptions X x ^C C c select files incertain order abort task V visual mode v invertselection B b ^B move upone page N searchprevious n search next ^N new tab M change (5)linemode m savebookmark < , > . ? show help (6) / :search F1 help F3 inspect file F4 edit F5 copy F6 cut F7 :mkdir F8
fn evaluate functions: (addr handle function), bindings: (addr table), scratch: (addr line), end: (addr word), out: (addr value-stack) {
  var line/eax: (addr line) <- copy scratch
  var word-ah/eax: (addr handle word) <- get line, data
  var curr/eax: (addr word) <- lookup *word-ah
  var curr-stream-storage: (stream byte 0x10)
  var curr-stream/edi: (addr stream byte) <- address curr-stream-storage
  clear-value-stack out
  $evaluate:loop: {
    # precondition (should never hit)
    compare curr, 0
    break-if-=
    # update curr-stream
    emit-word curr, curr-stream
#?     print-string-to-real-screen "eval: "
#?     print-stream-to-real-screen curr-stream
#?     print-string-to-real-screen "\n"
    $evaluate:process-word: {
      ### if curr-stream is an operator, perform it
      ## numbers
      {
        var add?/eax: boolean <- stream-data-equal? curr-stream, "+"
        compare add?, 0
        break-if-=
        var _b/xmm0: float <- pop-number-from-value-stack out
        var b/xmm1: float <- copy _b
        var a/xmm0: float <- pop-number-from-value-stack out
        a <- add b
        push-number-to-value-stack out, a
        break $evaluate:process-word
      }
      {
        var sub?/eax: boolean <- stream-data-equal? curr-stream, "-"
        compare sub?, 0
        break-if-=
        var _b/xmm0: float <- pop-number-from-value-stack out
        var b/xmm1: float <- copy _b
        var a/xmm0: float <- pop-number-from-value-stack out
        a <- subtract b
        push-number-to-value-stack out, a
        break $evaluate:process-word
      }
      {
        var mul?/eax: boolean <- stream-data-equal? curr-stream, "*"
        compare mul?, 0
        break-if-=
        var _b/xmm0: float <- pop-number-from-value-stack out
        var b/xmm1: float <- copy _b
        var a/xmm0: float <- pop-number-from-value-stack out
        a <- multiply b
        push-number-to-value-stack out, a
        break $evaluate:process-word
      }
      {
        var div?/eax: boolean <- stream-data-equal? curr-stream, "/"
        compare div?, 0
        break-if-=
        var _b/xmm0: float <- pop-number-from-value-stack out
        var b/xmm1: float <- copy _b
        var a/xmm0: float <- pop-number-from-value-stack out
        a <- divide b
        push-number-to-value-stack out, a
        break $evaluate:process-word
      }
      {
        var sqrt?/eax: boolean <- stream-data-equal? curr-stream, "sqrt"
        compare sqrt?, 0
        break-if-=
        var a/xmm0: float <- pop-number-from-value-stack out
        a <- square-root a
        push-number-to-value-stack out, a
        break $evaluate:process-word
      }
      ## strings/arrays
      {
        var len?/eax: boolean <- stream-data-equal? curr-stream, "len"
        compare len?, 0
        break-if-=
#?         print-string 0, "is len\n"
        # pop target-val from out
        var out2/esi: (addr value-stack) <- copy out
        var top-addr/ecx: (addr int) <- get out2, top
        compare *top-addr, 0
        break-if-<=
#?         print-string 0, "stack has stuff\n"
        var data-ah/eax: (addr handle array value) <- get out2, data
        var data/eax: (addr array value) <- lookup *data-ah
        var top/edx: int <- copy *top-addr
        top <- decrement
        var dest-offset/edx: (offset value) <- compute-offset data, top
        var target-val/edx: (addr value) <- index data, dest-offset
        # check target-val is a string or array
        var target-type-addr/eax: (addr int) <- get target-val, type
        compare *target-type-addr, 1/string
        {
          break-if-!=
          # compute length
          var src-ah/eax: (addr handle array byte) <- get target-val, text-data
          var src/eax: (addr array byte) <- lookup *src-ah
          var result/ebx: int <- length src
          var result-f/xmm0: float <- convert result
          # save result into target-val
          var type-addr/eax: (addr int) <- get target-val, type
          copy-to *type-addr, 0/int
          var target-string-ah/eax: (addr handle array byte) <- get target-val, text-data
          clear-object target-string-ah
          var target/eax: (addr float) <- get target-val, number-data
          copy-to *target, result-f
          break $evaluate:process-word
        }
        compare *target-type-addr, 2/array
        {
          break-if-!=
          # compute length
          var src-ah/eax: (addr handle array value) <- get target-val, array-data
          var src/eax: (addr array value) <- lookup *src-ah
          var result/ebx: int <- length src
          var result-f/xmm0: float <- convert result
          # save result into target-val
          var type-addr/eax: (addr int) <- get target-val, type
          copy-to *type-addr, 0/int
          var target-array-ah/eax: (addr handle array value) <- get target-val, array-data
          clear-object target-array-ah
          var target/eax: (addr float) <- get target-val, number-data
          copy-to *target, result-f
          break $evaluate:process-word
        }
      }
      ## files
      {
        var open?/eax: boolean <- stream-data-equal? curr-stream, "open"
        compare open?, 0
        br