https://github.com/akkartik/mu/blob/main/apps/tile/main.mu
  1 fn main args-on-stack: (addr array addr array byte) -> _/ebx: int {
  2   var args/eax: (addr array addr array byte) <- copy args-on-stack
  3   var len/ecx: int <- length args
  4   compare len, 2
  5   {
  6     break-if-!=
  7     # if single arg is 'test', run tests
  8     var tmp/ecx: (addr addr array byte) <- index args, 1
  9     var tmp2/eax: boolean <- string-equal? *tmp, "test"
 10     compare tmp2, 0  # false
 11     {
 12       break-if-=
 13       run-tests
 14       return 0  # TODO: get at Num-test-failures somehow
 15     }
 16     # if single arg is 'screen', run in full-screen mode
 17     tmp2 <- string-equal? *tmp, "screen"
 18     compare tmp2, 0  # false
 19     {
 20       break-if-=
 21       interactive
 22       return 0
 23     }
 24     # if single arg is 'type', run in typewriter mode
 25     tmp2 <- string-equal? *tmp, "type"
 26     compare tmp2, 0  # false
 27     {
 28       break-if-=
 29       repl
 30       return 0
 31     }
 32     # if single arg is 'test' ...
 33     tmp2 <- string-equal? *tmp, "test2"
 34     compare tmp2, 0  # false
 35     {
 36       break-if-=
 37       test
 38       return 0
 39     }
 40   }
 41   # otherwise error message
 42   print-string-to-real-screen "usage:\n"
 43   print-string-to-real-screen "  to run tests: tile test\n"
 44   print-string-to-real-screen "  full-screen mode: tile screen\n"
 45   print-string-to-real-screen "  regular REPL: tile type\n"
 46   return 1
 47 }
 48 
 49 fn interactive {
 50   enable-screen-grid-mode
 51   enable-keyboard-immediate-mode
 52   var env-storage: environment
 53   var env/esi: (addr environment) <- address env-storage
 54   initialize-environment env
 55   draw-screen env
 56   {
 57     var key/eax: grapheme <- read-key-from-real-keyboard
 58     compare key, 0x11  # 'ctrl-q'
 59     break-if-=
 60     process env, key
 61     render env
 62     loop
 63   }
 64   enable-keyboard-type-mode
 65   enable-screen-type-mode
 66 }
 67 
 68 fn test {
 69   var env-storage: environment
 70   var env/esi: (addr environment) <- address env-storage
 71   initialize-environment-with-fake-screen env, 0x20, 0xa0
 72   process-all env, "3 3 fake-screen =s"
 73   process env, 0xc  # ctrl-l
 74   process-all env, "s 1 down 1 right"
 75   process env, 4  # ctrl-d: start defining function
 76   process-all env, "foo"
 77   process env, 0xa  # newline: define function
 78   process env, 0x435b1b  # right-arrow
 79 #?   process env, 5  # ctrl-e: end of line
 80   print-string 0, "==\n"
 81   process env, 0xa  # newline: expand
 82   render env
 83 }
 84 
 85 fn process-all env: (addr environment), cmds: (addr array byte) {
 86   var cmds-stream: (stream byte 0x100)
 87   var cmds-stream-a/esi: (addr stream byte) <- address cmds-stream
 88   write cmds-stream-a, cmds
 89   {
 90     var done?/eax: boolean <- stream-empty? cmds-stream-a
 91     compare done?, 0  # false
 92     break-if-!=
 93     var g/eax: grapheme <- read-grapheme cmds-stream-a
 94     process env, g
 95     loop
 96   }
 97 }
 98 
 99 fn repl {
100   {
101     # prompt
102     print-string-to-real-screen "> "
103     # read
104     var line-storage: (stream byte 0x100)
105     var line/ecx: (addr stream byte) <- address line-storage
106     clear-stream line
107     read-line-from-real-keyboard line
108     var done?/eax: boolean <- stream-empty? line
109     compare done?, 0  # false
110     break-if-!=
111     # parse
112     var env-storage: environment
113     var env/esi: (addr environment) <- address env-storage
114     initialize-environment env
115     {
116       var done?/eax: boolean <- stream-empty? line
117       compare done?, 0  # false
118       break-if-!=
119       var g/eax: grapheme <- read-grapheme line
120       process env, g
121       loop
122     }
123     # eval
124     var stack-storage: value-stack
125     var stack/edi: (addr value-stack) <- address stack-storage
126     initialize-value-stack stack, 0x10
127     evaluate-environment env, stack
128     # print
129     var empty?/eax: boolean <- value-stack-empty? stack
130     {
131       compare empty?, 0  # false
132       break-if-!=
133       var result/xmm0: float <- pop-number-from-value-stack stack
134       print-float-decimal-approximate 0, result, 3
135       print-string 0, "\n"
136       print-string 0, "width: "
137       var width/eax: int <- float-size result, 3
138       print-int32-decimal 0, width
139       print-string 0, "\n"
140     }
141     #
142     loop
143   }
144 }