about summary refs log tree commit diff stats
path: root/apps/tile/main.mu
blob: e0daaf1bd0a8003d4771b2a27757fc62004613e0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highl
fn main args-on-stack: (addr array addr array byte) -> _/ebx: int {
  var args/eax: (addr array addr array byte) <- copy args-on-stack
  var len/ecx: int <- length args
  compare len, 2
  {
    break-if-!=
    # if single arg is 'test', run tests
    var tmp/ecx: (addr addr array byte) <- index args, 1
    var tmp2/eax: boolean <- string-equal? *tmp, "test"
    compare tmp2, 0/false
    {
      break-if-=
      run-tests
      return 0  # TODO: get at Num-test-failures somehow
    }
    # if single arg is 'screen', run in full-screen mode
    tmp2 <- string-equal? *tmp, "screen"
    compare tmp2, 0/false
    {
      break-if-=
      interactive
      return 0
    }
    # if single arg is 'type', run in typewriter mode
    tmp2 <- string-equal? *tmp, "type"
    compare tmp2, 0/false
    {
      break-if-=
      repl
      return 0
    }
    # if single arg is 'test' ...
    tmp2 <- string-equal? *tmp, "test2"
    compare tmp2, 0/false
    {
      break-if-=
      test
      return 0
    }
  }
  # otherwise error message
  print-string-to-real-screen "usage:\n"
  print-string-to-real-screen "  to run tests: tile test\n"
  print-string-to-real-screen "  full-screen mode: tile screen\n"
  print-string-to-real-screen "  regular REPL: tile type\n"
  return 1
}

fn interactive {
  enable-screen-grid-mode
  enable-keyboard-immediate-mode
  var env-storage: environment
  var env/esi: (addr environment) <- address env-storage
  initialize-environment env
  {
    render env
    var key/eax: grapheme <- read-key-from-real-keyboard
    compare key, 0x11/ctrl-q
    break-if-=
    process env, key
    loop
  }
  enable-keyboard-type-mode
  enable-screen-type-mode
}

fn test {
  var env-storage: environment
  var env/esi: (addr environment) <- address env-storage
  initialize-environment-with-fake-screen env, 0x20, 0xa0
  render env
}

fn process-all env: (addr environment), cmds: (addr array byte) {
  var cmds-stream: (stream byte 0x100)
  var cmds-stream-a/esi: (addr stream byte) <- address cmds-stream
  write cmds-stream-a, cmds
  {
    var done?/eax: boolean <- stream-empty? cmds-stream-a
    compare done?, 0/false
    break-if-!=
    var g/eax: grapheme <- read-grapheme cmds-stream-a
    process env, g
    loop
  }
}

fn repl {
  {
    # prompt
    print-string-to-real-screen "> "
    # read
    var line-storage: (stream byte 0x100)
    var line/ecx: (addr stream byte) <- address line-storage
    clear-stream line
    read-line-from-real-keyboard line
    var done?/eax: boolean <- stream-empty? line
    compare done?, 0/false
    break-if-!=
    # parse
    var env-storage: environment
    var env/esi: (addr environment) <- address env-storage
    initialize-environment env
    {
      var done?/eax: boolean <- stream-empty? line
      compare done?, 0/false
      break-if-!=
      var g/eax: grapheme <- read-grapheme line
      process env, g
      loop
    }
    # eval
    var stack-storage: value-stack
    var stack/edi: (addr value-stack) <- address stack-storage
    initialize-value-stack stack, 0x10
    evaluate-environment env, stack
    # print
    var empty?/eax: boolean <- value-stack-empty? stack
    {
      compare empty?, 0/false
      break-if-!=
      var result/xmm0: float <- pop-number-from-value-stack stack
      print-float-decimal-approximate 0, result, 3
      print-string 0, "\n"
      print-string 0, "width: "
      var width/eax: int <- float-size result, 3
      print-int32-decimal 0, width
      print-string 0, "\n"
    }
    #
    loop
  }
}