kolibrios/programs/develop/koldbg/parser.inc

397 lines
8.7 KiB
PHP
Raw Normal View History

;-----------------------------------------------------------------------------
TokenEnd = 1
TokenReg = 2
TokenHex = 3
TokenOr = 4
TokenAnd = 5
TokenXor = 6
TokenAdd = 7
TokenSub = 8
TokenMul = 9
TokenDiv = 10
TokenLP = 11
TokenRP = 12
TokenErr = -1
;-----------------------------------------------------------------------------
RegTable:
db 2,'al',0
db 2,'cl',1
db 2,'dl',2
db 2,'bl',3
db 2,'ah',4
db 2,'ch',5
db 2,'dh',6
db 2,'bh',7
db 2,'ax',8
db 2,'cx',9
db 2,'dx',10
db 2,'bx',11
db 2,'sp',12
db 2,'bp',13
db 2,'si',14
db 2,'di',15
db 3,'eax',16
db 3,'ecx',17
db 3,'edx',18
db 3,'ebx',19
db 3,'esp',20
db 3,'ebp',21
db 3,'esi',22
db 3,'edi',23
db 3,'eip',24
db 0
;-----------------------------------------------------------------------------
; Check if byte is hex digit
IsHexDigit:
cmp al,'0'
jb .No
cmp al,'9'
jbe .09
cmp al,'A'
jb .No
cmp al,'F'
jbe .AF
cmp al,'a'
jb .No
cmp al,'f'
jbe .FA
.No:
stc
ret
.09:
sub al,'0'
; clc
ret
.AF:
sub al,'A'-10
; clc
ret
.FA:
sub al,'a'-10
; clc
ret
;-----------------------------------------------------------------------------
; Find register in the table
FindReg:
mov edi,RegTable
.FindReg:
movzx ecx,byte [edi]
stc
jecxz .RegNotFound
inc edi
push esi edi ecx
@@:
lodsb
or al,20h
scasb
loopz @B
pop ecx edi esi
lea edi,[edi+ecx+1]
jnz .FindReg
movzx edi,byte [edi-1]
add esi,ecx
.RegNotFound:
ret
;-----------------------------------------------------------------------------
; Tokenize expressions
ExprGetToken:
lodsb
cmp al,0
jz .EndToken
cmp al,' '
jbe ExprGetToken
cmp al,'|'
jz .Or
cmp al,'&'
jz .And
cmp al,'^'
jz .Xor
cmp al,'+'
jz .Add
cmp al,'-'
jz .Sub
cmp al,'*'
jz .Mul
cmp al,'/'
jz .Div
cmp al,'('
jz .LP
cmp al,')'
jnz .NotSign
.RP:
mov al,TokenRP
ret
.Or:
mov al,TokenOr
ret
.And:
mov al,TokenAnd
ret
.Xor:
mov al,TokenXor
ret
.Div:
mov al,TokenDiv
ret
.EndToken:
mov al,TokenEnd
ret
.Add:
mov al,TokenAdd
ret
.Sub:
mov al,TokenSub
ret
.Mul:
mov al,TokenMul
ret
.LP:
mov al,TokenLP
ret
.NotSign:
dec esi
call FindReg
jc .RegNotFound
mov al,TokenReg
ret
.RegNotFound:
; test for symbol
push esi
@@:
lodsb
cmp al,' '
ja @B
push eax
mov byte [esi],0
xchg esi,[esp+4]
call FindSymbolName
mov edi,eax
pop eax
xchg esi,[esp]
mov byte [esi],al
jc @F
add esp,4
mov al,TokenHex
ret
@@:
pop esi
; test for hex number
xor ecx,ecx
xor edi,edi
xor eax,eax
@@:
lodsb
call IsHexDigit
jc @F
shl edi,4
or edi,eax
inc ecx
jmp @B
@@:
dec esi
jecxz .Err
cmp ecx,8
ja .Err
mov al,TokenHex
ret
.Err:
mov al,TokenErr
mov esi,aParseError
ret
;-----------------------------------------------------------------------------
ExprRead2:
cmp al,TokenHex
jz .Hex
cmp al,TokenReg
jz .Reg
cmp al,TokenLP
jz .LP
mov al,TokenErr
mov esi,aParseError
ret
.Hex:
mov ebp,edi
.Ret:
jmp ExprGetToken
.Reg:
cmp edi,24
jz .EIP
sub edi,4
jb .8LO
sub edi,4
jb .8HI
sub edi,8
jb .16
mov ebp,[_EAX+edi*4]
jmp .Ret
.16:
movzx ebp,word [_EAX+(edi+8)*4]
jmp .Ret
.8LO:
movzx ebp,byte [_EAX+(edi+4)*4]
jmp .Ret
.8HI:
movzx ebp,byte [_EAX+(edi+4)*4+1]
jmp .Ret
.EIP:
mov ebp,[_EIP]
jmp .Ret
.LP:
call ExprGetToken
call ExprRead0
cmp al,TokenErr
jz @F
cmp al,TokenRP
jz ExprGetToken
mov al,TokenErr
mov esi,aParseError
@@:
ret
;-----------------------------------------------------------------------------
ExprRead1:
call ExprRead2
.1:
cmp al,TokenMul
jz .Mul
cmp al,TokenDiv
jz .Div
ret
.Mul:
push ebp
call ExprGetToken
call ExprRead2
pop edx
; ebp := edx*ebp
imul ebp,edx
jmp .1
.Div:
push ebp
call ExprGetToken
call ExprRead2
pop edx
; ebp := edx/ebp
test ebp,ebp
jz .Div0
push eax
xor eax,eax
xchg eax,edx
div ebp
xchg eax,ebp
pop eax
jmp .1
.Div0:
mov al,TokenErr
mov esi,aDivByZero
ret
;-----------------------------------------------------------------------------
ExprRead0:
xor ebp,ebp
cmp al,TokenOr
jz .Or
cmp al,TokenAnd
jz .And
cmp al,TokenXor
jz .Xor
cmp al,TokenAdd
jz .Add
cmp al,TokenSub
jz .Sub
call ExprRead1
.1:
cmp al,TokenOr
jz .Or
cmp al,TokenAnd
jz .And
cmp al,TokenXor
jz .Xor
cmp al,TokenAdd
jz .Add
cmp al,TokenSub
jz .Sub
ret
.Or:
push ebp
call ExprGetToken
call ExprRead1
pop edx
; ebp := edx | ebp
or ebp,edx
jmp .1
.And:
push ebp
call ExprGetToken
call ExprRead1
pop edx
; ebp := edx & ebp
and ebp,edx
jmp .1
.Xor:
push ebp
call ExprGetToken
call ExprRead1
pop edx
; ebp := edx ^ ebp
xor ebp,edx
jmp .1
.Add:
push ebp
call ExprGetToken
call ExprRead1
pop edx
; ebp := edx+ebp
add ebp,edx
jmp .1
.Sub:
push ebp
call ExprGetToken
call ExprRead1
pop edx
; ebp := edx-ebp
xchg edx,ebp
sub ebp,edx
jmp .1
;-----------------------------------------------------------------------------
; in: esi->expression
; out: CF=1 if error
; CF=0 and ebp=value if ok
CalcExpression:
call ExprGetToken
call ExprRead0
cmp al,TokenEnd
jz .End
cmp al,TokenErr
jz @F
mov esi,aParseError
@@:
call PutMessage
stc
ret
.End:
clc
ret
GetArg:
lodsb
cmp al,' '
ja GetArg
mov byte [esi-1],0
cmp al,0
jnz .SkipSpaces
dec esi
.SkipSpaces:
lodsb
cmp al,0
jz @F
cmp al,' '
jbe .SkipSpaces
@@:
dec esi
ret