ReC98/libs/BorlandC/scanner.asm

761 lines
12 KiB
NASM

ScanNextArgPointer macro
call scn_NextArgPtr
ifdef __HUGE__
jnc $+5
jmp scn_END
endif
endm
scn_pushSrceP macro
if LDATA
push word ptr [bp+@@srceP+2]
endif
push word ptr [bp+@@srceP]
endm
; int __cdecl scanner(int (__cdecl __near near *Get)(), void (__cdecl __near near *UnGet)(), void *srceP, const char *formP, va_list varPP)
_scanner proc near
@@bitSet = byte ptr -2Ah
@@width = word ptr -0Ah
@@status = word ptr -8
@@charCt = word ptr -6
@@count = word ptr -4
@@flags = byte ptr -1
@@Get = word ptr 4
@@UnGet = word ptr 6
@@srceP = DPTR_ (8)
@@formP = DPTR_ (8 + dPtrSize)
@@varPP = DPTR_ (8 + dPtrSize + dPtrSize)
push bp
mov bp, sp
sub sp, 2Ah
push si
push di
mov [bp+@@count], 0
mov [bp+@@charCt], 0
jmp short RealCodeStart
scn_NextArgPtr:
LES_ di, [bp+@@varPP]
test [bp+@@flags], isFarPtr
jz short scn_nextNear
les di, ES_[di]
add word ptr [bp+@@varPP], 4
ifdef __HUGE__
clc
endif
retn
scn_nextNear:
ifdef __HUGE__
stc
else
mov di, ES_[di]
push ds
pop es
assume es:dseg
add word ptr [bp+@@varPP], 2
endif
ret
RealCodeStart:
push es
cld
scn_NEXT:
mov si, word ptr [bp+@@formP]
scn_nextChar:
if LDATA
mov es, word ptr [bp+@@formP+2]
endif
assume es:nothing
lods byte ptr ES_[si]
or al, al
jz short scn_respondJmp
cmp al, '%'
jz short scn_CONV
scn_percent:
xor ah, ah
xchg ax, di
inc [bp+@@charCt]
scn_pushSrceP
call [bp+@@Get]
popCX_
pop cx
or ax, ax
jl short scn_EOFjmp
xor ah, ah
test di, 80h
jnz short scn_mustMatch
cmp scanCtype[di], 1
jnz short scn_mustMatch
scn_matchSpace:
xchg ax, bx
or bl, bl
js short scn_spaceEnded
cmp scanCtype[bx], 1
jnz short scn_spaceEnded
inc [bp+@@charCt]
scn_pushSrceP
call [bp+@@Get]
popCX_
pop cx
or ax, ax
jg short scn_matchSpace
scn_EOFjmp:
jmp scn_EOF
scn_spaceEnded:
scn_pushSrceP
push bx
call [bp+@@UnGet]
add sp, 2 + dPtrSize
dec [bp+@@charCt]
jmp short scn_nextChar
scn_mustMatch:
cmp ax, di
jz short scn_nextChar
scn_pushSrceP
push ax
call [bp+@@UnGet]
add sp, 2 + dPtrSize
dec [bp+@@charCt]
jmp scn_END
scn_respondJmp:
jmp scn_END
scn_CONV:
mov [bp+@@width], -1
if LDATA
mov es, word ptr [bp+@@formP+2]
mov [bp+@@flags], isFarPtr
else
mov [bp+@@flags], 0
endif
scn_convNext:
lods byte ptr ES_[si]
xor ah, ah
mov word ptr [bp+@@formP], si
or al, al
xchg ax, di
jl short scn_anyOther
mov bl, scanCtype[di]
xor bh, bh
cmp bx, 15h
jbe short scn_switch
jmp scn_EOF
scn_switch:
add bx, bx
jmp cs:scn_table[bx]
scn_case_pc:
xchg ax, di
jmp scn_percent
scn_anyOther:
jmp scn_END
scn_case_su:
or [bp+@@flags], isSuppressed
jmp short scn_convNext
scn_case_nu:
sub di, '0'
xchg di, [bp+@@width]
or di, di
jl short scn_convNext
mov ax, 10
mul di
add [bp+@@width], ax
jmp short scn_convNext
scn_case_ld:
or [bp+@@flags], isLongDouble
jmp short scn_convNext
scn_case_lo:
or [bp+@@flags], isLong
jmp short scn_convNext
scn_case_ha:
or [bp+@@flags], isHalf
jmp short scn_convNext
scn_case_ne:
and [bp+@@flags], not isFarPtr
jmp short scn_convNext
scn_case_fa:
or [bp+@@flags], isFarPtr
jmp short scn_convNext
scn_case_ct:
mov ax, [bp+@@charCt]
sub dx, dx
test [bp+@@flags], isSuppressed
jz short scn_PUTINT
jmp scn_NEXT
scn_case_oc:
mov si, 8
jmp short scn_INT
scn_case_un_de:
mov si, 10
jmp short scn_INT
scn_case_he:
mov si, 16
jmp short scn_INT
scn_case_in:
xor si, si
scn_INT:
test di, 20h
jnz short scn_scantol
cmp di, 'X'
jz short scn_scantol
or [bp+@@flags], isLong
scn_scantol:
pushSS_
lea ax, [bp+@@status]
push ax
pushSS_
lea ax, [bp+@@charCt]
push ax
mov ax, [bp+@@width]
and ax, 7FFFh
push ax
push si
scn_pushSrceP
push [bp+@@UnGet]
push [bp+@@Get]
call __scantol
add sp, 8 + (dPtrSize * 3)
cmp [bp+@@status], 0
jle short scn_intEnd
test [bp+@@flags], isSuppressed
jnz short scn_intUpdated
inc [bp+@@count]
scn_PUTINT:
ScanNextArgPointer
stosw
test [bp+@@flags], isLong
jz short scn_intUpdated
xchg ax, dx
stosw
scn_intUpdated:
jmp scn_NEXT
scn_intEnd:
jl short scn_intEOF
jmp scn_END
scn_intEOF:
jmp scn_EOF
scn_case_pt:
call $+3
jmp scn_SkipSpace
scn_pushSrceP
push ax
call [bp+@@UnGet]
add sp, 2 + dPtrSize
dec [bp+@@charCt]
and [bp+@@width], 7FFFh
call $+3
jmp scn_InHex4
push dx
cmp al, ':'
jz short scn_ptrLSW
or ax, ax
jle short scn_noLookAhead
scn_pushSrceP
push ax
call [bp+@@UnGet]
add sp, 2 + dPtrSize
dec [bp+@@charCt]
scn_noLookAhead:
pop dx
mov bx, ds
jmp short scn_pointerReady
scn_ptrLSW:
call $+3
jmp scn_InHex4
pop bx
or ax, ax
jle short scn_pointerReady
push dx
push bx
scn_pushSrceP
push ax
call [bp+@@UnGet]
add sp, 2 + dPtrSize
dec [bp+@@charCt]
pop bx
pop dx
scn_pointerReady:
test [bp+@@flags], isSuppressed
jnz short scn_ptrUpdated
ScanNextArgPointer
inc [bp+@@count]
xchg ax, dx
stosw
test [bp+@@flags], isFarPtr
jz short scn_ptrUpdated
xchg ax, bx
stosw
scn_ptrUpdated:
jmp scn_NEXT
scn_jmpEOF:
jmp scn_EOF
scn_case_fl:
pushSS_
lea ax, [bp+@@status]
push ax
pushSS_
lea ax, [bp+@@charCt]
push ax
mov ax, 7FFFh
and ax, [bp+@@width]
push ax
scn_pushSrceP
push [bp+@@UnGet]
push [bp+@@Get]
call _scantod
add sp, (3 * dPtrSize) + 2 + (2 * 2)
cmp [bp+@@status], 0
jle short scn_endFloat
mov al, [bp+@@flags]
cbw
test al, isSuppressed
jnz short scn_popFloat
ScanNextArgPointer
inc [bp+@@count]
test [bp+@@flags], isLong
jz short test_longDOuble
mov ax, isLong
jmp short push_type
test_longDOuble:
test [bp+@@flags], isLongDouble
jz short its_default_float
mov ax, isLongDouble
jmp short push_type
its_default_float:
xor ax, ax
push_type:
push ax
test [bp+@@flags], isFarPtr
jz short push_far
push es
jmp short scn_scanrslt
push_far:
push ds
scn_scanrslt:
push di
call _scanrslt
add sp, 6
jmp scn_NEXT
scn_popFloat:
call _scanpop
jmp scn_NEXT
scn_endFloat:
call _scanpop
jl short scn_jmpEOF
jmp scn_END
scn_case_st:
call $+3
jmp scn_SkipSpace
test [bp+@@flags], isSuppressed
jnz short scn_tokenWidth
ScanNextArgPointer
inc [bp+@@count]
scn_tokenWidth:
and [bp+@@width], 7FFFh
jz short scn_tokenEnd
scn_whileToken:
test [bp+@@flags], isSuppressed
jnz short scn_tokenNextCh
stosb
scn_tokenNextCh:
inc [bp+@@charCt]
push es
scn_pushSrceP
call [bp+@@Get]
popCX_
pop cx
pop es
or ax, ax
jle short scn_tokenEnd
or al, al
js short scn_isToken
xchg ax, bx
cmp scanCtype[bx], 1
xchg ax, bx
jle short scn_tokenEnd
scn_isToken:
dec [bp+@@width]
jg short scn_whileToken
scn_tokenEnd:
push es
scn_pushSrceP
push ax
call [bp+@@UnGet]
add sp, 2 + dPtrSize
pop es
dec [bp+@@charCt]
test [bp+@@flags], isSuppressed
jnz short scn_tokenUpdated
mov al, 0
stosb
scn_tokenUpdated:
jmp scn_NEXT
scn_case_ch:
test [bp+@@flags], isSuppressed
jnz short scn_checkWidth
ScanNextArgPointer
scn_checkWidth:
mov si, [bp+@@width]
or si, si
jge short scn_charWidened
mov si, 1
scn_charWidened:
jz short scn_charEnd
scn_charLoop:
inc [bp+@@charCt]
push es
scn_pushSrceP
call [bp+@@Get]
popCX_
pop cx
pop es
or ax, ax
jl short scn_charEOF
test [bp+@@flags], isSuppressed
jnz short scn_charNoPut
stosb
scn_charNoPut:
dec si
jg short scn_charLoop
scn_charEnd:
test [bp+@@flags], isSuppressed
jnz short scn_charNext
inc [bp+@@count]
scn_charNext:
jmp scn_NEXT
scn_charEOF:
jmp scn_EOF
scn_case_sc:
if LDATA
push es
endif
sub ax, ax
cld
push ss
pop es
lea di, [bp+@@bitSet]
mov cx, 16
rep stosw
if LDATA
pop es
endif
lods byte ptr ES_[si]
and [bp+@@flags], not isExclusive
cmp al, '^'
jnz short scn_scanInc
or [bp+@@flags], isExclusive
lods byte ptr ES_[si]
scn_scanInc:
mov ah, 0
scn_scanSetBit:
mov dl, al
mov di, ax
mov cl, 3
shr di, cl
mov cx, 107h
and cl, dl
shl ch, cl
or [bp+di+@@bitSet], ch
scn_setNext:
lods byte ptr ES_[si]
cmp al, 0
jz short scn_scanOpen
cmp al, ']'
jz short scn_scanBounded
cmp al, '-'
jnz short scn_scanSetBit
cmp dl, ES_[si]
ja short scn_scanSetBit
cmp byte ptr ES_[si], ']'
jz short scn_scanSetBit
lods byte ptr ES_[si]
sub al, dl
jz short scn_setNext
add dl, al
scn_setRange:
rol ch, 1
adc di, 0
or [bp+di+@@bitSet], ch
dec al
jnz short scn_setRange
jmp short scn_setNext
scn_scanOpen:
jmp scn_END
scn_scanBounded:
mov word ptr [bp+@@formP], si
and [bp+@@width], 7FFFh
mov si, [bp+@@width]
test [bp+@@flags], isSuppressed
jnz short scn_scanLoop
ScanNextArgPointer
scn_scanLoop:
dec si
jl short scn_scanLimited
inc [bp+@@charCt]
push es
scn_pushSrceP
call [bp+@@Get]
popCX_
pop cx
pop es
or ax, ax
jl short scn_scanEOF
xchg ax, si
mov bx, si
mov cl, 3
shr si, cl
mov cx, 107h
and cl, bl
shl ch, cl
test [bp+si+@@bitSet], ch
xchg ax, si
xchg ax, bx
jz short scn_scanNotIn
test [bp+@@flags], isExclusive
jz short scn_scanAccept
jmp short scn_scanTerminate
scn_scanNotIn:
test [bp+@@flags], isExclusive
jz short scn_scanTerminate
scn_scanAccept:
test [bp+@@flags], isSuppressed
jnz short scn_scanLoop
stosb
jmp short scn_scanLoop
scn_scanTerminate:
push es
scn_pushSrceP
push ax
call [bp+@@UnGet]
add sp, 2 + dPtrSize
pop es
dec [bp+@@charCt]
inc si
cmp si, [bp+@@width]
jge short scn_scanEND
scn_scanLimited:
test [bp+@@flags], isSuppressed
jnz short scn_scanUpdated
inc [bp+@@count]
scn_scanEND:
test [bp+@@flags], isSuppressed
jnz short scn_scanUpdated
mov al, 0
stosb
scn_scanUpdated:
jmp scn_NEXT
scn_scanEOF:
inc si
cmp si, [bp+@@width]
jge short scn_EOF
test [bp+@@flags], isSuppressed
jnz short scn_EOF
mov al, 0
stosb
inc [bp+@@count]
scn_EOF:
scn_pushSrceP
mov ax, EOF
push ax
call [bp+@@UnGet]
add sp, 2 + dPtrSize
cmp [bp+@@count], 1
sbb [bp+@@count], 0
scn_END:
pop es
mov ax, [bp+@@count]
jmp scn_ret
scn_SkipSpace:
inc [bp+@@charCt]
scn_pushSrceP
call [bp+@@Get]
popCX_
pop cx
or ax, ax
jle short scn_skipEOF
or al, al
js short scn_skipEnd
xchg ax, bx
cmp scanCtype[bx], 1
xchg ax, bx
jz short scn_SkipSpace
scn_skipEnd:
pop cx
add cx, 3
jmp cx
scn_skipEOF:
jz short scn_skipEnd
pop cx
jmp short scn_EOF
scn_InHex4:
sub dx, dx
mov cx, 4
scn_h4loop:
dec [bp+@@width]
jl short scn_h4limited
push dx
push cx
inc [bp+@@charCt]
scn_pushSrceP
call [bp+@@Get]
popCX_
pop cx
pop cx
pop dx
or ax, ax
jle short scn_h4end
dec cl
jl short scn_h4end
mov ch, al
sub ch, '0'
jb short scn_h4end
cmp ch, 10
jb short scn_h4isDigit
sub ch, 'A' - '0'
jb short scn_h4end
cmp ch, 6
jb short scn_h4isHex
sub ch, 'a' - 'A'
jb short scn_h4end
cmp ch, 6
jnb short scn_h4end
scn_h4isHex:
add ch, 10
scn_h4isDigit:
shl dx, 1
shl dx, 1
shl dx, 1
shl dx, 1
add dl, ch
jmp short scn_h4loop
scn_h4limited:
sub ax, ax
scn_h4end:
cmp cl, 4
jz short scn_h4eof
pop cx
add cx, 3
jmp cx
scn_h4eof:
pop cx
jmp scn_EOF
scn_ret:
pop di
pop si
mov sp, bp
pop bp
ret
_scanner endp
scn_table dw offset scn_END
dw offset scn_END
dw offset scn_END
dw offset scn_case_pc
dw offset scn_case_su
dw offset scn_case_nu
dw offset scn_case_ch
dw offset scn_case_un_de
dw offset scn_case_un_de
dw offset scn_case_in
dw offset scn_case_fl
dw offset scn_case_ld
dw offset scn_case_ha
dw offset scn_case_lo
dw offset scn_case_oc
dw offset scn_case_st
dw offset scn_case_sc
dw offset scn_case_ct
dw offset scn_case_he
dw offset scn_case_pt
dw offset scn_case_ne
dw offset scn_case_fa