⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lsid.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 3 页
字号:


;***************************************************************************
; LrStReDimTo
; Purpose:
;	if 1st DIM opcode in this statement, list DIM, else list ','
;
;	[[")" expZ "," expY "," expX ... exp1 "(" typeChar oNam]] ==>
;	  [[")" expZ TO expY "," expX ... exp1 "(" typeChar oNam]]
;	opDimOptionBase gets listed as "?" internally, so this function
;	eliminates those nodes when found.
;
;***************************************************************************
ListRule LrStReDimTo
	mov	ax,ORW_REDIM		;ax = reserved word of stmt 
	call	PushTempRwOrComma	;push "," or RW of stmt
	call	PushTempShared		;list SHARED if opShared was seen
	call	PopRoot			;ax = offset to node to be DIMed
; handle the special case where an StReDimTo is being used in place
; of what used to be a StReDimScalar in QB4.0
	test	BYTE PTR[opList+1],HIGH(OPCODE_MASK+1) 
	jnz	GotRedimScalar		;brif if normal ReDimTo
	call	StripOptBase		;walk through list ax, eliminating
					; nodes created by opDimOptionBase
					; and converting ',' to TO.
					; ax still = offset to node to DIM
GotRedimScalar:
	call	PushTemp		;push array node to temp stack
	jmp	PushListStg1		;push temp list to root as 1 node
					; and return to outer loop

;***************************************************************************
; StripOptBase
; Purpose:
;	ax = offset to [[")" exp ", " exp ", " exp "(" typeChar oNam]]
;	walk through this list, eliminating "?" "," nodes (which
;	were created by opDimOptionBase), and converting every other
;	comma to " TO "
; Preserves: ax
;
;***************************************************************************
StripOptBase PROC NEAR
	push	ax
	push	si
	call	ListOffToPtr		;bx = ptr to node ax
	mov	ax,WORD PTR [bx.LN_val_list]
					;bx = offset to 1st node in list
					; This could be ")" or [AS <type>]
	call	ListOffToPtr		;bx = ptr to node ax
	cmp	BYTE PTR [bx.LN_type],LNT_CHAR
	je	StripLoop		;brif it is ")"
	call	ListSibPtr		;bx = sibbling(bx) ")"
