📄 txtmgr.asm
字号:
TcNotBigE:
dec ax ;restore ax = oPrs we're in
push ax ;otxDelFirst falls within a DEF FN
call PrsActivateCP ;activate it (for var mgr)
; *--------------------------------------------------------------
; * Examine the block of pcode being deleted opcode by
; * opcode, taking special action for each opcode of
; * interest. May result in AskCantCont, ModuleRudeEdit, SystemDescan.
; *
; *---------------------------------------------------------------
TcNotDefFn:
test [mrsCur.MRS_flags2],FM2_NoPcode
jne TcInBigEdit ;brif editing document or immediate
; window - no need to ever back out
; of edit. If we didn't do this,
; we could get out-of-memory error
; when trying to delete immediate window
; history, which we do when we're
; trying to recover from tight memory
cmp [bigEditState],BIG_EDIT_FALSE
jne TcInBigEdit ;brif we're in a BigEdit, if so
;TxtStartBigEdit already set this
;flag, and TxtDelete may have been
;called independantly of TxtChange
mov [fFillScrap],1 ;tell TxtDelete to copy text to scrap
; so we can back-out of edit
TcInBigEdit:
push si ;pass otxDelFirst
push [otxDelLast]
call TxtDelete ;delete the text
mov [fFillScrap],FALSE
jne TcDelOk ;brif TxtDelete returned FALSE in ax
TcRetGoDirect:
mov [result], MSG_GoDirect
J1_TcRet:
jmp TcRet ;brif user wants to back out of edit
;just return without doing anything
;Set up ps.tEtCur[] with the default types for this point in the source
;
TcDelOk:
;save current oRs for reactivation
; after Redefining/Deleting undefined
; prs entries. It is guaranteed that
; that this is safe, since SUB/FUNCs
; only get PrsFreed at ?rsDiscard time.
; DEF FNs have the Mrs active at edit
; time.
call ChkAllUndefPrsSaveRs ;Find new "defining" references for all
; Prs entries which had defining.
; references deleted. If no more
; references to prs exist, free it.
cmp [fNoInsert],0 ;is there any text to parse and insert?
jne J1_TcRet ;brif not - finished
; We can't call OtxDefTypeCur if accumulating opReparses for BigEdit,
; since the linked list are not updated until we start processing the
; reparse list at TxtEndBigEdit time. The processing of the reparse
; list will insure the the DEF type state is accurate.
cmp [bigEditState],BIG_EDIT_ACTIVE
je TcDoReParse ;brif we're accumulating BigEdit
;changes, but TxtEndBigEdit has not
;been called yet
mov ax,si ;ax = text offset
call OtxDefTypeCur
TcLoading1:
test [mrsCur.MRS_flags2],FM2_NoPcode
je TcNotDoc ;brif not a document module
;this module is not BASIC source, just text (maybe Scrap,
; command window, document file)
TcDoReParse:
call ResetDstPbCur ;so ParseUndo won't do anything
jmp TcReParse1
;Parse the source line to pcode
TcNotDoc:
;tell parser (and type manager) to recognize any TYPEs which have been
; declared before the place this line is being inserted. This
; prevents forward referencing of types, which BASCOM cannot support.
mov [ps.PS_otxLine],si
;Call the parser to parse the source line. grs.oPrs is updated
;if a SUB/FUNCTION/DEF statement for an as yet undefined procedure
;is parsed, in which case, the we insert the text at the beginning
;of the new text table.
mov ax,[grs.GRS_oPrsCur]
mov [oPrsPreParse],ax
mov ax,[grs.GRS_oRsCur] ;save Entry so we can tell UI to
mov [oRsPreParse],ax ; display new text table if we create
; a new SUB/FUNCTION.
mov al,[prsCur.PRS_flags] ;get prs flags in case we insert a
mov [flagsPrsPreParse],al ;SUB/FUNCTION statement. If we are
; just renaming then FP_DEFINED will
; have be cleared when the Sub/Func
; was deleted.
Retry:
mov [ps.PS_flags],0
call ParseLine
jnc TcNoParseErr ;brif parser encountered no error
;ParseLine encountered some error
mov ax,[oPrsPreParse]
call TxtParseUndo
test [ps.PS_flags],PSF_UndoEdit
jne J1_TcUndo ;brif user said he wants to back out
; of the edit while we were in ParseLine
; (i.e. ParseLine called AskCantCont)
test BYTE PTR [ps.PS_errCode + 1],PSERR_fRude / 100h
je TcNotRude ;brif error isn't cause for a rude-edit
;Variable manager returned an error code which
;means a RudeEdit is being performed.
;Save the line in an opReParse, but do not report the error to
;the user. SsDescan the module to SS_Rude (if the user wants
;to go through with the edit).
;See if user wants to back out of edit or descan to SS_RUDE
call AskRudeEdit ;see if user wants to back out of edit
jne TcNotRude ;brif user didn't back out of edit
J1_TcUndo:
jmp TcUndo ;undo delete (if any) and return
;See if the parser wants us to try parsing this line again. This can
;happen when:
; We saw something that made us need to ModuleRudeEdit, but part
; of the line's pcode had already been emitted in SS_PARSE
; Variable manager could not add a variable, because variable heap
; was locked (because we can CONTinue). Parser called AskCantCont
; and now wants us to try again (much easier than trying to call
; varmgr again from within parser).
;
TcNotRude:
test [ps.PS_flags],PSF_fRetry
jne Retry ;brif ParseLine wants us to try again
jmp SHORT TcParseErr
TcNoParseErr:
; *--------------------------------------------------------------
; * At this point, source line has been parsed with no errors.
; * Examine the block of pcode being inserted opcode by
; * opcode, calling a text-mgr routine for each opcode of interest.
; * Each of these routines in addition to doing other work,
; * returns a value which will cause either
; * No Action, ModuleRudeEdit(), SystemDescan(), or CantCont().
; *
; * NOTE: When reviewing changes to this block, make sure it isn't possible
; * to take some state-changing action, then encounter an error which
; * causes the edit to be discarded (AskCantCont or MakeOpReParse).
; * In general, it is safer to 'remember' state changing actions to
; * be taken, and take them when the pcode has actually been inserted.
; *
; *--------------------------------------------------------------
call ChkAllUndefPrsSaveRs ;check all undefed prs entries
;in case this was a rename
push [ps.PS_bdpDst.BDP_pb]
PUSHI ax,<CODEOFFSET tOpPreIns>
call TxtFindOpDS ;ax = ptr to 1st interesting opcode
PiLoop:
cmp dl,PI_opEot
je J1_PiDone ;brif done with loop
xchg di,ax ;di = ptr to current opcode
sub dh,dh ;dx = dispatch index
shl dx,1 ;dx = dispatch offset
mov ax,di ;ax = pointer to opcode of interest
sub di,[ps.PS_bdpDst.BDP_pb] ;convert ptr to offset in case
; dispatched function causes
; ps.bdpDst to move
mov bx,dx ;bx = dispatch offset
jmp WORD PTR cs:PiDispatch[bx]
;All the PiOpxxx dispatches either branch to an error handler, or PiNext
PiNext:
add di,[ps.PS_bdpDst.BDP_pb] ;convert offset back to pointer
push di ;pass otxCur
PUSHI ax,<CODEOFFSET tOpPreIns>
call TxtFindNextOpDS ;ax = pointer to next opcode of interest
jmp SHORT PiLoop
J1_PiDone:
jmp SHORT PiDone ;finished with loop
TcParseErr:
mov ax,[ps.PS_oSrcErr]
mov [txtErr.TXER_oSrc],ax
mov ax,[ps.PS_errCode]
mov dx,ax
.errnz PSERR_fAsciiMsg - 8000h ;TxtChange callers assume it is high bit
and ah,(PSERR_fAsciiMsg + PSERR_errCode) / 100h
;mask off parser flags
;pass error code in ax to TcReParse or TcAlert
test dh,PSERR_fAlert / 100h
jne TcAlert ;serious error, event at entry time,
; let alone reparse time
jmp SHORT TcReParse ;brif not a serious error
;ax = error code
TcAlert0:
mov [txtErr.TXER_oSrc],UNDEFINED
;for txtmgr detected errors, we cant
;detect the column, compute from otx
;Encountered some error, make sure entry prs is active before
;Undoing the change. This solves the bug where you enter a
;SUB line and the SUB already exists, but is undefined
; (SUB stmt is a reparse). The line parses without error, and
;the parser changes to the new prs. When we call PrsMake, we
;get a duplicate definition error. We were getting here with
;the wrong prs active.
mov bx,[oPrsPreParse]
cmp bx,[grs.GRS_oPrsCur]
je TcAlert ;brif parser didn't move into a new PRS
push ax ;save error code
push bx
call PrsActivateCP ;get back to module level/old prs
pop ax ;recover error code
TcAlert:
cmp [fSyntaxCheck],0
je TcReParse ;brif user has disabled editor
; syntax error reporting
mov [result],ax ;serious error - return code in ax
TcReParse:
mov [txtErr.TXER_errCode],ax
TcReParse1:
mov ax,[oPrsPreParse]
call TxtParseUndo ;undo any changes to prs table or
; name table which parsing this
; line caused.
test [ps.PS_flags],PSF_fRudeIfErr
je MakeOpRp
;Some irreversible action took place, like calling varmgr to
;create a CONSTant, and then some error took place. The user
;already said he didn't want to CONT before PSF_fRudeIfErr was
;set, so its ok to blow away the module's variable table.
call ModuleRudeEdit
MakeOpRp:
call MakeOpReParse
and [flagsTc],NOT (FTC_GotEndProc+FTC_GotEnterProc)
jmp SHORT TcPrescanDone ;don't call LoadEnterProc, LoadExitProc
;si = otxDelFirst
PiDone:
FLoadActive
jne TcPrescanDone ;brif LOADing a file
test [txdCur.TXD_flags],FTX_mrs
jne TcPrescanDone ;brif we're in a module's text table
call ChkInsProc ;see if valid line to insert in proc
je TcPrescanDone ;brif valid line
jns TcAlert0 ;brif illegal
jmp J1_TcUndo ;user wants to back out of edit
;MakeOpReParse could have resulted in an out-of-memory error
;check for it
;si = otxDelFirst
;
TcPrescanDone:
mov ax,[ps.PS_errCode]
cmp al,ER_OM
je J1_TcOmErr ;brif out-of-memory error
; *--------------------------------------------------------------
; * At this point, the user does not want to back out of the edit
; * for the sake of edit & continue, and we are not going to
; * convert the line to an opReParse due to errors.
; *--------------------------------------------------------------
sub [ps.PS_bdpDst.BDP_cbLogical],2 ;don't count opEot as part
; of the line to be inserted
;make room for new text by copying old text up in memory
;making sure there's enough free space in the current text table
;to insert the pcode we want to insert
;si = otxDelFirst
;
TcDoMove1:
mov ax,[ps.PS_bdpDst.BDP_cbLogical]
mov [cbIns],ax
call TxtInsert ;insert ps.bdpDst in text table @ si
je J1_TcOmErr ;brif out-of-memory
; *--------------------------------------------------------------
; * If we've gotten a SUB or FUNCTION statement
; * Move SUB/FUNCTION statement to a new PRS text table,
; * generating synthetic DEFxxx statements, and keeping leading
; * comments in SUB/FUNCTION's text table.
; *
; * NOTE: LoadEnterProc modifies ps.bdpDst
; * It also moves REMs from the module table to the start of
; * the procedure text table, since these REMs may be a proc header.
; * otxDelFirst (si) is updated to reflect this insert.
; *
; *--------------------------------------------------------------
;
TcAfterIns:
test [flagsTc],FTC_GotEnterProc
je TcNoEnterProc ;brif not inserting SUB/FUNC stmt
sub si,[txdCur.TXD_bdlText_cbLogical]
push [otxMrsDelFirst]
call LoadEnterProc ;move pcode from module to proc tbl
jne TcNotOm3
call PrsDeactivate ;make module active for error recovery
J1_TcOmErr:
jmp TcOmErr ;brif out-of-memory error
TcNotOm3:
;update otxDelFirst after copying leading remarks, defints etc. to prs
add si,[txdCur.TXD_bdlText_cbLogical]
; *--------------------------------------------------------------
; * Call TxtInsUpdate to examine every opcode which was inserted
; * in the text table, taking any opcode specific action required.
; *
; *--------------------------------------------------------------
;
TcNoEnterProc:
mov bx,si ;bx = updated otxDelFirst
add bx,[cbIns] ;bx = offset beyond inserted pcode
call TxtInsUpdate ;update program counter and other
; static entries which are affected
; by pcode movement.
je J1_TcOmErr ;brif out-of-memory
cmp [bigEditState],BIG_EDIT_FALSE
je TcNotInBigEdit ;brif we're not accumulating BigEdit
; changes
test [flagsTc],FTC_GotEnterProc
jnz TcNoIncr ;don't increment cbBigIns if proc
mov ax,[cbIns]
add [cbBigIns],ax ;remember how much text we've inserted
TcNoIncr:
cmp si,[otxBigIns]
jae TcNotInBigEdit
mov [otxBigIns],si ;remember base of inserted pcode
; (so we can later back out of BigEdit)
; *--------------------------------------------------------------
; * If we've gotten an END SUB or END FUNCTION statement
; * restore the module's text table.
; *
; *--------------------------------------------------------------
;
TcNotInBigEdit:
test [flagsTc],FTC_GotEndProc
je TcNoExitProc
FLoadActive
je TcNoExitProc ;brif not LOADing a file
call LoadExitProc ;clean up, return to Module level
jnc TcNoExitProc
jmp TcOmErr ;brif out of memory error
TcNoExitProc:
test [flagsTm],FTM_BpDeleted
je TcNoBp ;brif breakpoint was not deleted
push si ;pass otxDelFirst
call LnOfOtx ;ax = line text was inserted
push ax
call FAR PTR ToggleBp ;s
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -