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 }