Expression	proc	near
	call	CheckStack
	call	ClearSymbol
	call	Expr1
	cmp	[si].aType,tMEM
	jne	@@1
	test	[si].aRegs,rfInd
	jz	MemRefErr
@@1:	ret
Expression	endp

Expr1	proc	near
	call	Expr2
@@1:	lea	bx,@@5
	call	MatchToken
	jz	@@2
	call	NeedNumber
	call	AllocSymbol
	call	Expr2
	call	NeedNumber
	call	FreeSymbol
	mov	ax,[di].aValue.W0
	mov	cx,[di].aValue.W2
	call	bx
	add	sp,size TAsmSymbol
	jmp	@@1
@@2:	ret
@@3:	or	[si].aValue.W0,ax
	or	[si].aValue.W2,cx
	ret
@@4:	xor	[si].aValue.W0,ax
	xor	[si].aValue.W2,cx
	ret
@@5	db	tOR
	dw	@@3-@@5
	db	tXOR
	dw	@@4-@@5
	db	0
Expr1	endp

Expr2	proc	near
	call	Expr3
@@1:	mov	al,tAND
	call	CheckToken
	jz	@@2
	call	NeedNumber
	call	AllocSymbol
	call	Expr3
	call	NeedNumber
	call	FreeSymbol
	mov	ax,[di].aValue.W0
	and	[si].aValue.W0,ax
	mov	ax,[di].aValue.W2
	and	[si].aValue.W2,ax
	add	sp,size TAsmSymbol
	jmp	@@1
@@2:	ret
Expr2	endp

Expr3	proc	near
	call	CheckStack
	lea	bx,@@1
	call	MatchToken
	jz	Expr4
	call	Expr3
	call	NeedNumber
	not	[si].aValue.W0
	not	[si].aValue.W2
	mov	StringBuf[0],0
	ret
@@1	db	tNOT
	dw	0
	db	0
Expr3	endp

Expr4	proc	near
	call	Expr6
@@1:	lea	bx,@@5
	call	MatchToken
	jz	@@4
	call	AllocSymbol
	call	Expr6
	call	FreeSymbol
	call	bx
	add	sp,size TAsmSymbol
	jmp	@@1
@@2:	xchg	si,di
	call	NeedMemOrNum
	xchg	si,di
	neg	[di].aValue.W0
	adc	[di].aValue.W2,0
	neg	[di].aValue.W2
@@3:	call	AddSymbols
	mov	StringBuf[0],0
@@4:	ret
@@5	db	'+'
	dw	@@3-@@5
	db	'-'
	dw	@@2-@@5
	db	0
Expr4	endp

Expr6	proc	near
	call	Expr7
@@1:	lea	bx,@@12
	call	MatchToken
	jz	@@8
	call	NeedNumber
	call	AllocSymbol
	call	Expr7
	call	NeedNumber
	call	FreeSymbol
	push	dx
	mov	ax,[si].aValue.W0
	mov	dx,[si].aValue.W2
	mov	cx,[di].aValue.W0
	call	bx
	mov	[si].aValue.W0,ax
	mov	[si].aValue.W2,dx
	pop	dx
	add	sp,size TAsmSymbol
	jmp	@@1
@@2:	neg	cx
@@3:	and	cx,803fh
	js	@@5
	jz	@@8
@@4:	shr	dx,1
	rcr	ax,1
	loop	@@4
	ret
@@5:	neg	cx
	jo	@@8
@@6:	and	cx,803fh
	js	@@2
	jz	@@8
@@7:	shl	ax,1
	rcl	dx,1
	loop	@@7
@@8:	ret
@@9:	mov	bx,[di].aValue.W2
	jmp	LongMul
@@10:	mov	bx,[di].aValue.W2
	jmp	LongDiv
@@11:	call	@@10
	xchg	ax,cx
	xchg	dx,bx
	ret
