4948
This seems like the final helper we need for Phase 2. Now to build the business logic itself.
This commit is contained in:
parent
4cb7d1fb77
commit
cb82bd2364
File diff suppressed because it is too large
Load Diff
BIN
subx/apps/pack
BIN
subx/apps/pack
Binary file not shown.
|
@ -21,7 +21,7 @@
|
|||
# . 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
|
||||
|
||||
# for debugging: run a single test
|
||||
#? e8/call test-has-metadata-true/disp32
|
||||
#? e8/call test-emit-non-number-with-metadata/disp32
|
||||
#? 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX Num-test-failures/disp32 # copy *Num-test-failures to EBX
|
||||
#? eb/jump $main:end/disp8
|
||||
|
||||
|
@ -134,11 +134,6 @@ $main:end:
|
|||
# next-token(stream, slice, delim char) -> slice'
|
||||
# slice-equal?(slice, string)
|
||||
|
||||
# helpers:
|
||||
# emit(out : &buffered-file, word : &slice, width : int)
|
||||
# if slice is all hex digits, parse and print appropriate digits
|
||||
# otherwise just write-slice
|
||||
|
||||
convert: # in : (address buffered-file), out : (address buffered-file), err : (address buffered-file), ed : (address exit-descriptor) -> <void>
|
||||
# pseudocode:
|
||||
# line = new-stream(512, 1)
|
||||
|
@ -618,6 +613,338 @@ test-has-metadata-multiple-false:
|
|||
5d/pop-to-EBP
|
||||
c3/return
|
||||
|
||||
# if the name of 'word' is all hex digits, parse and emit it in 'width' bytes
|
||||
# of hex otherwise just write-slice
|
||||
emit: # out : (address buffered-file), word : (address slice), width : int
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
# . save registers
|
||||
50/push-EAX
|
||||
56/push-ESI
|
||||
57/push-EDI
|
||||
# ESI = word
|
||||
8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 0xc/disp8 . # copy *(EBP+12) to ESI
|
||||
# var name/EDI : (address slice) = {0, 0}
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 7/rm32/EDI . . . 4/r32/ESP . . # copy ESP to EDI
|
||||
# name = next-token-from-slice(word->start, word->end, '/')
|
||||
# . . push args
|
||||
57/push-EDI
|
||||
68/push 0x2f/imm32/slash
|
||||
ff 6/subop/push 1/mod/*+disp8 6/rm32/ESI . . . . 4/disp8 . # push *(ESI+4)
|
||||
ff 6/subop/push 0/mod/indirect 6/rm32/ESI . . . . . . # push *ESI
|
||||
# . . call
|
||||
e8/call next-token-from-slice/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP
|
||||
# if !is-hex-int?(name) write-slice(out, word) and return
|
||||
# . is-hex-int?(name)
|
||||
# . . push args
|
||||
57/push-EDI
|
||||
# . . call
|
||||
e8/call is-hex-int?/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
|
||||
# . if EAX == 0
|
||||
81 7/subop/compare 3/mod/direct 0/rm32/EAX . . . . . 0/imm32 # compare EAX
|
||||
75/jump-if-not-equal $emit:hex-int/disp8
|
||||
# . write-slice(out, word)
|
||||
# . . push args
|
||||
56/push-ESI
|
||||
ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8)
|
||||
# . . call
|
||||
e8/call write-slice/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
|
||||
# . return
|
||||
eb/jump $emit:end/disp8
|
||||
# otherwise emit-hex(out, parse-hex-int(name), width)
|
||||
$emit:hex-int:
|
||||
# . n/EAX = parse-hex-int(name)
|
||||
# . . push args
|
||||
57/push-EDI
|
||||
# . . call
|
||||
e8/call parse-hex-int/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
|
||||
# . emit-hex(out, n, width)
|
||||
# . . push args
|
||||
ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0x10/disp8 . # push *(EBP+16)
|
||||
50/push-EAX
|
||||
ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8)
|
||||
# . . call
|
||||
e8/call emit-hex/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
|
||||
$emit:end:
|
||||
# . reclaim locals
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
|
||||
# . restore registers
|
||||
5f/pop-to-EDI
|
||||
5e/pop-to-ESI
|
||||
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-emit-number:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
# 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
|
||||
# var slice/ECX = "-2"
|
||||
68/push _test-slice-negative-two-end/imm32/end
|
||||
68/push _test-slice-negative-two/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX
|
||||
# emit(_test-buffered-file, slice, 2)
|
||||
# . . push args
|
||||
68/push 2/imm32
|
||||
51/push-ECX
|
||||
68/push _test-buffered-file/imm32
|
||||
# . . call
|
||||
e8/call emit/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
|
||||
# flush(_test-buffered-file)
|
||||
# . . push args
|
||||
68/push _test-buffered-file/imm32
|
||||
# . . call
|
||||
e8/call flush/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
|
||||
# check(_test-stream->data == 'fe ff ')
|
||||
# . check-ints-equal(_test-stream->data[0..3], 'fe f', msg)
|
||||
# . . push args
|
||||
68/push "F - test-emit-number/1"/imm32
|
||||
68/push 0x66206566/imm32
|
||||
# . . push *_test-stream->data
|
||||
b8/copy-to-EAX _test-stream/imm32
|
||||
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12)
|
||||
# . . 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-ints-equal(_test-stream->data[4..7], 'f ', msg)
|
||||
# . . push args
|
||||
68/push "F - test-emit-number/2"/imm32
|
||||
68/push 0x2066/imm32
|
||||
# . . push *_test-stream->data
|
||||
b8/copy-to-EAX _test-stream/imm32
|
||||
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0x10/disp8 . # push *(EAX+16)
|
||||
# . . call
|
||||
e8/call check-ints-equal/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
|
||||
# . epilog
|
||||
89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP
|
||||
5d/pop-to-EBP
|
||||
c3/return
|
||||
|
||||
test-emit-number-with-metadata:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
# 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
|
||||
# var slice/ECX = "-2/foo"
|
||||
68/push _test-slice-negative-two-metadata-end/imm32/end
|
||||
68/push _test-slice-negative-two/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX
|
||||
# emit(_test-buffered-file, slice, 2)
|
||||
# . . push args
|
||||
68/push 2/imm32
|
||||
51/push-ECX
|
||||
68/push _test-buffered-file/imm32
|
||||
# . . call
|
||||
e8/call emit/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
|
||||
# flush(_test-buffered-file)
|
||||
# . . push args
|
||||
68/push _test-buffered-file/imm32
|
||||
# . . call
|
||||
e8/call flush/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
|
||||
# the '/foo' will have no impact on the output
|
||||
# check(_test-stream->data == 'fe ff ')
|
||||
# . check-ints-equal(_test-stream->data[0..3], 'fe f', msg)
|
||||
# . . push args
|
||||
68/push "F - test-emit-number-with-metadata/1"/imm32
|
||||
68/push 0x66206566/imm32
|
||||
# . . push *_test-stream->data
|
||||
b8/copy-to-EAX _test-stream/imm32
|
||||
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12)
|
||||
# . . 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-ints-equal(_test-stream->data[4..7], 'f ', msg)
|
||||
# . . push args
|
||||
68/push "F - test-emit-number-with-metadata/2"/imm32
|
||||
68/push 0x2066/imm32
|
||||
# . . push *_test-stream->data
|
||||
b8/copy-to-EAX _test-stream/imm32
|
||||
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0x10/disp8 . # push *(EAX+16)
|
||||
# . . call
|
||||
e8/call check-ints-equal/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
|
||||
# . epilog
|
||||
89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP
|
||||
5d/pop-to-EBP
|
||||
c3/return
|
||||
|
||||
test-emit-non-number:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
# 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
|
||||
# var slice/ECX = "xyz"
|
||||
68/push _test-slice-non-number-word-end/imm32/end
|
||||
68/push _test-slice-non-number-word/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX
|
||||
# emit(_test-buffered-file, slice, 2)
|
||||
# . . push args
|
||||
68/push 2/imm32
|
||||
51/push-ECX
|
||||
68/push _test-buffered-file/imm32
|
||||
# . . call
|
||||
e8/call emit/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
|
||||
# flush(_test-buffered-file)
|
||||
# . . push args
|
||||
68/push _test-buffered-file/imm32
|
||||
# . . call
|
||||
e8/call flush/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
|
||||
# check(_test-stream->data == 'xyz')
|
||||
# . check-ints-equal(_test-stream->data[0..3], 'xyz', msg)
|
||||
# . . push args
|
||||
68/push "F - test-emit-non-number"/imm32
|
||||
68/push 0x7a7978/imm32
|
||||
# . . push *_test-stream->data
|
||||
b8/copy-to-EAX _test-stream/imm32
|
||||
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12)
|
||||
# . . call
|
||||
e8/call check-ints-equal/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
|
||||
# . epilog
|
||||
89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP
|
||||
5d/pop-to-EBP
|
||||
c3/return
|
||||
|
||||
test-emit-non-number-with-metadata:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
# 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
|
||||
# var slice/ECX = "xyz/"
|
||||
68/push _test-slice-non-number-word-metadata-end/imm32/end
|
||||
68/push _test-slice-non-number-word/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX
|
||||
# emit(_test-buffered-file, slice, 2)
|
||||
# . . push args
|
||||
68/push 2/imm32
|
||||
51/push-ECX
|
||||
68/push _test-buffered-file/imm32
|
||||
# . . call
|
||||
e8/call emit/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
|
||||
# flush(_test-buffered-file)
|
||||
# . . push args
|
||||
68/push _test-buffered-file/imm32
|
||||
# . . call
|
||||
e8/call flush/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
|
||||
# check(_test-stream->data == 'xyz/')
|
||||
# . check-ints-equal(_test-stream->data[0..3], 'xyz/', msg)
|
||||
# . . push args
|
||||
68/push "F - test-emit-non-number-with-metadata"/imm32
|
||||
68/push 0x2f7a7978/imm32
|
||||
# . . push *_test-stream->data
|
||||
b8/copy-to-EAX _test-stream/imm32
|
||||
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 0xc/disp8 . # push *(EAX+12)
|
||||
# . . call
|
||||
e8/call check-ints-equal/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
|
||||
# . epilog
|
||||
89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP
|
||||
5d/pop-to-EBP
|
||||
c3/return
|
||||
|
||||
# print 'n' in hex in 'width' bytes in lower-endian order, with a space after every byte
|
||||
emit-hex: # out : (address buffered-file), n : int, width : int
|
||||
# . prolog
|
||||
|
@ -907,5 +1234,13 @@ test-emit-hex-negative:
|
|||
_test-slice-negative-two:
|
||||
2d/- 32/2
|
||||
_test-slice-negative-two-end:
|
||||
2f/slash 66/f 6f/o 6f/o
|
||||
_test-slice-negative-two-metadata-end:
|
||||
|
||||
_test-slice-non-number-word:
|
||||
78/x 79/y 7a/z
|
||||
_test-slice-non-number-word-end:
|
||||
2f/slash
|
||||
_test-slice-non-number-word-metadata-end:
|
||||
|
||||
# . . vim:nowrap:textwidth=0
|
||||
|
|
Loading…
Reference in New Issue