about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--subx/apps/dquotesbin22553 -> 23219 bytes
-rw-r--r--subx/apps/dquotes.subx139
2 files changed, 138 insertions, 1 deletions
diff --git a/subx/apps/dquotes b/subx/apps/dquotes
index 83fac224..a91f829d 100644
--- a/subx/apps/dquotes
+++ b/subx/apps/dquotes
Binary files differdiff --git a/subx/apps/dquotes.subx b/subx/apps/dquotes.subx
index 749fc6aa..514c2d06 100644
--- a/subx/apps/dquotes.subx
+++ b/subx/apps/dquotes.subx
@@ -807,13 +807,136 @@ test-convert-processes-string-literals:
 
 # generate the data segment contents byte by byte for a given slice
 emit-string-literal-data:  # out : (address stream), word : (address slice)
+    # pseudocode
+    #   curr = word->start
+    #   ++curr  # skip '"'
+    #   while true
+    #     if (curr >= word->end) break
+    #     c = *curr
+    #     if (c == '"') break
+    #     append-byte-hex(out, c)
+    #     if c is alphanumeric:
+    #       write(out, "/")
+    #       append-byte(out, c)
+    #     write(out, " ")
+    #     ++curr
+    #
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
     # . save registers
+    50/push-EAX
+    51/push-ECX
+    52/push-EDX
+    56/push-ESI
+    # ESI = word
+    8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           6/r32/ESI   0xc/disp8       .                 # copy *(EBP+12) to ESI
+    # curr/EDX = word->start
+    8b/copy                         0/mod/indirect  6/rm32/ESI    .           .             .           2/r32/EDX   .               .                 # copy *ESI to EDX
+    # ++curr  # skip initial '"'
+    42/increment-EDX
+    # max/ESI = word->end
+    8b/copy                         1/mod/*+disp8   6/rm32/ESI    .           .             .           6/r32/ESI   4/disp8         .                 # copy *(ESI+4) to ESI
+    # ECX = 0
+    31/xor                          3/mod/direct    1/rm32/ECX    .           .             .           1/r32/ECX   .               .                 # clear ECX
+$emit-string-literal-data:loop:
+    # if (curr >= max) break
+    39/compare                      3/mod/direct    2/rm32/EDX    .           .             .           6/r32/ESI   .               .                 # compare EDX with ESI
+    7d/jump-if-greater-or-equal  $emit-string-literal-data:end/disp8
+    # CL = *curr
+    8a/copy-byte                    0/mod/indirect  2/rm32/EDX    .           .             .           1/r32/CL    .               .                 # copy byte at *EDX to CL
+    # if (ECX == '"') break
+    81          7/subop/compare     3/mod/direct    1/rm32/ECX    .           .             .           .           .               0x22/imm32/dquote # compare ECX
+    74/jump-if-equal  $emit-string-literal-data:end/disp8
+    # append-byte-hex(out, CL)
+    # . . push args
+    51/push-ECX
+    ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           8/disp8         .                 # push *(EBP+8)
+    # . . call
+    e8/call  append-byte-hex/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # if (is-alphanumeric?(*curr)) print(out, "/#{*curr}")
+    # . EAX = is-alphanumeric?(CL)
+    # . . push args
+    51/push-ECX
+    # . . call
+    e8/call  is-alphanumeric?/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+    # . if (EAX == 0) goto char-done
+    3d/compare-EAX-and  0/imm32
+    74/jump-if-equal  $emit-string-literal-data:char-done/disp8
+    # . write(out, "/")
+    # . . push args
+    68/push  Slash/imm32
+    ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           8/disp8         .                 # push *(EBP+8)
+    # . . call
+    e8/call  write/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # . append-byte(out, *curr)
+    # . . push args
+    51/push-ECX
+    ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           8/disp8         .                 # push *(EBP+8)
+    # . . call
+    e8/call  append-byte/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+$emit-string-literal-data:char-done:
+    # write(out, " ")
+    # . . push args
+    68/push  Space/imm32
+    ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           8/disp8         .                 # push *(EBP+8)
+    # . . call
+    e8/call  write/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # ++curr
+    42/increment-EDX
+    eb/jump $emit-string-literal-data:loop/disp8
 $emit-string-literal-data:end:
-    # . reclaim locals
     # . restore registers
+    5e/pop-to-ESI
+    5a/pop-to-EDX
+    59/pop-to-ECX
+    58/pop-to-EAX
+    # . epilog
+    89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+    5d/pop-to-EBP
+    c3/return
+
+is-alphanumeric?:  # c : int -> EAX : boolean
+    # . prolog
+    55/push-EBP
+    89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+    # EAX = c
+    8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           0/r32/EAX   8/disp8         .                 # copy *(EBP+8) to EAX
+    # if (EAX < '0') return false
+    3d/compare-EAX-with  0x30/imm32/0
+    7c/jump-if-lesser  $is-alphanumeric?:false/disp8
+    # if (EAX <= '9') return true
+    3d/compare-EAX-with  0x39/imm32/9
+    7e/jump-if-lesser-or-equal  $is-alphanumeric?:true/disp8
+    # if (EAX < 'A') return false
+    3d/compare-EAX-with  0x41/imm32/A
+    7c/jump-if-lesser  $is-alphanumeric?:false/disp8
+    # if (EAX <= 'Z') return true
+    3d/compare-EAX-with  0x5a/imm32/Z
+    7e/jump-if-lesser-or-equal  $is-alphanumeric?:true/disp8
+    # if (EAX < 'a') return false
+    3d/compare-EAX-with  0x61/imm32/a
+    7c/jump-if-lesser  $is-alphanumeric?:false/disp8
+    # if (EAX <= 'z') return true
+    3d/compare-EAX-with  0x7a/imm32/z
+    7e/jump-if-lesser-or-equal  $is-alphanumeric?:true/disp8
+    # return false
+$is-alphanumeric?:false:
+    b8/copy-to-EAX  0/imm32/false
+    eb/jump  $is-alphanumeric?:end/disp8
+$is-alphanumeric?:true:
+    b8/copy-to-EAX  1/imm32/true
+$is-alphanumeric?:end:
     # . epilog
     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
     5d/pop-to-EBP
@@ -1569,6 +1692,20 @@ Segment-size:
 Next-string-literal:  # tracks the next auto-generated variable name
   1/imm32
 
+# length-prefixed string containing just a single space
+Space:
+    # size
+    1/imm32
+    # data
+    20/space
+
+# length-prefixed string containing just a single slash
+Slash:
+    # size
+    1/imm32
+    # data
+    2f/slash
+
 _test-slice-abc:
   22/dquote 61/a 62/b 63/c 22/dquote  # "abc"
 _test-slice-abc-end: