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

📄 txtdir.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	TITLE	txtdir.asm - Text Mgr's Direct Mode Statement support

;==========================================================================
;
;Module:  txtdir.asm - Text Mgr's Direct Mode Statement support
;System:  Quick BASIC Interpreter
;
;=========================================================================*/
;
;		How a direct-mode statement gets executed
;
;                               User-Interface
;                                   /    |
;                          TxtDirect     |
;                              |   \     |
;               +--------------+    \    |
;               |              |     \   |
;               |         ParseLine  SystemScan
;               |                        |
;               |                    ForEach...
;               |                        |
;               |        +---------------+
;               |        |               |
;         +-----+-+  ScanTxtTbl      ReParseTbl
;         |       |   |
;         |  +----)---+
;         |  |    |   |
;     SsRudeScan  SsScan
;
;                                                  
;   User-Interface calls SystemScan for Single-Step, in case user edited
;     program between single steps.  It also calls SystemScan for the
;     Compile... menu, so we don't try to compile a program with errors.
;   TxtDirect calls ParseLine, SsRudeScan and SsScan for the direct
;     mode statement.
;   ReParseTbl calls DoReParse for any statements not yet accepted
;     by the parser, then ScanTypeBlocks, so variable manager knows
;     about all TYPE/END TYPE blocks.
;   ScanTxtTbl then calls SsRudeScan (if necessary) and SsScan (if necessary)
;     to get the text table ready to execute.
;   Some direct mode statements (like SYSTEM) don't require all loaded pcode
;     to be scanned.  In these cases, TxtDirect never calls SystemScan.
;
;=========================================================================*/

	.xlist
	include		version.inc
	TXTDIR_ASM = ON
	includeOnce	architec
	includeOnce	context
	includeOnce	lister
	includeOnce	opcontrl
	includeOnce	opid
	includeOnce	opmin
	includeOnce	opstmt
	IncludeOnce	opaftqb4
	includeOnce	parser
	includeOnce	pcode
	includeOnce	qbimsgs
	includeOnce	rtinterp		
	includeOnce	scanner
	includeOnce	txtint
	includeOnce	txtmgr
	includeOnce	ui
	.list

	assumes	DS,DATA
	assumes	SS,DATA
	assumes	ES,NOTHING



sBegin	DATA
scanTo		DB	0	;used by ScanTxtTbl


sEnd	DATA

sBegin	CODE

;These opcodes are of special interest whenever they appear in direct mode:
;
tOpDirect LABEL WORD
	opTabStartAll	DIR
	;list of opcodes which are illegal in direct mode
	;many more illegal stmts are caught by NtStatement()
	opTabEntry	DIR,opBolLab
	opTabEntry	DIR,opBolLabSp
	opTabEntry	DIR,opBolInclude
	opTabEntry	DIR,opBolIncludeSp
	opTabEntry	DIR,op_Static
	opTabEntry	DIR,op_Dynamic
	opTabEntry	DIR,op_Include
	opTabEntry	DIR,opStData
	opTabEntry	DIR,opStDefFn
	opTabEntry	DIR,opStEndDef
	opTabEntry	DIR,opStEndIfBlock
	opTabEntry	DIR,opStEndProc
	opTabEntry	DIR,opStEndType
		DIR_ILLEGAL EQU DIR_opStEndType
;All opcodes until end of list cause entire program to be scanned
	;list of opcodes which have direct mode variants
	opTabEntry	DIR,opStGosub
	opTabEntry	DIR,opStGoto
	opTabEntry	DIR,opStElseLab
	opTabEntry	DIR,opStIfLab
		DIR_DM_VARIANT EQU DIR_opStIfLab
	;list of opcodes which cause entire program to be scanned & CantCont
	opTabEntry	DIR,opStRunLabel
	opTabEntry	DIR,opStRunMain
		DIR_CANTCONT EQU DIR_opStRunMain
	opTabEntry	DIR,opStChain
	opTabEntry	DIR,opStCallS
	opTabEntry	DIR,opStCall
	opTabEntry	DIR,opStCallLess
	opTabEntry	DIR,opStRead
	opTabEntry	DIR,opStResume0
	opTabEntry	DIR,opStResumeNext
	opTabEntry	DIR,opStReturn0
	opTabEntry	DIR,opEot

sEnd	CODE

sBegin	CP
assumes	cs,CP


;--------------------------------
; TxtDirect and support functions
;--------------------------------

