- Visual C++源码
- Visual Basic源码
- C++ Builder源码
- Java源码
- Delphi源码
- C/C++源码
- PHP源码
- Perl源码
- Python源码
- Asm源码
- Pascal源码
- Borland C++源码
- Others源码
- SQL源码
- VBScript源码
- JavaScript源码
- ASP/ASPX源码
- C#源码
- Flash/ActionScript源码
- matlab源码
- PowerBuilder源码
- LabView源码
- Flex源码
- MathCAD源码
- VBA源码
- IDL源码
- Lisp/Scheme源码
- VHDL源码
- Objective-C源码
- Fortran源码
- tcl/tk源码
- QT源码
ssif.asm
资源名称:DOS系统的源代码.rar [点击查看]
上传用户:xiaoan1112
上传日期:2013-04-11
资源大小:19621k
文件大小:14k
源码类别:
操作系统开发
开发平台:
Visual C++
- page 49,132
- TITLE ssif - scan support for IF related opcodes
- ;***
- ;ssif.asm
- ;
- ; Copyright <C> 1986, Microsoft Corporation
- ;
- ;Purpose:
- ; Scan IF statement opcodes.
- ;
- ; Runtime behavior of IF-THEN-ELSE opcodes:
- ; ----------------------------------------
- ; <exp> opStIf(oText) - branch to oText if exp is zero (false)
- ; <exp> opStIfLab(label) - branch to label if exp is non-zero (true)
- ; <exp> opStIfLabDirect(label) - branch to label if exp is non-zero (true)
- ; opStElse(oText) - unconditionally branch to oText
- ; opStElseLab(label) - unconditionally branch to label
- ; opStElseLabDirect(label) - unconditionally branch to label
- ; opStElseNop - nop
- ; <exp> opStIfBlock(oText) - branch to oText if exp is zero (false)
- ; <exp> opStElseIf(oText) - branch to oText if exp is zero (false)
- ; opStEndIfBlock - nop
- ;
- ; NOTE: When in direct mode, Parser emits opStIfLabDirect instead of
- ; opStIfLab, and opStElseLabDirect instead of opStElseLab.
- ;
- ; Single line IF statement syntax to pcode mappings:
- ; -------------------------------------------------
- ;
- ; Syntax: IF <exp> GOTO <label>
- ;
- ; Pcode: <exp> opStIfLab(label)
- ;
- ; ============================================================
- ; Syntax: IF <exp> THEN <stmt list>
- ;
- ; +--------------+
- ; Pcode: <exp> opStIf(|) <stmt list> | opBol
- ;
- ; ============================================================
- ; Syntax: IF <exp> THEN <label> ELSE <label>
- ;
- ; Pcode: <exp> opStIfLab(label) opStElseNop opStElseLab(label)
- ;
- ; ============================================================
- ; Syntax: IF <exp> THEN <label> ELSE <stmt list>
- ;
- ; Pcode: <exp> opStIfLab(label) opStElseNop <stmt list>
- ;
- ; NOTE: <stmt list> can contain more single line IF stmts
- ;
- ; ============================================================
- ; Syntax: IF <exp> THEN <stmt list> ELSE <label>
- ;
- ; +-------------------------+
- ; Pcode: <exp> opStIf(|) <stmt list> opStElse(|)|opStElseLab(label)|opBol
- ; +--------------------+
- ;
- ; ============================================================
- ; Syntax: IF <exp> THEN <stmt list> ELSE <stmt list>
- ;
- ; +--------------------------+
- ; Pcode: <exp> opStIf(|) <stmt list> opStElse(|) | <stmt list> | opBol
- ; +----------------+
- ;
- ; Block IF statement syntax to pcode mappings:
- ; -------------------------------------------
- ; Syntax: IF <exp> THEN
- ;
- ; Pcode: <exp> opStIfBlock(oText to <exp> before ELSEIF, or oText
- ; beyond ELSE/END IF opcode)
- ;
- ; ============================================================
- ; Syntax: ELSEIF <exp> THEN
- ;
- ; Pcode: opBol <exp> opStElseIf(oTx beyond ELSEIF/ELSE/END IF)
- ;
- ; +- to beyond END IF
- ; Bound: opBol exBranch(|) <exp> opStElseIf(oTx past ELSEIF/ELSE/END IF)
- ;
- ; NOTE: Scanner inserts exBranch(oText to beyond END IF opcode)
- ; after the opBol and before <exp>, so code falling into the
- ; ELSEIF will branch beyond END IF without evaluating <exp>.
- ;
- ; ============================================================
- ; Syntax: ELSE
- ;
- ; Pcode: opStElse(oText to beyond END IF opcode)
- ;
- ; ============================================================
- ; Syntax: END IF
- ;
- ; Pcode: opStEndIfBlock
- ;
- ; The scan routines within this module depend on the BOL scan routine
- ; to bind unbound line IF and ELSE operands. The BOL scan routine
- ; binds all IF/ELSE frame entries until it discovers a Block IF/ELSE
- ; entry, some other control structure frame that can't be bound, or
- ; the bottom of the stack.
- ;
- ; For speed, the IF and ELSE scan routines set a flag to let BOL know
- ; that a line version of IF or ELSE has been pushed. The flag is
- ; cleared by BOL after binding all line IF and ELSE entries.
- ;
- ; The IF and ELSE scan routines will not push a Block frame on the stack
- ; when there is a Line frame already on the stack.
- ;
- ;
- ;****************************************************************************
- .xlist
- include version.inc
- SSIF_ASM = ON
- IncludeOnce qbimsgs
- IncludeOnce opmin
- IncludeOnce ssint
- IncludeOnce variable
- .list
- assumes ds, DATA
- assumes es, NOTHING
- assumes ss, DATA
- assumes cs, SCAN
- sBegin SCAN
- subttl Static data area definitons.
- page
- ;***
- ;Ss_If, Ss_IfBlock
- ;Purpose:
- ; Scan entries for IF.
- ;
- ; Scan tasks for IF include:
- ; - ensuring the entry type is a fundamental, non string data type.
- ; - selecting the IF executor varient for the argument data type.
- ; - binding the label of opStIfLab<Direct|>
- ; - pushing an IF frame on the scan stack as follows:
- ; push UNDEFINED for start of block IF exBranch chain
- ; push oTx of IF operand
- ; push IF frame label (identifying Standard, Block, or Label IF)
- ;
- ;Input:
- ; Standard scan entrypoint
- ;Output:
- ; Standard scan exit
- ;***************************************************************************
- SsProc IfLab
- mov dx,STYP_IfLab ;Type of stack entry for IF w/ a label
- jmp short SsIfCom
- SsProc IfBlock
- mov dx,STYP_IfBlock ;Type of stack entry for block IF
- jmp short SsIfCom ;Common IF code
- SsProc If
- mov dx,STYP_IF ;Push an IF entry on the stack
- SsIfCom:
- or SsFlags,SSF_If ;Set end of line IF handling flag
- pop ax ;Get type of last expression
- pop cx ;Remove expression address
- cCall MapOpToExeNumeric ;Type explode the executor
- STOSWTX ;Emit the executor
- PUSHI ax,UNDEFINED ;Push end of Block IF ExBranch chain
- push di ;Push operand address
- push dx ;Push frame type
- test dx,STYP_Lab ;Is this an IF w/ a label
- jnz SsIfLab ;Brif yes
- MOVSWTX ;Skip the operand in source and dest.
- SsIfComX:
- mov bx,sp
- sub bx,2
- mov [SsBosStack],bx ; Reset BOS SP mark for 1 Line If
- mov [SsOTxStart],di ; Reset DOS oTx mark for 1 Line If
- jmp [ScanRet]
- SsIfLab:
- mov ax,PTRTX[si+2]
- sub ax,opBos ; Is this an opBos?
- jz @F ; Brif yes
- dec ax ; Is this an opBosSp
- jne ElsePresent ; Brif yes. Works ok!
- @@:
- push [ScanRet] ; Save exit address
- mov [ScanRet],scanOFFSET BindIfLab ; We need to clean up
- ElsePresent:
- ;Bind the label for this If
- mov cx,1 ;need to bind 1 label
- jmp LabelBindCur ;Bind label to current scope and return to
- ;to main scan loop
- BindIfLab:
- pop [ScanRet] ; Restore loop address
- mov bx,di ; Insert at current location
- call InsertBranch ; Insert exBranch. CY set if error.
- jc SsIfComX ; Brif error
- mov bx,sp ; Get stack frame pointer
- lea ax,[di-2] ; oTx of exBranch operand
- mov [bx].FIF_Id,STYP_Else ; Allow BOL update
- mov [bx].FIF_oTx,ax ; Update in frame
- jmp SsIfComX ; Exit
- ;***
- ;Ss_Else,Ss_ElseNop
- ;Purpose
- ; Scan ELSE varients.
- ;
- ; opElseLab<|Direct> requires label binding only. These are always
- ; immediately preceeded by an opStElseNop or opStElse. Therefore,
- ; opElseLab<|Direct> does not need to examine or push a stack entry.
- ; So, opElseLab<|Direct> are scanned as label reference opcodes like
- ; GOTO.
- ;
- ; Scan tasks for other Else variants are:
- ; - emit executor
- ; - walk stack frames to find first non-Else/non-ElseNop frame
- ; - check for if frame, check errors:
- ; + IF nesting error if frame is not an IF
- ; - change IF stack frame to ELSE stack frame
- ; + frame type is Block if IF was a Block type
- ; + set ELSE variant frame type
- ; + opStElseNop just changes frame to Set STYP_Lab bit -
- ; it requires no further binding.
- ; + leave address of exBranch chain, will be bound at ENDIF time
- ; + set address of ELSE operand
- ; - bind IF to address of ELSE if it was not a label varient of IF
- ;
- ; Scan tasks for ELSEIF are:
- ; - ensure the entry type is a fundamental, non string data type.
- ; - select and emit the ELSEIF executor varient for the argument
- ; data type.
- ; - insert an exBranch at BOS for exit from IF clause.
- ; - check for an IF frame, check errors:
- ; + IF nesting error if top frame is not an IF
- ; + BLOCK IF error if IF is not a BLOCK IF.
- ; - insert new exBranch into chain
- ; - change Block IF frame to an ELSEIF frame on the scan stack as follows:
- ; set new start of exBranch chain
- ; set oTx of ELSEIF operand
- ; leave IF frame id so next ELSEIF sees a BLOCK IF entry
- ;
- ;Input:
- ; Standard scanner convention
- ;Output:
- ; Standard scanner convention
- ;***************************************************************************
- SsProc ElseIf
- pop ax ;Get type of last expression
- pop dx ;Remove expression address
- cCall MapOpToExeNumeric ;Type explode the executor
- ; ax = executor
- STOSWTX ;Emit it
- mov bx,sp ;point to stack frame
- mov cx,[bx.FIF_oTxBranch] ;get next entry in ExBranch chain
- call InsertBranchBos ;insert exBranch after opBos
- ;bx = oTx after exBranch operand
- jc ElseIfScopeError ;Quit if OME
- xchg ax,bx ;ax = oTx after exBranch operand
- mov bx,sp ;point to stack frame
- cmp [bx.FIF_Id],STYP_IfBlock ;ELSEIF must match block IF
- jnz ElseIfScopeError ;brif nesting error
- dec ax
- dec ax ;point to exBranch operand
- mov [bx.FIF_oTxBranch],ax ;set next link in exBranch chain
- mov cx,[bx.FIF_oTx] ;get if operand address
- mov [bx.FIF_oTx],di ;set addr of else operand
- xchg ax,bx ;bx = ptr to txt
- MOVSWTX ;skip operand in source and destination
- inc bx
- inc bx ;move past exBranch operand
- xchg bx,cx ;bx = ptr to if operand, cx points past
- ;inserted exbranch
- mov PTRTX[bx],cx ;Bind if to ElseIf expression
- SsElseIfX:
- jmp short SsIfComX
- ;Error processing for Else opcodes.
- ElseIfScopeError:
- mov cx,STYP_Else ;push an ELSE frame for ELSEIF error
- ElseScopeError:
- mov ax,MSG_ElseWI ;ELSE without IF error
- call SsError
- cmp cx,STYP_ElseNop ;is this ElseNop?
- jz SsElseIfX ;brif ElseNop - don't push a frame
- PushI ax,UNDEFINED ;Flag no exbranch chain
- push di ;push else operand location
- push cx ;push else frame
- MOVSWTX ;skip operand in source and dest
- or [SsFlags],SSF_IF ;need BOS If processing to remove frame
- ElseScopeErrX:
- jmp short SsElseIfX ;continue scanning
- SsProc ElseNop
- mov cx,STYP_ElseNop ;Signal no stack entry
- jmp short SsElseCom
- SsProc Else
- mov cx,STYP_Else ;Prepare to build ELSE frame
- SsElseCom:
- STOSWTX ; and emit it
- mov bx,sp ;set up Frame addressablity
- sub bx,SIZE FIF ;Adjust for following add
- ; Skip all nested single line else's currently on scan stack. Walk
- ; back to first non-single else frame. If this frame is not an IF/ELSEIF
- ; frame, then we have a scoping error. Multiple Single else frames can
- ; be on the stack if a nested single if occurs in a single line else clause.
- SkipSingleElseLoop:
- add bx,SIZE FIF ;point to next stack frame
- mov ax,[bx.FIF_Id] ;ax = frame type
- cmp ax,STYP_Else ;is this a single line else frame?
- jz SkipSingleElseLoop ;brif so, examine next frame
- cmp ax,STYP_ElseNop ;is this a frame left from an if <lab>?
- jz SkipSingleElseLoop ;brif so, examine next frame
- ; bx - points to first non-single else stack frame.
- ; ax - frame type of stack frame
- ; cx - else variant we are processing
- test ax,STYP_If or STYP_Block
- jz ElseScopeError ;Not an IF on the stack - scoping error.
- mov dx,[bx.FIF_oTx] ;dx = oTx of preceding if operand
- test ax,STYP_Block ;is frame for BLOCK IF variant?
- jz NotBlockElse ;brif not - single line variant
- or cx,STYP_Block ;make this a block else
- NotBlockElse:
- DbAssertRel cx,nz,<STYP_IfBlock OR STYP_Lab>,SCAN,<Ss_ElseNop:saw opElseNop after BLOCK IF>
- or SsFlags,SSF_IF ;we may need BOL If processing
- mov [bx.FIF_Id],cx ;set frame as processed
- test cx,STYP_Lab ;is this ElseNop?
- jnz SsElseX ;brif so, no binding needed
- mov [bx.FIF_oTx],di ;emit else op location for else binding
- MOVSWTX ;skip operand in source and dest
- mov bx,dx ;bx = If operand location
- mov PTRTX[bx],di ;bind previous IF/ELSEIF to ELSE
- SsElseX:
- jmp SsIfComX
- EndIfScopeError:
- push ax ;Restore stack state
- mov ax,MSG_EWI ;ENDIF without block IF
- call SsError
- jmp short EndifX
- SsProc EndIf
- STOSWTX ; and emit it
- pop ax
- test ax,STYP_Block ;Is it a Block type frame entry
- jz EndIfScopeError ;Not a block IF or ELSE
- pop bx ;Pop stack frame
- mov PTRTX[bx],di ;Bind block IF or ELSE to this location
- pop bx ;get ptr to start of exBranch chain
- call BindExitCur ;call common EXIT chain binder
- EndifX:
- jmp [ScanRet] ; and continue
- ;MapOpToExeNumeric
- ;Purpose:
- ; Type explode to executor for this opcode.
- ;
- ; This routine works for full type explosion for numeric
- ; data types only
- ;Input:
- ; ax = type from stack entry
- ; bx = opcode * 2
- ;Output:
- ; ax = executor
- ;Preserves:
- ; cx,dx
- public MapOpToExeNumeric
- MapOpToExeNumeric:
- mov bx,mpOpExe[bx] ;Load the exe map address
- .erre ST_Typ_Mask EQ 0ffh ; Assure CBW is sufficient
- cbw ; Clear flags in scan stack
- .erre ET_RC EQ 0 ; Assure that DEC is sufficient
- dec ax ; ET_RC -> 0FFFFh
- cmp al,ET_MaxNum ; Detect user defined type
- jb MapType ;SD and record version not in language
- call TMError
- .erre ET_I2 EQ 1 ; Assure XOR is sufficient
- xor ax,ax ; Use I2 executor
- MapType:
- add bx,ax
- add bx,ax ;Index to executor for this type
- mov ax,word ptr cs:[bx] ; Load executor, zero relative
- ret
- subttl Opcode to executor maps for IF
- page
- public mStIfBlockOpExe
- mStIfBlockOpExe:
- DWEXT exStIfBlockI2
- DWEXT exStIfBlockI4
- DWEXT exStIfBlockR8
- DWEXT exStIfBlockR8
- public mStIfLabDirectOpExe
- mStIfLabDirectOpExe:
- DWEXT exStIfLabDirectI2
- DWEXT exStIfLabDirectI4
- DWEXT exStIfLabDirectR8
- DWEXT exStIfLabDirectR8
- public mStIfOpExe
- mStIfOpExe:
- DWEXT exStIfI2
- DWEXT exStIfI4
- DWEXT exStIfR8
- DWEXT exStIfR8
- public mStIfLabOpExe
- mStIfLabOpExe:
- DWEXT exStIfLabI2
- DWEXT exStIfLabI4
- DWEXT exStIfLabR8
- DWEXT exStIfLabR8
- public mStIfGotoLabOpExe
- mStIfGotoLabOpExe:
- DWEXT exStIfGotoLabI2
- DWEXT exStIfGotoLabI4
- DWEXT exStIfGotoLabR8
- DWEXT exStIfGotoLabR8
- public mStElseIfOpExe
- mStElseIfOpExe:
- DWEXT exStElseIfI2
- DWEXT exStElseIfI4
- DWEXT exStElseIfR8
- DWEXT exStElseIfR8
- sEnd SCAN
- end