https://github.com/akkartik/mu/blob/main/shell/cell.mu

      1 type cell {
      2   type: int
      3   # type 0: pair; the unit of lists, trees, DAGS or graphs
      4   left: (handle cell)
      5   right: (handle cell)
      6   # type 1: number
      7   number-data: float
      8   # type 2: symbol
      9   # type 3: stream
     10   text-data: (handle stream byte)
     11   # type 4: primitive function
     12   index-data: int
     13   # type 5: screen
     14   screen-data: (handle screen)
     15   # type 6: keyboard
     16   keyboard-data: (handle gap-buffer)
     17   # TODO: array, (associative) table
     18 }
     19
     20 fn allocate-symbol _out: (addr handle cell) {
     21   var out/eax: (addr handle cell) <- copy _out
     22   allocate out
     23   var out-addr/eax: (addr cell) <- lookup *out
     24   var type/ecx: (addr int) <- get out-addr, type
     25   copy-to *type, 2/symbol
     26   var dest-ah/eax: (addr handle stream byte) <- get out-addr, text-data
     27   populate-stream dest-ah, 0x40/max-symbol-size
     28 }
     29
     30 fn initialize-symbol _out: (addr handle cell), val: (addr array byte) {
     31   var out/eax: (addr handle cell) <- copy _out
     32   var out-addr/eax: (addr cell) <- lookup *out
     33   var dest-ah/eax: (addr handle stream byte) <- get out-addr, text-data
     34   var dest/eax: (addr stream byte) <- lookup *dest-ah
     35   write dest, val
     36 }
     37
     38 fn new-symbol out: (addr handle cell), val: (addr array byte) {
     39   allocate-symbol out
     40   initialize-symbol out, val
     41 }
     42
     43 fn symbol-equal? _in: (addr cell), name: (addr array byte) -> _/eax: boolean {
     44   var in/esi: (addr cell) <- copy _in
     45   var in-type/eax: (addr int) <- get in, type
     46   compare *in-type, 2/symbol
     47   {
     48     break-if-=
     49     return 0/false
     50   }
     51   var in-data-ah/eax: (addr handle stream byte) <- get in, text-data
     52   var in-data/eax: (addr stream byte) <- lookup *in-data-ah
     53   var result/eax: boolean <- stream-data-equal? in-data, name
     54   return result
     55 }
     56
     57 fn allocate-stream _out: (addr handle cell) {
     58   var out/eax: (addr handle cell) <- copy _out
     59   allocate out
     60   var out-addr/eax: (addr cell) <- lookup *out
     61   var type/ecx: (addr int) <- get out-addr, type
     62   copy-to *type, 3/stream
     63   var dest-ah/eax: (addr handle stream byte) <- get out-addr, text-data
     64   populate-stream dest-ah, 0x40/max-stream-size
     65 }
     66
     67 fn allocate-number _out: (addr handle cell) {
     68   var out/eax: (addr handle cell) <- copy _out
     69   allocate out
     70   var out-addr/eax: (addr cell) <- lookup *out
     71   var type/ecx: (addr int) <- get out-addr, type
     72   copy-to *type, 1/number
     73 }
     74
     75 fn initialize-integer _out: (addr handle cell), n: int {
     76   var out/eax: (addr handle cell) <- copy _out
     77   var out-addr/eax: (addr cell) <- lookup *out
     78   var dest-addr/eax: (addr float) <- get out-addr, number-data
     79   var src/xmm0: float <- convert n
     80   copy-to *dest-addr, src
     81 }
     82
     83 fn new-integer out: (addr handle cell), n: int {
     84   allocate-number out
     85   initialize-integer out, n
     86 }
     87
     88 fn initialize-float _out: (addr handle cell), n: float {
     89   var out/eax: (addr handle cell) <- copy _out
     90   var out-addr/eax: (addr cell) <- lookup *out
     91   var dest-ah/eax: (addr float) <- get out-addr, number-data
     92   var src/xmm0: float <- copy n
     93   copy-to *dest-ah, src
     94 }
     95
     96 fn new-float out: (addr handle cell), n: float {
     97   allocate-number out
     98   initialize-float out, n
     99 }
    100
    101 fn allocate-pair out: (addr handle cell) {
    102   allocate out
    103   # new cells have type pair by default
    104 }
    105
    106 fn initialize-pair _out: (addr handle cell), left: (handle cell), right: (handle cell) {
    107   var out/eax: (addr handle cell) <- copy _out
    108   var out-addr/eax: (addr cell) <- lookup *out
    109   var dest-ah/ecx: (addr handle cell) <- get out-addr, left
    110   copy-handle left, dest-ah
    111   dest-ah <- get out-addr, right
    112   copy-handle right, dest-ah
    113 }
    114
    115 fn new-pair out: (addr handle cell), left: (handle cell), right: (handle cell) {
    116   allocate-pair out
    117   initialize-pair out, left, right
    118 }
    119
    120 fn nil out: (addr handle cell) {
    121   allocate-pair out
    122 }
    123
    124 fn allocate-primitive-function _out: (addr handle cell) {
    125   var out/eax: (addr handle cell) <- copy _out
    126   allocate out
    127   var out-addr/eax: (addr cell) <- lookup *out
    128   var type/ecx: (addr int) <- get out-addr, type
    129   copy-to *type, 4/primitive-function
    130 }
    131
    132 fn initialize-primitive-function _out: (addr handle cell), n: int {
    133   var out/eax: (addr handle cell) <- copy _out
    134   var out-addr/eax: (addr cell) <- lookup *out
    135   var dest-addr/eax: (addr int) <- get out-addr, index-data
    136   var src/ecx: int <- copy n
    137   copy-to *dest-addr, src
    138 }
    139
    140 fn new-primitive-function out: (addr handle cell), n: int {
    141   allocate-primitive-function out
    142   initialize-primitive-function out, n
    143 }
    144
    145 fn allocate-screen _out: (addr handle cell) {
    146   var out/eax: (addr handle cell) <- copy _out
    147   allocate out
    148   var out-addr/eax: (addr cell) <- lookup *out
    149   var type/ecx: (addr int) <- get out-addr, type
    150   copy-to *type, 5/screen
    151 }
    152
    153 fn new-fake-screen _out: (addr handle cell), width: int, height: int, pixel-graphics?: boolean {
    154   var out/eax: (addr handle cell) <- copy _out
    155   allocate-screen out
    156   var out-addr/eax: (addr cell) <- lookup *out
    157   var dest-ah/eax: (addr handle screen) <- get out-addr, screen-data
    158   allocate dest-ah
    159   var dest-addr/eax: (addr screen) <- lookup *dest-ah
    160   initialize-screen dest-addr, width, height, pixel-graphics?
    161 }
    162
    163 fn clear-screen-cell _self-ah: (addr handle cell) {
    164   var self-ah/eax: (addr handle cell) <- copy _self-ah
    165   var self/eax: (addr cell) <- lookup *self-ah
    166   compare self, 0
    167   {
    168     break-if-!=
    169     return
    170   }
    171   var screen-ah/eax: (addr handle screen) <- get self, screen-data
    172   var screen/eax: (addr screen) <- lookup *screen-ah
    173   clear-screen screen
    174 }
    175
    176 fn allocate-keyboard _out: (addr handle cell) {
    177   var out/eax: (addr handle cell) <- copy _out
    178   allocate out
    179   var out-addr/eax: (addr cell) <- lookup *out
    180   var type/ecx: (addr int) <- get out-addr, type
    181   copy-to *type, 6/keyboard
    182 }
    183
    184 fn new-fake-keyboard _out: (addr handle cell), capacity: int {
    185   var out/eax: (addr handle cell) <- copy _out
    186   allocate-keyboard out
    187   var out-addr/eax: (addr cell) <- lookup *out
    188   var dest-ah/eax: (addr handle gap-buffer) <- get out-addr, keyboard-data
    189   allocate dest-ah
    190   var dest-addr/eax: (addr gap-buffer) <- lookup *dest-ah
    191   initialize-gap-buffer dest-addr, capacity
    192 }
    193
    194 fn rewind-keyboard-cell _self-ah: (addr handle cell) {
    195   var self-ah/eax: (addr handle cell) <- copy _self-ah
    196   var self/eax: (addr cell) <- lookup *self-ah
    197   compare self, 0
    198   {
    199     break-if-!=
    200     return
    201   }
    202   var keyboard-ah/eax: (addr handle gap-buffer) <- get self, keyboard-data
    203   var keyboard/eax: (addr gap-buffer) <- lookup *keyboard-ah
    204   rewind-gap-buffer keyboard
    205 }