;**************************************************************
; boolean ScanTxtTbl()
; Purpose:
;	Called by SystemScan via ForEachTxtTbl(ScanTxtTbl).
;
;	Make sure all SUBs and FUNCTIONs are defined and terminated.
;	Note this isn't called for DEF FNs.  Any change to a DEF FN
;	causes a RUDE descan, so rude-scanner is responsible for
;	making sure all DEF FNs are terminated.
;
;	If the text table's scan-state > [scanTo],
;	   First, it makes sure all TYPE/END types have been made known to
;	 the variable manager.
;	   Then it traverses the text table's ReParse linked list,
;	 calling TxtChange() for each line.
;	   Then it calls SsRudeScan(SS_PARSE) to scan the text table to SS_PARSE
;	   or SsScan() to scan the text table to SS_EXECUTE
;
; Entry:
;	grs.fDirect = FALSE
;	Text table to be scanned has been loaded by context mgr.
;
; Exit:
;	ps.bdpSrc (parser's input buffer) is used.
;	If no errors were encountered by either TxtChange or SsScan,
;	   return value is TRUE (so ForEach... will continue)
;	else
;	   return value is FALSE,
;	   it is caller's responsibility to set grs.fDirect = FALSE
;	   txtErr.errCode = an offset into the QBI Message Table (MSG_xxx) or,
;	     if high-bit set, ps.bdpError contains the parser-built
;	     ASCII error message,
;	   txtErr.fDirect is set to FALSE,
;	   txtErr.oRs identifies the text table with the error,
;	   txtErr.otx contains the offset into the text table to the offending
;	     source line (otxDelFirst).
;	   txtErr.oSrcErr contains the column offset into the source line
;	     to the offending token.
;
;Alters:
;	ps.bdpSrc (parser's source buffer)
;
;**************************************************************
DbPub ScanTxtTbl 			
cProc	ScanTxtTbl,<NEAR>
cBegin


	test	txdCur.TXD_flags,FTX_mrs
	jne	ScanTxt 		;brif not a SUB/FUNCTION text table

	test	[prsCur.PRS_flags],FP_DEFINED
	je	ScnSubErr		;brif proc does not have a SUB/FUNC
	test	[prsCur.PRS_flags],FP_ENDPROC
	jne	ScanTxt			;brif proc has END DEF/SUB/FUNCTION

	;error - this SUB/FUNCTION has no END SUB/FUNCTION
	mov	ax,MSG_ProcNoEnd	;SUB/FUNCTION/DEF without END SUB/F...
	mov	dx,[prsCur.PRS_otxDef]
	jmp	short ScnSubErrCom

ScnSubErr:
	;Give "Statement cannot precede SUB/FUNCTION definition" error
	mov	ax,MSG_InvBeforeProcDef	;ax = error code
	sub	dx,dx			;text offset of error = 0

ScnSubErrCom:
	mov	[txtErr.TXER_oSrc],0
DJMP	jmp	SHORT ScanErrCommon	

ScanTxt:
	test	[mrsCur.MRS_flags3],FM3_NotFound 
	je	FileLoaded

	;The user loaded a .MAK file which named this module, but
	;the module could not be found.
	
	mov	[grs.GRS_otxCur],0
	mov	ax,[grs.GRS_oMrsCur]
	call	SetPsErrMsg		;set ps.bdErr to name of module
	;if static err buf, OM err not possible
	mov	ax,ER_OM
   DJMP je	ScanErr			;brif out-of-memory
	mov	ax,MSG_MrsNotFound
	; 'Module not found.  Unload from program? <OK/Cancel>.
	; ReportError() will Unload mrs if OK and MSG_MrsNotFound.
   DJMP jmp	SHORT ScanErr

FileLoaded:
	and	[mrsCur.MRS_flags],NOT FM_AllSsRude ;we have at least one non
					;SS_RUDE text table in this module.
	mov	al,[scanTo]		;al = desired state
	cmp	al,[txdCur.TXD_scanState]
   DJMP jae	SctGoodExit		;brif this table is already scanned
					; to at least [scanTo]
;***** Start Revision [41]
;***** End Revision [41]

STT_DoScan:
	cmp	al,SS_EXECUTE
	je	ToExecute		;brif scanning to SS_EXECUTE
	PUSHI	ax,SS_PARSE		;pass target state to SsRudeScan
	call	SsRudeScan		;scan to SS_PARSE
	or	ax,ax			
	jz	SctGoodExit		; brif no error
					;ax = error code
	jmp	SHORT ScanErr

;Scan current text table from SS_PARSE to SS_EXECUTE
ToExecute:
	call	SsScan			;scan text table to SS_EXECUTE
					;ax = scanner error (0 if none)
					;grs.otxCur = location of error
	DbChk	TxdOps			;see if scanner inserted bad opcode
	or	ax,ax			
	jne	ScanErr			;brif scanner encountered errors
	and	[flagsTm],NOT FTM_NoSsExecute ;we now have a table in
					;SS_EXECUTE

SctGoodExit:

	    mov     ax,UNDEFINED	;double duty - - - non-zero == TRUE
	    cmp     [grs.GRS_otxCONT],ax
	    jnz     SctExit		;brif can CONTinue

	    call    ResetData		;ensure the next READ is to the
					;  first DATA stmt in this module
					;  this is needed only for READ in
					;  direct mode buffer after we set
					;  Cant CONTinue.
	    ;AX already set non-Zero by call to ResetData

SctExit:
	or	ax,ax			
cEnd

;ax = error code, grs.otxCur = text offset to error
ScanErr:
	mov	dx,[grs.GRS_otxCur]	;dx = otx of reported error
	mov	[txtErr.TXER_oSrc],UNDEFINED
					;for scanner detected errors, we cant
					;detect the column, compute from otx
;ax = error code, dx = text offset to error
ScanErrCommon:
	mov	[txtErr.TXER_errCode],ax
	

	
	cmp	dx,UNDEFINED		
	je	SetOtx			;brif otx of error is UNDEFINED

	;Scanner sometimes leaves grs.otxCur pointing within an opcode
	;Force it to an opcode boundary for accurate error reporting.
	;Scanner sets low bit of otx if the otx points to an oVar
	;within an opStDeclare opcode.
	
	mov	bx,dx			;bx = dx = otx of err
	and	dl,0FEh			;turn off low bit
	cmp	bx,dx
	jne	SetOtx			;brif error was within opStDeclare
	sub	ax,ax			;tell TxtSkipOp to start at StartOTx
SeOtxLoop:
	push	bx			;save otxErr
	push	ax			;save otxPrev
	cCall	TxtSkipOp		;ax = otx to next opcode after ax
	pop	dx			;dx = otxPrev
	pop	bx			;bx = otxErr
	cmp	ax,bx
	jbe	SeOtxLoop		;brif current opcode's otx <= otxErr
SetOtx:
	mov	[txtErr.TXER_otx],dx	;save real text offset to error
	mov	ax,[grs.GRS_oRsCur]
	mov	[txtErr.TXER_oRs],ax
	mov	al,[grs.GRS_fDirect]	
	mov	[txtErr.TXER_fDirect],al
	call	ChkWatchErr		;modify txtErr if error in Watch expr
;txtErr.otx = text offset of error
;txtErr.oSrc = column of error
;txtErr.errCode = error code
	sub	ax,ax			;return FALSE
	jmp	SHORT SctExit


;**************************************************************
; boolean SystemScan
; Purpose:
;	Scan all text tables to SS_EXECUTE
; Exit:
;	if any scanner or reparse errors were encountered:
;	   txtErr.errCode = an offset into the QBI Message Table (MSG_xxx) or,
;	     if high-bit set, ps.bdpError contains the parser-built
;	     ASCII error message,
;	   txtErr.fDirect is FALSE,
;	   txtErr.oRs identifies the text table with the error,
;	   txtErr.otx is an offset into the text table where the error
;	      was detected.
;	   txtErr.oSrc identifies the column within the source line where
;	      the error was detected.
;	else
;	   txterr.errCode = 0
;	condition codes set based on value in txterr.errCode == 0
;
;**************************************************************
cProc	SystemScan,<PUBLIC,FAR>
cBegin
	mov	[txtErr.TXER_errCode],0	;assume no errors

	test	[grs.GRS_flags],FG_allSsExecute
	jnz	SsExit			
NotDone:
	SetfDirect	al,FALSE	;tells scanner, parser we're not
					;scanning direct mode stmt,
					;if we find any errors, they won't be
					;in the direct mode buffer
	;See if user entered/loaded a $INCLUDE <filename> statement
	; and the file was not found, or saved an Include file.
	;If so, re-evaluate all $INCLUDE statements in all text tables.
	
	call	NotSavedInc		;save all unsaved INCLUDE files
	or	ax,ax			
					; if files saved ok, ax=0
					; if no need to save any, ax=-1
					; if CANCEL, ax=MSG_GoDirect
					; if NO, ax=-2
					; if I/O error, ax = error code
	jg	SsError			; brif I/O error or cancel
	inc	ax			;test for -1
	je	SsNoSave		;brif no files needed to be saved
	jl	SsCancel		;brif user decided not to save
					; one or more INCLUDE files
SsNoSave:
	call	TxtReInclude		;re-parse all $INCLUDE lines if
					; any INCLUDE mrs's have been saved
	or	ax,ax			;ax = txtErr.errCode
	jne	SsDone			;brif error (errors like FileNotFound
					; would not get caught in ReParse loop)

	call	TxtMoved		;remember pcode has moved


	mov	ax,-MSG_Compiling	;display Loading msg in intense video
	call	StatusMsgCP		; to tell user we're compiling

	;First make sure all DEFFNs/SUBs/FUNCTIONs are defined and terminated

	mov	al,FE_PcodeMrs+FE_CallMrs+FE_SaveRs
	mov	bx,CPOFFSET ReParseTbl
	call	ForEachCP		;re-parse until no more opReParse
					; opcodes in the system.
	je	SsDone			;brif error

	xor	ax,ax
	mov	[SsLineCount],ax
	cCall	UpdStatusLn,<ax>

	;Next, scan all text tables to SS_PARSE state
	mov	[scanTo],SS_PARSE
	mov	bx,CPOFFSET ScanTxtTbl
	call	ForEachTxtTbl
	je	SsDone			;brif error

	mov	[SsLineCount],0

	;Next, scan all text tables to SS_EXECUTE state
	;If we didn't do it in this order, it would be possible to
	;scan one text table to SS_EXECUTE, which contained references
	;to a function in another text table which was still in SS_RUDE
	;state.  This would be trouble, because the function's return

⌨️ 快捷键说明

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