about summary refs log tree commit diff stats
path: root/subx/apps/assort.subx
diff options
context:
space:
mode:
Diffstat (limited to 'subx/apps/assort.subx')
-rw-r--r--subx/apps/assort.subx279
1 files changed, 4 insertions, 275 deletions
diff --git a/subx/apps/assort.subx b/subx/apps/assort.subx
index 4a23fdbd..14956d82 100644
--- a/subx/apps/assort.subx
+++ b/subx/apps/assort.subx
@@ -453,7 +453,7 @@ read-segments:  # in : (address buffered-file), table : (address stream {string,
     #       continue
     #     if slice-equal?(word-slice, "==")
     #       var segment-name = next-word(line)
-    #       curr-segment = get-or-insert-segment(table, segment-name, Segment-size)
+    #       curr-segment = get-or-insert-stream(table, segment-name, Segment-size)
     #       if curr-segment->write == 0
     #         rewind-stream(line)
     #         write-stream(curr-segment, line)
@@ -611,7 +611,7 @@ $read-segments:check-for-segment-header:
 #?     # }}}
     # if slice-equal?(word-slice, "==")
     #   segment-name = next-word(line)
-    #   curr-segment = get-or-insert(table, segment-name)
+    #   curr-segment = get-or-insert-stream(table, segment-name)
     #   if (curr-segment->write > 0) continue
     # . EAX = slice-equal?(word-slice, "==")
     # . . push args
@@ -674,13 +674,13 @@ $read-segments:check-for-segment-header:
 #?     # . . discard args
 #?     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
 #?     # }}}
-    # . EAX = get-or-insert-segment(table, segment-name, Segment-size)
+    # . EAX = get-or-insert-stream(table, segment-name, Segment-size)
     # . . push args
     ff          6/subop/push        0/mod/indirect  5/rm32/.disp32            .             .           .           Segment-size/disp32               # push *Segment-size
     52/push-EDX
     ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           0xc/disp8       .                 # push *(EBP+12)
     # . . call
-    e8/call  get-or-insert-segment/disp32
+    e8/call  get-or-insert-stream/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
     # . curr-segment = EAX
@@ -786,269 +786,6 @@ $write-segments:end:
 
 ## helpers
 
-# TODO: pass in an allocation descriptor
-get-or-insert-segment:  # table : (address stream {string, (address stream byte)}), s : (address slice), n : int -> EAX : (address stream)
-    # pseudocode:
-    #   curr = table->data
-    #   max = &table->data[table->write]
-    #   while curr < max
-    #     if slice-equal?(s, *curr)
-    #       return *(curr+4)
-    #     curr += 8
-    #   if table->write < table->length
-    #     *max = slice-to-string(Heap, s)
-    #     result = new-stream(Heap, n, 1)
-    #     *(max+4) = result
-    #     table->write += 8
-    #     return result
-    #   return 0
-    #
-    # . prolog
-    55/push-EBP
-    89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # . save registers
-    51/push-ECX
-    52/push-EDX
-    56/push-ESI
-    # ESI = table
-    8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           6/r32/ESI   8/disp8         .                 # copy *(EBP+8) to ESI
-    # curr/ECX = table->data
-    8d/copy-address                 1/mod/*+disp8   6/rm32/ESI    .           .             .           1/r32/ECX   0xc/disp8       .                 # copy ESI+12 to ECX
-    # max/EDX = table->data + table->write
-    8b/copy                         0/mod/indirect  6/rm32/ESI    .           .             .           2/r32/EDX   .               .                 # copy *ESI to EDX
-    8d/copy-address                 0/mod/indirect  4/rm32/sib    1/base/ECX  2/index/EDX   .           2/r32/EDX   .               .                 # copy ECX+EDX to EDX
-$get-or-insert-segment:search-loop:
-    # if (curr >= max) break
-    39/compare                      3/mod/direct    1/rm32/ECX    .           .             .           2/r32/EDX   .               .                 # compare ECX with EDX
-    7d/jump-if-greater-or-equal  $get-or-insert-segment:not-found/disp8
-    # if (slice-equal?(s, *curr)) return *(curr+4)
-    # . EAX = slice-equal?(s, *curr)
-    # . . push args
-    ff          6/subop/push        0/mod/indirect  1/rm32/ECX    .           .             .           .           .               .                 # push *ECX
-    ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           0xc/disp8       .                 # push *(EBP+12)
-    # . . call
-    e8/call  slice-equal?/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-    # . if (EAX != 0) return EAX = *(curr+4)
-    3d/compare-EAX-and  0/imm32
-    74/jump-if-equal  $get-or-insert-segment:mismatch/disp8
-    8b/copy                         1/mod/*+disp8   1/rm32/ECX    .           .             .           0/r32/EAX   4/disp8         .                 # copy *(ECX+4) to EAX
-    eb/jump  $get-or-insert-segment:end/disp8
-$get-or-insert-segment:mismatch:
-    # curr += 8
-    81          0/subop/add         3/mod/direct    1/rm32/ECX    .           .             .           .           .               8/imm32           # add to ECX
-    # loop
-    eb/jump  $get-or-insert-segment:search-loop/disp8
-$get-or-insert-segment:not-found:
-    # result/EAX = 0
-    31/xor                          3/mod/direct    0/rm32/EAX    .           .             .           0/r32/EAX   .               .                 # clear EAX
-    # if (table->write >= table->length) abort
-    8b/copy                         0/mod/indirect  6/rm32/ESI    .           .             .           1/r32/ECX   .               .                 # copy *ESI to ECX
-    3b/compare                      1/mod/*+disp8   6/rm32/ESI    .           .             .           1/r32/ECX   8/disp8         .                 # compare ECX with *(ESI+8)
-    7d/jump-if-greater-or-equal  $get-or-insert-segment:abort/disp8
-    # *max = slice-to-string(Heap, s)
-    # . EAX = slice-to-string(Heap, s)
-    # . . push args
-    ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           0xc/disp8       .                 # push *(EBP+12)
-    68/push  Heap/imm32
-    # . . call
-    e8/call  slice-to-string/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-    # . *max = EAX
-    89/copy                         0/mod/indirect  2/rm32/EDX    .           .             .           0/r32/EAX   .               .                 # copy EAX to *EDX
-    # result/EAX = new-stream(Heap, n, 1)
-    # . . push args
-    68/push  1/imm32
-    ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           0x10/disp8      .                 # push *(EBP+16)
-    68/push  Heap/imm32
-    # . . call
-    e8/call  new-stream/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-    # *(max+4) = result
-    89/copy                         1/mod/*+disp8   2/rm32/EDX    .           .             .           0/r32/EAX   4/disp8         .                 # copy EAX to *(EDX+4)
-    # table->write += 8
-    81          0/subop/add         0/mod/indirect  6/rm32/ESI    .           .             .           .           .               8/imm32           # add to *ESI
-$get-or-insert-segment:end:
-    # . restore registers
-    5e/pop-to-ESI
-    5a/pop-to-EDX
-    59/pop-to-ECX
-    # . epilog
-    89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
-    5d/pop-to-EBP
-    c3/return
-
-$get-or-insert-segment:abort:
-    # . _write(2/stderr, error)
-    # . . push args
-    68/push  "get-or-insert-segment: too many segments"/imm32
-    68/push  2/imm32/stderr
-    # . . call
-    e8/call  _write/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-    # . syscall(exit, 1)
-    bb/copy-to-EBX  1/imm32
-    b8/copy-to-EAX  1/imm32/exit
-    cd/syscall  0x80/imm8
-    # never gets here
-
-test-get-or-insert-segment:
-    # . prolog
-    55/push-EBP
-    89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # var table/ECX : (address stream byte) = stream(2 * 8)
-    81          5/subop/subtract    3/mod/direct    4/rm32/ESP    .           .             .           .           .               0x10/imm32        # subtract from ESP
-    68/push  0x10/imm32/length
-    68/push  0/imm32/read
-    68/push  0/imm32/write
-    89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
-    # EDX : (address slice) = "code"
-    68/push  _test-code-segment-end/imm32/end
-    68/push  _test-code-segment/imm32/start
-    89/copy                         3/mod/direct    2/rm32/EDX    .           .             .           4/r32/ESP   .               .                 # copy ESP to EDX
-$test-get-or-insert-segment:first-call:
-    # - start with an empty table, insert one segment, verify that it was inserted
-    # segment/EAX = get-or-insert-segment(table, "code" slice, 10)
-    # . . push args
-    68/push  0xa/imm32/segment-length
-    52/push-EDX
-    51/push-ECX
-    # . . call
-    e8/call  get-or-insert-segment/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-    # save segment
-    50/push-EAX
-    # if (segment != 0) goto next check
-    3d/compare-EAX-and  0/imm32
-    75/jump-if-not-equal  $test-get-or-insert-segment:check1/disp8
-    # fail test
-    # . _write(2/stderr, msg)
-    # . . push args
-    68/push  "F - test-get-or-insert-segment/0\n"/imm32
-    68/push  2/imm32/stderr
-    # . . call
-    e8/call  _write/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-    # . increment Num-test-failures
-    ff          0/subop/increment   0/mod/indirect  5/rm32/.disp32            .             .           .           Num-test-failures/disp32          # increment *Num-test-failures
-    e9/jump  $test-get-or-insert-segment:end/disp32
-$test-get-or-insert-segment:check1:
-    # check-ints-equal(segment->length, 10, msg)
-    # . . push args
-    68/push  "F - test-get-or-insert-segment/1"/imm32
-    68/push  0xa/imm32/segment-length
-    ff          6/subop/push        1/mod/*+disp8   0/rm32/EAX    .           .             .           .           8/disp8         .                 # push *(EAX+8)
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-$test-get-or-insert-segment:check2:
-    # check-ints-equal(table->write, row-size = 8, msg)
-    # . . push args
-    68/push  "F - test-get-or-insert-segment/2"/imm32
-    68/push  8/imm32/row-size
-    ff          6/subop/push        0/mod/indirect  1/rm32/ECX    .           .             .           .           .               .                 # push *ECX
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-    # EAX = string-equal?(*table->data, "code")
-    # . . push args
-    68/push  "code"/imm32
-    ff          6/subop/push        1/mod/*+disp8   1/rm32/ECX    .           .             .           .           0xc/disp8       .                 # push *(ECX+12)
-    # . . call
-    e8/call  string-equal?/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-    # check-ints-equal(EAX, 1, msg)
-    # . . push args
-    68/push  "F - test-get-or-insert-segment/3"/imm32
-    68/push  1/imm32
-    50/push-EAX
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-$test-get-or-insert-segment:check3:
-    # stream/EAX = *(table->data+4)
-    8b/copy                         1/mod/*+disp8   1/rm32/ECX    .           .             .           0/r32/EAX   0x10/disp8      .                 # copy *(ECX+16) to EAX
-    # check-ints-equal(stream->length, 10, msg)
-    # . . push args
-    68/push  "F - test-get-or-insert-segment/4"/imm32
-    68/push  0xa/imm32/segment-size
-    ff          6/subop/push        1/mod/*+disp8   0/rm32/EAX    .           .             .           .           8/disp8         .                 # push *(EAX+8)
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-$test-get-or-insert-segment:second-call:
-    # - insert the same segment name again, verify that it was reused
-    # segment2/EAX = get-or-insert-segment(table, "code" slice, 8)
-    # . . push args
-    68/push  8/imm32/segment-length
-    52/push-EDX
-    51/push-ECX
-    # . . call
-    e8/call  get-or-insert-segment/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-    # restore old segment1
-    5a/pop-to-EDX
-    # check-ints-equal(segment2/EAX, segment1/EDX, msg)
-    # . . push args
-    68/push  "F - test-get-or-insert-segment/5"/imm32
-    52/push-EDX
-    50/push-EAX
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-    # no change to table size
-    # . check-ints-equal(table->write, row-size = 8, msg)
-    # . . push args
-    68/push  "F - test-get-or-insert-segment/6"/imm32
-    68/push  8/imm32/row-size
-    ff          6/subop/push        0/mod/indirect  1/rm32/ECX    .           .             .           .           .               .                 # push *ECX
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-$test-get-or-insert-segment:third-call:
-    # - insert a new segment name, verify that it was inserted
-    # EDX : (address slice) = "data"
-    c7          0/subop/copy        0/mod/indirect  2/rm32/EDX    .           .             .           .           .               _test-data-segment/imm32  # copy to *EDX
-    c7          0/subop/copy        1/mod/*+disp8   2/rm32/EDX    .           .             .           .           4/disp8         _test-data-segment-end/imm32  # copy to *(EDX+4)
-    # segment2/EAX = get-or-insert-segment(table, "data" slice, 8)
-    # . . push args
-    68/push  8/imm32/segment-length
-    52/push-EDX
-    51/push-ECX
-    # . . call
-    e8/call  get-or-insert-segment/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-    # table gets a new row
-    # . check-ints-equal(table->write, 2 rows = 16, msg)
-    # . . push args
-    68/push  "F - test-get-or-insert-segment/7"/imm32
-    68/push  0x10/imm32/two-rows
-    ff          6/subop/push        0/mod/indirect  1/rm32/ECX    .           .             .           .           .               .                 # push *ECX
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-$test-get-or-insert-segment:end:
-    # . epilog
-    89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
-    5d/pop-to-EBP
-    c3/return
-
 # (re)compute the bounds of the next word in the line
 # return empty string on reaching end of file
 next-word:  # line : (address stream byte), out : (address slice)
@@ -1297,14 +1034,6 @@ test-next-word-returns-empty-string-on-eof:
 
 == data
 
-_test-code-segment:
-  63/c 6f/o 64/d 65/e
-_test-code-segment-end:
-
-_test-data-segment:
-  64/d 61/a 74/t 61/a
-_test-data-segment-end:
-
 Segment-size:
   0x1000/imm32/4KB