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: string
 10   text-data: (handle stream byte)
 11   # type 4: primitive function
 12   index-data: int
 13   # TODO: array, (associative) table, stream
 14 }
 15 
 16 fn allocate-symbol _out: (addr handle cell) {
 17   var out/eax: (addr handle cell) <- copy _out
 18   allocate out
 19   var out-addr/eax: (addr cell) <- lookup *out
 20   var type/ecx: (addr int) <- get out-addr, type
 21   copy-to *type, 2/symbol
 22   var dest-ah/eax: (addr handle stream byte) <- get out-addr, text-data
 23   populate-stream dest-ah, 0x40/max-symbol-size
 24 }
 25 
 26 fn initialize-symbol _out: (addr handle cell), val: (addr array byte) {
 27   var out/eax: (addr handle cell) <- copy _out
 28   var out-addr/eax: (addr cell) <- lookup *out
 29   var dest-ah/eax: (addr handle stream byte) <- get out-addr, text-data
 30   var dest/eax: (addr stream byte) <- lookup *dest-ah
 31   write dest, val
 32 }
 33 
 34 fn new-symbol out: (addr handle cell), val: (addr array byte) {
 35   allocate-symbol out
 36   initialize-symbol out, val
 37 }
 38 
 39 fn allocate-number _out: (addr handle cell) {
 40   var out/eax: (addr handle cell) <- copy _out
 41   allocate out
 42   var out-addr/eax: (addr cell) <- lookup *out
 43   var type/ecx: (addr int) <- get out-addr, type
 44   copy-to *type, 1/number
 45 }
 46 
 47 fn initialize-integer _out: (addr handle cell), n: int {
 48   var out/eax: (addr handle cell) <- copy _out
 49   var out-addr/eax: (addr cell) <- lookup *out
 50   var dest-addr/eax: (addr float) <- get out-addr, number-data
 51   var src/xmm0: float <- convert n
 52   copy-to *dest-addr, src
 53 }
 54 
 55 fn new-integer out: (addr handle cell), n: int {
 56   allocate-number out
 57   initialize-integer out, n
 58 }
 59 
 60 fn initialize-float _out: (addr handle cell), n: float {
 61   var out/eax: (addr handle cell) <- copy _out
 62   var out-addr/eax: (addr cell) <- lookup *out
 63   var dest-ah/eax: (addr float) <- get out-addr, number-data
 64   var src/xmm0: float <- copy n
 65   copy-to *dest-ah, src
 66 }
 67 
 68 fn new-float out: (addr handle cell), n: float {
 69   allocate-number out
 70   initialize-float out, n
 71 }
 72 
 73 fn allocate-pair _out: (addr handle cell) {
 74   var out/eax: (addr handle cell) <- copy _out
 75   allocate out
 76   # new cells have type pair by default
 77 }
 78 
 79 fn initialize-pair _out: (addr handle cell), left: (handle cell), right: (handle cell) {
 80   var out/eax: (addr handle cell) <- copy _out
 81   var out-addr/eax: (addr cell) <- lookup *out
 82   var dest-ah/ecx: (addr handle cell) <- get out-addr, left
 83   copy-handle left, dest-ah
 84   dest-ah <- get out-addr, right
 85   copy-handle right, dest-ah
 86 }
 87 
 88 fn new-pair out: (addr handle cell), left: (handle cell), right: (handle cell) {
 89   allocate-pair out
 90   initialize-pair out, left, right
 91 }
 92 
 93 fn allocate-primitive-function _out: (addr handle cell) {
 94   var out/eax: (addr handle cell) <- copy _out
 95   allocate out
 96   var out-addr/eax: (addr cell) <- lookup *out
 97   var type/ecx: (addr int) <- get out-addr, type
 98   copy-to *type, 4/primitive-function
 99 }
100 
101 fn initialize-primitive-function _out: (addr handle cell), n: int {
102   var out/eax: (addr handle cell) <- copy _out
103   var out-addr/eax: (addr cell) <- lookup *out
104   var dest-addr/eax: (addr int) <- get out-addr, index-data
105   var src/ecx: int <- copy n
106   copy-to *dest-addr, src
107 }
108 
109 fn new-primitive-function out: (addr handle cell), n: int {
110   allocate-primitive-function out
111   initialize-primitive-function out, n
112 }