couple of helpers for parsing expressions in parens
This commit is contained in:
parent
db1874cae2
commit
ab87ccf62e
BIN
apps/desugar
BIN
apps/desugar
Binary file not shown.
|
@ -792,6 +792,336 @@ test-emit-indirect-mode-2:
|
|||
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-until-close-paren: # 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-until-close-paren-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-until-close-paren-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-until-close-paren: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-until-close-paren:
|
||||
# . 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-until-close-paren/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-until-close-paren(_test-input-stream)
|
||||
# . . push args
|
||||
68/push _test-input-stream/imm32
|
||||
# . . call
|
||||
e8/call skip-until-close-paren/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-until-close-paren"/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-until-close-paren-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")
|
||||
# . . 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-until-close-paren-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-until-close-paren(_test-input-stream)
|
||||
# . . push args
|
||||
68/push _test-input-stream/imm32
|
||||
# . . call
|
||||
e8/call skip-until-close-paren/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-until-close-paren-ignores-spaces"/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-until-close-paren-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")
|
||||
# . . 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: _test-input-stream->read == 2
|
||||
c7 0/subop/copy 1/mod/*+disp8 0/rm32/EAX . . . . 4/disp8 2/imm32 # copy to *(EAX+4)
|
||||
# skip-until-close-paren(_test-input-stream)
|
||||
# . . push args
|
||||
68/push _test-input-stream/imm32
|
||||
# . . call
|
||||
e8/call skip-until-close-paren/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
|
||||
# check-ints-equal(_test-input-stream->read, 8, msg)
|
||||
# . . push args
|
||||
68/push "F - test-skip-until-close-paren-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-until-close-paren-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
|
||||
# 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-until-close-paren-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-until-close-paren-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-until-close-paren-in-slice:check-close:
|
||||
# if (EAX == ')') break
|
||||
3d/compare-EAX-and 0x29/imm32/close-paren
|
||||
74/jump-if-equal $skip-until-close-paren-in-slice:break/disp8
|
||||
# ++curr
|
||||
41/increment-ECX
|
||||
eb/jump $skip-until-close-paren-in-slice:loop/disp8
|
||||
$skip-until-close-paren-in-slice:break:
|
||||
# skip close-paren itself
|
||||
41/increment-ECX
|
||||
$skip-until-close-paren-in-slice:return-curr:
|
||||
# return curr
|
||||
89/copy 3/mod/direct 0/rm32/EAX . . . 1/r32/ECX . . # copy ECX to EAX
|
||||
$skip-until-close-paren-in-slice:end:
|
||||
# . restore registers
|
||||
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-until-close-paren-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-until-close-paren-in-slice(EAX, ECX)
|
||||
# . . push args
|
||||
51/push-ECX
|
||||
50/push-EAX
|
||||
# . . call
|
||||
e8/call skip-until-close-paren-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-until-close-paren-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-until-close-paren-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-until-close-paren-in-slice(EAX, ECX)
|
||||
# . . push args
|
||||
51/push-ECX
|
||||
50/push-EAX
|
||||
# . . call
|
||||
e8/call skip-until-close-paren-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-until-close-paren-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-until-close-paren-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-until-close-paren-in-slice(EAX, ECX)
|
||||
# . . push args
|
||||
51/push-ECX
|
||||
50/push-EAX
|
||||
# . . call
|
||||
e8/call skip-until-close-paren-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-until-close-paren-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
|
||||
|
||||
== data
|
||||
Registers: # (table string int)
|
||||
# a table is a stream
|
||||
|
|
Loading…
Reference in New Issue
Block a user