about summary refs log tree commit diff stats
path: root/081read-line.subx
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2019-09-19 21:01:43 -0700
committerKartik Agaram <vc@akkartik.com>2019-09-19 23:25:49 -0700
commitfd91f7f61bfa84cbc24590d5394d75891cc1cfcc (patch)
tree6cbaebc23ed7c3b8627dac22e7054f14c4d38fe9 /081read-line.subx
parent881c7f02708ceaef54a0d8b5fcc136a3003d3e09 (diff)
downloadmu-fd91f7f61bfa84cbc24590d5394d75891cc1cfcc.tar.gz
5675 - move helpers from subx-common into layers
This undoes 5672 in favor of a new plan:

Layers 000 - 099 are for running without syntax sugar. We use them for
building syntax-sugar passes.

Layers 100 and up are for running with all syntax sugar.

The layers are arranged in approximate order so more phases rely on earlier
layers than later ones.

I plan to not use intermediate syntax sugar (just sigils without calls,
or sigils and calls without braces) anywhere except in the specific passes
implementing them.
Diffstat (limited to '081read-line.subx')
-rw-r--r--081read-line.subx391
1 files changed, 0 insertions, 391 deletions
diff --git a/081read-line.subx b/081read-line.subx
deleted file mode 100644
index bce42750..00000000
--- a/081read-line.subx
+++ /dev/null
@@ -1,391 +0,0 @@
-== code
-#   instruction                     effective address                                                   register    displacement    immediate
-# . op          subop               mod             rm32          base        index         scale       r32
-# . 1-3 bytes   3 bits              2 bits          3 bits        3 bits      3 bits        2 bits      2 bits      0/1/2/4 bytes   0/1/2/4 bytes
-
-# read bytes from 'f' until (and including) a newline and store them into 's'
-# 's' fails to grow if and only if no data found
-# just abort if 's' is too small
-read-line-buffered:  # f : (address buffered-file), s : (address stream byte) -> <void>
-    # pseudocode:
-    #   while true
-    #     if (s->write >= s->length) abort
-    #     if (f->read >= f->write) populate stream from file
-    #     if (f->write == 0) break
-    #     AL = f->data[f->read]
-    #     s->data[s->write] = AL
-    #     ++f->read
-    #     ++s->write
-    #     if (AL == '\n') break
-    # . 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
-    57/push-edi
-    # esi = f
-    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           6/r32/esi   8/disp8         .                 # copy *(ebp+8) to esi
-    # ecx = f->read
-    8b/copy                         1/mod/*+disp8   6/rm32/esi    .           .             .           1/r32/ecx   8/disp8         .                 # copy *(esi+8) to ecx
-    # edi = s
-    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           7/r32/edi   0xc/disp8       .                 # copy *(ebp+12) to edi
-    # edx = s->write
-    8b/copy                         0/mod/indirect  7/rm32/edi    .           .             .           2/r32/edx   .               .                 # copy *edi to edx
-$read-line-buffered:loop:
-    # if (s->write >= s->length) abort
-    3b/compare                      1/mod/*+disp8   7/rm32/edi    .           .             .           2/r32/edx   8/disp8         .                 # compare edx with *(edi+8)
-    7d/jump-if-greater-or-equal  $read-line-buffered:abort/disp8
-    # if (f->read >= f->write) populate stream from file
-    3b/compare                      1/mod/*+disp8   6/rm32/esi    .           .             .           1/r32/ecx   4/disp8         .                 # compare ecx with *(esi+4)
-    7c/jump-if-lesser  $read-line-buffered:from-stream/disp8
-    # . clear-stream(stream = f+4)
-    # . . push args
-    8d/copy-address                 1/mod/*+disp8   6/rm32/esi    .           .             .           0/r32/eax   4/disp8         .                 # copy esi+4 to eax
-    50/push-eax
-    # . . call
-    e8/call  clear-stream/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
-    # . f->read must now be 0; update its cache at ecx
-    31/xor                          3/mod/direct    1/rm32/ecx    .           .             .           1/r32/ecx   .               .                 # clear ecx
-    # . eax = read(f->fd, stream = f+4)
-    # . . push args
-    50/push-eax
-    ff          6/subop/push        0/mod/indirect  6/rm32/esi    .           .             .           .           .               .                 # push *esi
-    # . . call
-    e8/call  read/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-    # if (f->write == 0) break
-    # since f->read was initially 0, eax is the same as f->write
-    # . if (eax == 0) return true
-    3d/compare-eax-and  0/imm32
-    74/jump-if-equal  $read-line-buffered:end/disp8
-$read-line-buffered:from-stream:
-    # AL = f->data[f->read]
-    31/xor                          3/mod/direct    0/rm32/eax    .           .             .           0/r32/eax   .               .                 # clear eax
-    8a/copy-byte                    1/mod/*+disp8   4/rm32/sib    6/base/esi  1/index/ecx   .           0/r32/AL    0x10/disp8      .                 # copy byte at *(esi+ecx+16) to AL
-    # s->data[s->write] = AL
-    88/copy-byte                    1/mod/*+disp8   4/rm32/sib    7/base/edi  2/index/edx   .           0/r32/AL    0xc/disp8       .                 # copy AL to *(edi+edx+12)
-    # ++f->read
-    41/increment-ecx
-    # ++s->write
-    42/increment-edx
-    # if (AL == '\n') return
-    3d/compare-eax-and  0xa/imm32
-    75/jump-if-not-equal  $read-line-buffered:loop/disp8
-$read-line-buffered:end:
-    # save f->read
-    89/copy                         1/mod/*+disp8   6/rm32/esi    .           .             .           1/r32/ecx   8/disp8         .                 # copy ecx to *(esi+8)
-    # save s->write
-    89/copy                         0/mod/indirect  7/rm32/edi    .           .             .           2/r32/edx   .               .                 # copy edx to *edi
-    # . restore registers
-    5f/pop-to-edi
-    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
-
-$read-line-buffered:abort:
-    # . _write(2/stderr, error)
-    # . . push args
-    68/push  "read-line-buffered: line too long\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
-    # . syscall(exit, 1)
-    bb/copy-to-ebx  1/imm32
-    b8/copy-to-eax  1/imm32/exit
-    cd/syscall  0x80/imm8
-    # never gets here
-
-test-read-line-buffered:
-    # - check that read-line-buffered stops at a newline
-    # setup
-    # . clear-stream(_test-stream)
-    # . . push args
-    68/push  _test-stream/imm32
-    # . . call
-    e8/call  clear-stream/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
-    # . clear-stream(_test-buffered-file+4)
-    # . . push args
-    b8/copy-to-eax  _test-buffered-file/imm32
-    05/add-to-eax  4/imm32
-    50/push-eax
-    # . . call
-    e8/call  clear-stream/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
-    # . clear-stream(_test-tmp-stream)
-    # . . push args
-    68/push  _test-tmp-stream/imm32
-    # . . call
-    e8/call  clear-stream/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
-    # write(_test-stream, "ab\ncd")
-    # . . push args
-    68/push  "ab\ncd"/imm32
-    68/push  _test-stream/imm32
-    # . . call
-    e8/call  write/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-    # read a line from _test-stream (buffered by _test-buffered-file) into _test-tmp-stream
-    # . eax = read-line-buffered(_test-buffered-file, _test-tmp-stream)
-    # . . push args
-    68/push  _test-tmp-stream/imm32
-    68/push  _test-buffered-file/imm32
-    # . . call
-    e8/call  read-line-buffered/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-    # check-next-stream-line-equal(_test-tmp-stream, "ab", msg)
-    # . . push args
-    68/push  "F - test-read-line-buffered"/imm32
-    68/push  "ab"/imm32
-    68/push  _test-tmp-stream/imm32
-    # . . call
-    e8/call  check-next-stream-line-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-    # end
-    c3/return
-
-test-read-line-buffered-reads-final-line-until-Eof:
-    # setup
-    # . clear-stream(_test-stream)
-    # . . push args
-    68/push  _test-stream/imm32
-    # . . call
-    e8/call  clear-stream/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
-    # . clear-stream(_test-buffered-file+4)
-    # . . push args
-    b8/copy-to-eax  _test-buffered-file/imm32
-    05/add-to-eax  4/imm32
-    50/push-eax
-    # . . call
-    e8/call  clear-stream/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
-    # . clear-stream(_test-tmp-stream)
-    # . . push args
-    68/push  _test-tmp-stream/imm32
-    # . . call
-    e8/call  clear-stream/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
-    # write(_test-stream, "cd")
-    # . . push args
-    68/push  "cd"/imm32
-    68/push  _test-stream/imm32
-    # . . call
-    e8/call  write/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-    # read a line from _test-stream (buffered by _test-buffered-file) into _test-tmp-stream
-    # . eax = read-line-buffered(_test-buffered-file, _test-tmp-stream)
-    # . . push args
-    68/push  _test-tmp-stream/imm32
-    68/push  _test-buffered-file/imm32
-    # . . call
-    e8/call  read-line-buffered/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-    # check-stream-equal(_test-tmp-stream, "cd", msg)
-    # . . push args
-    68/push  "F - test-read-line-buffered-reads-final-line-until-Eof"/imm32
-    68/push  "cd"/imm32
-    68/push  _test-tmp-stream/imm32
-    # . . call
-    e8/call  check-stream-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-    # end
-    c3/return
-
-# read bytes from 'f' until (and including) a newline and store them into 's'
-# 's' fails to grow if and only if no data found
-# just abort if 's' is too small
-read-line:  # f : (address stream), s : (address stream byte) -> <void>
-    # pseudocode:
-    #   while true
-    #     if (s->write >= s->length) abort
-    #     if (f->read >= f->write) break
-    #     AL = f->data[f->read]
-    #     s->data[s->write] = AL
-    #     ++f->read
-    #     ++s->write
-    #     if (AL == '\n') break
-    # . 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
-    57/push-edi
-    # esi = f
-    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           6/r32/esi   8/disp8         .                 # copy *(ebp+8) to esi
-    # ecx = f->read
-    8b/copy                         1/mod/*+disp8   6/rm32/esi    .           .             .           1/r32/ecx   4/disp8         .                 # copy *(esi+4) to ecx
-    # edi = s
-    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           7/r32/edi   0xc/disp8       .                 # copy *(ebp+12) to edi
-    # edx = s->write
-    8b/copy                         0/mod/indirect  7/rm32/edi    .           .             .           2/r32/edx   .               .                 # copy *edi to edx
-$read-line:loop:
-    # if (s->write >= s->length) abort
-    3b/compare                      1/mod/*+disp8   7/rm32/edi    .           .             .           2/r32/edx   8/disp8         .                 # compare edx with *(edi+8)
-    0f 8d/jump-if-greater-or-equal  $read-line:abort/disp32
-    # if (f->read >= f->write) break
-    3b/compare                      0/mod/indirect  6/rm32/esi    .           .             .           1/r32/ecx   .               .                 # compare ecx with *esi
-    7d/jump-if-greater-or-equal  $read-line:end/disp8
-    # AL = f->data[f->read]
-    31/xor                          3/mod/direct    0/rm32/eax    .           .             .           0/r32/eax   .               .                 # clear eax
-    8a/copy-byte                    1/mod/*+disp8   4/rm32/sib    6/base/esi  1/index/ecx   .           0/r32/AL    0xc/disp8       .                 # copy byte at *(esi+ecx+12) to AL
-    # s->data[s->write] = AL
-    88/copy-byte                    1/mod/*+disp8   4/rm32/sib    7/base/edi  2/index/edx   .           0/r32/AL    0xc/disp8       .                 # copy AL to *(edi+edx+12)
-    # ++f->read
-    41/increment-ecx
-    # ++s->write
-    42/increment-edx
-    # if (AL == '\n') return
-    3d/compare-eax-and  0xa/imm32
-    0f 85/jump-if-not-equal  $read-line:loop/disp32
-$read-line:end:
-    # save f->read
-    89/copy                         1/mod/*+disp8   6/rm32/esi    .           .             .           1/r32/ecx   4/disp8         .                 # copy ecx to *(esi+4)
-    # save s->write
-    89/copy                         0/mod/indirect  7/rm32/edi    .           .             .           2/r32/edx   .               .                 # copy edx to *edi
-    # . restore registers
-    5f/pop-to-edi
-    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
-
-$read-line:abort:
-    # . _write(2/stderr, error)
-    # . . push args
-    68/push  "read-line: line too long\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
-    # . syscall(exit, 1)
-    bb/copy-to-ebx  1/imm32
-    b8/copy-to-eax  1/imm32/exit
-    cd/syscall  0x80/imm8
-    # never gets here
-
-test-read-line:
-    # - check that read-line stops at a newline
-    # setup
-    # . clear-stream(_test-stream)
-    # . . push args
-    68/push  _test-stream/imm32
-    # . . call
-    e8/call  clear-stream/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
-    # . clear-stream(_test-tmp-stream)
-    # . . push args
-    68/push  _test-tmp-stream/imm32
-    # . . call
-    e8/call  clear-stream/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
-    # write(_test-stream, "ab\ncd")
-    # . . push args
-    68/push  "ab\ncd"/imm32
-    68/push  _test-stream/imm32
-    # . . call
-    e8/call  write/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-    # read a line from _test-stream into _test-tmp-stream
-    # . eax = read-line(_test-stream, _test-tmp-stream)
-    # . . push args
-    68/push  _test-tmp-stream/imm32
-    68/push  _test-stream/imm32
-    # . . call
-    e8/call  read-line/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-    # check-next-stream-line-equal(_test-tmp-stream, "ab", msg)
-    # . . push args
-    68/push  "F - test-read-line"/imm32
-    68/push  "ab"/imm32
-    68/push  _test-tmp-stream/imm32
-    # . . call
-    e8/call  check-next-stream-line-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-    # end
-    c3/return
-
-test-read-line-reads-final-line-until-Eof:
-    # setup
-    # . clear-stream(_test-stream)
-    # . . push args
-    68/push  _test-stream/imm32
-    # . . call
-    e8/call  clear-stream/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
-    # . clear-stream(_test-tmp-stream)
-    # . . push args
-    68/push  _test-tmp-stream/imm32
-    # . . call
-    e8/call  clear-stream/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
-    # write(_test-stream, "cd")
-    # . . push args
-    68/push  "cd"/imm32
-    68/push  _test-stream/imm32
-    # . . call
-    e8/call  write/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-    # read a line from _test-stream into _test-tmp-stream
-    # . eax = read-line(_test-stream, _test-tmp-stream)
-    # . . push args
-    68/push  _test-tmp-stream/imm32
-    68/push  _test-stream/imm32
-    # . . call
-    e8/call  read-line/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-    # check-stream-equal(_test-tmp-stream, "cd", msg)
-    # . . push args
-    68/push  "F - test-read-line-reads-final-line-until-Eof"/imm32
-    68/push  "cd"/imm32
-    68/push  _test-tmp-stream/imm32
-    # . . call
-    e8/call  check-stream-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-    # end
-    c3/return
-
-# . . vim:nowrap:textwidth=0