5586 - bugfix: no desugar inside string literals
This commit is contained in:
parent
dac833572b
commit
d8c2f71ce9
BIN
apps/assort
BIN
apps/assort
Binary file not shown.
BIN
apps/desugar
BIN
apps/desugar
Binary file not shown.
|
@ -1371,7 +1371,7 @@ $next-word-or-expression:check0:
|
|||
# . return out = {0, 0}
|
||||
c7 0/subop/copy 0/mod/direct 7/rm32/EDI . . . . . 0/imm32 # copy to *EDI
|
||||
c7 0/subop/copy 1/mod/*+disp8 7/rm32/EDI . . . . 4/disp8 0/imm32 # copy to *(EDI+4)
|
||||
eb/jump $next-word-or-expression:end/disp8
|
||||
e9/jump $next-word-or-expression:end/disp32
|
||||
$next-word-or-expression:check-for-comment:
|
||||
# out->start = &line->data[line->read]
|
||||
8b/copy 1/mod/*+disp8 6/rm32/ESI . . . 1/r32/ECX 4/disp8 . # copy *(ESI+4) to ECX
|
||||
|
@ -1383,7 +1383,7 @@ $next-word-or-expression:check-for-comment:
|
|||
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
|
||||
# . compare
|
||||
3d/compare-EAX-and 0x23/imm32/pound
|
||||
75/jump-if-not-equal $next-word-or-expression:check-for-paren/disp8
|
||||
75/jump-if-not-equal $next-word-or-expression:check-for-string-literal/disp8
|
||||
$next-word-or-expression:comment:
|
||||
# out->end = &line->data[line->write]
|
||||
8b/copy 0/mod/indirect 6/rm32/ESI . . . 0/r32/EAX . . # copy *ESI to EAX
|
||||
|
@ -1394,6 +1394,24 @@ $next-word-or-expression:comment:
|
|||
89/copy 1/mod/*+disp8 6/rm32/ESI . . . 0/r32/EAX 4/disp8 . # copy EAX to *(ESI+4)
|
||||
# return
|
||||
eb/jump $next-word-or-expression:end/disp8
|
||||
$next-word-or-expression:check-for-string-literal:
|
||||
# if (line->data[line->read] != '"') goto next check
|
||||
# . EAX = line->data[line->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
|
||||
# . compare
|
||||
3d/compare-EAX-and 0x22/imm32/dquote
|
||||
75/jump-if-not-equal $next-word-or-expression:check-for-paren/disp8
|
||||
$next-word-or-expression:string-literal:
|
||||
# skip-string(line)
|
||||
# . . push args
|
||||
56/push-ESI
|
||||
# . . call
|
||||
e8/call skip-string/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
|
||||
# skip rest of word
|
||||
eb/jump $next-word-or-expression:regular-word/disp8
|
||||
$next-word-or-expression:check-for-paren:
|
||||
# if (line->data[line->read] != '*') goto next check
|
||||
# . EAX = line->data[line->read]
|
||||
|
@ -1676,7 +1694,7 @@ test-next-word-or-expression-returns-whole-comment:
|
|||
5d/pop-to-EBP
|
||||
c3/return
|
||||
|
||||
test-next-word-or-expression-returns-empty-expression-on-eof:
|
||||
test-next-word-or-expression-returns-empty-slice-on-eof:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
|
@ -1718,6 +1736,132 @@ test-next-word-or-expression-returns-empty-expression-on-eof:
|
|||
5d/pop-to-EBP
|
||||
c3/return
|
||||
|
||||
test-next-word-or-expression-returns-string-literal:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
# setup
|
||||
# . clear-stream(_test-input-stream)
|
||||
# . . push args
|
||||
68/push _test-input-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
|
||||
# var slice/ECX = {0, 0}
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX
|
||||
# write(_test-input-stream, " \"a b\"/imm32 ")
|
||||
# . . push args
|
||||
68/push " \"a b\"/imm32 "/imm32
|
||||
68/push _test-input-stream/imm32
|
||||
# . . call
|
||||
e8/call write/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
|
||||
# next-word-or-expression(_test-input-stream, slice)
|
||||
# . . push args
|
||||
51/push-ECX
|
||||
68/push _test-input-stream/imm32
|
||||
# . . call
|
||||
e8/call next-word-or-expression/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
|
||||
# check-ints-equal(slice->start - _test-input-stream->data, 1, msg)
|
||||
# . check-ints-equal(slice->start - _test-input-stream, 13, msg)
|
||||
# . . push args
|
||||
68/push "F - test-next-word-or-expression-returns-string-literal: start"/imm32
|
||||
68/push 0xd/imm32
|
||||
# . . push slice->start - _test-input-stream
|
||||
8b/copy 0/mod/indirect 1/rm32/ECX . . . 0/r32/EAX . . # copy *ECX to EAX
|
||||
81 5/subop/subtract 3/mod/direct 0/rm32/EAX . . . . . _test-input-stream/imm32 # subtract 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
|
||||
# check-ints-equal(slice->end - _test-input-stream->data, 12, msg)
|
||||
# . check-ints-equal(slice->end - _test-input-stream, 24, msg)
|
||||
# . . push args
|
||||
68/push "F - test-next-word-or-expression-returns-string-literal: end"/imm32
|
||||
68/push 0x18/imm32
|
||||
# . . push slice->end - _test-input-stream
|
||||
8b/copy 1/mod/*+disp8 1/rm32/ECX . . . 0/r32/EAX 4/disp8 . # copy *(ECX+4) to EAX
|
||||
81 5/subop/subtract 3/mod/direct 0/rm32/EAX . . . . . _test-input-stream/imm32 # subtract 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
|
||||
# . epilog
|
||||
89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP
|
||||
5d/pop-to-EBP
|
||||
c3/return
|
||||
|
||||
test-next-word-or-expression-returns-string-with-escapes:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
# setup
|
||||
# . clear-stream(_test-input-stream)
|
||||
# . . push args
|
||||
68/push _test-input-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
|
||||
# var slice/ECX = {0, 0}
|
||||
68/push 0/imm32/end
|
||||
68/push 0/imm32/start
|
||||
89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX
|
||||
# write(_test-input-stream, " \"a\\\"b\"/x")
|
||||
# . . push args
|
||||
68/push " \"a\\\"b\"/x"/imm32
|
||||
68/push _test-input-stream/imm32
|
||||
# . . call
|
||||
e8/call write/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
|
||||
# next-word-or-expression(_test-input-stream, slice)
|
||||
# . . push args
|
||||
51/push-ECX
|
||||
68/push _test-input-stream/imm32
|
||||
# . . call
|
||||
e8/call next-word-or-expression/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
|
||||
# check-ints-equal(slice->start - _test-input-stream->data, 1, msg)
|
||||
# . check-ints-equal(slice->start - _test-input-stream, 13, msg)
|
||||
# . . push args
|
||||
68/push "F - test-next-word-or-expression-returns-string-with-escapes: start"/imm32
|
||||
68/push 0xd/imm32
|
||||
# . . push slice->start - _test-input-stream
|
||||
8b/copy 0/mod/indirect 1/rm32/ECX . . . 0/r32/EAX . . # copy *ECX to EAX
|
||||
81 5/subop/subtract 3/mod/direct 0/rm32/EAX . . . . . _test-input-stream/imm32 # subtract 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
|
||||
# check-ints-equal(slice->end - _test-input-stream->data, 9, msg)
|
||||
# . check-ints-equal(slice->end - _test-input-stream, 21, msg)
|
||||
# . . push args
|
||||
68/push "F - test-next-word-or-expression-returns-string-with-escapes: end"/imm32
|
||||
68/push 0x15/imm32
|
||||
# . . push slice->end - _test-input-stream
|
||||
8b/copy 1/mod/*+disp8 1/rm32/ECX . . . 0/r32/EAX 4/disp8 . # copy *(ECX+4) to EAX
|
||||
81 5/subop/subtract 3/mod/direct 0/rm32/EAX . . . . . _test-input-stream/imm32 # subtract 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
|
||||
# . epilog
|
||||
89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP
|
||||
5d/pop-to-EBP
|
||||
c3/return
|
||||
|
||||
test-next-word-or-expression-returns-whole-expression:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
|
|
BIN
apps/dquotes
BIN
apps/dquotes
Binary file not shown.
|
@ -2002,7 +2002,7 @@ test-next-word-or-string-returns-whole-comment:
|
|||
5d/pop-to-EBP
|
||||
c3/return
|
||||
|
||||
test-next-word-or-string-returns-empty-string-on-eof:
|
||||
test-next-word-or-string-returns-empty-slice-on-eof:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
|
@ -2044,7 +2044,7 @@ test-next-word-or-string-returns-empty-string-on-eof:
|
|||
5d/pop-to-EBP
|
||||
c3/return
|
||||
|
||||
test-next-word-or-string-returns-whole-string:
|
||||
test-next-word-or-string-returns-string-literal:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
|
@ -2079,7 +2079,7 @@ test-next-word-or-string-returns-whole-string:
|
|||
# check-ints-equal(slice->start - _test-input-stream->data, 1, msg)
|
||||
# . check-ints-equal(slice->start - _test-input-stream, 13, msg)
|
||||
# . . push args
|
||||
68/push "F - test-next-word-or-string-returns-whole-string: start"/imm32
|
||||
68/push "F - test-next-word-or-string-returns-string-literal: start"/imm32
|
||||
68/push 0xd/imm32
|
||||
# . . push slice->start - _test-input-stream
|
||||
8b/copy 0/mod/indirect 1/rm32/ECX . . . 0/r32/EAX . . # copy *ECX to EAX
|
||||
|
@ -2092,7 +2092,7 @@ test-next-word-or-string-returns-whole-string:
|
|||
# check-ints-equal(slice->end - _test-input-stream->data, 12, msg)
|
||||
# . check-ints-equal(slice->end - _test-input-stream, 24, msg)
|
||||
# . . push args
|
||||
68/push "F - test-next-word-or-string-returns-whole-string: end"/imm32
|
||||
68/push "F - test-next-word-or-string-returns-string-literal: end"/imm32
|
||||
68/push 0x18/imm32
|
||||
# . . push slice->end - _test-input-stream
|
||||
8b/copy 1/mod/*+disp8 1/rm32/ECX . . . 0/r32/EAX 4/disp8 . # copy *(ECX+4) to EAX
|
||||
|
@ -2170,433 +2170,6 @@ test-next-word-or-string-returns-string-with-escapes:
|
|||
5d/pop-to-EBP
|
||||
c3/return
|
||||
|
||||
# update line->read to end of string literal surrounded by double quotes
|
||||
# line->read must start out at a double-quote
|
||||
skip-string: # line : (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
|
||||
52/push-EDX
|
||||
# ECX = line
|
||||
8b/copy 1/mod/*+disp8 5/rm32/EBP . . 1/r32/ECX 8/disp8 . # copy *(EBP+8) to ECX
|
||||
# EAX = skip-string-in-slice(&line->data[line->read], &line->data[line->write])
|
||||
# . . push &line->data[line->write]
|
||||
8b/copy 1/mod/*+disp8 1/rm32/ECX . . 2/r32/EDX 8/disp8 . # copy *(ECX+8) to EDX
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 1/base/ECX 2/index/EDX . 2/r32/EDX 0xc/disp8 . # copy ECX+EDX+12 to EDX
|
||||
52/push-EDX
|
||||
# . . push &line->data[line->read]
|
||||
8b/copy 1/mod/*+disp8 1/rm32/ECX . . 2/r32/EDX 4/disp8 . # copy *(ECX+4) to EDX
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 1/base/ECX 2/index/EDX . 2/r32/EDX 0xc/disp8 . # copy ECX+EDX+12 to EDX
|
||||
52/push-EDX
|
||||
# . . call
|
||||
e8/call skip-string-in-slice/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
|
||||
# line->read = EAX - line->data
|
||||
29/subtract 3/mod/direct 0/rm32/EAX . . . 1/r32/ECX . . # subtract ECX from EAX
|
||||
2d/subtract-from-EAX 0xc/imm32
|
||||
89/copy 1/mod/*+disp8 1/rm32/ECX . . 0/r32/EAX 4/disp8 . # copy EAX to *(ECX+4)
|
||||
$skip-string:end:
|
||||
# . restore registers
|
||||
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
|
||||
|
||||
test-skip-string:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
# setup
|
||||
# . clear-stream(_test-input-stream)
|
||||
# . . push args
|
||||
68/push _test-input-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-input-stream, "\"abc\" def")
|
||||
# . indices: 0123 45
|
||||
# . . push args
|
||||
68/push "\"abc\" def"/imm32
|
||||
68/push _test-input-stream/imm32
|
||||
# . . call
|
||||
e8/call write/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
|
||||
# precondition: line->read == 0
|
||||
# . . push args
|
||||
68/push "F - test-skip-string/precondition"/imm32
|
||||
68/push 0/imm32
|
||||
b8/copy-to-EAX _test-input-stream/imm32
|
||||
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 4/disp8 . # push *(EAX+4)
|
||||
# . . call
|
||||
e8/call check-ints-equal/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
|
||||
# skip-string(_test-input-stream)
|
||||
# . . push args
|
||||
68/push _test-input-stream/imm32
|
||||
# . . call
|
||||
e8/call skip-string/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
|
||||
# check-ints-equal(line->read, 5, msg)
|
||||
# . . push args
|
||||
68/push "F - test-skip-string"/imm32
|
||||
68/push 5/imm32
|
||||
b8/copy-to-EAX _test-input-stream/imm32
|
||||
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 4/disp8 . # push *(EAX+4)
|
||||
# . . 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-skip-string-ignores-spaces:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
# setup
|
||||
# . clear-stream(_test-input-stream)
|
||||
# . . push args
|
||||
68/push _test-input-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-input-stream, "\"a b\"/yz")
|
||||
# . indices: 0123 45
|
||||
# . . push args
|
||||
68/push "\"a b\"/yz"/imm32
|
||||
68/push _test-input-stream/imm32
|
||||
# . . call
|
||||
e8/call write/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
|
||||
# precondition: line->read == 0
|
||||
# . . push args
|
||||
68/push "F - test-skip-string-ignores-spaces/precondition"/imm32
|
||||
68/push 0/imm32
|
||||
b8/copy-to-EAX _test-input-stream/imm32
|
||||
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 4/disp8 . # push *(EAX+4)
|
||||
# . . call
|
||||
e8/call check-ints-equal/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
|
||||
# skip-string(_test-input-stream)
|
||||
# . . push args
|
||||
68/push _test-input-stream/imm32
|
||||
# . . call
|
||||
e8/call skip-string/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
|
||||
# check-ints-equal(line->read, 5, msg)
|
||||
# . . push args
|
||||
68/push "F - test-skip-string-ignores-spaces"/imm32
|
||||
68/push 5/imm32
|
||||
b8/copy-to-EAX _test-input-stream/imm32
|
||||
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 4/disp8 . # push *(EAX+4)
|
||||
# . . 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-skip-string-ignores-escapes:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
# setup
|
||||
# . clear-stream(_test-input-stream)
|
||||
# . . push args
|
||||
68/push _test-input-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-input-stream, "\"a\\\"b\"/yz")
|
||||
# . indices: 01 2 34 56
|
||||
# . . push args
|
||||
68/push "\"a\\\"b\"/yz"/imm32
|
||||
68/push _test-input-stream/imm32
|
||||
# . . call
|
||||
e8/call write/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
|
||||
# precondition: line->read == 0
|
||||
# . . push args
|
||||
68/push "F - test-skip-string-ignores-escapes/precondition"/imm32
|
||||
68/push 0/imm32
|
||||
b8/copy-to-EAX _test-input-stream/imm32
|
||||
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 4/disp8 . # push *(EAX+4)
|
||||
# . . call
|
||||
e8/call check-ints-equal/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
|
||||
# skip-string(_test-input-stream)
|
||||
# . . push args
|
||||
68/push _test-input-stream/imm32
|
||||
# . . call
|
||||
e8/call skip-string/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
|
||||
# check-ints-equal(line->read, 6, msg)
|
||||
# . . push args
|
||||
68/push "F - test-skip-string-ignores-escapes"/imm32
|
||||
68/push 6/imm32
|
||||
b8/copy-to-EAX _test-input-stream/imm32
|
||||
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 4/disp8 . # push *(EAX+4)
|
||||
# . . 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-skip-string-works-from-mid-stream:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
# setup
|
||||
# . clear-stream(_test-input-stream)
|
||||
# . . push args
|
||||
68/push _test-input-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-input-stream, "0 \"a\\\"b\"/yz")
|
||||
# . indices: 01 2 34 56
|
||||
# . . push args
|
||||
68/push "0 \"a\\\"b\"/yz"/imm32
|
||||
68/push _test-input-stream/imm32
|
||||
# . . call
|
||||
e8/call write/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
|
||||
# precondition: line->read == 2
|
||||
c7 0/subop/copy 1/mod/*+disp8 0/rm32/EAX . . . . 4/disp8 2/imm32 # copy to *(EAX+4)
|
||||
# skip-string(_test-input-stream)
|
||||
# . . push args
|
||||
68/push _test-input-stream/imm32
|
||||
# . . call
|
||||
e8/call skip-string/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
|
||||
# check-ints-equal(line->read, 8, msg)
|
||||
# . . push args
|
||||
68/push "F - test-skip-string-works-from-mid-stream"/imm32
|
||||
68/push 8/imm32
|
||||
b8/copy-to-EAX _test-input-stream/imm32
|
||||
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 4/disp8 . # push *(EAX+4)
|
||||
# . . 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
|
||||
|
||||
skip-string-in-slice: # curr : (address byte), end : (address byte) -> new_curr/EAX
|
||||
# . 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
|
||||
53/push-EBX
|
||||
# ECX = curr
|
||||
8b/copy 1/mod/*+disp8 5/rm32/EBP . . 1/r32/ECX 8/disp8 . # copy *(EBP+8) to ECX
|
||||
# EDX = end
|
||||
8b/copy 1/mod/*+disp8 5/rm32/EBP . . 2/r32/EDX 0xc/disp8 . # copy *(EBP+12) to EDX
|
||||
# EAX = 0
|
||||
31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX
|
||||
# skip initial dquote
|
||||
41/increment-ECX
|
||||
$skip-string-in-slice:loop:
|
||||
# if (curr >= end) return curr
|
||||
39/compare 3/mod/direct 1/rm32/ECX . . . 2/r32/EDX . . # compare ECX with EDX
|
||||
73/jump-if-greater-unsigned-or-equal $skip-string-in-slice:return-curr/disp8
|
||||
# AL = *curr
|
||||
8a/copy-byte 0/mod/indirect 1/rm32/ECX . . . 0/r32/AL . . # copy byte at *ECX to AL
|
||||
$skip-string-in-slice:dquote:
|
||||
# if (EAX == '"') break
|
||||
3d/compare-EAX-and 0x22/imm32/double-quote
|
||||
74/jump-if-equal $skip-string-in-slice:break/disp8
|
||||
$skip-string-in-slice:check-for-escape:
|
||||
# if (EAX == '\') escape next char
|
||||
3d/compare-EAX-and 0x5c/imm32/backslash
|
||||
75/jump-if-not-equal $skip-string-in-slice:continue/disp8
|
||||
$skip-string-in-slice:escape:
|
||||
41/increment-ECX
|
||||
$skip-string-in-slice:continue:
|
||||
# ++curr
|
||||
41/increment-ECX
|
||||
eb/jump $skip-string-in-slice:loop/disp8
|
||||
$skip-string-in-slice:break:
|
||||
# skip final dquote
|
||||
41/increment-ECX
|
||||
$skip-string-in-slice:return-curr:
|
||||
# return curr
|
||||
89/copy 3/mod/direct 0/rm32/EAX . . . 1/r32/ECX . . # copy ECX to EAX
|
||||
$skip-string-in-slice:end:
|
||||
# . restore registers
|
||||
5b/pop-to-EBX
|
||||
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-skip-string-in-slice:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
# setup: (EAX..ECX) = "\"abc\" def"
|
||||
b8/copy-to-EAX "\"abc\" def"/imm32
|
||||
8b/copy 0/mod/indirect 0/rm32/EAX . . . 1/r32/ECX . . # copy *EAX to ECX
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/EAX 1/index/ECX . 1/r32/ECX 4/disp8 . # copy EAX+ECX+4 to ECX
|
||||
05/add-to-EAX 4/imm32
|
||||
# EAX = skip-string-in-slice(EAX, ECX)
|
||||
# . . push args
|
||||
51/push-ECX
|
||||
50/push-EAX
|
||||
# . . call
|
||||
e8/call skip-string-in-slice/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
|
||||
# check-ints-equal(ECX-EAX, 4, msg) # number of chars remaining after the string literal
|
||||
# . . push args
|
||||
68/push "F - test-skip-string-in-slice"/imm32
|
||||
68/push 4/imm32
|
||||
# . . push ECX-EAX
|
||||
29/subtract 3/mod/direct 1/rm32/ECX . . . 0/r32/EAX . . # subtract EAX from ECX
|
||||
51/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
|
||||
# . epilog
|
||||
89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP
|
||||
5d/pop-to-EBP
|
||||
c3/return
|
||||
|
||||
test-skip-string-in-slice-ignores-spaces:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
# setup: (EAX..ECX) = "\"a b\"/yz"
|
||||
b8/copy-to-EAX "\"a b\"/yz"/imm32
|
||||
8b/copy 0/mod/indirect 0/rm32/EAX . . . 1/r32/ECX . . # copy *EAX to ECX
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/EAX 1/index/ECX . 1/r32/ECX 4/disp8 . # copy EAX+ECX+4 to ECX
|
||||
05/add-to-EAX 4/imm32
|
||||
# EAX = skip-string-in-slice(EAX, ECX)
|
||||
# . . push args
|
||||
51/push-ECX
|
||||
50/push-EAX
|
||||
# . . call
|
||||
e8/call skip-string-in-slice/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
|
||||
# check-ints-equal(ECX-EAX, 3, msg) # number of chars remaining after the string literal
|
||||
# . . push args
|
||||
68/push "F - test-skip-string-in-slice-ignores-spaces"/imm32
|
||||
68/push 3/imm32
|
||||
# . . push ECX-EAX
|
||||
29/subtract 3/mod/direct 1/rm32/ECX . . . 0/r32/EAX . . # subtract EAX from ECX
|
||||
51/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
|
||||
# . epilog
|
||||
89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP
|
||||
5d/pop-to-EBP
|
||||
c3/return
|
||||
|
||||
test-skip-string-in-slice-ignores-escapes:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
# setup: (EAX..ECX) = "\"a\\\"b\"/yz"
|
||||
b8/copy-to-EAX "\"a\\\"b\"/yz"/imm32
|
||||
8b/copy 0/mod/indirect 0/rm32/EAX . . . 1/r32/ECX . . # copy *EAX to ECX
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/EAX 1/index/ECX . 1/r32/ECX 4/disp8 . # copy EAX+ECX+4 to ECX
|
||||
05/add-to-EAX 4/imm32
|
||||
# EAX = skip-string-in-slice(EAX, ECX)
|
||||
# . . push args
|
||||
51/push-ECX
|
||||
50/push-EAX
|
||||
# . . call
|
||||
e8/call skip-string-in-slice/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
|
||||
# check-ints-equal(ECX-EAX, 3, msg) # number of chars remaining after the string literal
|
||||
# . . push args
|
||||
68/push "F - test-skip-string-in-slice-ignores-escapes"/imm32
|
||||
68/push 3/imm32
|
||||
# . . push ECX-EAX
|
||||
29/subtract 3/mod/direct 1/rm32/ECX . . . 0/r32/EAX . . # subtract EAX from ECX
|
||||
51/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
|
||||
# . epilog
|
||||
89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP
|
||||
5d/pop-to-EBP
|
||||
c3/return
|
||||
|
||||
test-skip-string-in-slice-stops-at-end:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
# setup: (EAX..ECX) = "\"abc" # unbalanced dquote
|
||||
b8/copy-to-EAX "\"abc"/imm32
|
||||
8b/copy 0/mod/indirect 0/rm32/EAX . . . 1/r32/ECX . . # copy *EAX to ECX
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/EAX 1/index/ECX . 1/r32/ECX 4/disp8 . # copy EAX+ECX+4 to ECX
|
||||
05/add-to-EAX 4/imm32
|
||||
# EAX = skip-string-in-slice(EAX, ECX)
|
||||
# . . push args
|
||||
51/push-ECX
|
||||
50/push-EAX
|
||||
# . . call
|
||||
e8/call skip-string-in-slice/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
|
||||
# check-ints-equal(ECX-EAX, 0, msg) # skipped to end of slice
|
||||
# . . push args
|
||||
68/push "F - test-skip-string-in-slice-stops-at-end"/imm32
|
||||
68/push 0/imm32
|
||||
# . . push ECX-EAX
|
||||
29/subtract 3/mod/direct 1/rm32/ECX . . . 0/r32/EAX . . # subtract EAX from ECX
|
||||
51/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
|
||||
# . epilog
|
||||
89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP
|
||||
5d/pop-to-EBP
|
||||
c3/return
|
||||
|
||||
string-length-at-start-of-slice: # curr : (address byte), end : (address byte) -> length/EAX
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
|
|
|
@ -270,6 +270,433 @@ test-next-word-returns-empty-string-on-eof:
|
|||
5d/pop-to-EBP
|
||||
c3/return
|
||||
|
||||
# update line->read to end of string literal surrounded by double quotes
|
||||
# line->read must start out at a double-quote
|
||||
skip-string: # line : (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
|
||||
52/push-EDX
|
||||
# ECX = line
|
||||
8b/copy 1/mod/*+disp8 5/rm32/EBP . . 1/r32/ECX 8/disp8 . # copy *(EBP+8) to ECX
|
||||
# EAX = skip-string-in-slice(&line->data[line->read], &line->data[line->write])
|
||||
# . . push &line->data[line->write]
|
||||
8b/copy 1/mod/*+disp8 1/rm32/ECX . . 2/r32/EDX 8/disp8 . # copy *(ECX+8) to EDX
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 1/base/ECX 2/index/EDX . 2/r32/EDX 0xc/disp8 . # copy ECX+EDX+12 to EDX
|
||||
52/push-EDX
|
||||
# . . push &line->data[line->read]
|
||||
8b/copy 1/mod/*+disp8 1/rm32/ECX . . 2/r32/EDX 4/disp8 . # copy *(ECX+4) to EDX
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 1/base/ECX 2/index/EDX . 2/r32/EDX 0xc/disp8 . # copy ECX+EDX+12 to EDX
|
||||
52/push-EDX
|
||||
# . . call
|
||||
e8/call skip-string-in-slice/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
|
||||
# line->read = EAX - line->data
|
||||
29/subtract 3/mod/direct 0/rm32/EAX . . . 1/r32/ECX . . # subtract ECX from EAX
|
||||
2d/subtract-from-EAX 0xc/imm32
|
||||
89/copy 1/mod/*+disp8 1/rm32/ECX . . 0/r32/EAX 4/disp8 . # copy EAX to *(ECX+4)
|
||||
$skip-string:end:
|
||||
# . restore registers
|
||||
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
|
||||
|
||||
test-skip-string:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
# setup
|
||||
# . clear-stream(_test-input-stream)
|
||||
# . . push args
|
||||
68/push _test-input-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-input-stream, "\"abc\" def")
|
||||
# . indices: 0123 45
|
||||
# . . push args
|
||||
68/push "\"abc\" def"/imm32
|
||||
68/push _test-input-stream/imm32
|
||||
# . . call
|
||||
e8/call write/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
|
||||
# precondition: line->read == 0
|
||||
# . . push args
|
||||
68/push "F - test-skip-string/precondition"/imm32
|
||||
68/push 0/imm32
|
||||
b8/copy-to-EAX _test-input-stream/imm32
|
||||
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 4/disp8 . # push *(EAX+4)
|
||||
# . . call
|
||||
e8/call check-ints-equal/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
|
||||
# skip-string(_test-input-stream)
|
||||
# . . push args
|
||||
68/push _test-input-stream/imm32
|
||||
# . . call
|
||||
e8/call skip-string/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
|
||||
# check-ints-equal(line->read, 5, msg)
|
||||
# . . push args
|
||||
68/push "F - test-skip-string"/imm32
|
||||
68/push 5/imm32
|
||||
b8/copy-to-EAX _test-input-stream/imm32
|
||||
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 4/disp8 . # push *(EAX+4)
|
||||
# . . 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-skip-string-ignores-spaces:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
# setup
|
||||
# . clear-stream(_test-input-stream)
|
||||
# . . push args
|
||||
68/push _test-input-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-input-stream, "\"a b\"/yz")
|
||||
# . indices: 0123 45
|
||||
# . . push args
|
||||
68/push "\"a b\"/yz"/imm32
|
||||
68/push _test-input-stream/imm32
|
||||
# . . call
|
||||
e8/call write/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
|
||||
# precondition: line->read == 0
|
||||
# . . push args
|
||||
68/push "F - test-skip-string-ignores-spaces/precondition"/imm32
|
||||
68/push 0/imm32
|
||||
b8/copy-to-EAX _test-input-stream/imm32
|
||||
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 4/disp8 . # push *(EAX+4)
|
||||
# . . call
|
||||
e8/call check-ints-equal/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
|
||||
# skip-string(_test-input-stream)
|
||||
# . . push args
|
||||
68/push _test-input-stream/imm32
|
||||
# . . call
|
||||
e8/call skip-string/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
|
||||
# check-ints-equal(line->read, 5, msg)
|
||||
# . . push args
|
||||
68/push "F - test-skip-string-ignores-spaces"/imm32
|
||||
68/push 5/imm32
|
||||
b8/copy-to-EAX _test-input-stream/imm32
|
||||
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 4/disp8 . # push *(EAX+4)
|
||||
# . . 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-skip-string-ignores-escapes:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
# setup
|
||||
# . clear-stream(_test-input-stream)
|
||||
# . . push args
|
||||
68/push _test-input-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-input-stream, "\"a\\\"b\"/yz")
|
||||
# . indices: 01 2 34 56
|
||||
# . . push args
|
||||
68/push "\"a\\\"b\"/yz"/imm32
|
||||
68/push _test-input-stream/imm32
|
||||
# . . call
|
||||
e8/call write/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
|
||||
# precondition: line->read == 0
|
||||
# . . push args
|
||||
68/push "F - test-skip-string-ignores-escapes/precondition"/imm32
|
||||
68/push 0/imm32
|
||||
b8/copy-to-EAX _test-input-stream/imm32
|
||||
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 4/disp8 . # push *(EAX+4)
|
||||
# . . call
|
||||
e8/call check-ints-equal/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
|
||||
# skip-string(_test-input-stream)
|
||||
# . . push args
|
||||
68/push _test-input-stream/imm32
|
||||
# . . call
|
||||
e8/call skip-string/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
|
||||
# check-ints-equal(line->read, 6, msg)
|
||||
# . . push args
|
||||
68/push "F - test-skip-string-ignores-escapes"/imm32
|
||||
68/push 6/imm32
|
||||
b8/copy-to-EAX _test-input-stream/imm32
|
||||
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 4/disp8 . # push *(EAX+4)
|
||||
# . . 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-skip-string-works-from-mid-stream:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
# setup
|
||||
# . clear-stream(_test-input-stream)
|
||||
# . . push args
|
||||
68/push _test-input-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-input-stream, "0 \"a\\\"b\"/yz")
|
||||
# . indices: 01 2 34 56
|
||||
# . . push args
|
||||
68/push "0 \"a\\\"b\"/yz"/imm32
|
||||
68/push _test-input-stream/imm32
|
||||
# . . call
|
||||
e8/call write/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
|
||||
# precondition: line->read == 2
|
||||
c7 0/subop/copy 1/mod/*+disp8 0/rm32/EAX . . . . 4/disp8 2/imm32 # copy to *(EAX+4)
|
||||
# skip-string(_test-input-stream)
|
||||
# . . push args
|
||||
68/push _test-input-stream/imm32
|
||||
# . . call
|
||||
e8/call skip-string/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
|
||||
# check-ints-equal(line->read, 8, msg)
|
||||
# . . push args
|
||||
68/push "F - test-skip-string-works-from-mid-stream"/imm32
|
||||
68/push 8/imm32
|
||||
b8/copy-to-EAX _test-input-stream/imm32
|
||||
ff 6/subop/push 1/mod/*+disp8 0/rm32/EAX . . . . 4/disp8 . # push *(EAX+4)
|
||||
# . . 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
|
||||
|
||||
skip-string-in-slice: # curr : (address byte), end : (address byte) -> new_curr/EAX
|
||||
# . 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
|
||||
53/push-EBX
|
||||
# ECX = curr
|
||||
8b/copy 1/mod/*+disp8 5/rm32/EBP . . 1/r32/ECX 8/disp8 . # copy *(EBP+8) to ECX
|
||||
# EDX = end
|
||||
8b/copy 1/mod/*+disp8 5/rm32/EBP . . 2/r32/EDX 0xc/disp8 . # copy *(EBP+12) to EDX
|
||||
# EAX = 0
|
||||
31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX
|
||||
# skip initial dquote
|
||||
41/increment-ECX
|
||||
$skip-string-in-slice:loop:
|
||||
# if (curr >= end) return curr
|
||||
39/compare 3/mod/direct 1/rm32/ECX . . . 2/r32/EDX . . # compare ECX with EDX
|
||||
73/jump-if-greater-unsigned-or-equal $skip-string-in-slice:return-curr/disp8
|
||||
# AL = *curr
|
||||
8a/copy-byte 0/mod/indirect 1/rm32/ECX . . . 0/r32/AL . . # copy byte at *ECX to AL
|
||||
$skip-string-in-slice:dquote:
|
||||
# if (EAX == '"') break
|
||||
3d/compare-EAX-and 0x22/imm32/double-quote
|
||||
74/jump-if-equal $skip-string-in-slice:break/disp8
|
||||
$skip-string-in-slice:check-for-escape:
|
||||
# if (EAX == '\') escape next char
|
||||
3d/compare-EAX-and 0x5c/imm32/backslash
|
||||
75/jump-if-not-equal $skip-string-in-slice:continue/disp8
|
||||
$skip-string-in-slice:escape:
|
||||
41/increment-ECX
|
||||
$skip-string-in-slice:continue:
|
||||
# ++curr
|
||||
41/increment-ECX
|
||||
eb/jump $skip-string-in-slice:loop/disp8
|
||||
$skip-string-in-slice:break:
|
||||
# skip final dquote
|
||||
41/increment-ECX
|
||||
$skip-string-in-slice:return-curr:
|
||||
# return curr
|
||||
89/copy 3/mod/direct 0/rm32/EAX . . . 1/r32/ECX . . # copy ECX to EAX
|
||||
$skip-string-in-slice:end:
|
||||
# . restore registers
|
||||
5b/pop-to-EBX
|
||||
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-skip-string-in-slice:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
# setup: (EAX..ECX) = "\"abc\" def"
|
||||
b8/copy-to-EAX "\"abc\" def"/imm32
|
||||
8b/copy 0/mod/indirect 0/rm32/EAX . . . 1/r32/ECX . . # copy *EAX to ECX
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/EAX 1/index/ECX . 1/r32/ECX 4/disp8 . # copy EAX+ECX+4 to ECX
|
||||
05/add-to-EAX 4/imm32
|
||||
# EAX = skip-string-in-slice(EAX, ECX)
|
||||
# . . push args
|
||||
51/push-ECX
|
||||
50/push-EAX
|
||||
# . . call
|
||||
e8/call skip-string-in-slice/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
|
||||
# check-ints-equal(ECX-EAX, 4, msg) # number of chars remaining after the string literal
|
||||
# . . push args
|
||||
68/push "F - test-skip-string-in-slice"/imm32
|
||||
68/push 4/imm32
|
||||
# . . push ECX-EAX
|
||||
29/subtract 3/mod/direct 1/rm32/ECX . . . 0/r32/EAX . . # subtract EAX from ECX
|
||||
51/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
|
||||
# . epilog
|
||||
89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP
|
||||
5d/pop-to-EBP
|
||||
c3/return
|
||||
|
||||
test-skip-string-in-slice-ignores-spaces:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
# setup: (EAX..ECX) = "\"a b\"/yz"
|
||||
b8/copy-to-EAX "\"a b\"/yz"/imm32
|
||||
8b/copy 0/mod/indirect 0/rm32/EAX . . . 1/r32/ECX . . # copy *EAX to ECX
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/EAX 1/index/ECX . 1/r32/ECX 4/disp8 . # copy EAX+ECX+4 to ECX
|
||||
05/add-to-EAX 4/imm32
|
||||
# EAX = skip-string-in-slice(EAX, ECX)
|
||||
# . . push args
|
||||
51/push-ECX
|
||||
50/push-EAX
|
||||
# . . call
|
||||
e8/call skip-string-in-slice/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
|
||||
# check-ints-equal(ECX-EAX, 3, msg) # number of chars remaining after the string literal
|
||||
# . . push args
|
||||
68/push "F - test-skip-string-in-slice-ignores-spaces"/imm32
|
||||
68/push 3/imm32
|
||||
# . . push ECX-EAX
|
||||
29/subtract 3/mod/direct 1/rm32/ECX . . . 0/r32/EAX . . # subtract EAX from ECX
|
||||
51/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
|
||||
# . epilog
|
||||
89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP
|
||||
5d/pop-to-EBP
|
||||
c3/return
|
||||
|
||||
test-skip-string-in-slice-ignores-escapes:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
# setup: (EAX..ECX) = "\"a\\\"b\"/yz"
|
||||
b8/copy-to-EAX "\"a\\\"b\"/yz"/imm32
|
||||
8b/copy 0/mod/indirect 0/rm32/EAX . . . 1/r32/ECX . . # copy *EAX to ECX
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/EAX 1/index/ECX . 1/r32/ECX 4/disp8 . # copy EAX+ECX+4 to ECX
|
||||
05/add-to-EAX 4/imm32
|
||||
# EAX = skip-string-in-slice(EAX, ECX)
|
||||
# . . push args
|
||||
51/push-ECX
|
||||
50/push-EAX
|
||||
# . . call
|
||||
e8/call skip-string-in-slice/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
|
||||
# check-ints-equal(ECX-EAX, 3, msg) # number of chars remaining after the string literal
|
||||
# . . push args
|
||||
68/push "F - test-skip-string-in-slice-ignores-escapes"/imm32
|
||||
68/push 3/imm32
|
||||
# . . push ECX-EAX
|
||||
29/subtract 3/mod/direct 1/rm32/ECX . . . 0/r32/EAX . . # subtract EAX from ECX
|
||||
51/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
|
||||
# . epilog
|
||||
89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP
|
||||
5d/pop-to-EBP
|
||||
c3/return
|
||||
|
||||
test-skip-string-in-slice-stops-at-end:
|
||||
# . prolog
|
||||
55/push-EBP
|
||||
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
|
||||
# setup: (EAX..ECX) = "\"abc" # unbalanced dquote
|
||||
b8/copy-to-EAX "\"abc"/imm32
|
||||
8b/copy 0/mod/indirect 0/rm32/EAX . . . 1/r32/ECX . . # copy *EAX to ECX
|
||||
8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/EAX 1/index/ECX . 1/r32/ECX 4/disp8 . # copy EAX+ECX+4 to ECX
|
||||
05/add-to-EAX 4/imm32
|
||||
# EAX = skip-string-in-slice(EAX, ECX)
|
||||
# . . push args
|
||||
51/push-ECX
|
||||
50/push-EAX
|
||||
# . . call
|
||||
e8/call skip-string-in-slice/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
|
||||
# check-ints-equal(ECX-EAX, 0, msg) # skipped to end of slice
|
||||
# . . push args
|
||||
68/push "F - test-skip-string-in-slice-stops-at-end"/imm32
|
||||
68/push 0/imm32
|
||||
# . . push ECX-EAX
|
||||
29/subtract 3/mod/direct 1/rm32/ECX . . . 0/r32/EAX . . # subtract EAX from ECX
|
||||
51/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
|
||||
# . epilog
|
||||
89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP
|
||||
5d/pop-to-EBP
|
||||
c3/return
|
||||
|
||||
# write an entire stream's contents to a buffered-file
|
||||
# ways to do this:
|
||||
# - construct a 'maximal slice' and pass it to write-slice-buffered
|
||||
|
|
BIN
apps/survey
BIN
apps/survey
Binary file not shown.
BIN
apps/tests
BIN
apps/tests
Binary file not shown.
Loading…
Reference in New Issue