ssrules.asm
上传用户:xiaoan1112
上传日期:2013-04-11
资源大小:19621k
文件大小:23k
源码类别:

操作系统开发

开发平台:

Visual C++

  1. page 49,132
  2. TITLE ssrules - Scanner Table Definitions
  3. ;***
  4. ;ssrules.asm - Scanner Table Definitions
  5. ;
  6. ; Copyright <C> 1986, Microsoft Corporation
  7. ;
  8. ;Purpose:
  9. ;
  10. ;   This module defines the coercion and rules tables used by the scanner.
  11. ;   The following is a description of how all scan tables are organized.
  12. ;
  13. ;   tOpSsDisp:     tOpAtr:     tOpRule:     tOpExe:
  14. ;     ssOp1     op1Atr     op1Rule     ex1
  15. ;     ssOp2     op2Atr     op2Rule     ex2
  16. ;     ...      ...      ...      ...
  17. ;
  18. ;   tOpSsDisp is the scan dispatch for the opcode.  Entries are 1 word.
  19. ;
  20. ;   tOpAtr is the atribute byte for the opcode. Entries are 1 byte.  The
  21. ;   atribute value is the number of operand bytes owned by the opcode.
  22. ;   Some opcodes own a variable number of operand bytes.  In these cases
  23. ;   the first operand word is the number of operand bytes - 2. This is
  24. ;   signified by LOW UNDEFINED in the atribute table.
  25. ;
  26. ;   tOpRule is a scan helper byte that can be:
  27. ; 1. a rule table index. Used in this way when there are more than one
  28. ;    variables in the opcode to executor algorithm.  The rule table index
  29. ;    is used to index tRuleWord and tRuleByte desribed below.
  30. ; 2. an ET type. Used in this manner when the emitted type is the only
  31. ;    variable in the opcode to executor algorithm.  An example is all
  32. ;    intrinsic functions that have no operands (ERR, ERL,...).
  33. ;
  34. ;   tOpExe is the executor for the opcode.  If an opcode has several executors
  35. ;   then tOpExe contains the address of an ordered list of executors for
  36. ;   the opcode.
  37. ;
  38. ;   tRuleWord:
  39. ; This table usually contains one of the following:
  40. ; 1. coercion table address
  41. ; 2. other scan routine specific information such as an ET type.
  42. ;
  43. ;   tRuleByte:
  44. ; This table almost always contains an ET type which is the emitted
  45. ; type for opcodes using this rule.  The special emitted type
  46. ; LOW UNDEFINED indicates that the coerced input type is to be emitted.
  47. ; For example, opAdd emits an I2 when the arguments are I2.
  48. ;
  49. ;   tCo<rule>
  50. ; These are the coercion tables. They are either one or two dimensional
  51. ; and overlay each other as much as possible in order to save space.
  52. ; Coercion tables contain:
  53. ; 1. ET types.  These are present when coercion may be required. The
  54. ;    type is the target type to which the current argument(s) must be
  55. ;    coerced.
  56. ; 2. 0.  This value is used as a speed hack.  It is present when it is
  57. ;    known that coercion is not required.
  58. ; 3. LOW UNDEFINED.  This value is used to indicate "type mismatch"
  59. ;    was detected.
  60. ;
  61. ;   tCoerceExe is a 2 dimensional (typeXtype) table of coercion executor
  62. ;   addresses.
  63. ;
  64. ;In general, these tables are accessed as follows (refer to following diagram):
  65. ; 1. The opcode is used to index into tOpRule to find the rule index
  66. ;    for the current op. This allows a single scan routine to scan
  67. ;    a family of related opcodes.
  68. ; 2. The rule index is used to find the coercion table and the emitted
  69. ;    type for the current op.
  70. ; 3. Arguments are popped from the scan stack and used to index the
  71. ;    coercion table.
  72. ; 4. For opcodes that emit a value the emitted type and current
  73. ;    expression fragment pcode address are pushed on the stack.
  74. ;
  75. ; tOpRule:    tRuleWord: tRuleByte:
  76. ;     [index]
  77. ;    opcode-------->[index]--------> [ptCoerce][ET_emit]
  78. ;     [...  ]  |
  79. ;  +---------------->tCoerce
  80. ;
  81. ;
  82. ;****************************************************************************
  83. .xlist
  84. include  version.inc
  85. SSRULES_ASM = ON
  86. IncludeOnce context      
  87. IncludeOnce opintrsc
  88. IncludeOnce pcode
  89. IncludeOnce qbimsgs
  90. IncludeOnce ssint
  91. IncludeOnce txtmgr
  92. IncludeOnce variable
  93. .list
  94. assumes cs, SCAN
  95. assumes ds, DATA
  96. assumes SS, DATA
  97. sBegin CODE
  98. extrn exLitI21:near ;Literal executor
  99.     extrn   exPushSeg:near
  100.     extrn   exCopyTmpAr:near
  101. sEnd CODE
  102. subttl Coercion Label Definitions
  103. sBegin SCAN
  104. extrn GetTrueType:near
  105. mOpExLitR8 label word     
  106. DWEXT exLitR80     
  107. DWEXT exLitR81     
  108. DWEXT exLitR82     
  109. DWEXT exLitR83     
  110. DWEXT exLitR84     
  111. DWEXT exLitR85     
  112. DWEXT exLitR86     
  113. DWEXT exLitR87     
  114. DWEXT exLitR88     
  115. DWEXT exLitR89     
  116. DWEXT exLitR810     
  117. subttl Coercion Support Functions
  118. page
  119. ;***
  120. ;SsCoerceN - coerce n expressions on the scan stack to specified type
  121. ;Purpose:
  122. ; Coerce n expressions on the scan stack to specified type.
  123. ;
  124. ;Input:
  125. ; ax = oTyp of target (Record = ET_RC)
  126. ; cx = count to coerce
  127. ; si/di scan source and destination in pcode
  128. ;Output:
  129. ; si/di updated if any coercion was required.
  130. ; f_StaticCalc set FALSE if any expression was not a literal
  131. ;
  132. ;Preserves:
  133. ; ax,bx
  134. ;***************************************************************************
  135. public SsCoerceN
  136. SsCoerceN:
  137. pop [SsParmCnt] ; Get return address out of the way
  138. jcxz EndCoerceN
  139. .erre ET_RC EQ 0 ; Assure DEC is sufficient
  140. dec ax ; Force ET_RC -> 0ffffh
  141. cmp ax,ET_MaxNum ; Numeric type?
  142. jb SsCoerceNStart
  143. call TMError 
  144. xor ax,ax ; Use valid type (ET_I2)
  145. SsCoerceNStart: 
  146. inc ax ; Restore correct oTyp
  147. SsCoerceNLoop:
  148. pop dx ; Get oType
  149. push dx ; But keep it on stack
  150. xor dh,high ST_Lit?  ;High bits now zero if literal
  151. test dh,0C0H  ;Determine if this index is a literal.
  152. jz SsCoerceNNotLit  ;Not a literal index
  153. mov f_StaticCalc,FALSE ;Indicate not a $STATIC array if this
  154. SsCoerceNNotLit: ; is the first reference.
  155. test dh,ST_ByVal+ST_Seg ; Have ByVal or Seg been used?
  156. jz @F ; Brif no
  157. call TMError 
  158. @@:
  159. call EnsureArgType
  160. loop SsCoerceNLoop ;Go check next index
  161. EndCoerceN:
  162. jmp [SsParmCnt] ; Return to caller
  163. page
  164. ;***
  165. ;EnsureArgType
  166. ;Purpose:
  167. ; Ensure that the expression entry on the stack is of the desired
  168. ; type.
  169. ;Input:
  170. ; ax = type required for this expression
  171. ; si/di scan source and emit
  172. ;
  173. ; ParmW oTxExp
  174. ; ParmW oTypExp (Records use ET_RC)
  175. ;
  176. ;Output:
  177. ; ax = oTyp of target (Records use true oTyp)
  178. ;Preserves:
  179. ; bx,cx,dx
  180. ;****
  181. cProc EnsureArgType,<NEAR,PUBLIC>,<ax,bx,cx,dx>
  182. ParmW oTxExp
  183. ParmW oTypExp
  184. cBegin
  185. mov bx,oTxExp ;Expression location
  186. cmp ax,ET_MaxNum ; Is target numeric ?
  187. xchg cx,ax ;CX = oTyp of target
  188. jbe Numeric 
  189. mov ax,oTypExp ;AX = oTyp of source (Record = ET_RC)
  190. TestX ax,ST_Var? ;Is it a variable?
  191. jz Coerce ;If not, it won't move
  192. mov dh,0 ;Assume near - SD/FS
  193. or al,al ;[5] Is it a record?
  194. jnz SafeRef  ; Make sure reference is safe
  195. mov dh,FarArg ;Must be record - want far ref
  196. SafeRef:
  197. call SsRefArg ;Make sure it's safe from moving
  198. Numeric:
  199. mov ax,oTypExp ;AX = oTyp of source (Record = ET_RC)
  200. Coerce:
  201. call SsCoerceReg
  202. cEnd
  203. ;SsCoerceReg
  204. ;
  205. ;Purpose:
  206. ; Insert a coercion token to cause an expression to be coerced to a
  207. ; specified type.
  208. ;
  209. ; Literals 0 through 10 may be coerced from I2 to R4 by modification
  210. ; of the executor for these literals.
  211. ;
  212. ; If types match, no action is performed.
  213. ;
  214. ;Inputs:
  215. ; ax = oTyp of expression (with high bits set) (Record = ET_RC)
  216. ; bx = oTx of expression
  217. ; cx = oTyp of target
  218. ;Outputs:
  219. ; bx = oTx of expression, after coercion
  220. ; si and di updated if insertion needed
  221. ;Exceptions:
  222. ; If expression or target type is not numeric, Type Mismatch Error
  223. ; is generated.
  224. ;
  225. ; Coercion token insertion may cause the text table to grow.  This
  226. ; may result in OME.
  227. public SsCoerceReg
  228. SsCoerceReg:
  229. cmp ax,ET_I2+ST_Lit  ;Determine if lit without operand
  230. jne NoLitCoerce ;Can't optimize by replacing lit executor
  231. cmp     cx,ET_R4
  232. jz LitCoerce
  233. cmp cx,ET_R8
  234. jne NoLitCoerce
  235. LitCoerce:
  236. ;Target type is R4/R8, so replace executor with 1 word 8087 literal
  237. mov dx,bx ;Preserve address of this executor
  238. mov bx,PTRTX[bx-2] ;Load literal executor
  239. GetCodeIntoDs SCAN
  240. mov bl,byte ptr [bx-1] ; Load MSB of opcode
  241. push ss
  242. pop     ds
  243. .erre OPCODE_MASK EQ 03ffh ; Assure following code is ok
  244. ; and bx,HIGH (NOT OPCODE_MASK)
  245. and bx,0fch  ; Clear unwanted bits
  246. shr bx,1 ; Convert to word offset
  247. mov     ax,mOpExLitR8[bx] ; Get corresponding R8 lit executor
  248. mov bx,dx ;Restore address of I2 executor in text
  249. mov PTRTX[bx-2],ax ;Store the new R4 literal executor.
  250. EndCoerce:
  251. ret
  252. RecordChk:
  253. ; At this point, the coercion has been determined to be from a record.
  254. ; However, the true oTyp of the record is not saved on the scan stack
  255. ; ET_RC was used instead.  This code will use the oTx of the IdLd to
  256. ; find the oVar and in turn the true oTyp of the source. This is
  257. ; then compared to CX to check that types match. No coercion is
  258. ; possible among records so there is either an error or nothing.
  259. ;
  260. ; ax = oTyp of source expression
  261. ; bx = oTx of source expression
  262. ; cx = oTyp of target
  263. ;In non-SizeD versions, it is possible that the oTx from the scan
  264. ;stack will point after an exCopyTmpAr and exPushSeg instead of an
  265. ;exIdLd, exAIdLd, or exOffLd.  To differentiate between the two, the
  266. ;exPushSeg executor is forced to start at an odd address.  Since an
  267. ;oVar and oElem must be even, the exPushSeg can be recognized.
  268.     cmp     PTRTX[bx-2],codeOFFSET exPushSeg
  269.     jne     @F ; Brif exIdLd, exAIdLd, or exOffLd
  270.     DbAssertRel PTRTX[bx-10],e,<codeOFFSET exCopyTmpAr>,SCAN,<SsCoerceReg: exCopyTmpAr>
  271.     sub     bx,10 ; Backup over inserted executors
  272. @@:
  273. mov dx,cx ; DX = oTyp of target
  274. call GetTrueType ; CX = oTyp of source
  275. cmp cx,dx ; Do oTyps match?
  276. public TMError,TMErrorNZ
  277. TMErrorNZ:
  278. ;Report type mismatch error if Z flag not set.
  279. jz NoError
  280. TMError:
  281. ;Report type mismatch error.  All registers preserved.
  282. push ax
  283. mov ax,ER_TM ;Type mismatch error
  284. call SsError
  285. pop ax
  286. NoError:
  287. ret
  288. NoLitCoerce:
  289. ;Calculate the implicit coercion executor by entering tImpCo as a two
  290. ;dimensioned table of executor addresses.
  291. .erre ET_RC EQ 0 ; Assure JZ is sufficient
  292. or al,al
  293. jz RecordChk ; Brif source is record
  294. cmp cx,ET_MAX ; Is target a primitive type?
  295. ja TMError  ; Brif not.  This is an error
  296. call MSdFs ; Map ET types: FS=SD
  297. xchg ax,cx ; AX = Target type
  298. call MSdFs ; Map target type too
  299. cmp ax,cx ;Types already match?
  300. je EndCoerce ; If match, skip coercion
  301.         .erre   ET_SD EQ 5
  302. add ax,cx ;AX = Source + Target
  303. shl cx,1 ;CX = Source * 2
  304. shl cx,1 ;CX = Source * 4
  305. add ax,cx ;AX = Source * (5|7) + Target
  306. xchg ax,bx ;AX = oTx, BX = Table index
  307. shl bx,1 ;To word index
  308. mov cx,tImpCo[bx] ;Enter coercion executor table for executor
  309. xchg bx,ax ; oTx to bx
  310. jcxz EndCoerce
  311. mov ax,cx ;Executor to insert to ax
  312. dec cx ; Is this 1 (incompatible types)?
  313. jcxz TMError  ; Brif yes
  314. ; jmp short Insert ;Fall into Insert, below
  315. ;*** Insert - Insert word into pcode
  316. ;
  317. ;Inputs:
  318. ; ax = word to insert
  319. ; bx = oTx to insert
  320. ; cx = Number of bytes to make room for (InsertCx only)
  321. ; si = scan source
  322. ; di = scan destination
  323. ;Outputs:
  324. ; cx = number of bytes inserted
  325. ; bx = input bx + output cx: oTx of point after insertion
  326. ; si, di updated for text moves
  327. ;Exceptions:
  328. ; If OME:
  329. ; Error recorded by SsError
  330. ; Carry flag set
  331. ;Preserves:
  332. ; ax,bx,dx (bx updated)
  333. public Insert,InsertCx,InsertBranchBos,InsertBranch,Insert1Op
  334. extrn exBranch:near
  335. Insert:
  336. mov cx,2 ;Make room for two bytes
  337. InsertCx:
  338. cmp [SsErr],0 ;Any errors?
  339. jnz InsertFail ;Don't let error location get invalid
  340. push ax
  341. push bx
  342. push cx
  343. push dx
  344. ;Ensure room.  This may cause source side of text to move within the segment.
  345. call SsEnsureGap ;Ensure reasonable gap size
  346. pop dx
  347. pop cx
  348. pop bx
  349. pop ax
  350. jc InsertOME ;Out of memory error
  351. or [SsBosFlags],SSBOSF_Inserted ;Remember insertion occured
  352. ;Expand the destination text to make room for add'l executor
  353. push si
  354. mov si,di
  355. add di,cx ;New emit address
  356. push di
  357. push cx
  358. mov cx,si
  359. sub cx,bx ;cb between insert oTx and old emit oTx
  360. shr cx,1 ;count of words
  361. inc cx ;Include word at old emit address
  362. push es
  363. pop ds ;Prepare for es -> es copy
  364. std ;Copy direction is down
  365. rep movsw ;Copy to make room for executor
  366. cld
  367. mov [bx],ax  ;Insert additional executor
  368. pop cx
  369. add bx,cx ;Point bx to next insertion point
  370. push ss
  371. pop ds ;Restore data segment
  372. pop di
  373. pop si
  374. ret
  375. InsertOME:
  376. push ax
  377. mov ax,ER_OM ;Signal out-of-memory error
  378. call SsError
  379. pop ax
  380. InsertFail:
  381. stc ;Inform caller to make sure nothing is inserted
  382. ret
  383. ;***
  384. ;InsertBranchBos
  385. ;
  386. ;Purpose:
  387. ; Inserts an exBranch after opBos in current line.
  388. ;Entry:
  389. ; cx = operand
  390. ;Exit:
  391. ; bx - oTx after inserted exBranch
  392. ; si, di - adjusted for inserted pcode
  393. ;Preserves:
  394. ; cx
  395. ;******************************************************************************
  396. InsertBranchBos: ;Insert Branch after opBos
  397. mov bx,[SsOTxStart]  ; Points to first opcode after BOS
  398. InsertBranch:
  399. mov ax,codeOFFSET exBranch
  400. Insert1Op:
  401. ;Insert opcode in ax with operand in cx
  402. ;Preserves all (bx updated)
  403. push cx
  404. mov cx,4 ;Has a 2-byte operand
  405. call InsertCx
  406. pop cx
  407. jc NoOperand
  408. mov PTRTX[bx-2],cx
  409. NoOperand:
  410. ret
  411. subttl Executor Input Types Maps
  412. page
  413. ; These tables allow rapid calculation of what coercion is required
  414. ; for parameters for most BAsiC statements and functions.
  415. ;
  416. ; The naming convention is:
  417. ; tCo<input arg count><input type reqs|>to<required type>
  418. ;
  419. ; where:
  420. ; <input arg count> is the number of dimensions in the table.
  421. ; <input type reqs> shows the limitations on the types handled
  422. ;   by the statements/functions using this table.
  423. ;   This field may be empty.
  424. ; <required type>   This is the required final coerced type rule.
  425. ;   This is different for "+" and "*" for
  426. ;   example, as both have the same required type
  427. ;   rule (types must be the same), but "*" has
  428. ;   an input types restriction (no strings).
  429. ;
  430. ;
  431. ; These tables are used to calculate the required input type for unary
  432. ; operators and cases where binary operators require input types coerced
  433. ; to be equal.
  434. ;
  435. ; RulTab and related macros added with [14]
  436. ;
  437. ;------------------------------------------------------------
  438. ;Initialize a two-dimensional coercion table
  439. StartTab MACRO
  440. LinNo = 0
  441. ENDM
  442. ;Only define a byte if condition is true
  443. DbIf MACRO Byte,Cond
  444. IF Cond
  445. db Byte
  446. ENDIF
  447. ENDM
  448. ;Associate a line number (LinNo) with a type
  449. LinNo = 0
  450. IRP Typ,<I2,I4,R4,R8,Cy,Sd,Tx,Field>
  451. LinNo = LinNo+1
  452. Lin&Typ = LinNo
  453. ENDM
  454. ;Make a line of two-dimensional table
  455. RulTab MACRO I2,I4,R4,R8,Cy,Sd,Tx,Field
  456. LinNo = LinNo+1
  457. IF LinNo EQ LinCy
  458. EXITM
  459. ENDIF
  460. IF LinNo EQ LinTx
  461. EXITM
  462. ENDIF
  463. IF LinNo EQ LinField
  464. EXITM
  465. ENDIF
  466. RulLine I2,I4,R4,R8,Cy,Sd,Tx,Field
  467. ENDM
  468. ;Make a line of a coercion table using only those types enabled
  469. RulLine MACRO I2,I4,R4,R8,Cy,Sd,Tx,Field
  470. Db I2
  471. Db I4
  472. Db R4
  473. Db R8
  474. Db Sd
  475. ENDM
  476. tCo2toSame:
  477. StartTab
  478. public tCo1toNotSD
  479. tCo1toNotSD:
  480. RulTab ET_I2, ET_I4, ET_R4, ET_R8, ET_CY, LOWUND,   LOWUND, ET_FIELD;I2
  481. RulTab ET_I4, ET_I4, ET_R8, ET_R8, ET_CY, LOWUND,   LOWUND, ET_FIELD;I4
  482. RulTab ET_R4, ET_R8, ET_R4, ET_R8, ET_CY, LOWUND,   LOWUND, ET_FIELD;R4
  483. RulTab ET_R8, ET_R8, ET_R8, ET_R8, ET_CY, LOWUND,   LOWUND, ET_FIELD;R8
  484. RulTab ET_CY, ET_CY, ET_CY, ET_CY, ET_CY, LOWUND,   LOWUND, ET_FIELD;CY
  485. RulTab LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, ET_SD,   ET_TX,  ET_FIELD;SD
  486. RulTab LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, ET_TX,   ET_TX,  ET_TX   ;TX
  487. RulTab ET_FIELD,  ET_FIELD,  ET_FIELD,  ET_FIELD,  ET_FIELD,  ET_FIELD, ET_TX,  ET_FIELD;Field
  488. ;------------------------------------------------------------
  489. tCo2NotSdtoSame:
  490. StartTab
  491. RulTab ET_I2, ET_I4, ET_R4, ET_R8, ET_CY, LOWUND, LOWUND, ET_FIELD;I2
  492. RulTab ET_I4, ET_I4, ET_R8, ET_R8, ET_CY, LOWUND, LOWUND, ET_FIELD;I4
  493. RulTab ET_R4, ET_R8, ET_R4, ET_R8, ET_CY, LOWUND, LOWUND, ET_FIELD;R4
  494. RulTab ET_R8, ET_R8, ET_R8, ET_R8, ET_CY, LOWUND, LOWUND, ET_FIELD;R8
  495. RulTab ET_CY, ET_CY, ET_CY, ET_CY, ET_CY, LOWUND, LOWUND, ET_FIELD;CY
  496. RulTab LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND ;SD
  497. RulTab LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND ;TX
  498. RulTab ET_FIELD,  ET_FIELD,  ET_FIELD,  ET_FIELD,  ET_FIELD,  LOWUND, LOWUND, ET_FIELD   ;Field
  499. ;------------------------------------------------------------
  500. ;------------------------------------------------------------
  501. tCo2toI2I4:
  502. StartTab
  503. RulTab ET_I2, ET_I4, ET_I4, ET_I4, ET_I4, LOWUND, LOWUND, ET_I4 ;I2
  504. RulTab ET_I4, ET_I4, ET_I4, ET_I4, ET_I4, LOWUND, LOWUND, ET_I4 ;I4
  505. RulTab ET_I4, ET_I4, ET_I4, ET_I4, ET_I4, LOWUND, LOWUND, ET_I4 ;R4
  506. RulTab ET_I4, ET_I4, ET_I4, ET_I4, ET_I4, LOWUND, LOWUND, ET_I4 ;R8
  507. RulTab ET_I4, ET_I4, ET_I4, ET_I4, ET_I4, LOWUND, LOWUND, ET_I4 ;CY
  508. RulTab LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND ;SD
  509. RulTab LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND ;TX
  510. RulTab ET_I4, ET_I4, ET_I4, ET_I4, ET_I4, LOWUND, LOWUND, ET_I4 ;Field
  511. ;------------------------------------------------------------
  512. tCo2toR4R8:
  513. StartTab
  514. RulTab ET_R4, ET_R8, ET_R4, ET_R8, ET_R8, LOWUND, LOWUND, ET_R8 ;I2
  515. RulTab ET_R8, ET_R8, ET_R8, ET_R8, ET_R8, LOWUND, LOWUND, ET_R8 ;I4
  516. RulTab ET_R4, ET_R8, ET_R4, ET_R8, ET_R8, LOWUND, LOWUND, ET_R8 ;R4
  517. RulTab ET_R8, ET_R8, ET_R8, ET_R8, ET_R8, LOWUND, LOWUND, ET_R8 ;R8
  518. RulTab ET_R8, ET_R8, ET_R8, ET_R8, ET_R8, LOWUND, LOWUND, ET_R8 ;CY
  519. RulTab LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND ;SD
  520. RulTab LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND ;TX
  521. RulTab ET_R8, ET_R8, ET_R8, ET_R8, ET_R8, LOWUND, LOWUND, ET_R8 ;Field
  522. ;------------------------------------------------------------
  523. ;------------------------------------------------------------
  524. tCo2toI2R4:
  525. StartTab
  526. RulTab ET_I2, ET_R4, ET_R4, ET_R4, ET_R4, LOWUND, LOWUND, ET_R4 ;I2
  527. RulTab ET_R4, ET_R4, ET_R4, ET_R4, ET_R4, LOWUND, LOWUND, ET_R4 ;I4
  528. RulTab ET_R4, ET_R4, ET_R4, ET_R4, ET_R4, LOWUND, LOWUND, ET_R4 ;R8
  529. RulTab ET_R4, ET_R4, ET_R4, ET_R4, ET_R4, LOWUND, LOWUND, ET_R4 ;R8
  530. RulTab ET_R4, ET_R4, ET_R4, ET_R4, ET_R4, LOWUND, LOWUND, ET_R4 ;CY
  531. RulTab LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND ;SD
  532. RulTab LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND, LOWUND ;TX
  533. RulTab ET_R4, ET_R4, ET_R4, ET_R4, ET_R4, LOWUND, LOWUND, ET_R4 ;Field
  534. ;------------------------------------------------------------
  535. tCo1toI2SD:
  536. RulLine ET_I2, ET_I2, ET_I2, ET_I2, ET_I2, ET_SD, ET_TX, ET_FIELD
  537. ;------------------------------------------------------------
  538. tCo1toI2I4:
  539. RulLine ET_I2, ET_I4, ET_I4, ET_I4, ET_I4, LOWUND, LOWUND, ET_I4
  540. ;------------------------------------------------------------
  541. tCo1toSame:
  542. RulLine ET_I2, ET_I4, ET_R4, ET_R8, ET_CY, ET_SD, ET_TX, ET_FIELD
  543. subttl Coercion Rules Table
  544. page
  545. MakRule MACRO
  546. irule = 0
  547. ;Rule names are composed of two parts - the input specification
  548. ;   and the output specification.  The naming convention is:
  549. ;
  550. ; SSR_<input spec>_<output spec>
  551. ;
  552. ; <input spec> starts with the number of arguments
  553. ; <output spec> of <LOWUND> indicates op emits the input type.
  554. ;
  555. ;NOTE:
  556. ;   Rules that have an output type the same as the only input type could
  557. ;   be represented with <LOWUND> or an explicit type as <output spec>.
  558. ;   These are not the same rule, as some scan routines require explicit
  559. ;   type as <output spec>.  However, there are no scan routines that
  560. ;   handle <LOWUND> as <output spec> but do not handle an explicit type.
  561. ;
  562. ;NOTE:
  563. ;   If output type = ET_MAX then no coercion routine uses that output type.
  564. ;   That rule field could be modified for use by some other scan routine.
  565. ;
  566. ;params:       <ispec><ospec>, coercion table,  output type
  567. ruler 2Any_Same, tCo2toSame, <LOWUND>
  568. ruler 2NotSD_Same, tCo2NotSDtoSame,<LOWUND>
  569. ruler 2I2I4_Same, tCo2toI2I4, <LOWUND>
  570. ruler 2R4R8_Same, tCo2toR4R8, <LOWUND>
  571. public SSR_Div      
  572. SSR_Div equ SSR_2R4R8_Same     
  573. ruler 2I2R4_I2, tCo2toI2R4, ET_I2
  574. ruler 2Any_I2, tCo2toSame, ET_I2
  575. ruler 2I2R4_None, tCo2toI2R4, 0
  576. ruler 1NotSD_Same, tCo1toNotSD, <LOWUND>
  577. ruler 1I2I4_Same, tCo1toI2I4, <LOWUND>
  578. ruler 1I2I4_SD, tCo1toI2I4, ET_SD
  579. ruler 1I2SD_SD, tCo1toI2SD, ET_SD
  580. ruler 1I2SD_I4, tCo1toI2SD, ET_I4
  581. ruler 1NotSD_I2, tCo1toNotSD, ET_I2
  582. ruler 1NotSD_SD, tCo1toNotSD, ET_SD
  583. ruler 1Any_None, tCo1toSame, 0
  584. ruler 1I2SD_None, tCo1toI2SD, 0
  585. ;Label Reference Rules
  586. ;        <#labs,#args> <arg coercion> <#label>
  587. ruler 1Lab0Arg, UNDEFINED, 1
  588. ruler 1LabMain0Arg, UNDEFINED, <1 OR 80h>
  589. ruler nLab1Arg, 0, LOWUND
  590. ;Rules for SS_4ET_ET
  591. ;     NOTE: The low order nibble applies to the LAST argument in the syntax.
  592. ;     The rule names are in syntax order.
  593. ruler I2_None, <ET_I2>,  0
  594. ruler I4_None, <ET_I4>,  0
  595. ruler R4_None, <ET_R4>,  0
  596. ruler R8_None, <ET_R8>,  0
  597. ruler SD_None, <ET_SD>,  0
  598. ruler I4I2_None, <ET_I4,ET_I2>, 0
  599. ruler I2I4_None, <ET_I2,ET_I4>, 0
  600. ruler R4I2_None, <ET_R4,ET_I2>, 0
  601. ruler I2SD_None, <ET_I2,ET_SD>, 0
  602. ruler 2I2_None, <ET_I2,ET_I2>, 0
  603. ruler 2SD_None, <ET_SD,ET_SD>, 0
  604. ruler I2R4_None, <ET_I2,ET_R4>, 0
  605. ruler SDI2_None, <ET_SD,ET_I2>, 0
  606. ruler SDI4_None, <ET_SD,ET_I4>, 0
  607. ruler SD2I4_None, <ET_SD,ET_I4,ET_I4>, 0
  608. ruler I42I2_None, <ET_I4,ET_I2,ET_I2>, 0
  609. ruler SD2I2_None, <ET_SD,ET_I2,ET_I2>, 0
  610. ruler SDI2SD_None, <ET_SD,ET_I2,ET_SD>, 0
  611. ruler 4I2_None, <ET_I2,ET_I2,ET_I2,ET_I2>,0
  612. ruler 4R4_None, <ET_R4,ET_R4,ET_R4,ET_R4>,0
  613. ruler SDI2SDI2_None, <ET_SD,ET_I2,ET_SD,ET_I2>,0
  614. ruler I2_I2, <ET_I2>,  ET_I2
  615. ruler I2_I4, <ET_I2>,  ET_I4
  616. ruler I2_R4, <ET_I2>,  ET_R4
  617. ruler I2_SD, <ET_I2>,  ET_SD
  618. ruler I4_I2, <ET_I4>,  ET_I2
  619. ruler I4_I4, <ET_I4>,  ET_I4
  620. ruler I4_SD, <ET_I4>,  ET_SD
  621. ruler R4_R4, <ET_R4>,  ET_R4
  622. ruler R4_SD, <ET_R4>,  ET_SD
  623. ruler R8_SD, <ET_R8>,  ET_SD
  624. ruler SD_I2, <ET_SD>, ET_I2
  625. ruler SD_I4, <ET_SD>, ET_I4
  626. ruler SD_R4, <ET_SD>, ET_R4
  627. ruler SD_R8, <ET_SD>, ET_R8
  628. ruler SD_SD, <ET_SD>, ET_SD
  629. ruler I2I4_I2, <ET_I2,ET_I4>, ET_I2
  630. ruler I2I2_SD, <ET_I2,ET_I2>, ET_SD
  631. ruler I2I2_I2, <ET_I2,ET_I2>, ET_I2
  632. ruler I2I2_I4, <ET_I2,ET_I2>, ET_I4
  633. ruler SDSD_I2, <ET_SD,ET_SD>, ET_I2
  634. ruler I2SD_SD, <ET_I2,ET_SD>, ET_SD
  635. ruler SDI2_SD, <ET_SD,ET_I2>, ET_SD
  636. ruler R4I2_R4, <ET_R4,ET_I2>, ET_R4
  637. ruler 3I2_I2,  <ET_I2,ET_I2,ET_I2>, ET_I2
  638. ruler I2SDSD_I2, <ET_I2,ET_SD,ET_SD>, ET_I2
  639. ruler SD2I2_SD, <ET_SD,ET_I2,ET_I2>, ET_SD
  640. ENDM
  641. ;First define the rule name constant and build a table of the word parameter
  642. ruler MACRO rname,ptCoerce,oTypOut
  643. ;params are rule name, coercion table, output type
  644. SSR_&rname = irule
  645. irule = irule + 1
  646. Rule = 0
  647. IRP Arg,<ptCoerce>
  648. Rule = Rule*10H+Arg
  649. ENDM
  650. dw Rule
  651. ENDM
  652. PUBLIC tRuleWord
  653. tRuleWord:
  654. MakRule
  655. ;Next build a table of the byte parameter
  656. ruler MACRO rname,ptCoerce,oTypOut
  657. ;params are rule name, coercion table, output type
  658. db oTypOut
  659. ENDM
  660. PUBLIC tRuleByte
  661. tRuleByte:
  662. MakRule
  663. .xlist
  664. include ssoprule.inc
  665. .list
  666. sEnd SCAN
  667. end