📄 prsutil.asm
字号:
mov ah,PSERR_fAlert / 100h ;set ALERT flag in result
;this error is reported at entry
;time, rather than waiting until
;the pre-run reparse loop
SKIP2_PSW ;skip following mov ah,0 instruction
ReparseErr:
mov ah,0 ;DON'T alter condition codes
BindRude:
jmp SHORT ParseErr ;ParseErr(ax,bx)
; result doesn't matter because of error
PErrVarMgr ENDP
;error "id can't end with % & ! # or $", al=PR_BadSyntax on exit
;
PUBLIC PErrExpIdImp
PErrExpIdImp PROC NEAR
mov ax,MSG_IdImp ;"id can't end with % & ! # or $"
PErrExpIdImp ENDP
;fall into PErrMsg_AX
;*********************************************************************
; VOID NEAR PErrMsg_AX, PErrPrevTok_AX, PErrMsg_AX_BX
;
; Purpose:
; Append the standard message identified by iMsgErr to current error line.
;
; Entry:
; ax = error code (from qbimsgs.inc)
; pTokScan->oSrc is used for column offset by PErrMsg_AX
; OR
; bx->oSrc is used for column offset by PErrMsg_AX_BX [09]
;
; Exit:
; al = PR_BadSyntax, condition codes set based on al
;
;*********************************************************************
;PErrPrevTok_Ax uses the column offset of the last token consumed
;for reporting the error
PUBLIC PErrPrevTok_AX
PErrPrevTok_AX PROC NEAR
mov bx,[pTokLastConsumed] ;bx -> last consumed token
; fall into PErrMsg_AX_BX
jmp SHORT PErrMsg_Ax_Bx
PErrPrevTok_AX ENDP
PUBLIC PErrMsg_AX
PErrMsg_AX PROC NEAR
mov bx,[pTokScan]
; fall into PErrMsg_AX_BX
PErrMsg_AX ENDP
cProc PErrMsg_AX_BX,<PUBLIC,NEAR>
cBegin PErrMsg_AX_BX
test BYTE PTR([ps.PS_errCode+1]),PSERR_fAsciiMsg / 100h
jne GotEos1 ;brif not 1st msg for this line
test BYTE PTR([ps.PS_errCode+1]),PSERR_fAlert / 100h
jne NoOmErr ;brif already got an error not
; consisting of pasting together
; messages into ps.bdErr (like
; Id too long, or Out of memory)
;This still overrides errors like ER_DD
; so syntax errors get reported before
; variable mgr re-parse type errors
; (because a syntax error is more
; valuable to the user).
push ax ;save msg id
mov [ps.PS_bdErr.BD_cbLogical],0 ;reset bdErr buffer
mov ax,PSERR_fAsciiMsg + PSERR_fAlert
;tells ParseLine's caller that err msg
; is in ps.bdErr
call ParseErr ;set ps.errCode, ps.oSrcErr
GetEos:
call NtEndStatement
jne GotEos ;brif current token is end-of-stmt
call ScanTok
jmp SHORT GetEos
GotEos:
pop ax ;restore ax = msg id
GotEos1:
push ax ;pass msgId to ListStdMsgToBd
PUSHI ax,<dataOFFSET ps.PS_bdErr>
call ListStdMsgToBd ;append std msg to error buffer
or ax,ax
jne NoOmErr ;brif not out-of-memory
call ParseErrOm ;Error "Out of memory"
NoOmErr:
mov al,PR_BadSyntax
or al,al ;set condition codes for caller
cEnd PErrMsg_AX_BX
;*********************************************************************
; VOID NEAR PErrExpectedOr()
;
; Purpose:
; If this is the 1st clause of this err msg, output 'Expected: '
; Otherwise output ' or '.
;
; Exit:
; al = PR_BadSyntax, condition codes set based on al
;
;*********************************************************************
PErrExpectedOr PROC NEAR
mov ax,MSG_or
test BYTE PTR([ps.PS_errCode+1]),PSERR_fAsciiMsg / 100h
jne OrNot1stMsg ;brif not 1st msg for this line
mov ax,MSG_expected
OrNot1stMsg:
jmp SHORT PErrMsg_AX ;emit msg, al = PR_BadSyntax
; return to caller
PErrExpectedOr ENDP
;*********************************************************************
; VOID NEAR PErrExpRw_AX
;
; Purpose:
; Produce the error message: "Expected <reserved word>"
;
; Entry:
; ax = IRW for expected reserved word (from prsirw.inc)
; Exit:
; al = PR_BadSyntax
;
;*********************************************************************
cProc PErrExpRw_AX,<PUBLIC,NEAR,NODATA>,<si>
cBegin
xchg si,ax ;si = IRW for expected reserved word
DbAssertRel si,be,NTOKENS,CP,<Illegal token in PErrExpRw>
;list ASCII this opcode maps to
call PErrExpectedOr ;output "Expected" or "or"
cmp si,IRW_NewLine
jne NotNewLine
mov ax,MSG_eos
call PErrMsg_AX ;output "end of statement"
jmp SHORT PErrExpRwExit
NotNewLine:
push si
call ListIRW ;output reserved word's name to
; bufStdMsg, ax = byte count
DbAssertRel ax,ne,0,CP,<ListIRW called with bad IRW>
PUSHI bx,<dataOFFSET ps.PS_bdErr> ;pass ptr to destination buffer
PUSHI bx,<dataOFFSET bufStdMsg>
;pass ptr to 1st byte of text
push ax ;push byte count
call BdAppend
PErrExpRwExit:
mov al,PR_BadSyntax ;return PR_BadSyntax
cEnd
;error "Expected id", al=PR_BadSyntax on exit
;
PUBLIC PErrExpId
PErrExpId PROC NEAR
mov ax,MSG_ExpId
;; jmp SHORT PErrExpMsg_AX
PErrExpId ENDP
;fall into PErrExpMsg_AX
;*********************************************************************
; VOID NEAR PErrExpMsg_AX
;
; Purpose:
; Produce the error message: "Expected <Standard BASIC Message>"
;
; Entry:
; ax = error code (from qbimsgs.inc)
;
; Exit:
; al = PR_BadSyntax, condition codes set based on al
;
;*********************************************************************
PUBLIC PErrExpMsg_AX
PErrExpMsg_AX PROC NEAR
push ax ;save msgId
call PErrExpectedOr
pop ax ;restore ax = msgId
jmp PErrMsg_AX ;al = PR_BadSyntax
;return to caller
PErrExpMsg_AX ENDP
if ND_ACCEPT - 0
Error: PErrState assumes ND_ACCEPT = 0
endif
if ND_REJECT - 1
Error: PErrState assumes ND_REJECT = 1
endif
if ND_MARK - 2
Error: PErrState assumes ND_MARK = 2
endif
if ND_EMIT - 3
Error: PErrState assumes ND_EMIT = 3
endif
if ND_BRANCH - 4
Error: PErrState assumes ND_BRANCH = 4
endif
;*************************************************************************
; VOID NEAR PErrState
;
; Purpose:
; Append an error message to the error buffer indicating
; 'A or B or C ... or Z' was expected.
;
; Entry:
; ushort pStateLastScan - pointer into tState for expected syntax
; when last token was scanned.
; ushort pStateLastGood - pointer into tState for expected syntax
; when last non-terminal was accepted.
;
; Exit:
; al = PR_BadSyntax
;
;*************************************************************************
cProc PErrState,<PUBLIC,NODATA,NEAR>,<si>
cBegin PErrState
test BYTE PTR([ps.PS_errCode+1]),PSERR_fAlert / 100h
jne GotBadSyntax ;brif already got an error not
; consisting of pasting together
; messages into ps.bdErr (like
; Id too long, or Out of memory)
;This still overrides errors like ER_DD
; so syntax errors get reported before
; variable mgr re-parse type errors
; (because a syntax error is more
; valuable to the user).
mov ax,[pStateLastScan]
call PErrState1 ;PErrState(pStateLastScan - tState)
test BYTE PTR([ps.PS_errCode+1]),PSERR_fAsciiMsg / 100h
jne GotBadSyntax ;brif PErrState1 didn't generate anything
mov ax,[pStateLastGood]
call PErrState1
GotBadSyntax:
mov al,PR_BadSyntax
cEnd PErrState
;Register usage:
; dx = pStateTrue
; cx = nodeId
; si = pState
;
cProc PErrState1,<NODATA,NEAR>,<si>
cBegin PErrState1
xchg si,ax ;si = pState
or si,si
jne ErrLoop ;brif not NULL pState
J1_ErrLoopExit:
jmp ErrLoopExit ;brif ACCEPT or REJECT node (done)
ErrLoop:
lods BYTE PTR cs:[si] ;al = node id
cmp al,ND_REJECT
jbe J1_ErrLoopExit ;brif ACCEPT or REJECT node
cmp al,ND_EMIT
ja NotEmitOrMark ;brif not EMIT or MARK node
lodsb ;bump si without changing status flags
jne ErrLoop ;brif MARK node (1 byte operand)
inc si ;EMIT has 2 byte operand
jmp SHORT ErrLoop
;got a branch, token, or nonterminal - fetch its id
NotEmitOrMark:
sub ah,ah ;ax = nodeId
cmp al,ENCODE1BYTE
jb OneByteNodeId ;brif 1 byte nodeId
;nodeId = ((nodeId-ENCODE1BYTE) << 8) + (*pState++) + ENCODE1BYTE
mov ah,al
lods BYTE PTR cs:[si] ;ax = nodeId * 256 + next byte
sub ax,255 * ENCODE1BYTE
OneByteNodeId:
xchg cx,ax ;save nodeId in cx
;node is followed by 1 or 2 byte branch operand, fetch it
lods BYTE PTR cs:[si]
sub ah,ah ;ax = operand
cmp al,ENCODE1BYTE
jb OneByteOperand ;brif 1 byte operand (< ENCODE1BYTE)
cmp al,255
je HandleNode ;brif special id->accept node
; never generated for a BRANCH node,
; which is the only reason we care
; about the operand in this function
;operand is 2 byte offset into tState
;operand = ((operand-ENCODE1BYTE) << 8) + *pState++
mov ah,al
lods BYTE PTR cs:[si] ;ax = operand * 256 + next byte
sub ax,256 * ENCODE1BYTE
add ax,OFFSET CP:tState
xchg dx,ax ;pStateTrue = &tState[operand]
jmp SHORT HandleNode
OneByteOperand:
;operand is 1 byte relative branch in state table
mov dx,ax ;dx = offset to new state
add dx,si ;pStateTrue = pState + operand
cmp al,ENCODE1BYTE/2
jbe HandleNode ;brif positive relative branch
sub dx,ENCODE1BYTE ;negative relative branch
HandleNode:
xchg ax,cx ;ax = nodeId
cmp ax,ND_BRANCH
jne NotBranchNode
mov si,dx ;unconditional branch to another state,
; pState = pStateTrue
jmp SHORT ErrLoop ; continue scanning
NotBranchNode:
sub ax,ND_BRANCH + 1
cmp ax,NUMNTINT
jae NotIntNt
;we expected a non-terminal described by a state tree
xchg bx,ax
shl bx,1
mov ax,cs:tIntNtDisp[bx]
add ax,CPOFFSET tState ;ax = pState
call PErrState1 ;recurse
J1_ErrLoop:
jmp SHORT ErrLoop
NotIntNt:
sub ax,NUMNTINT
cmp ax,NUMNTEXT
jae NotExtNt
;we expected a non-terminal defined by a C function
xchg bx,ax
shl bx,1
mov ax,cs:tExtNtHelp[bx]
;iMsg = tExtNtHelp[nodeId]
or ax,ax
je J1_ErrLoop ;brif no error msg for this nonterminal
call PErrExpMsg_AX ;emit the message
jmp SHORT J1_ErrLoop
NotExtNt:
;we expected a reserved word: Error "Expected <reserved word>"
sub ax,NUMNTEXT ;ax = nodeId
call PErrExpRw_AX ;PErrExpRw(ax:nodeId)
jmp SHORT J1_ErrLoop
ErrLoopExit:
cEnd PErrState1
sEnd CP
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -