📄 lsrules.asm
字号:
call PushTempRwSpc ;push ON
call PopRootPushTemp ;move exp from root to temp stack
call PushTempSpc ;list space between exp and GOTO/GOSUB
call PushTempOpRwSpc ;push GOTO/GOSUB
lods WORD PTR es:[si] ;ax = byte count of label args
shr ax,1 ;ax = count of label args
mov [cLsArgs],al ;setup for call to PushCommaArgs
; (guarenteed by parser to be > 0)
xchg cx,ax ;cx = count of label args
EmitLabLoop:
push cx ;save count of label args
call PushRootLabel ;consume and push <label>
call GrowBdNodes ;grow list buffer if necessary
; preserves cx
pop cx ;restore count of label args
je OnGosubExit ;brif out-of-memory - We'll abort
; ListLine next time through Stg1Loop
loop EmitLabLoop ;repeat for each label in list
call PushCommaArgs ;move labels from root to temp
; stack, inserting commas
OnGosubExit:
jmp PushListStg1 ;push temp list to root as 1 node
; and return to outer loop
; [exp ...] ==> [[exp space CASE space SELECT] ...]
;
ListRule LrStSelectCase
call PushTempOpRwSpc ;push SELECT onto temp stack
mov ax,ORW_CASE
call PushTempRwSpc ;push ON
call PopRootPushTemp ;move expNode from root to temp stk
inc si ;skip operand
inc si
jmp PushListStg1 ;push temp list to root as 1 node
; and return to outer loop
;***************************************************************************
; PushCaseOrComma
; Purpose:
; 1st opCase in a statement gets mapped to CASE,
; all subsequent ones get mapped to ','.
;
;***************************************************************************
PushCaseOrComma PROC NEAR
mov ax,ORW_CASE
jmp PushTempRwOrComma
PushCaseOrComma ENDP
; [exp2 exp1 ...] ==> [[exp2 space TO space exp1 space CASE]]
;
ListRule LrStCaseTo
call PushCaseOrComma ;emit CASE space or ',' space
call PopRoot ;ax = exp2
push ax ;save it for later
call PopRootPushTemp ;move exp1 from root to temp stk
call PushTempSpc
call PushTempOpRwSpc ;list opcode's resword (TO)
pop ax ;ax = exp1
call PushTemp
jmp PushListStg1 ;push temp list to root as 1 node
; and return to outer loop
; [...] ==> [ELSE space CASE ...]
;
ListRule LrStCaseElse
call PushRootOpRwSpc ;list opcode's resword (CASE)
mov ax,ORW_ELSE
PushRootRwStg1:
call PushRootRw ;list ELSE
jmp Stg1Loop ;return to outer loop
; [exp ...] ==> [[exp space CASE ...]]
;
ListRule LrStCase
call PushCaseOrComma ;emit CASE space or ',' space
call PopRootPushTemp ;move expNode from root to temp stk
jmp PushListStg1 ;push temp list to root as 1 node
; and return to outer loop
; [exp ...] ==> [[exp space <relation> space IS space CASE]]
;
ListRule LrStCaseRel
call PushCaseOrComma ;emit "CASE " space or ", " to temp stk
mov ax,ORW_IS
call PushTempRwSpc ;list "IS "
call PushTempOpChars ;list opcode's char(s)
call PushTempSpc ;surround operator with blanks
call PopRootPushTemp ;move expNode from root to temp stk
jmp PushListStg1 ;push temp list to root as 1 node
; and return to outer loop
; [exp ...] ==> [[exp space WHILE/UNTIL space DO]]
;
ListRule LrStDoWhile
ListRule LrStDoUntil
mov ax,ORW_DO
call PushTempRw ;list DO
LrStLoop1:
call PushTempSpc
call PushTempOpRwSpc ;list WHILE or UNTIL
call PopRootPushTemp ;move expNode from root to temp stk
inc si ;skip oText operand
inc si
jmp PushListStg1 ;push temp list to root as 1 node
; and return to outer loop
; [exp ...] ==> [[exp space WHILE/UNTIL space LOOP]]
;
ListRule LrStLoopUntil
ListRule LrStLoopWhile
mov ax,ORW_LOOP
call PushTempRw ;list LOOP
jmp SHORT LrStLoop1 ;share code with DO
; [exp3 exp2 exp1 id ...] ==> [[exp3 STEP exp2 TO exp1 = id FOR]]
;
ListRule LrStForStep
call PopRootPushTemp ;move exp3 from root to temp stk
call PushTempSpc
mov ax,ORW_STEP
call PushTempRwSpc ;list STEP
;fall into LrStFor
; [exp2 exp1 id ...] ==> [[exp2 TO exp1 = id FOR]]
;
ListRule LrStFor
add si,4 ;skip oBP, oText operands
call PopRootPushTemp ;move exp2 from root to temp stk
call PushTempSpc
mov ax,ORW_TO
call PushTempRwSpc ;list TO
call PopRootPushTemp ;move exp1 from root to temp stk
call PushTempSpc
mov ax,'= '
call PushTempChars ;list ' ='
call PopRootPushTemp ;move id node from root to temp stk
call PushTempSpc
call PushTempOpRw ;list FOR
jmp PushRevListStg1 ;move temp stk to root in reverse order
; and return to outer loop
; [...] ==> [NEXT ...]
;
ListRule LrStNext
cmp [txdCur.TXD_scanState],SS_EXECUTE
jne NotExecute
call PopRoot ;discard offset to id node (it was
; synthetically generated by scanner,
; will be removed by SsDescan()
NotExecute:
add si,4 ;skip oBP and oText operands
jmp short LrRw ;list NEXT
; and return to outer loop
; [id ...] ==> [id NEXT ...]
;
ListRule LrStNextId ;advance past oBP, oText operands
inc si ;skip oBP operand
inc si
ListRule LrStWhile ;advance past oText operand
inc si ;skip oText operand
inc si
ListRule LrStRead
call PushTempOpRwOrComma ;push opcode's reserved word (or comma)
;followed by a space
jmp short PopPushPushListStg1 ;list exp and return to Stg1Loop
; [...] ==> [LOOP/WEND ...]
;
ListRule LrStLoop
ListRule LrStWend
inc si ;skip link field
inc si
jmp short LrRw ;list LOOP or WEND
; and return to outer loop
; [...] ==> [NEXT space RESUME ...]
;
ListRule LrStResumeNext
call PushRootOpRwSpc ;list RESUME
mov ax,ORW_NEXT
jmp PushRootRwStg1 ;list NEXT
;return to outer loop
subttl Generic opcode listers
;------------------------------------------------------------------
; Generic opcode listers
;------------------------------------------------------------------
;***************************************************************************
; LrRw
; Purpose:
; [...] ==> [resWord ...]
;
;***************************************************************************
ListRule LrRw
call PushRootOpRw ;push opcode's reserved word
jmp Stg1Loop ;return to outer loop
; [...] ==> [space <opcode's resword> ...]
;
ListRule LrRwSpc
call PushRootOpRwSpc ;push opcode's reserved word
jmp Stg1Loop ;return to outer loop
;***************************************************************************
; LrChar
; Purpose:
; [...] ==> [char ...]
;
;***************************************************************************
ListRule LrChar
mov ax,[mpOpLsArg + bx] ;ax = char(s) to be listed
PushRootCharsStg1:
call PushRootChars ;push char(s) to be listed to root stack
jmp Stg1Loop ;return to outer loop
;***************************************************************************
; LrRwExp1
; Purpose:
; [exp] ==> [[exp space resWord]]
; Examples include opStChain, opStRandomize1, opNot
;
;***************************************************************************
ListRule LrRwExp1
call PushTempOpRwSpc ;push opcode's reserved word
;followed by a space
PopPushPushListStg1:
call PopRootPushTemp ;move expNode from root to temp stk
jmp PushListStg1 ;push temp list to root as 1 node
; and return to outer loop
;***************************************************************************
; LrUnaryChar
; Purpose:
; [exp] ==> [[exp char]]
;
;***************************************************************************
ListRule LrUnaryChar
ListRule LrUnaryOp
call PushTempOpChars
jmp SHORT PopPushPushListStg1 ;list exp and return to outer loop
; [exp2 exp1 ...] ==>
; [exp2 space comma exp1 space comma <opcode's resword>]
;
ListRule LrStSwap
inc si ;consume opStSwap's operand
inc si
ListRule LrRwExp2
mov [cLsArgs],2
ListStmtArgs:
call PushTempOpRwSpc ;push opcode's reserved word
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
; [exp3 exp2 exp1 ...] ==>
; [exp3 space comma exp2 space comma exp1 space comma <opcode's resword>]
;
ListRule LrRwExp3
mov [cLsArgs],3
jmp SHORT ListStmtArgs
;***************************************************************************
; LrFunc1Arg
; Purpose:
; [exp] ==> [[")" exp "(" resWord]]
;
;***************************************************************************
ListRule LrFnLen
ListRule LrFnVarptr_
inc si ;skip size operand
inc si
ListRule LrFunc1Arg
mov [cLsArgs],1
ListFuncArgs:
call PushTempOpRw ;push opcode's reserved word
ListFuncArgs2:
call PushTempLParen ;push '(' onto temp stack
call PushCommaArgs ;copy cLsArgs from root to temp
; and separate them by commas
call PushTempRParen ;push ')' onto temp stack
jmp PushListStg1 ;push temp list to root as 1 node
; and return to outer loop
ListRule LrFunc2Args
mov [cLsArgs],2
jmp SHORT ListFuncArgs
ListRule LrFunc3Args
mov [cLsArgs],3
jmp SHORT ListFuncArgs
mptypRwCoerce equ $-2
dw ORW_CInt ; I2
dw ORW_CLng ; I4
dw ORW_CSng ; R4
dw ORW_CDbl ; R8
ListRule LrCoerce
mov [cLsArgs],1
mov bl,byte ptr [opList+1] ; BL = ET type * 4 + garbage
.erre OPCODE_MASK EQ 03ffh ; Assure SHR is correct
; and bx,HIGH (NOT OPCODE_MASK)
and bx,0FCh
shr bx,1 ; BX = ET type * 2
mov ax,word ptr mptypRwCoerce[bx] ; Translate to reserved word
call PushTempRw ; Push opcode's reserved word
jmp short ListFuncArgs2
;Start of [22]
;End of [22]
subttl Misc opcode listers
;------------------------------------------------------------------
; Misc opcode listers
;------------------------------------------------------------------
ListRule LrScanStop
DbHalt LIST,<Illegal opcode found in ListLine>
;Emitted to indicate defaulted parm - lists as nothing
ListRule LrUndef
mov ax,100h
SKIP2_PSW
ListRule LrNull
sub ax,ax
jmp PushRootCharsStg1 ;list null
;return to outer loop
tOrwKey LABEL WORD
DW ORW_OFF
DW ORW_ON
DW ORW_LIST
ListRule LrStKey
call PushRootOpRwSpc ;list KEY
lods WORD PTR es:[si] ;ax = 0,1,2 for ON,OFF,LIST
shl ax,1
xchg bx,ax ;bx = index into tOrwKey
mov ax,[tOrwKey+bx] ;ax = ON,OFF,LIST
jmp PushRootRwStg1 ;list it
;return to outer loop
PushDefSeg PROC NEAR
call PushRootOpRwSpc ;list DEF
mov ax,ORW_SEG
jmp PushRootRwSpc ;list SEG
; and return to caller
PushDefSeg ENDP
ListRule LrStDefSeg1
call PopRootPushTemp
call PushDefSeg ;list "DEF SEG "
mov ax,' ='
call PushRootChars ;list "= "
jmp PushListStg1 ;push temp list to root as 1 node
; and return to outer loop
ListRule LrStDefSeg0
call PushDefSeg ;list "DEF SEG "
J3_Stg1Loop:
jmp Stg1Loop ;return to outer loop
ListRule LrStOptionBase0
ListRule LrStOptionBase1
mov ax,ORW_OPTION
call PushRootRwSpc ;list OPTION
mov ax,ORW_BASE
call PushRootRwSpc ;list BASE
call PushRootOpChars ;list opcode's char ('0' or '1')
jmp Stg1Loop ;return to outer loop
;***************************************************************************
; LrStWidthLprint
; Purpose:
; [exp] ==> [[exp LPRINT WIDTH]]
;
;***************************************************************************
ListRule LrStWidthLprint
call PushTempOpRwSpc ;list WIDTH
mov ax,ORW_LPRINT
jmp SHORT Palette1 ;list LPRINT exp, return to outer loop
ListRule LrStPaletteUsing
call PushTempOpRwSpc ;list PALETTE
mov ax,ORW_USING
Palette1:
call PushTempRwSpc ;list USING
Palette2:
jmp PopPushPushListStg1 ;list exp and return to outer loop
; [exp] ==> [[exp = DATE$/TIME$]]
;
ListRule LrStDate_
ListRule LrStTime_
call PushTempOpRwSpc ;list DATE$/TIME$
mov ax,' ='
call PushTempChars ;list '= '
jmp PopPushPushListStg1 ;list exp and return to outer loop
;***************************************************************************
; LrStLocate
; Purpose:
; List a statement like CLEAR or LOCATE which takes a variable number
; of optional arguments.
; [exp, ..., exp] ==> [[exp, ... LOCATE]]
; For example, if the stmt was SCREEN ,,x,y
; the pcode would be:
; opLit0 opLit0 opIdLd(x) opLit1 opIdLd(y) opLit1 opStScreen
; and the root stack on entry would have:
; [1 y 1 x 0 0]
; On exit, the root stack would have:
; [y "," x "," "," LOCATE]
;
;***************************************************************************
ListRule LrStLocate
ListRule LrStScreen
ListRule LrStColor
ListRule LrStClear
call PushTempOpRwSpc ;push opcode's resword
lods WORD PTR es:[si] ;ax = number of arguments
mov [cLsArgs],al
call PushCommaArgs ;copy cLsArgs from root to temp
; and separate them by commas
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -