about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--078table.subx165
-rwxr-xr-xapps/assortbin34812 -> 35256 bytes
-rwxr-xr-xapps/crenshaw2-1bin27806 -> 28250 bytes
-rwxr-xr-xapps/crenshaw2-1bbin28365 -> 28809 bytes
-rwxr-xr-xapps/desugarbin34075 -> 34519 bytes
-rwxr-xr-xapps/dquotesbin41368 -> 41812 bytes
-rwxr-xr-xapps/factorialbin26722 -> 27166 bytes
-rwxr-xr-xapps/handlebin27576 -> 28020 bytes
-rwxr-xr-xapps/hexbin37367 -> 37811 bytes
-rwxr-xr-xapps/packbin47498 -> 47942 bytes
-rwxr-xr-xapps/surveybin44095 -> 44539 bytes
-rwxr-xr-xapps/testsbin33624 -> 34068 bytes
12 files changed, 165 insertions, 0 deletions
diff --git a/078table.subx b/078table.subx
index d172209a..c0b64890 100644
--- a/078table.subx
+++ b/078table.subx
@@ -1068,4 +1068,169 @@ $test-maybe-get:end:
     5d/pop-to-EBP
     c3/return
 
+# if no row is found, return null (0)
+maybe-get-slice:  # table : (address stream {string, _}), key : (address slice), row-size : int -> EAX : (address _)
+    # pseudocode:
+    #   curr = table->data
+    #   max = &table->data[table->write]
+    #   while curr < max
+    #     if slice-equal?(key, *curr)
+    #       return curr+4
+    #     curr += row-size
+    #   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
+$maybe-get-slice:search-loop:
+    # if (curr >= max) return null
+    39/compare                      3/mod/direct    1/rm32/ECX    .           .             .           2/r32/EDX   .               .                 # compare ECX with EDX
+    73/jump-if-greater-or-equal-unsigned  $maybe-get-slice:null/disp8
+    # if (slice-equal?(key, *curr)) return curr+4
+    # . EAX = slice-equal?(key, *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  $maybe-get-slice:mismatch/disp8
+    8d/copy-address                 1/mod/*+disp8   1/rm32/ECX    .           .             .           0/r32/EAX   4/disp8         .                 # copy ECX+4 to EAX
+    eb/jump  $maybe-get-slice:end/disp8
+$maybe-get-slice:mismatch:
+    # curr += row-size
+    03/add                          1/mod/*+disp8   5/rm32/EBP    .           .             .           1/r32/ECX   0x10/disp8      .                 # add *(EBP+16) to ECX
+    # loop
+    eb/jump  $maybe-get-slice:search-loop/disp8
+$maybe-get-slice:null:
+    b8/copy-to-EAX  0/imm32
+$maybe-get-slice: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
+
+test-maybe-get-slice:
+    # . prolog
+    55/push-EBP
+    89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+    # - setup: create a table with one row
+    # var table/ECX : (address stream {string, number}) = stream(2 rows * 8 bytes)
+    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
+    # insert(table, "code", 8 bytes per row)
+    # . . push args
+    68/push  8/imm32/row-size
+    68/push  "code"/imm32
+    51/push-ECX
+    # . . call
+    e8/call  get-or-insert/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+$test-maybe-get-slice:success:
+    # - check for the same key, verify that it was reused
+    # (EAX..EDX) = "code"
+    b8/copy-to-EAX  "code"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           2/r32/EDX   .               .                 # copy *EAX to EDX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  2/index/EDX   .           2/r32/EDX   4/disp8         .                 # copy EAX+EDX+4 to EDX
+    05/add-to-EAX  4/imm32
+    # var slice/EDX = {EAX, EDX}
+    52/push-EDX
+    50/push-EAX
+    89/copy                         3/mod/direct    2/rm32/EDX    .           .             .           4/r32/ESP   .               .                 # copy ESP to EDX
+    # EAX = maybe-get-slice(table, "code" slice, 8 bytes per row)
+    # . . push args
+    68/push  8/imm32/row-size
+    52/push-EDX
+    51/push-ECX
+    # . . call
+    e8/call  maybe-get-slice/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+    # check-ints-equal(EAX - table->data, 4, msg)
+    # . check-ints-equal(EAX - table, 16, msg)
+    # . . push args
+    68/push  "F - test-maybe-get-slice/0"/imm32
+    68/push  0x10/imm32
+    29/subtract                     3/mod/direct    0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # subtract ECX from EAX
+    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 new row inserted
+    # . check-ints-equal(table->write, row-size = 8, msg)
+    # . . push args
+    68/push  "F - test-maybe-get-slice/1"/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
+    # check-string-equal(*table->data, "code", msg)
+    # . . push args
+    68/push  "F - test-maybe-get-slice/2"/imm32
+    68/push  "code"/imm32
+    ff          6/subop/push        1/mod/*+disp8   1/rm32/ECX    .           .             .           .           0xc/disp8       .                 # push *(ECX+12)
+    # . . call
+    e8/call  check-string-equal/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+$test-maybe-get-slice:failure:
+    # - search for a new key
+    # (EAX..EDX) = "data"
+    b8/copy-to-EAX  "data"/imm32
+    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           2/r32/EDX   .               .                 # copy *EAX to EDX
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  2/index/EDX   .           2/r32/EDX   4/disp8         .                 # copy EAX+EDX+4 to EDX
+    05/add-to-EAX  4/imm32
+    # var slice/EDX = {EAX, EDX}
+    52/push-EDX
+    50/push-EAX
+    89/copy                         3/mod/direct    2/rm32/EDX    .           .             .           4/r32/ESP   .               .                 # copy ESP to EDX
+    # EAX = maybe-get-slice(table, "data" slice, 8 bytes per row)
+    # . . push args
+    68/push  8/imm32/row-size
+    52/push-EDX
+    51/push-ECX
+    # . . call
+    e8/call  maybe-get-slice/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+    # check-ints-equal(EAX, 0, msg)
+    # . . push args
+    68/push  "F - test-maybe-get-slice/3"/imm32
+    68/push  0/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-maybe-get-slice:end:
+    # . epilog
+    89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+    5d/pop-to-EBP
+    c3/return
+
 # . . vim:nowrap:textwidth=0
diff --git a/apps/assort b/apps/assort
index 08795d45..e9609e0e 100755
--- a/apps/assort
+++ b/apps/assort
Binary files differdiff --git a/apps/crenshaw2-1 b/apps/crenshaw2-1
index a30a6230..4fe94ff5 100755
--- a/apps/crenshaw2-1
+++ b/apps/crenshaw2-1
Binary files differdiff --git a/apps/crenshaw2-1b b/apps/crenshaw2-1b
index 4913856a..2a4f4234 100755
--- a/apps/crenshaw2-1b
+++ b/apps/crenshaw2-1b
Binary files differdiff --git a/apps/desugar b/apps/desugar
index a7f798ef..5fb360c1 100755
--- a/apps/desugar
+++ b/apps/desugar
Binary files differdiff --git a/apps/dquotes b/apps/dquotes
index 6bcdd993..739326e7 100755
--- a/apps/dquotes
+++ b/apps/dquotes
Binary files differdiff --git a/apps/factorial b/apps/factorial
index 96d40859..c98f0377 100755
--- a/apps/factorial
+++ b/apps/factorial
Binary files differdiff --git a/apps/handle b/apps/handle
index 87c25a9d..611831f1 100755
--- a/apps/handle
+++ b/apps/handle
Binary files differdiff --git a/apps/hex b/apps/hex
index d0660086..9e1c4757 100755
--- a/apps/hex
+++ b/apps/hex
Binary files differdiff --git a/apps/pack b/apps/pack
index a8b58e43..eeacd172 100755
--- a/apps/pack
+++ b/apps/pack
Binary files differdiff --git a/apps/survey b/apps/survey
index 08026c71..02b3498c 100755
--- a/apps/survey
+++ b/apps/survey
Binary files differdiff --git a/apps/tests b/apps/tests
index ee832d05..9b0f292f 100755
--- a/apps/tests
+++ b/apps/tests
Binary files differ