@@12	db	'*'
	dw	@@9-@@12
	db	'/'
	dw	@@10-@@12
	db	tMOD
	dw	@@11-@@12
	db	tSHR
	dw	@@3-@@12
	db	tSHL
	dw	@@6-@@12
	db	0
Expr6	endp

Expr7	proc	near
@@1:	call	CheckStack
	lea	bx,@@9
	call	MatchToken
	jz	@@2
	push	bx
	call	ClearSymbol
	jmp	@@1
@@2:	call	Expr8
	mov	al,tPTR
	call	CheckToken
	jnz	@@3
	cmp	[si].aRegNum.B0,szSreg
	jne	@@4
	cmp	[si].aType,tREG
	jne	@@4
	mov	al,':'
	call	CheckToken
	jz	@@4
	push	word ptr [si].aRegNum.B1
	call	ClearSymbol
	call	Expr7
	pop	ax
	mov	cl,3
	shl	al,cl
	or	al,26h
	mov	[si].aSeg,al
	or	[si].aRegs,rfInd
	call	MakeIndirect
	jmp	short @@4
@@3:	call	AllocSymbol
	call	Expr7
	call	FreeSymbol
	push	[si].aSize
	push	[si].aParent.Offs
	push	[si].aParent.Segm
	call	CopySymbol
	pop	[si].aParent.Segm
	pop	[si].aParent.Offs
	pop	[si].aSize
	mov	[si].aType,tMEM
	or	[si].aRegs,rfInd
	add	sp,size TAsmSymbol
@@4:	ret
@@5:	mov	[si].aHalf,fOffs
	jmp	short @@8
@@6:	mov	[si].aHalf,fSegm
	mov	ax,[si].aValue.W2
	mov	[si].aValue.W0,ax
	jmp	short @@8
@@7:	mov	ax,[si].aSize
	mov	[si].aValue.W0,ax
	xor	ax,ax
	mov	[si].aAddr.W0,ax
	mov	[si].aAddr.W2,ax
@@8:	mov	[si].aType,tNUMBER
	xor	bx,bx
	mov	[si].aRegs,bl
	mov	[si].aSeg,bl
	mov	[si].aValue.W2,bx
	mov	[si].aSize,bx
	mov	ax,[si].aAddr.Offs
	or	ax,[si].aAddr.Segm
	jnz	@@4
	mov	[si].aHalf,bl
	ret
@@9:	db	tOFFSET
	dw	@@5-@@9
	db	tSEG
	dw	@@6-@@9
	db	tTYPE
	dw	@@7-@@9
	db	0
Expr7	endp

Expr8	proc	near
@@1:	lea	bx,@@4
	call	MatchToken
	jz	Expr9
	call	CheckStack
	push	bx
	jmp	@@1
@@2:	call	NeedMemOrNum
	neg	[si].aValue.W0
	adc	[si].aValue.W2,0
	neg	[si].aValue.W2
@@3:	mov	StringBuf[0],0
	ret
@@4	db	'+'
	dw	@@3-@@4
	db	'-'
	dw	@@2-@@4
	db	0
Expr8	endp

Expr9	proc	near
@@1:	lea	bx,@@4
	call	MatchToken
	jz	Expr10
	call	CheckStack
	push	bx
	jmp	@@1
@@2:	mov	cl,8
	ror	[si].aValue.W0,cl
@@3:	mov	[si].aValue.B1,0
	mov	[si].aValue.W2,0
	ret
@@4	db	tHIGH
	dw	@@2-@@4
	db	tLOW
	dw	@@3-@@4
	db	0
Expr9	endp

Expr10	proc	near
	call	CheckStack
	call	Expr11
@@1:	cmp	dh,'.'
	je	@@4
	cmp	dh,'['
	je	@@2
	cmp	dh,'('
	je	@@2
	ret
@@2:	call	AllocSymbol
	call	Expr11
	call	FreeSymbol
	mov	cx,[si].aSize
	jcxz	@@3
	mov	[di].aSize,0
@@3:	call	AddSymbols
	add	sp,size TAsmSymbol
	jmp	@@1
