about summary refs log tree commit diff stats
path: root/304screen.subx
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-08-02 15:31:56 -0700
committerKartik Agaram <vc@akkartik.com>2020-08-02 15:50:19 -0700
commit89c9ed80f9f7f4d4d40fea44c6e08362cfde50c7 (patch)
tree2ab8f044346695447468303e1f74372e5f158d76 /304screen.subx
parent0f5d0ec519c5b6fbb36ace912426e6a3fb8aa8ec (diff)
downloadmu-89c9ed80f9f7f4d4d40fea44c6e08362cfde50c7.tar.gz
6706 - support utf-8
For example:

  fn main -> r/ebx: int {
    var x/eax: grapheme <- copy 0x9286e2  # code point 0x2192 in utf-8
    print-grapheme-to-real-screen x
    print-string-to-real-screen "\n"
  }

Graphemes must fit in 4 bytes (21 bits for code points). Unclear what we
should do for longer clusters since graphemes are a fixed-size type at
the moment.
Diffstat (limited to '304screen.subx')
-rw-r--r--304screen.subx48
1 files changed, 46 insertions, 2 deletions
diff --git a/304screen.subx b/304screen.subx
index 2badb1eb..2e3635ee 100644
--- a/304screen.subx
+++ b/304screen.subx
@@ -131,19 +131,63 @@ $print-string-to-real-screen:end:
     5d/pop-to-ebp
     c3/return
 
-# currently only supports ascii
+# print a grapheme in utf-8 (only up to 4 bytes so far)
 print-grapheme-to-real-screen:  # c: grapheme
     # . prologue
     55/push-ebp
     89/<- %ebp 4/r32/esp
     # . save registers
+    50/push-eax
+    # var curr/eax: byte = 0
+    b8/copy-to-eax 0/imm32
+    # curr = *(ebp+8)
+    8a/byte-> *(ebp+8) 0/r32/al
+    # if (curr == 0) return
+    3d/compare-eax-and 0/imm32
+    74/jump-if-= $print-grapheme-to-real-screen:end/disp8
+    #
+    (print-byte-to-real-screen %eax)
+    # curr = *(ebp+9)
+    8a/byte-> *(ebp+9) 0/r32/al
+    # if (curr == 0) return
+    3d/compare-eax-and 0/imm32
+    74/jump-if-= $print-grapheme-to-real-screen:end/disp8
+    #
+    (print-byte-to-real-screen %eax)
+    # curr = *(ebp+10)
+    8a/byte-> *(ebp+0xa) 0/r32/al
+    # if (curr == 0) return
+    3d/compare-eax-and 0/imm32
+    74/jump-if-= $print-grapheme-to-real-screen:end/disp8
+    #
+    (print-byte-to-real-screen %eax)
+    # curr = *(ebp+11)
+    8a/byte-> *(ebp+0xb) 0/r32/al
+    # if (curr == 0) return
+    3d/compare-eax-and 0/imm32
+    74/jump-if-= $print-grapheme-to-real-screen:end/disp8
+    #
+    (print-byte-to-real-screen %eax)
+$print-grapheme-to-real-screen:end:
+    # . restore registers
+    58/pop-to-eax
+    # . epilogue
+    89/<- %esp 5/r32/ebp
+    5d/pop-to-ebp
+    c3/return
+
+print-byte-to-real-screen:  # c: byte
+    # . prologue
+    55/push-ebp
+    89/<- %ebp 4/r32/esp
+    # . save registers
     51/push-ecx
     # var s/ecx: (addr array byte)
     ff 6/subop/push *(ebp+8)
     68/push 1/imm32/size
     89/<- %ecx 4/r32/esp
     (write 1 %ecx)
-$print-grapheme-to-real-screen:end:
+$print-byte-to-real-screen:end:
     # . reclaim locals
     81 0/subop/add %esp 8/imm32
     # . restore registers