StripLoop:
	call	ListSibPtr		;bx = sibbling(bx) (dim's UPPER index)
	call	ListSibPtr		;bx = sibbling(bx) (comma)
	mov	si,bx			;save ptr to it
	mov	WORD PTR [si.LN_val_char],'OT'	;convert comma to TO
	call	ListSibPtr		;bx = sibbling(bx) (dim's LOWER index
					; or "?" put there by opDimOptionBase)
	cmp	BYTE PTR [bx.LN_type],LNT_CHAR
	jne	NotDefault		;brif couldn't be "?"
	cmp	BYTE PTR [bx.LN_val_char],'?'
	jne	NotDefault		;brif not "?"
	sub	ax,ax			;ax = 0
	mov	WORD PTR [si.LN_val_char],ax	;convert comma node to NULL
	mov	WORD PTR [bx.LN_val_char],ax	; and LOWER index node to NULL
NotDefault:
	call	ListSibPtr		;bx = sibbling(bx) (comma or '(')
	cmp	BYTE PTR [bx.LN_val_char],','
	je	StripLoop		;brif ","
StripExit:				
	pop	si
	pop	ax			;ax = offset to node to be DIMed
	ret
StripOptBase ENDP

ListRule LrStErase
	call	PushTempOpRwSpc		;emit opcode's resword (ERASE)
	lods	WORD PTR es:[si]	;ax = opStErase's cnt operand
	mov	[cLsArgs],al
	call	PushCommaArgs		;copy cLsArgs from root to temp
					; and separate them by commas
	jmp	PushListStg1		;push temp list to root as 1 node
					; and return to outer loop

; The statement "COMMON SHARED /foo/ a,b" produces the pcode:
; opShared, opCommon(oNam(foo)), opIdVTRef(a), opIdVTRef(b)
;
ListRule LrStCommon
	call	PushRootOpRwSpc		;emit opcode's resword (COMMON)
	call	PushRootShared		;list SHARED if opShared seen
	inc	si			;skip cntEos operand
	inc	si
	lods	WORD PTR es:[si]	;ax = common block's oNam (FFFF if none)
	cmp	ax,UNDEFINED
	je	NotBlockCommon
	push	ax
	mov	al,'/'			;list "/"
	call	PushRootChar
	pop	ax
	call	PushRootONam		;list block's name
	mov	ax,' /'
	call	PushRootChars		;list "/ "
NotBlockCommon:
	or	[lsBosFlags],FBOS_DoIdCommas
					;every opIdVTRef in this statement
					; is to be preceeded by "," except
					; the first.
	jmp	Stg1Loop		;return to outer loop

; The statement "SHARED a,b" produces the pcode:
; opStShared opIdVTRef(a), opIdVTRef(b)
;
ListRule LrStStatic
ListRule LrStShared
	inc	si			;skip oText operand
	inc	si
	call	PushRootOpRwSpc		;emit opcode's resword (SHARED/STATIC)
	or	[lsBosFlags],FBOS_DoIdCommas
					;every opIdVTRef in this statement
					; is to be preceeded by "," except
					; the first.
	jmp	Stg1Loop		;return to outer loop

;	DIM, AUTO, PUBLIC, and EB STATIC
ListRule LrStoClassDecl
	inc	si			; skip oText operand
	inc	si			
	or	[lsBosFlags2],FBOS2_DIM 
	call	PushRootOpRwSpc		
	call	PushRootShared		;list SHARED if opShared seen
	jmp	Stg1Loop		;return to outer loop


;***************************************************************************
; LrStDefType
; Purpose:
;	List opStDefType opcode.  Opcode's operand is link field followed
;	by 32 bit mask/type as follows:
;	   high 26 bits, 1 bit for each letter A..Z
;	   low 6 bits = ET_xx
; Algorithm:
;	letterCur = 'A'-1
;	cLetters = 0
;	fNotFirst = FALSE
;	while mask != 0
;	   letterCur = letterCur + 1
;	   shift mask left 1 bit
;	   if carry is set
;	      if cLetters == 0
;	         if fNotFirst
;	            list ", "
;	         list letterCur
;	         fNotFirst = TRUE
;	      cLetters++
;	   else
;	      if cLetters > 0
;	         if cLetters > 1
;	            list "-"
;	            list letterCur-1
;		 cLetters = 0
;
; Register allocation:
;	letterCur = si
;	cLetters = cl
;	mask = dx:ax
;	fNotFirst = ch
;
;***************************************************************************
ListRule LrStDefType
	inc	si			;skip link field
	inc	si
	lods	WORD PTR es:[si]	;ax = low 16 bits of operand
	xchg	ax,dx			;dx = low 16 bits of operand
	lods	WORD PTR es:[si]	;ax = high 16 bits of operand
	xchg	ax,dx			;[dx:ax] = 32 bit operand
	mov	bl,al			;bl = type
	and	ax,0FFC0H		;ax = bit mask for last 10 letters
	push	si			;save si for duration of routine

	push	ax			;save low 16 bits of operand
	push	dx			;save high 16 bits of operand
	and	bx,03FH			;bx = type
	shl	bx,1			;bx = type * 2
	mov	ax,tRwDefType - 2[bx]	;ax = ORW_DEFINT .. ORW_DEFSTR
	call	PushRootRwSpc		;list DEFINT..DEFSTR

	mov	si,'A'-1		;si = letterCur = 'A'-1
	sub	cx,cx			;cLetters = 0, fNotFirst = 0
DefTypeLoop:
	pop	dx			;dx = bit mask for first 16 letters
	pop	ax			;ax = bit mask for last 10 letters
	mov	bx,ax			;test mask
	or	bl,cl			;don't exit if we're within a range
					; (like A-Z), so we can terminate it
	or	bx,dx			;test high word of mask as well
	je	EndDefType		;brif mask is 0
	inc	si			;letterCur = letterCur + 1
	shl	ax,1			;shift mask left 1 bit
	rcl	dx,1
	push	ax			;save mask on stack
	push	dx			; (gets popped by DefTypeLoop)
	push	cx			;save cLetters, fNotFirst
	jnc	NotThisLetter		;brif this letter is not set
	or	cl,cl
	jne	BumpCLetters		;brif we're already in a range
					; (ie we're at B in an A-Z range)
	or	ch,ch
	je	Not1stLetter		;brif this is the 1st letter output
	call	PushRootCommaSpc	;list ", "
Not1stLetter:
	mov	ax,si			;al = letterCur
	call	PushRootChar		;list letterCur
BumpCLetters:
	pop	cx			;restore cLetters, fNotFirst
	inc	cx			;cLetters++ (inc cl is bigger opcode)
	mov	ch,1			;fNotFirst = FALSE
	jmp	SHORT DefTypeLoop

NotThisLetter:
	or	cl,cl
	je	NotWithinRange		;brif cLetters = 0
	dec	cl
	je	NotWithinRange		;brif cLetters was 1
	mov	al,'-'
	call	PushRootChar		;list "-"
	mov	ax,si			;al = letterCur
	dec	al			;al = letterCur - 1
	call	PushRootChar
NotWithinRange:
	pop	cx
	sub	cl,cl			;cLetters = 0
	jmp	SHORT DefTypeLoop	;set fNotFirst = TRUE

EndDefType:
	pop	si			;restore si=text pointer
	jmp	Stg1Loop		;return to outer loop

subttl	Procedure related opcodes

;------------------------------------------------------------------
;		Procedure related opcodes
;------------------------------------------------------------------

tcEt LABEL BYTE
	.erre	ET_I2 EQ 1		
	DB	'%'			;ET_I2
	.erre	ET_I4 EQ 2		
	DB	'&'			;ET_I4
	.erre	ET_R4 EQ 3		
	DB	'!'			;ET_R4
	DB	'#'			;ET_R8
	db	'$'			;ET_SD

;***************************************************************************
; ListProc
; Purpose:
;	List a [DECLARE] SUB/FUNCTION/DEF [QB4] statement
; Entry:
;	ax = cnt operand
;	es:si points to oPrs operand
;	lsBosFlags2 & FBOS2_DECLARE is non-zero for DECLARE
;
;***************************************************************************
DbPub	ListProc
cProc	ListProc,<NEAR>
	localW	parmFlags
	localW	cbAlias
	localB	procType
	localW	procAtr				
	procAtr_LO EQU BYTE PTR (procAtr)
	procAtr_HI EQU BYTE PTR (procAtr+1)
cBegin
	add	ax,si			;ax -> beyond end of opcode's operands
	push	ax			;save till function exit
	lods	WORD PTR es:[si]	;ax = oPrs operand (oNam if opStDefFn
					; and we're in SS_RUDE scan state)

	;--------------------------------------------------------\
	;NOTE: Temp data is on stack until end of this block
	;      Don't branch into or out of this block
	push	es			;save es (restored after FieldsOfPrsFar)
	push	ax			;pass oPrs to FieldsOfPrsFar

	lods	WORD PTR es:[si]	;ax = procAtr operand
	mov	[procAtr],ax		;save procAtr
	.errnz	DCLA_procType - 0300h
	and	ah,3			;ah = procType
	mov	[procType],ah		;save for later
	xchg	dx,ax			;dh = procType

	mov	ax,ORW_SUB
	cmp	dh,PT_SUB
	je	LpGotOPrs		;brif we're in a SUB
	mov	ax,ORW_FUNCTION
	cmp	dh,PT_FUNCTION
	je	LpGotOPrs		;brif we're in a FUNCTION
	DbAssertRelB dh,e,PT_DEFFN,LIST,<LrStDeclare has invalid proc type>
	mov	ax,ORW_DEF
	cmp	[txdCur.TXD_scanState],SS_RUDE
	jb	LpGotOPrs		;brif not in SS_RUDE
	;opStDefFn has oNam as operand, not oPrs in RUDE state
	call	PushRootRwSpc		;push DEF to root stack
	pop	ax			;ax = oNam
	jmp	SHORT LpDefFn

LpGotOPrs:
	call	PushRootRwSpc		;push SUB/FUNCTION/DEF to root stack

					;parm to FieldsOfPrsFar pushed shortly
					; after entry to ListProc
	call	FieldsOfPrsFar		;ax = oNam of prs
;ax = oNam for procedure
LpDefFn:
	pop	es			;restore es = seg adr of txt table
	;NOTE: Temp data is now off stack
	;--------------------------------------------------------/

	call	PushRootONam		;list sub/func/def's name
					;high byte contains proc type
	mov	al,[procAtr_LO]
	.errnz	DCLA_Explicit - 0080h
	or	al,al
	jns	ImplicitTyp
	and	al,DCLA_oTyp		;al = explicit type
	DbAssertRelB al,ne,0,LIST,<ListProc: invalid explicit oTyp1>
	DbAssertRelB al,be,ET_MAX,LIST,<ListProc: invalid explicit oTyp2>
	mov	bx,LISTOFFSET tcEt - 1	;bx points to tcEt mapping table
	xlat	cs:[bx]			;al = explicit type char (%,&,etc.)
	call	PushRootChar		;list it
	call	CharToCharTok		;convert it to a LNT_CHARS_TOK node
ImplicitTyp:
	call	PushRootSpc
	test	[procAtr_HI],DCLA_cdecl / 100h
	.errnz	DCLA_cdecl - 8000h
	je	NotCDECL		;brif not declared as CDECL
	mov	ax,ORW_CDECL
	call	PushRootRwSpc		;list "CDECL "
NotCDECL:
	lods	WORD PTR es:[si]	;ax = parm cnt operand
	mov	[cLsArgs],al		;save parm count

	;List ALIAS "string" or LIB "string"
	mov	cl,[procAtr_HI]
	.errnz	DCLA_cbAlias - 7C00h
	and	cx,DCLA_cbAlias / 100h	;cx = cbAlias * 4
	shr	cl,1
	shr	cl,1			;cx = cbAlias
	jcxz	NoAliasOrLib		;brif alias clause not specified
	push	si			;save si points to 1st arg
	push	cx			;save byte count of ALIAS/LIB id

	; set si to point to ALIAS/LIB name
	mov	al,[cLsArgs]
	inc	al			;map 0 and UNDEFINED to 0
	je	NoParms			; brif cLsArgs was UNDEFINED
	dec	al			; restore dx = cLsArgs
NoParms:
	sub	ah,ah			;ax = cLsArgs
	mov	dx,ax			;dx = cLsArgs
	shl	ax,1			;ax = cLsArgs * 2
	add	ax,dx			;ax = cLsArgs * 3
	shl	ax,1			;ax = cLsArgs * 6
	add	si,ax			;si points to ALIAS or LIB name

	mov	ax,ORW_ALIAS
	call	PushRootRwSpc		;list ALIAS
	pop	ax			;restore ax = cbAlias
PushQStr:				
	call	PushRootQstr		
	call	PushRootSpc		;list " "
NoAlias:
	pop	si			;restore si points to 1st arg

NoAliasOrLib:
	cmp	[cLsArgs],0
	jg	GotProcParms		;brif cParms != UNDEFINED and != 0
					; (for DECLARE, UNDEFINED means 0
					;  parms, and no type checking - see
					;  pcode document)
	jl	NoTypeChk		;brif cParms == UNDEFINED
	test	[lsBosFlags2],FBOS2_DECLARE
	je	NoTypeChk		;brif not listing DECLARE
EnforceNoParms:
	mov	ax,')('
	call	PushRootChars		;list "() "
	call	PushRootSpc
NoTypeChk:
	jmp	NoProcParms

GotProcParms:
	call	PushRootLParen		;push '('
ProcParmLoop:
	cmp	si,[otxLsCursorTmp]
	jb	NotNdLsCursor		;brif not token of interest
	mov	[ndLsCursor],di
	mov	[otxLsCursorTmp],UNDEFINED ;make sure we don't set it again
NotNdLsCursor:
	test	[lsBosFlags2],FBOS2_DECLARE
	je	NotDeclParm		;brif not listing DECLARE
	lods	WORD PTR es:[si]	;ax = parm's oNam
	call	NewONam			;ax = offset to oNam node
					;bx = oNam
	jmp	SHORT ChkPrmFlgs
NotDeclParm:
	call	NewId			;consume id's operand, ax = node
					;bx = oNam
ChkPrmFlgs:
	push	bx			;save

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -