📄 ssrules.asm
字号:
;Expand the destination text to make room for add'l executor
push si
mov si,di
add di,cx ;New emit address
push di
push cx
mov cx,si
sub cx,bx ;cb between insert oTx and old emit oTx
shr cx,1 ;count of words
inc cx ;Include word at old emit address
push es
pop ds ;Prepare for es -> es copy
std ;Copy direction is down
rep movsw ;Copy to make room for executor
cld
mov [bx],ax ;Insert additional executor
pop cx
add bx,cx ;Point bx to next insertion point
push ss
pop ds ;Restore data segment
pop di
pop si
ret
InsertOME:
push ax
mov ax,ER_OM ;Signal out-of-memory error
call SsError
pop ax
InsertFail:
stc ;Inform caller to make sure nothing is inserted
ret
;***
;InsertBranchBos
;
;Purpose:
; Inserts an exBranch after opBos in current line.
;Entry:
; cx = operand
;Exit:
; bx - oTx after inserted exBranch
; si, di - adjusted for inserted pcode
;Preserves:
; cx
;******************************************************************************
InsertBranchBos: ;Insert Branch after opBos
mov bx,[SsOTxStart] ; Points to first opcode after BOS
InsertBranch:
mov ax,codeOFFSET exBranch
Insert1Op:
;Insert opcode in ax with operand in cx
;Preserves all (bx updated)
push cx
mov cx,4 ;Has a 2-byte operand
call InsertCx
pop cx
jc NoOperand
mov PTRTX[bx-2],cx
NoOperand:
ret
subttl Executor Input Types Maps
page
; These tables allow rapid calculation of what coercion is required
; for parameters for most BAsiC statements and functions.
;
; The naming convention is:
; tCo<input arg count><input type reqs|>to<required type>
;
; where:
; <input arg count> is the number of dimensions in the table.
; <input type reqs> shows the limitations on the types handled
; by the statements/functions using this table.
; This field may be empty.
; <required type> This is the required final coerced type rule.
; This is different for "+" and "*" for
; example, as both have the same required type
; rule (types must be the same), but "*" has
; an input types restriction (no strings).
;
;
; These tables are used to calculate the required input type for unary
; operators and cases where binary operators require input types coerced
; to be equal.
;
; RulTab and related macros added with [14]
;
;------------------------------------------------------------
;Initialize a two-dimensional coercion table
StartTab MACRO
LinNo = 0
ENDM
;Only define a byte if condition is true
DbIf MACRO Byte,Cond
IF Cond
db Byte
ENDIF
ENDM
;Associate a line number (LinNo) with a type
LinNo = 0
IRP Typ,<I2,I4,R4,R8,Cy,Sd,Tx,Field>
LinNo = LinNo+1
Lin&Typ = LinNo
ENDM
;Make a line of two-dimensional table
RulTab MACRO I2,I4,R4,R8,Cy,Sd,Tx,Field
LinNo = LinNo+1
IF LinNo EQ LinCy
EXITM
ENDIF
IF LinNo EQ LinTx
EXITM
ENDIF
IF LinNo EQ LinField
EXITM
ENDIF
RulLine I2,I4,R4,R8,Cy,Sd,Tx,Field
ENDM
;Make a line of a coercion table using only those types enabled
RulLine MACRO I2,I4,R4,R8,Cy,Sd,Tx,Field
Db I2
Db I4
Db R4
Db R8
Db Sd
ENDM
tCo2toSame:
StartTab
public tCo1toNotSD
tCo1toNotSD:
RulTab ET_I2, ET_I4, ET_R4, ET_R8, ET_CY, LOWUND, LOWUND, ET_FIELD;I2
RulTab ET_I4, ET_I4, ET_R8, ET_R8, ET_CY, LOWUND, LOWUND, ET_FIELD;I4
RulTab ET_R4, ET_R8, ET_R4, ET_R8, ET_CY, LOWUND, LOWUND, ET_FIELD;R4
RulTab ET_R8, ET_R8, ET_R8, ET_R8, ET_CY, LOWUND, LOWUND, ET_FIELD;R8
RulTab ET_CY, ET_CY, ET_CY, ET_CY, ET_CY, LOWUND, LOWUND, ET_FIELD;CY
RulTab LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, ET_SD, ET_TX, ET_FIELD;SD
RulTab LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, ET_TX, ET_TX, ET_TX ;TX
RulTab ET_FIELD, ET_FIELD, ET_FIELD, ET_FIELD, ET_FIELD, ET_FIELD, ET_TX, ET_FIELD;Field
;------------------------------------------------------------
tCo2NotSdtoSame:
StartTab
RulTab ET_I2, ET_I4, ET_R4, ET_R8, ET_CY, LOWUND, LOWUND, ET_FIELD;I2
RulTab ET_I4, ET_I4, ET_R8, ET_R8, ET_CY, LOWUND, LOWUND, ET_FIELD;I4
RulTab ET_R4, ET_R8, ET_R4, ET_R8, ET_CY, LOWUND, LOWUND, ET_FIELD;R4
RulTab ET_R8, ET_R8, ET_R8, ET_R8, ET_CY, LOWUND, LOWUND, ET_FIELD;R8
RulTab ET_CY, ET_CY, ET_CY, ET_CY, ET_CY, LOWUND, LOWUND, ET_FIELD;CY
RulTab LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND ;SD
RulTab LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND ;TX
RulTab ET_FIELD, ET_FIELD, ET_FIELD, ET_FIELD, ET_FIELD, LOWUND, LOWUND, ET_FIELD ;Field
;------------------------------------------------------------
;------------------------------------------------------------
tCo2toI2I4:
StartTab
RulTab ET_I2, ET_I4, ET_I4, ET_I4, ET_I4, LOWUND, LOWUND, ET_I4 ;I2
RulTab ET_I4, ET_I4, ET_I4, ET_I4, ET_I4, LOWUND, LOWUND, ET_I4 ;I4
RulTab ET_I4, ET_I4, ET_I4, ET_I4, ET_I4, LOWUND, LOWUND, ET_I4 ;R4
RulTab ET_I4, ET_I4, ET_I4, ET_I4, ET_I4, LOWUND, LOWUND, ET_I4 ;R8
RulTab ET_I4, ET_I4, ET_I4, ET_I4, ET_I4, LOWUND, LOWUND, ET_I4 ;CY
RulTab LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND ;SD
RulTab LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND ;TX
RulTab ET_I4, ET_I4, ET_I4, ET_I4, ET_I4, LOWUND, LOWUND, ET_I4 ;Field
;------------------------------------------------------------
tCo2toR4R8:
StartTab
RulTab ET_R4, ET_R8, ET_R4, ET_R8, ET_R8, LOWUND, LOWUND, ET_R8 ;I2
RulTab ET_R8, ET_R8, ET_R8, ET_R8, ET_R8, LOWUND, LOWUND, ET_R8 ;I4
RulTab ET_R4, ET_R8, ET_R4, ET_R8, ET_R8, LOWUND, LOWUND, ET_R8 ;R4
RulTab ET_R8, ET_R8, ET_R8, ET_R8, ET_R8, LOWUND, LOWUND, ET_R8 ;R8
RulTab ET_R8, ET_R8, ET_R8, ET_R8, ET_R8, LOWUND, LOWUND, ET_R8 ;CY
RulTab LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND ;SD
RulTab LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND ;TX
RulTab ET_R8, ET_R8, ET_R8, ET_R8, ET_R8, LOWUND, LOWUND, ET_R8 ;Field
;------------------------------------------------------------
;------------------------------------------------------------
tCo2toI2R4:
StartTab
RulTab ET_I2, ET_R4, ET_R4, ET_R4, ET_R4, LOWUND, LOWUND, ET_R4 ;I2
RulTab ET_R4, ET_R4, ET_R4, ET_R4, ET_R4, LOWUND, LOWUND, ET_R4 ;I4
RulTab ET_R4, ET_R4, ET_R4, ET_R4, ET_R4, LOWUND, LOWUND, ET_R4 ;R8
RulTab ET_R4, ET_R4, ET_R4, ET_R4, ET_R4, LOWUND, LOWUND, ET_R4 ;R8
RulTab ET_R4, ET_R4, ET_R4, ET_R4, ET_R4, LOWUND, LOWUND, ET_R4 ;CY
RulTab LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND ;SD
RulTab LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND ;TX
RulTab ET_R4, ET_R4, ET_R4, ET_R4, ET_R4, LOWUND, LOWUND, ET_R4 ;Field
;------------------------------------------------------------
tCo1toI2SD:
RulLine ET_I2, ET_I2, ET_I2, ET_I2, ET_I2, ET_SD, ET_TX, ET_FIELD
;------------------------------------------------------------
tCo1toI2I4:
RulLine ET_I2, ET_I4, ET_I4, ET_I4, ET_I4, LOWUND, LOWUND, ET_I4
;------------------------------------------------------------
tCo1toSame:
RulLine ET_I2, ET_I4, ET_R4, ET_R8, ET_CY, ET_SD, ET_TX, ET_FIELD
subttl Coercion Rules Table
page
MakRule MACRO
irule = 0
;Rule names are composed of two parts - the input specification
; and the output specification. The naming convention is:
;
; SSR_<input spec>_<output spec>
;
; <input spec> starts with the number of arguments
; <output spec> of <LOWUND> indicates op emits the input type.
;
;NOTE:
; Rules that have an output type the same as the only input type could
; be represented with <LOWUND> or an explicit type as <output spec>.
; These are not the same rule, as some scan routines require explicit
; type as <output spec>. However, there are no scan routines that
; handle <LOWUND> as <output spec> but do not handle an explicit type.
;
;NOTE:
; If output type = ET_MAX then no coercion routine uses that output type.
; That rule field could be modified for use by some other scan routine.
;
;params: <ispec><ospec>, coercion table, output type
ruler 2Any_Same, tCo2toSame, <LOWUND>
ruler 2NotSD_Same, tCo2NotSDtoSame,<LOWUND>
ruler 2I2I4_Same, tCo2toI2I4, <LOWUND>
ruler 2R4R8_Same, tCo2toR4R8, <LOWUND>
public SSR_Div
SSR_Div equ SSR_2R4R8_Same
ruler 2I2R4_I2, tCo2toI2R4, ET_I2
ruler 2Any_I2, tCo2toSame, ET_I2
ruler 2I2R4_None, tCo2toI2R4, 0
ruler 1NotSD_Same, tCo1toNotSD, <LOWUND>
ruler 1I2I4_Same, tCo1toI2I4, <LOWUND>
ruler 1I2I4_SD, tCo1toI2I4, ET_SD
ruler 1I2SD_SD, tCo1toI2SD, ET_SD
ruler 1I2SD_I4, tCo1toI2SD, ET_I4
ruler 1NotSD_I2, tCo1toNotSD, ET_I2
ruler 1NotSD_SD, tCo1toNotSD, ET_SD
ruler 1Any_None, tCo1toSame, 0
ruler 1I2SD_None, tCo1toI2SD, 0
;Label Reference Rules
; <#labs,#args> <arg coercion> <#label>
ruler 1Lab0Arg, UNDEFINED, 1
ruler 1LabMain0Arg, UNDEFINED, <1 OR 80h>
ruler nLab1Arg, 0, LOWUND
;Rules for SS_4ET_ET
; NOTE: The low order nibble applies to the LAST argument in the syntax.
; The rule names are in syntax order.
ruler I2_None, <ET_I2>, 0
ruler I4_None, <ET_I4>, 0
ruler R4_None, <ET_R4>, 0
ruler R8_None, <ET_R8>, 0
ruler SD_None, <ET_SD>, 0
ruler I4I2_None, <ET_I4,ET_I2>, 0
ruler I2I4_None, <ET_I2,ET_I4>, 0
ruler R4I2_None, <ET_R4,ET_I2>, 0
ruler I2SD_None, <ET_I2,ET_SD>, 0
ruler 2I2_None, <ET_I2,ET_I2>, 0
ruler 2SD_None, <ET_SD,ET_SD>, 0
ruler I2R4_None, <ET_I2,ET_R4>, 0
ruler SDI2_None, <ET_SD,ET_I2>, 0
ruler SDI4_None, <ET_SD,ET_I4>, 0
ruler SD2I4_None, <ET_SD,ET_I4,ET_I4>, 0
ruler I42I2_None, <ET_I4,ET_I2,ET_I2>, 0
ruler SD2I2_None, <ET_SD,ET_I2,ET_I2>, 0
ruler SDI2SD_None, <ET_SD,ET_I2,ET_SD>, 0
ruler 4I2_None, <ET_I2,ET_I2,ET_I2,ET_I2>,0
ruler 4R4_None, <ET_R4,ET_R4,ET_R4,ET_R4>,0
ruler SDI2SDI2_None, <ET_SD,ET_I2,ET_SD,ET_I2>,0
ruler I2_I2, <ET_I2>, ET_I2
ruler I2_I4, <ET_I2>, ET_I4
ruler I2_R4, <ET_I2>, ET_R4
ruler I2_SD, <ET_I2>, ET_SD
ruler I4_I2, <ET_I4>, ET_I2
ruler I4_I4, <ET_I4>, ET_I4
ruler I4_SD, <ET_I4>, ET_SD
ruler R4_R4, <ET_R4>, ET_R4
ruler R4_SD, <ET_R4>, ET_SD
ruler R8_SD, <ET_R8>, ET_SD
ruler SD_I2, <ET_SD>, ET_I2
ruler SD_I4, <ET_SD>, ET_I4
ruler SD_R4, <ET_SD>, ET_R4
ruler SD_R8, <ET_SD>, ET_R8
ruler SD_SD, <ET_SD>, ET_SD
ruler I2I4_I2, <ET_I2,ET_I4>, ET_I2
ruler I2I2_SD, <ET_I2,ET_I2>, ET_SD
ruler I2I2_I2, <ET_I2,ET_I2>, ET_I2
ruler I2I2_I4, <ET_I2,ET_I2>, ET_I4
ruler SDSD_I2, <ET_SD,ET_SD>, ET_I2
ruler I2SD_SD, <ET_I2,ET_SD>, ET_SD
ruler SDI2_SD, <ET_SD,ET_I2>, ET_SD
ruler R4I2_R4, <ET_R4,ET_I2>, ET_R4
ruler 3I2_I2, <ET_I2,ET_I2,ET_I2>, ET_I2
ruler I2SDSD_I2, <ET_I2,ET_SD,ET_SD>, ET_I2
ruler SD2I2_SD, <ET_SD,ET_I2,ET_I2>, ET_SD
ENDM
;First define the rule name constant and build a table of the word parameter
ruler MACRO rname,ptCoerce,oTypOut
;params are rule name, coercion table, output type
SSR_&rname = irule
irule = irule + 1
Rule = 0
IRP Arg,<ptCoerce>
Rule = Rule*10H+Arg
ENDM
dw Rule
ENDM
PUBLIC tRuleWord
tRuleWord:
MakRule
;Next build a table of the byte parameter
ruler MACRO rname,ptCoerce,oTypOut
;params are rule name, coercion table, output type
db oTypOut
ENDM
PUBLIC tRuleByte
tRuleByte:
MakRule
.xlist
include ssoprule.inc
.list
sEnd SCAN
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -