diff --git a/subx/055stream.subx b/subx/055stream.subx new file mode 100644 index 00000000..9711c60a --- /dev/null +++ b/subx/055stream.subx @@ -0,0 +1,61 @@ +# streams: data structure for operating on arrays in a stateful manner +# +# A stream looks like this: +# read : int # index that we've read until +# write : int # index at which writes go +# data : (array byte) # prefixed by length as usual +# +# primitives for operating on streams: +# - clear-stream (clears everything but the data length) +# - stream-equal? (compares stream data with a string; ignores read pointer) +# - rewind-reads (resets read pointer; not yet implemented) + +== 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 + +# main: + e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'. + # syscall(exit, Num-test-failures) + 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX Num-test-failures/disp32 # copy *Num-test-failures to EBX + b8/copy-to-EAX 1/imm32/exit + cd/syscall 0x80/imm8 + +clear-stream: # f : (address stream) -> + # . 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 + # EAX = f + 8b/copy 1/mod/*+disp8 5/rm32/EBP . . 0/r32/EAX 8/disp8 . # copy *(EBP+8) to EAX + # ECX = f->length + 8b/copy 1/mod/*+disp8 0/rm32/EAX . . . 1/r32/ECX 8/disp8 . # copy *(EAX+8) to ECX + # ECX = &f->data[f->length] + 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/EAX 1/index/ECX . 1/r32/ECX 0xc/disp8 . # copy EAX+ECX+12 to ECX + # f->write = 0 + c7 0/subop/copy 0/mod/direct 0/rm32/EAX . . . . . 0/imm32 # copy to *EAX + # f->read = 0 + c7 0/subop/copy 1/mod/*+disp8 0/rm32/EAX . . . . 4/disp8 0/imm32 # copy to *(EAX+4) + # EAX = f->data + 81 0/subop/add 3/mod/direct 0/rm32/EAX . . . . . 0xc/imm32 # add to EAX + # while (true) +$clear-stream:loop: + # if EAX >= ECX break + 39/compare 3/mod/direct 0/rm32/EAX . . . 1/r32/ECX . . # compare EAX with ECX + 7d/jump-if-greater-or-equal $clear-stream:end/disp8 + # *EAX = 0 + c6 0/subop/copy 0/mod/direct 0/rm32/EAX . . . . . 0/imm8 # copy byte to *EAX + # ++EAX + 40/increment-EAX + eb/jump $clear-stream:loop/disp8 +$clear-stream:end: + # . restore registers + 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 diff --git a/subx/055trace.subx b/subx/056trace.subx similarity index 99% rename from subx/055trace.subx rename to subx/056trace.subx index 17ecb29b..3b1a22e5 100644 --- a/subx/055trace.subx +++ b/subx/056trace.subx @@ -1,4 +1,4 @@ -# primitives for emitting traces to a trace stream, and for tests to check the trace stream +# primitives for emitting traces to a 'trace' stream, and for tests to make assertions on its contents # # A trace stream looks like this: # read : int # index that we've read until @@ -11,7 +11,6 @@ # - trace: stream, string # - die: stream (exit(1) if using real trace) # - check-trace-contains: stream, string/line, string/message (scans only from stream's read pointer, prints message to stderr on failure, updates stream's read pointer) -# - rewind-reads: stream (resets read pointer) # - scan-to-next-line: stream (advance read pointer past next newline) # # Traces are very fundamental, so many of the helpers we create here won't be diff --git a/subx/056write.subx b/subx/057write.subx similarity index 78% rename from subx/056write.subx rename to subx/057write.subx index 8f5de6e9..3f2f8a11 100644 --- a/subx/056write.subx +++ b/subx/057write.subx @@ -82,44 +82,6 @@ $write:end: 5d/pop-to-EBP c3/return -clear-stream: # f : (address stream) -> - # . 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 - # EAX = f - 8b/copy 1/mod/*+disp8 5/rm32/EBP . . 0/r32/EAX 8/disp8 . # copy *(EBP+8) to EAX - # ECX = f->length - 8b/copy 1/mod/*+disp8 0/rm32/EAX . . . 1/r32/ECX 8/disp8 . # copy *(EAX+8) to ECX - # ECX = &f->data[f->length] - 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/EAX 1/index/ECX . 1/r32/ECX 0xc/disp8 . # copy EAX+ECX+12 to ECX - # f->write = 0 - c7 0/subop/copy 0/mod/direct 0/rm32/EAX . . . . . 0/imm32 # copy to *EAX - # f->read = 0 - c7 0/subop/copy 1/mod/*+disp8 0/rm32/EAX . . . . 4/disp8 0/imm32 # copy to *(EAX+4) - # EAX = f->data - 81 0/subop/add 3/mod/direct 0/rm32/EAX . . . . . 0xc/imm32 # add to EAX - # while (true) -$clear-stream:loop: - # if EAX >= ECX break - 39/compare 3/mod/direct 0/rm32/EAX . . . 1/r32/ECX . . # compare EAX with ECX - 7d/jump-if-greater-or-equal $clear-stream:end/disp8 - # *EAX = 0 - c6 0/subop/copy 0/mod/direct 0/rm32/EAX . . . . . 0/imm8 # copy byte to *EAX - # ++EAX - 40/increment-EAX - eb/jump $clear-stream:loop/disp8 -$clear-stream:end: - # . restore registers - 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 - test-write-single: # clear-stream(_test-stream) # . . push args diff --git a/subx/057stop.subx b/subx/058stop.subx similarity index 100% rename from subx/057stop.subx rename to subx/058stop.subx diff --git a/subx/058read.subx b/subx/059read.subx similarity index 100% rename from subx/058read.subx rename to subx/059read.subx diff --git a/subx/059read-byte.subx b/subx/060read-byte.subx similarity index 100% rename from subx/059read-byte.subx rename to subx/060read-byte.subx diff --git a/subx/060write-stream.subx b/subx/061write-stream.subx similarity index 100% rename from subx/060write-stream.subx rename to subx/061write-stream.subx diff --git a/subx/061error.subx b/subx/062error.subx similarity index 100% rename from subx/061error.subx rename to subx/062error.subx diff --git a/subx/062write-byte.subx b/subx/063write-byte.subx similarity index 100% rename from subx/062write-byte.subx rename to subx/063write-byte.subx diff --git a/subx/063hex.subx b/subx/064hex.subx similarity index 100% rename from subx/063hex.subx rename to subx/064hex.subx diff --git a/subx/064print-byte.subx b/subx/065print-byte.subx similarity index 100% rename from subx/064print-byte.subx rename to subx/065print-byte.subx diff --git a/subx/065write-buffered.subx b/subx/066write-buffered.subx similarity index 100% rename from subx/065write-buffered.subx rename to subx/066write-buffered.subx diff --git a/subx/066error-byte.subx b/subx/067error-byte.subx similarity index 100% rename from subx/066error-byte.subx rename to subx/067error-byte.subx diff --git a/subx/067allocate.subx b/subx/068allocate.subx similarity index 100% rename from subx/067allocate.subx rename to subx/068allocate.subx diff --git a/subx/068new-stream.subx b/subx/069new-stream.subx similarity index 98% rename from subx/068new-stream.subx rename to subx/069new-stream.subx index 2020229d..e6f2e0cb 100644 --- a/subx/068new-stream.subx +++ b/subx/069new-stream.subx @@ -1,6 +1,4 @@ # Helper to allocate a stream on the heap. -# -# We'll now start gingerly supporting streams containing arbitrary types. == code # instruction effective address register displacement immediate diff --git a/subx/069read-line.subx b/subx/070read-line.subx similarity index 100% rename from subx/069read-line.subx rename to subx/070read-line.subx diff --git a/subx/070slice.subx b/subx/071slice.subx similarity index 100% rename from subx/070slice.subx rename to subx/071slice.subx diff --git a/subx/071next-token.subx b/subx/072next-token.subx similarity index 100% rename from subx/071next-token.subx rename to subx/072next-token.subx diff --git a/subx/apps/crenshaw2-1 b/subx/apps/crenshaw2-1 index 3e694fa1..082416cf 100755 Binary files a/subx/apps/crenshaw2-1 and b/subx/apps/crenshaw2-1 differ diff --git a/subx/apps/crenshaw2-1b b/subx/apps/crenshaw2-1b index 6e26f2c6..f8d52e06 100755 Binary files a/subx/apps/crenshaw2-1b and b/subx/apps/crenshaw2-1b differ diff --git a/subx/apps/factorial b/subx/apps/factorial index 52b8787d..ee7c9782 100755 Binary files a/subx/apps/factorial and b/subx/apps/factorial differ diff --git a/subx/apps/handle b/subx/apps/handle index 60337c7e..bfe7cf74 100755 Binary files a/subx/apps/handle and b/subx/apps/handle differ diff --git a/subx/apps/hex b/subx/apps/hex index 56f7471b..e67cc1fb 100755 Binary files a/subx/apps/hex and b/subx/apps/hex differ diff --git a/subx/apps/pack b/subx/apps/pack index 4d10e9bd..4e7ae680 100755 Binary files a/subx/apps/pack and b/subx/apps/pack differ