@@4:	mov	ax,[si].aParent.Offs
	mov	Symbol.sParent.Offs,ax
	mov	ax,[si].aParent.Segm
	mov	Symbol.sParent.Segm,ax
	xor	ax,ax
	mov	[si].aParent.Offs,ax
	mov	[si].aParent.Segm,ax
	call	GetToken
	call	AllocSymbol
	call	Expr7
	call	FreeSymbol
	cmp	[di].aType,tREG
	jne	@@5
	jmp	FieldErr
@@5:	mov	cx,[di].aSize
	jcxz	@@6
	mov	[si].aSize,0
@@6:	call	AddSymbols
	add	sp,size TAsmSymbol
	jmp	@@1
Expr10	endp

Expr11	proc near
	lea	bx,@@4
	call	MatchToken
	jz	Expr12
	push	bx
	call	Expr1
	ret
@@1:	mov	al,')'
	jmp	short @@3
@@2:	call	MakeIndirect
	or	[si].aRegs,rfInd
	mov	al,']'
@@3:	jmp	NeedToken
@@4	db	'('
	dw	@@1-@@4
	db	'['
	dw	@@2-@@4
	db	0
Expr11	endp

Expr12	proc	near
	call	Primary
	jmp	GetToken
Expr12	endp

Primary	proc	near
	mov	[si].aType,dh
	cmp	dh,tREG
	je	@@1
	cmp	dh,tNUMBER
	je	@@5
	cmp	dh,tSYM
	je	@@6
	cmp	dh,tTYP
	je	@@4
	jmp	SyntaxErr
@@1:	mov	ax,RegNum
	mov	[si].aRegNum,ax
	dec	al
	js	@@2
	jnz	@@3
	inc	[si].aSize
@@2:	inc	[si].aSize
@@3:	ret
@@4:	mov	[si].aType,tNUMBER
	mov	ax,Value.W0
	mov	[si].aSize,ax
	ret
@@5:	mov	ax,Value.W0
	mov	[si].aValue.W0,ax
	mov	ax,Value.W2
	mov	[si].aValue.W2,ax
	ret
@@6:	mov	[si].aType,tMEM
	mov	ax,Symbol.sSize
	mov	[si].aSize,ax
	mov	ax,Symbol.sValue.W0
	mov	[si].aValue.W0,ax
	mov	ax,Symbol.sValue.W2
	mov	[si].aValue.W2,ax
	mov	ax,Symbol.sParent.Offs
	mov	[si].aParent.Offs,ax
	mov	ax,Symbol.sParent.Segm
	mov	[si].aParent.Segm,ax
	xor	ax,ax
	mov	Symbol.sParent.Offs,ax
	mov	Symbol.sParent.Segm,ax
	mov	ax,Symbol.sAddr.Offs
	mov	cx,Symbol.sAddr.Segm
	inc	cx
	jz	@@8
	dec	cx
	mov	[si].aAddr.Offs,ax
	mov	[si].aAddr.Segm,cx
	test	Symbol.sFlag,1
	jz	@@7
	mov	[si].aSeg,2eh
@@7:	or	[si].aRegs,rfInd
	ret
@@8:	cmp	ax,-2
	jb	@@9
	je	@@10
	mov	[si].aType,tNUMBER
	ret
@@9:	mov	[si].aRegs,rfBP
@@10:	jmp	@@7
Primary	endp

CopySymbol	proc	near
	push	ds
	pop	es
	xchg	si,di
	mov	cx,size TAsmSymbol shr 1
	cld
	rep	movsw
	sub	si,size TAsmSymbol
	sub	di,size TAsmSymbol
	xchg	si,di
	ret
CopySymbol	endp

AddSymbols	proc	near
	push	dx
	cmp	[di].aType,tNUMBER
	jne	@@1
	cmp	[si].aType,tNUMBER
	je	@@2
	cmp	[si].aType,tREG
	jne	@@1
	cmp	[si].aRegNum.B0,szST
	jne	@@1
	mov	ax,[di].aValue.W0
	add	[si].aRegNum.B1,al
	and	[si].aRegNum.B1,7
	jmp	short @@8
@@1:	call	MakeIndirect
	xchg	si,di
	call	MakeIndirect
	xchg	si,di
@@2:	mov	ax,[di].aValue.W0
	mov	bx,[di].aValue.W2
	add	[si].aValue.W0,ax
	adc	[si].aValue.W2,bx
	mov	ax,[di].aParent.Offs
	mov	dx,[di].aParent.Segm
	or	ax,dx
	jz	@@3
	mov	ax,[di].aParent.Offs
	mov	[si].aParent.Offs,ax
	mov	ax,[di].aParent.Segm
	mov	[si].aParent.Segm,ax
@@3:	mov	cl,[di].aHalf
	mov	bx,[di].aAddr.Offs
	mov	dx,[di].aAddr.Segm
	mov	ax,dx
	or	ax,bx
	jz	@@4
	mov	[si].aHalf,cl
	xchg	bx,[si].aAddr.Offs
	xchg	dx,[si].aAddr.Segm
	or	bx,dx
	jz	@@4
	jmp	RelSymErr
@@4:	mov	cx,[di].aSize
	jcxz	@@5
	xchg	cx,[si].aSize
@@5:	mov	al,[di].aRegs
	mov	ah,al
	and	ah,[si].aRegs
	or	[si].aRegs,al
	and	ah,rfBX+rfBP+rfSI+rfDI
	jz	@@6
	jmp	InvRegErr
@@6:	mov	al,[di].aSeg
	or	al,al
	jz	@@8
	cmp	[si].aSeg,0
	jns	@@7
	jmp	SyntaxErr
@@7:	mov	[si].aSeg,al
@@8:	pop	dx
	ret
AddSymbols	endp

MakeIndirect	proc	near
	cmp	[si].aType,tNUMBER
	je	@@2
	cmp	[si].aType,tREG
	jne	@@1
	cmp	[si].aRegNum.B0,szWord
	jne	@@4
	xor	bx,bx
	add	bl,[si].aRegNum.B1
	add	bh,cs:@@3[bx]
	js	@@4
	mov	[si].aRegs,bh
	mov	[si].aSize,0
	jmp	short @@2
@@1:	cmp	[si].aType,tMEM
	je	@@2
	jmp	MemRefErr
@@2:	mov	[si].aType,tMEM
	ret
@@3	db	-1,-1,-1,rfBX,-1,rfBP,rfSI,rfDI
@@4:	jmp	InvRegErr
MakeIndirect	endp

MatchToken	proc	near
	mov	cx,bx
@@1:	mov	al,cs:[bx]
	add	bx,3
	or	al,al
	jz	@@2
	cmp	al,dh
	jne	@@1
	mov	bx,cs:[bx-2]
	add	bx,cx
	call	GetToken
	or	bx,bx
@@2:	ret
MatchToken	endp

AllocSymbol	proc	near
	pop	cx
	sub	sp,size TAsmSymbol
	mov	ax,sp
	push	si
	push	bx
	xchg	ax,si
	push	cx
ClearSymbol	label	near
	push	ds
	pop	es
	xor	ax,ax
	mov	cx,size TAsmSymbol shr 1
	push	di
	lea	di,[si]
	cld
	rep	stosw
	pop	di
	ret
AllocSymbol	endp

FreeSymbol	proc	near
	pop	ax
	pop	bx
	pop	si
	mov	di,sp
	push	ax
	ret
FreeSymbol	endp

NeedMemOrNum	proc	near
	cmp	[si].aType,tMEM
	je	@@1
NeedNumber	label	near
	cmp	[si].aType,tNUMBER
	jne	@@2
@@1:	mov	ax,[si].aAddr.Offs
	or	ax,[si].aAddr.Segm
	jnz	@@2
	ret
@@2:	jmp	ConstErr
NeedMemOrNum	endp
