diff options
Diffstat (limited to 'baremetal/shell/print.mu')
-rw-r--r-- | baremetal/shell/print.mu | 228 |
1 files changed, 210 insertions, 18 deletions
diff --git a/baremetal/shell/print.mu b/baremetal/shell/print.mu index d7f24eb2..d3eb6f1f 100644 --- a/baremetal/shell/print.mu +++ b/baremetal/shell/print.mu @@ -1,50 +1,242 @@ fn print-cell _in: (addr handle cell), out: (addr stream byte), trace: (addr trace) { - clear-stream out + trace-text trace, "print", "print-cell" + trace-lower trace var in/eax: (addr handle cell) <- copy _in var in-addr/eax: (addr cell) <- lookup *in + { + var is-nil?/eax: boolean <- is-nil? in-addr + compare is-nil?, 0/false + break-if-= + write out, "()" + trace-higher trace + return + } var in-type/ecx: (addr int) <- get in-addr, type + compare *in-type, 0/pair + { + break-if-!= + print-list in-addr, out, trace + trace-higher trace + return + } compare *in-type, 1/number { break-if-!= print-number in-addr, out, trace + trace-higher trace return } compare *in-type, 2/symbol { break-if-!= print-symbol in-addr, out, trace + trace-higher trace return } } fn print-symbol _in: (addr cell), out: (addr stream byte), trace: (addr trace) { - { - compare trace, 0 - break-if-= -#? trace-text trace, "print", "symbol" - } + trace-text trace, "print", "symbol" var in/esi: (addr cell) <- copy _in var data-ah/eax: (addr handle stream byte) <- get in, text-data var _data/eax: (addr stream byte) <- lookup *data-ah var data/esi: (addr stream byte) <- copy _data rewind-stream data - { - var done?/eax: boolean <- stream-empty? data - compare done?, 0/false - break-if-!= - var g/eax: grapheme <- read-grapheme data - write-grapheme out, g + write-stream out, data + # trace + rewind-stream data + var stream-storage: (stream byte 0x40) + var stream/ecx: (addr stream byte) <- address stream-storage + write stream, "=> symbol " + write-stream stream, data + trace trace, "print", stream +} + +fn print-number _in: (addr cell), out: (addr stream byte), trace: (addr trace) { + var in/esi: (addr cell) <- copy _in + var val/eax: (addr float) <- get in, number-data + write-float-decimal-approximate out, *val, 3/precision + # trace + var stream-storage: (stream byte 0x40) + var stream/ecx: (addr stream byte) <- address stream-storage + write stream, "=> number " + write-float-decimal-approximate stream, *val, 3/precision + trace trace, "print", stream +} + +fn print-list _in: (addr cell), out: (addr stream byte), trace: (addr trace) { + var curr/esi: (addr cell) <- copy _in + write out, "(" + $print-list:loop: { + var left/ecx: (addr handle cell) <- get curr, left + { + var left-addr/eax: (addr cell) <- lookup *left + var left-is-nil?/eax: boolean <- is-nil? left-addr + compare left-is-nil?, 0/false + { + break-if-= + trace-text trace, "print", "left is null" + break $print-list:loop + } + } + print-cell left, out, trace + var right/ecx: (addr handle cell) <- get curr, right + var right-addr/eax: (addr cell) <- lookup *right + { + compare right-addr, 0 + break-if-!= + abort "null encountered" + } + { + var right-is-nil?/eax: boolean <- is-nil? right-addr + compare right-is-nil?, 0/false + { + break-if-= + trace-text trace, "print", "right is null" + break $print-list:loop + } + } + write out, " " + var right-type-addr/edx: (addr int) <- get right-addr, type + { + compare *right-type-addr, 0/pair + break-if-= + write out, ". " + print-cell right, out, trace + break $print-list:loop + } + curr <- copy right-addr loop } + write out, ")" } -fn print-number _in: (addr cell), out: (addr stream byte), trace: (addr trace) { +# Most lisps intern nil, but we don't really have globals yet, so we'll be +# less efficient for now. +fn is-nil? _in: (addr cell) -> _/eax: boolean { + var in/esi: (addr cell) <- copy _in + # if type != pair, return false + var type/eax: (addr int) <- get in, type + compare *type, 0/pair { - compare trace, 0 break-if-= -#? trace-text trace, "print", "number" + return 0/false } - var in/esi: (addr cell) <- copy _in - var val/eax: (addr float) <- get in, number-data - write-float-decimal-approximate out, *val, 3/precision + # if left != null, return false + var left-ah/eax: (addr handle cell) <- get in, left + var left/eax: (addr cell) <- lookup *left-ah + compare left, 0 + { + break-if-= + return 0/false + } + # if right != null, return false + var right-ah/eax: (addr handle cell) <- get in, right + var right/eax: (addr cell) <- lookup *right-ah + compare right, 0 + { + break-if-= + return 0/false + } + return 1/true +} + +fn test-print-cell-zero { + var num-storage: (handle cell) + var num/esi: (addr handle cell) <- address num-storage + new-number num + # value is 0 by default + var out-storage: (stream byte 0x40) + var out/edi: (addr stream byte) <- address out-storage + print-cell num, out, 0/no-trace + check-stream-equal out, "0", "F - test-print-cell-zero" +} + +fn test-print-cell-integer { + var num-storage: (handle cell) + var num/esi: (addr handle cell) <- address num-storage + new-number num + var num-addr/eax: (addr cell) <- lookup *num + var num-data/eax: (addr float) <- get num-addr, number-data + var src/xmm0: float <- rational 1, 1 + copy-to *num-data, src + var out-storage: (stream byte 0x40) + var out/edi: (addr stream byte) <- address out-storage + print-cell num, out, 0/no-trace + check-stream-equal out, "1", "F - test-print-cell-integer" +} + +fn test-print-cell-integer-2 { + var num-storage: (handle cell) + var num/esi: (addr handle cell) <- address num-storage + new-number num + var num-addr/eax: (addr cell) <- lookup *num + var num-data/eax: (addr float) <- get num-addr, number-data + var src/xmm0: float <- rational 0x30, 1 + copy-to *num-data, src + var out-storage: (stream byte 0x40) + var out/edi: (addr stream byte) <- address out-storage + print-cell num, out, 0/no-trace + check-stream-equal out, "48", "F - test-print-cell-integer-2" +} + +fn test-print-cell-fraction { + var num-storage: (handle cell) + var num/esi: (addr handle cell) <- address num-storage + new-number num + var num-addr/eax: (addr cell) <- lookup *num + var num-data/eax: (addr float) <- get num-addr, number-data + var src/xmm0: float <- rational 1, 2 + copy-to *num-data, src + var out-storage: (stream byte 0x40) + var out/edi: (addr stream byte) <- address out-storage + print-cell num, out, 0/no-trace + check-stream-equal out, "0.5", "F - test-print-cell-fraction" +} + +fn test-print-cell-symbol { + var sym-storage: (handle cell) + var sym/esi: (addr handle cell) <- address sym-storage + new-symbol sym + var sym-addr/eax: (addr cell) <- lookup *sym + var sym-data-ah/eax: (addr handle stream byte) <- get sym-addr, text-data + var sym-data/eax: (addr stream byte) <- lookup *sym-data-ah + write sym-data, "abc" + var out-storage: (stream byte 0x40) + var out/edi: (addr stream byte) <- address out-storage + print-cell sym, out, 0/no-trace + check-stream-equal out, "abc", "F - test-print-cell-symbol" +} + +fn test-print-cell-nil-list { + var nil-storage: (handle cell) + var nil/esi: (addr handle cell) <- address nil-storage + new-pair nil + var out-storage: (stream byte 0x40) + var out/edi: (addr stream byte) <- address out-storage + print-cell nil, out, 0/no-trace + check-stream-equal out, "()", "F - test-print-cell-nil-list" +} + +fn test-print-cell-singleton-list { + var list-storage: (handle cell) + var list/esi: (addr handle cell) <- address list-storage + new-pair list + # left + var list-addr/eax: (addr cell) <- lookup *list + var list-left/eax: (addr handle cell) <- get list-addr, left + new-symbol list-left + var sym-addr/eax: (addr cell) <- lookup *list-left + var sym-data-ah/eax: (addr handle stream byte) <- get sym-addr, text-data + var sym-data/eax: (addr stream byte) <- lookup *sym-data-ah + write sym-data, "abc" + # right + var list-addr/eax: (addr cell) <- lookup *list + var list-right/eax: (addr handle cell) <- get list-addr, right + new-pair list-right + # + var out-storage: (stream byte 0x40) + var out/edi: (addr stream byte) <- address out-storage + print-cell list, out, 0/no-trace + check-stream-equal out, "(abc)", "F - test-print-cell-singleton-list" } |