TPSRC9 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600
  1. JNB exscret ;:ok
  2. CMP.B CL,#$08 ;string ?
  3. CALL errnz ;no:
  4. B $1F ;31:Simple expression expected
  5. MOV AX,#xstrch ;(string -> char)
  6. CALL ecall ;* CALL xstrch
  7. MOV CX,#$020C ;type: char in AX
  8. exscret RET ;"
  9. exstr CALL expr ;get string expression: do expr
  10. CMP.B CL,#$08 ;string ?
  11. JZ exstrret ;:yes
  12. CMP.B CL,#$0C ;char ?
  13. CALL errnz ;no:
  14. B $21 ;33:String expression expected
  15. OR.B CH,CH ;constant ?
  16. JNZ ecstrch ;:no
  17. MOV AX,exres ;get result
  18. MOV.B AH,AL ;char
  19. MOV AL,#$01 ;length
  20. CALL emovaxi ;* MOV AX,#...
  21. JMP.b exstrch2 ;'
  22. ecstrch CALL loadatom ;get atom
  23. CALL ecode ;* MOV AH,AL
  24. B $04,$8A,$E0,$B0,$01 ;* MOV AL,#01
  25. exstrch2 CALL epushax ;* PUSH AX
  26. MOV CL,#$08 ;type = string
  27. exstrret RET ;"
  28. excond CALL expr ;evaluate boolean expr: do expr
  29. CMP.B CL,#$0B ;boolean ?
  30. CALL errnz ;no:
  31. B $14 ;20:Boolean expression expected
  32. CALL loadatom ;get atom
  33. CMP.B CH,#$04 ;comparision outside ?
  34. JZ excondrt ;yes: ok
  35. MOV AL,#$75 ;store branch op: JNZ
  36. MOV brnchop,AL
  37. CMP.B CH,#$03 ;flags set ?
  38. JZ excondrt ;:yes
  39. CALL ecode ;* OR AX,AX
  40. B $02,$0B,$C0
  41. excondrt RET ;"
  42. exprax CALL expr ;read expression
  43. expload CMP.B CL,#$0A ;scalar ?
  44. JB excondrt ;below: ret
  45. CALL loadatom ;get atom
  46. JMP flgbool ;"flags -> boolean
  47. expvar MOV AX,#expload ;do expression - var pre-read
  48. PUSH AX ;set up return stack
  49. MOV AX,#expr2
  50. PUSH AX
  51. MOV AX,#add2
  52. PUSH AX
  53. MOV AX,#mul2
  54. PUSH AX
  55. JMP cvar2 ;"start with var
  56. expconst MOV AX,#expload ;do expression - const pre-read
  57. PUSH AX ;set up return stack
  58. MOV AX,#expr2
  59. PUSH AX
  60. MOV AX,#add2
  61. PUSH AX
  62. MOV AX,#mul2
  63. PUSH AX
  64. JMP cconst2 ;"start with const
  65. expr CALL addlevel ;Comparison level: do add level
  66. expr2 PUSH CX ;save type
  67. CALL ckey ;check comparisons
  68. B $02
  69. W tkcmp
  70. POP CX ;restore type
  71. JZ cmp1 ;found: do comparison
  72. RET ;'
  73. cmp1 INC.B AL ;IN ?
  74. JZ cmpin ;:yes
  75. PUSH BX ;save op ptr, type
  76. PUSH CX
  77. CALL pushres ;save entry
  78. PUSH pc ;save PC
  79. PUSH functp ;save type ptr
  80. CALL addlevel ;addition level
  81. POP comptp ;restore type ptr
  82. POP oldpc ;restore PC
  83. POP DX ;restore type
  84. CALL typeconv ;do type conversion
  85. POP BX ;restore op ptr
  86. CMP.B CL,#$0A ;scalar ?
  87. JB cmpdiff ;:no
  88. CS:
  89. MOV.B AL,[BX]$01 ;set branch opcode
  90. MOV brnchop,AL ;(from comparison table)
  91. MOV BX,#cmpcode ;emit parms for comparison
  92. CALL ecalc ;emit instruction
  93. MOV CX,#$040B ;return type: boolean, flags set
  94. RET ;'
  95. cmpdiff CS: ;real, string, set, ptr comparisons
  96. MOV.B BL,[BX] ;get offset in cmp table
  97. XOR.B BH,BH ;-> table index
  98. CMP.B CL,#$09 ;real ?
  99. JZ cmpfnd ;:yes
  100. INC BX ;+2
  101. INC BX
  102. CMP.B CL,#$08 ;string ?
  103. JZ cmpfnd ;:yes
  104. INC BX ;+2
  105. INC BX
  106. CMP.B CL,#$03 ;set ?
  107. JZ cmpfnd ;:yes
  108. INC BX ;+2;(pointer)
  109. INC BX
  110. cmpfnd CS:
  111. MOV AX,[BX]vcompare ;get vector from table
  112. OR AX,AX ;test it
  113. CALL errz ;47:Operand type(s) do
  114. B $2F ;not match operator
  115. JMP.b cmpemit ;'end it
  116. cmpin CALL loadatom ;IN: get atom
  117. CALL epushax ;* PUSH AX
  118. PUSH CX ;save type
  119. CALL addlevel ;do addition level
  120. POP DX ;restore type
  121. CMP.B CL,#$03 ;set ?
  122. CALL errnz ;47:Operand type(s) do
  123. B $2F ;not match operator
  124. OR.B CH,CH ;constant ?
  125. JZ cmpconst ;:yes
  126. CMP.B DL,CH ;compare types
  127. CALL errnz ;different base type:
  128. B $2C ;44:Type mismatch
  129. cmpconst MOV AX,#xsetin
  130. cmpemit CALL ecall ;* CALL xsetin
  131. MOV CX,#$030B ;boolean, flags set
  132. RET ;"
  133. vcompare W realeq,csteq,seteq,ptreq ;= vector table for comparisons
  134. W realne,cstne,setne,ptrne ;<>
  135. W realge,cstge,setge ;>=
  136. W $0000
  137. W realle,cstle,setle ;<=
  138. W $0000
  139. W realg,cstg ;>
  140. W $0000,$0000
  141. W reall,cstl ;<
  142. W $0000,$0000 ;"
  143. addlevel CALL mullevel ;Addition level: do mult level
  144. add2 PUSH CX ;save type
  145. CALL ckey ;check add ops
  146. B $05
  147. W tkadd
  148. POP CX ;restore type
  149. JZ addptr ;:found
  150. RET ;'
  151. addptr CMP.B CL,#$04 ;pointer ?
  152. CALL errz ;yes:
  153. B $2F ;47:Operand type(s) does not match op
  154. PUSH BX ;save op ptr
  155. PUSH CX ;save type
  156. CALL pushres ;save first result
  157. PUSH pc ;save PC
  158. CALL mullevel ;mult level
  159. CMP.B CL,#$0C ;char ?
  160. JNZ add3 ;:no
  161. OR.B CH,CH ;constant ?
  162. JNZ addch ;:no
  163. MOV AX,exres ;get resulting char
  164. MOV.B AH,AL
  165. MOV AL,#$01 ;convert to string
  166. CALL emovaxi ;* MOV AX,#..
  167. JMP.b addch2 ;'
  168. addch CALL loadatom ;load second result
  169. CALL ecode ;* MOV AH,AL
  170. B $04,$8A,$E0,$B0,$01 ;* MOV AL,#01
  171. addch2 CALL epushax ;* PUSH AX
  172. MOV CL,#$08 ;convert to string
  173. add3 POP oldpc ;restore PC
  174. POP DX ;type first part
  175. CALL typeconv ;do type conversions
  176. POP BX ;restore op ptr
  177. CS:
  178. CMP.B [BX],#$02 ;OR, XOR ?
  179. JNB addbool ;:yes
  180. MOV AX,#sunion ;(set +)
  181. MOV DX,#sdiff ;(set -)
  182. CMP.B CL,#$03 ;set ?
  183. JZ addset ;:yes
  184. MOV AX,#xadd ;(add real)
  185. MOV DX,#xsub ;(sub real)
  186. CMP.B CL,#$09 ;real ?
  187. JNZ addstr ;:no
  188. addset CS:
  189. CMP.B [BX],#$00 ;add ?
  190. JZ addadd ;:yes
  191. XCHG AX,DX ;get subtract vector
  192. addadd CALL ecall ;emit call
  193. JMP add2 ;'loop back
  194. addstr CMP.B CL,#$08 ;string ?
  195. JNZ addscal ;:no
  196. CS:
  197. CMP.B [BX],#$00 ;add ?
  198. CALL errnz ;no:
  199. B $2F ;47:Operand type(s) does not match op
  200. MOV AX,#xconcat ;(concat strings)
  201. JMP addadd ;'emit call, loop back
  202. addbool CMP.B CL,#$0B ;boolean ?
  203. JZ addsc2 ;:yes
  204. addscal CMP.B CL,#$0A ;scalar ?
  205. CALL errnz ;no:
  206. B $2F ;47:Operand type(s) does not match op
  207. addsc2 CALL ecalc ;emit instructions
  208. JMP add2 ;"loop back
  209. mullevel CALL neglevel ;Multiplication level: do unary level
  210. mul2 PUSH CX ;save result type
  211. CALL ckey ;check multiplication ops
  212. B $05
  213. W tkmul
  214. POP CX ;restore type
  215. JZ mulptr ;:found
  216. RET ;'
  217. mulptr CMP.B CL,#$04 ;pointer ?
  218. CALL errz ;yes:
  219. B $2F ;47:Operand type(s) does not match op
  220. PUSH BX ;save op ptr, type
  221. PUSH CX
  222. CALL pushres ;emit push first value
  223. PUSH pc
  224. CALL neglevel ;do unary level
  225. POP oldpc ;restore old PC
  226. POP DX ;type first op
  227. POP BX ;op ptr
  228. PUSH BX ;save it again
  229. CS:
  230. CMP.B [BX],#$01 ;division ?
  231. JNZ mulnodiv ;:no
  232. CMP.B CL,#$0A ;second = integer ?
  233. JNZ mulnodiv ;:no
  234. CALL loadatom ;load result
  235. MOV AX,#xintreal ;convert to real
  236. CALL ecall ;* CALL xintreal
  237. MOV CL,#$09 ;now real
  238. mulnodiv CALL typeconv ;do type conversions
  239. POP BX ;op ptr
  240. CS:
  241. CMP.B [BX],#$01 ;division ?
  242. JA muland ;higher: no reals, sets
  243. JZ muldiv ;:division
  244. MOV AX,#xmul ;(multiply real)
  245. CMP.B CL,#$09 ;real ?
  246. JZ mulreal ;:yes
  247. MOV AX,#sinter ;(set *)
  248. CMP.B CL,#$03 ;set ?
  249. JNZ muland ;no: go out
  250. mulreal CALL ecall ;emit call
  251. JMP mul2 ;'loop back
  252. muldiv MOV AX,#xdiv ;(divide real)
  253. CMP.B CL,#$09 ;real ?
  254. JZ mulreal ;:yes
  255. CALL err ;47:Operand type(s) does not match op
  256. B $2F ;'
  257. muland CS: ;AND ?
  258. CMP.B [BX],#$02
  259. JNZ mulscal ;:no
  260. CMP.B CL,#$0B ;boolean ?
  261. JZ mulemit ;:yes
  262. mulscal CMP.B CL,#$0A ;scalar ?
  263. CALL errnz ;no:
  264. B $2F ;47:Operand type(s) does not match op
  265. mulemit CALL ecalc ;emit arithmetic op
  266. JMP mul2 ;"loop back
  267. neglevel CALL ctoken ;Unary level
  268. W tknot ;NOT ?
  269. JNZ negneg ;:no
  270. CALL negneg ;do negation level
  271. CALL flgbool ;flags -> boolean
  272. CMP.B CL,#$0A ;integer ?
  273. JZ negnot ;:ok
  274. CMP.B CL,#$0B ;boolean ?
  275. CALL errnz ;no:
  276. B $2F ;47:Operand type(s) does not match op
  277. CALL loadatom ;load value
  278. CALL ecode ;* XOR AL,#01
  279. B $02,$34,$01
  280. MOV CH,#$03 ;flags set...
  281. RET ;'
  282. negnot CALL loadatom ;get value
  283. CALL ecode ;* NOT AX
  284. B $02,$F7,$D0
  285. RET ;'
  286. negneg PUSH negflg ;do negation: save flag
  287. CALL testsign ;test sign
  288. MOV negflg,DX ;store it
  289. CALL atom ;do atom
  290. MOV DX,negflg ;get neg flag
  291. CALL testnum ;test type
  292. JZ negend ;:ok
  293. CMP.B CL,#$0A ;integer ?
  294. JNZ negreal ;:no
  295. CALL loadatom ;get value
  296. CALL ecode ;* NEG AX
  297. B $02,$F7,$D8
  298. JMP.b negend ;'
  299. negreal MOV AX,#xneg ;(negate real)
  300. CALL ecall
  301. negend POP negflg ;restore neg flag
  302. RET ;"
  303. pushres CALL flgbool ;store result on stack
  304. CMP.B CL,#$0A ;integer ?
  305. JB pushptr ;:no
  306. CALL loadatom ;get value
  307. MOV.B flgpshax,#$01 ;set flag: PUSH AX
  308. RET ;'
  309. pushptr CMP.B CL,#$04 ;pointer ?
  310. JNZ pushret ;:no
  311. CALL ecode ;* PUSH DX
  312. B $02,$52,$50 ;* PUSH AX
  313. pushret RET ;"
  314. typeconv CALL flgbool ;Do type conversions
  315. MOV.B flgpshax,#$00 ;no PUSH AX
  316. CMP.B DL,#$09 ;first = real ?
  317. JNZ tcvstr ;:no
  318. CMP.B CL,#$0A ;second = integer ?
  319. JNZ tcvreal ;:no
  320. CALL loadatom ;get value
  321. MOV AX,#xintreal
  322. CALL ecall ;* CALL xintreal
  323. MOV CL,#$09 ;-> real
  324. JMP.b tcvreal ;'
  325. tcvstr CMP.B DL,#$08 ;first = string ?
  326. JNZ tcvreal ;:no
  327. CMP.B CL,#$0C ;second = char ?
  328. JNZ tcvreal ;:no
  329. OR.B CH,CH ;constant ?
  330. JNZ tcvchstr ;:no
  331. MOV AX,exres ;get char
  332. MOV.B AH,AL ;convert to string
  333. MOV AL,#$01
  334. CALL emovaxi ;* MOV AX,#i
  335. JMP.b tcvchst2 ;'
  336. tcvchstr CALL loadatom ;get value
  337. CALL ecode ;* MOV AH,AL (convert to string)
  338. B $04,$8A,$E0,$B0,$01 ;* MOV AL,#01
  339. tcvchst2 CALL epushax ;* PUSH AX
  340. MOV CL,#$08 ;-> string
  341. tcvreal CMP.B CL,#$09 ;second = real ?
  342. JNZ tcvchst1 ;:no
  343. CMP.B DL,#$0A ;first = integer ?
  344. JNZ tcvint ;:no
  345. MOV AX,#xintre2 ;convert first number
  346. CALL ecall
  347. MOV DL,#$09 ;first -> real
  348. JMP.b tcvint ;'
  349. tcvchst1 CMP.B CL,#$08 ;second = string ?
  350. JNZ tcvint ;:no
  351. CMP.B DL,#$0C ;first = char ?
  352. JNZ tcvint ;:no
  353. MOV AX,#xchstr ;first -> string
  354. CALL ecall ;* CALL xchstr1
  355. MOV DL,#$08 ;-> string
  356. tcvint CMP.B CL,#$0A ;second = integer ?
  357. JB tcvnoint ;:no
  358. CMP.B CH,#$02 ;calculated ?
  359. JNZ tcvpop ;:no
  360. CALL ecode ;* POP CX
  361. B $01,$59
  362. JMP.b tcvchk ;'
  363. tcvpop MOV AX,pc ;PC = old PC ?
  364. CMP AX,oldpc
  365. JZ tcvchk ;:yes
  366. CALL epopax ;* POP AX
  367. JMP.b tcvchk ;'
  368. tcvnoint CMP.B CL,#$04 ;pointer ?
  369. JNZ tcvchk ;:no
  370. CALL ecode ;* POP BX
  371. B $02,$5B,$59 ;* POP DX
  372. tcvchk CMP.B CL,DL ;first = second ?
  373. CALL errnz ;no:
  374. B $2C ;44:Type mismatch
  375. CMP.B CL,#$03 ;set ?
  376. JNZ tcvset ;:no
  377. CMP.B CH,DH ;same base types !
  378. JZ tcvret ;:ok
  379. OR.B DH,DH ;constant 1 ?
  380. JZ tcvret ;yes: ret
  381. OR.B CH,CH ;constant 2 ?
  382. MOV.B CH,DH ;copy base type
  383. JZ tcvret ;yes: ret
  384. CALL err ;44:Type mismatch
  385. B $2C ;'
  386. tcvset CMP.B CL,#$04 ;pointer ?
  387. JNZ tcvret ;:no
  388. CMP functp,#$00 ;untyped ?
  389. JZ tcvret ;yes: ret
  390. CMP comptp,#$00 ;untyped ?
  391. JZ tcvret ;yes: ret
  392. MOV AX,functp ;get type ptr
  393. CMP AX,comptp ;compare
  394. JZ tcvret ;equal: ok
  395. CALL err ;44:Type mismatch
  396. B $2C ;'
  397. tcvret RET ;"
  398. loadatom OR.B CH,CH ;load value -> AX
  399. JNZ latvar ;:no constant
  400. MOV AX,exres ;get result
  401. CALL emovaxi ;* MOV AX,#result
  402. JMP.b latres ;'
  403. latvar CMP.B CH,#$01 ;var ?
  404. JNZ latret ;no: ret - already in AX
  405. PUSH CX ;save
  406. PUSH DX
  407. CALL eload ;load var
  408. POP DX
  409. POP CX
  410. latres MOV CH,#$02 ;flag: in AX
  411. latret RET ;"
  412. flgbool CMP.B CL,#$0B ;Flags -> boolean
  413. JNZ flgbret ;:no boolean
  414. CMP.B CH,#$03 ;flags set ?
  415. JB flgbret ;:constant, var, AX
  416. JZ flgbres ;flags set: ok
  417. CALL ecode ;convert
  418. B $03,$B8,$01,$00 ;* MOV AX,#0001
  419. MOV AL,brnchop
  420. CALL ebyte ;emit branch op
  421. CALL ecode ;* offset
  422. B $02,$01,$48 ;* DEC AX
  423. flgbres MOV CH,#$02 ;flag: result in AX
  424. flgbret RET ;"
  425. ecalc PUSH CX ;Emit arithmetic operation
  426. OR.B CH,CH ;second = const ?
  427. JNZ ecvar ;:no
  428. CS:
  429. TEST.B [BX]$04,#$02 ;is there a const form ?
  430. JNZ ecnocn ;:no
  431. CS:
  432. MOV.B AL,[BX]$01 ;get its opcode
  433. CALL ebyte ;emit it
  434. MOV AX,exres ;emit the result
  435. CALL eword ;as immediate value
  436. JMP.b ecxchg2 ;'done
  437. ecnocn MOV AX,exres ;take immediate
  438. CALL emovcxi ;* MOV CX,#result
  439. JMP.b ecnoxchg ;'
  440. ecvar CMP.B CH,#$01 ;variable ?
  441. JNZ eccalc ;:no
  442. CS:
  443. TEST.B [BX]$04,#$04 ;is there a var form ?
  444. JNZ ecnovar ;:no
  445. CS:
  446. TEST.B [BX]$04,#$08 ;CWD needed ?
  447. JZ eccwd1 ;:no
  448. CALL ecode
  449. B $01,$99 ;* CWD
  450. eccwd1 CS:
  451. MOV DX,[BX]$02 ;base opcode
  452. AND.B DH,#$38 ;convert to AX,var
  453. CALL einstr ;emit instruction
  454. JMP.b ecxchg2 ;'done
  455. ecnovar MOV DX,#$088B ;* MOV CX,...
  456. CALL einstr ;emit instruction
  457. JMP.b ecnoxchg ;'
  458. eccalc CS: ;second number in AX
  459. TEST.B [BX]$04,#$01 ;XCHG needed ?
  460. JZ ecnoxchg ;:no
  461. CALL ecode
  462. B $01,$91 ;* XCHG CX,AX
  463. ecnoxchg CS:
  464. TEST.B [BX]$04,#$08 ;CWD needed ?
  465. JZ eccwd2 ;:no
  466. CALL ecode
  467. B $01,$99 ;* CWD
  468. eccwd2 CS:
  469. MOV DX,[BX]$02 ;base opcode
  470. CALL emitdx ;emit it
  471. ecxchg2 CS:
  472. TEST.B [BX]$04,#$10 ;second XCHG needed ?
  473. JZ ecres ;:no
  474. CALL ecode
  475. B $01,$92 ;* XCHG DX,AX (for MOD)
  476. ecres POP CX ;restore type
  477. MOV CH,#$02 ;result in AX
  478. RET ;"
  479. atom CALL cvar ;Do atom: do var
  480. JZ atomret ;:done
  481. CALL cconst ;do constant
  482. JZ atomret ;:done
  483. CALL cfunc ;do function
  484. JZ atomret ;:done
  485. CALL cset ;do set
  486. JZ atomret ;:done
  487. CALL cparens ;do parentheses
  488. JZ atomret ;:done
  489. CALL cstdfn ;do standard functions
  490. JZ atomret ;:done
  491. CALL ctype ;do type conversions
  492. JZ atomret ;:done
  493. CALL cnil ;test for NIL
  494. CALL errnz ;not found:
  495. B $29 ;41:Unknown ID or syntax error
  496. atomret RET ;"
  497. cvar CALL rdvar ;get var
  498. JNZ atomret ;no:ret
  499. cvar2 MOV AL,varctp ;component type:
  500. CMP AL,#$0A ;integer ?
  501. JB cvareal ;:below
  502. MOV CH,#$01 ;var
  503. CMP varsize,#$01 ;byte ?
  504. JA cvaint ;:no, word
  505. CALL eload ;load var
  506. MOV CH,#$02 ;now in AX
  507. cvaint MOV.B CL,varctp ;get component type
  508. JMP.b cvaok ;'ok
  509. cvareal CMP AL,#$09 ;real ?
  510. JZ cvaload ;:yes
  511. CMP AL,#$08 ;string ?
  512. JZ cvaload ;:yes
  513. CMP AL,#$03 ;set ?
  514. JZ cvaload ;:yes
  515. CMP AL,#$04 ;pointer ?
  516. JNZ cvaarrch ;:no
  517. cvaload CALL eload ;load var
  518. MOV BP,lower ;type ptr
  519. MOV functp,BP
  520. MOV.B CL,varctp ;component type
  521. CMP.B CL,#$03 ;set ?
  522. JNZ cvaok ;:no, ok
  523. MOV.B CH,[BP]-$08 ;get base type
  524. JMP.b cvaok ;'ok
  525. cvaarrch CMP AL,#$01 ;array ?
  526. CALL errnz ;no:
  527. B $3E ;62:Struct vars are not allowed here
  528. CALL varptr2 ;get var ptr
  529. MOV BP,lower ;type ptr
  530. CMP.B [BP]-$08,#$0C ;array of char ?
  531. CALL errnz ;no:
  532. B $3E ;62:Struct vars are not allowed here
  533. MOV BP,upper ;index type
  534. CMP.B [BP]-$08,#$0A ;= scalar ?
  535. CALL errnz ;no:
  536. B $3E ;62:Struct vars are not allowed here
  537. MOV AX,varsize ;component size
  538. OR.B AH,AH ;> 255 ?
  539. CALL errnz ;yes:
  540. B $3E ;62:Struct vars are not allowed here
  541. MOV.B AH,AL
  542. MOV AL,#$B1
  543. CALL eword ;* MOV CL,#len
  544. MOV AX,#xldarrch ;(load array of char)
  545. CALL ecall ;* CALL xldarrch
  546. MOV CL,#$08
  547. cvaok XOR AX,AX ;ok
  548. RET ;"
  549. cconst CALL constel ;get constant element
  550. JNZ ccnret ;no good: ret
  551. MOV DX,negflg ;negation flag
  552. CALL donegate ;do negation
  553. MOV negflg,#$0000 ;clear neg flag
  554. cconst2 CMP.B CL,#$09 ;real ?
  555. JNZ ccnstr ;:no
  556. MOV AX,#xrealcn ;(load real constant)
  557. CALL ecall ;* CALL xrealcn
  558. MOV AX,creal1 ;emit real constant
  559. CALL eword ;as inline code
  560. MOV AX,creal2
  561. CALL eword
  562. MOV AX,creal3
  563. CALL eword
  564. JMP.b ccnok ;'ok
  565. ccnstr CMP.B CL,#$08 ;string ?
  566. JNZ ccnscal ;:no
  567. MOV AX,#xstrcn ;(get inline string)
  568. CALL ecall ;* CALL xstrcn
  569. PUSH CX ;save
  570. CALL estring ;emit string
  571. POP CX
  572. JMP.b ccnok ;'ok
  573. ccnscal MOV exres,BX ;store result
  574. XOR.B CH,CH ;type: constant
  575. ccnok XOR AX,AX ;ok
  576. ccnret RET ;"
  577. cfunc MOV CX,#$0600 ;Do function
  578. CALL search ;search it
  579. JNZ cfnret ;not found: ret
  580. CALL estkchk ;emit stack check
  581. MOV BX,[BP]-$02 ;result type ptr
  582. SS:
  583. MOV AX,[BX]-$02 ;result type size
  584. CALL allotstk ;allot stack space for result
  585. CALL cproc2 ;call function (like procedure)
  586. CALL getvprm ;get var parms
  587. MOV AX,lower ;result type ptr
  588. MOV functp,AX
  589. MOV.B CL,varctp ;component type
  590. MOV CH,#$02 ;result in AX / on stack
  591. CMP.B CL,#$0B ;boolean ?
  592. JNZ cfnok ;:no
  593. MOV CH,#$03 ;flags set
  594. cfnok XOR AX,AX ;ok
  595. cfnret RET ;"
  596. allotstk CMP AX,#$0002 ;Allocate space on stack
  597. JA astksub ;:offset > 2
  598. XCHG AX,CX ;offset -> CX
  599. JCXZ cfnret ;:nothing to allot
  600. astkdec CALL ecode ;* DEC SP
  601. B $01,$4C
  602. LOOP astkdec ;:another byte
  603. RET ;'
  604. astksub CALL offslen ;short or long offset
  605. MOV DX,#$EC83 ;short
  606. JZ astkshrt ;:short
  607. MOV DL,#$81 ;long
  608. astkshrt PUSH AX ;save AX
  609. CALL emitdx ;* SUB SP,#....
  610. POP AX ;restore
  611. TEST.B DL,#$02 ;short ?
  612. JZ astklong ;:no
  613. JMP ebyte ;'emit byte offset
  614. astklong JMP eword ;"emit word offset
  615. cset CALL csqr1 ;Do set: [ ?
  616. JNZ csetret ;no:ret
  617. MOV AX,#sldempty ;(make empty set)
  618. CALL ecall ;* CALL sldempty
  619. CALL csqr2 ;] ?
  620. MOV CX,#$0003 ;type: untyped set
  621. JZ csetret ;:yes
  622. csetlp PUSH CX ;save type
  623. CALL exscal ;get scalar expression
  624. MOV.B AL,CL ;type read
  625. POP CX ;restore type
  626. OR.B CH,CH ;typed set ?
  627. JNZ csetcn ;:yes
  628. MOV.B CH,AL ;set type from const read
  629. csetcn CMP.B AL,CH ;compare base type
  630. CALL errnz ;not equal:
  631. B $2C ;44:Type mismatch
  632. PUSH CX ;save type
  633. CALL ctoken ;.. ?
  634. W tk2dot
  635. MOV AX,#setincl ;(include element in set)
  636. JNZ csetincl ;:no
  637. CALL epushax ;* PUSH AX
  638. CALL exscal ;get scalar expr
  639. MOV.B AL,CL ;result type
  640. POP CX
  641. PUSH CX
  642. CMP.B AL,CH ;= type of set ?
  643. CALL errnz ;no:
  644. B $2C ;44:Type mismatch
  645. MOV AX,#setinrng ;(include range in set)
  646. csetincl CALL ecall ;emit call
  647. POP CX ;restore type
  648. CALL ccomma ;, ?
  649. JZ csetlp ;yes: loop back
  650. CALL esqr2 ;! ]
  651. XOR AX,AX ;ok
  652. csetret RET ;"
  653. cparens CALL cbrack1 ;Do parentheses: ( ?
  654. JNZ cparret ;no:ret
  655. CALL expr ;get expression
  656. CALL ebrack2 ;! )
  657. XOR AX,AX ;ok
  658. cparret RET ;"
  659. ctype MOV CX,#$0300 ;Do type conversions
  660. CALL search ;search type
  661. JNZ ctpret ;not found: ret
  662. MOV BP,[BP]-$02 ;get type ptr
  663. MOV.B AL,[BP]-$08 ;get component type
  664. CMP AL,#$0A ;scalar ?
  665. CALL errb ;no:
  666. B $1E ;30:Simple type expected
  667. PUSH AX ;save type
  668. CALL ebrack1 ;! (
  669. CALL expr ;get expression
  670. CALL ebrack2 ;! )
  671. CALL chksimpl ;check simple type
  672. POP AX ;restore type
  673. MOV.B CL,AL ;convert to type wanted
  674. XOR AX,AX ;ok
  675. ctpret RET ;"
  676. cnil CALL ctoken ;test for NIL
  677. W tknil
  678. JNZ cnilret ;no:ret
  679. CALL ecode ;* XOR AX,AX
  680. B $04,$33,$C0,$33,$D2 ;* XOR DX,DX
  681. MOV CL,#$04 ;type: pointer
  682. XOR AX,AX ;ok
  683. MOV functp,AX ;untyped ptr
  684. cnilret RET ;"
  685. cstdfn CALL ckey ;Do standard functions
  686. B $02
  687. W stdfuncs
  688. JNZ csfret ;not found: ret
  689. CS:
  690. CALL [BX] ;call compiler routine
  691. MOV CH,#$02 ;flag: result in AX
  692. CMP.B CL,#$0B ;boolean ?
  693. JNZ csfok ;:no
  694. MOV CH,#$03 ;flags set
  695. csfok XOR AX,AX ;ok
  696. csfret RET ;"
  697. fsqr CALL getnum ;SQR (num)
  698. CMP.B CL,#$0A ;integer ?
  699. JNZ fsqr2 ;:no
  700. CALL ecode
  701. B $02,$F7,$E8 ;* IMUL AX
  702. RET ;'
  703. fsqr2 MOV AX,#xsqr ;(sqr real)
  704. fsqremit JMP ecall ;"emit call
  705. fabs CALL getnum ;ABS (num)
  706. MOV AX,#iabs ;(abs integer)
  707. CMP.B CL,#$0A ;integer ?
  708. JZ fsqremit ;yes: emit call
  709. MOV AX,#xabs ;(abs real)
  710. JMP fsqremit ;"
  711. fsqrt MOV AX,#xsqrt ;SQRT
  712. JMP.b freal ;'
  713. fsin MOV AX,#xsin ;SIN
  714. JMP.b freal ;'
  715. fcos MOV AX,#xcos ;COS
  716. JMP.b freal ;'
  717. farctan MOV AX,#xarctan ;ARCTAN
  718. JMP.b freal ;'
  719. fln MOV AX,#xln ;LN
  720. JMP.b freal ;'
  721. fexp MOV AX,#xexp ;EXP
  722. JMP.b freal ;'
  723. fint2 MOV AX,#xint ;INT
  724. JMP.b freal ;'
  725. ffrac MOV AX,#xfrac ;FRAC
  726. freal PUSH AX ;save function addr
  727. CALL getnum ;(num)
  728. CMP.B CL,#$09 ;real ?
  729. JZ freal2 ;:yes
  730. MOV AX,#xintreal ;(integer -> real)
  731. CALL ecall
  732. MOV CL,#$09 ;now: real
  733. freal2 POP AX ;restore addr
  734. JMP ecall ;"emit call
  735. ftrunc MOV AX,#xtrunc ;TRUNC
  736. JMP.b frnd2 ;'
  737. fround MOV AX,#xround ;ROUND
  738. frnd2 PUSH AX ;save addr
  739. CALL getnum ;(num)
  740. POP AX ;restore
  741. CMP.B CL,#$0A ;integer ?
  742. JNZ frndemit ;:no
  743. RET ;'int: do nothing
  744. frndemit MOV CL,#$0A ;convert to integer
  745. JMP ecall ;"emit call
  746. fsucc MOV AL,#$40 ;SUCC: INC AX
  747. JMP.b fpred2 ;'
  748. fpred MOV AL,#$48 ;PRED: DEC AX
  749. fpred2 PUSH AX ;save opcode
  750. CALL getscal ;(scal)
  751. POP AX ;restore op
  752. JMP ebyte ;"emit it
  753. flo CALL getint ;LO: (int)
  754. CALL ecode
  755. B $02,$32,$E4 ;* XOR AH,AH
  756. RET ;"
  757. fhi CALL getint ;HI: (int)
  758. CALL ecode ;* MOV AL,AH
  759. B $04,$8A,$C4,$32,$E4 ;* XOR AH,AH
  760. RET ;"
  761. fswap CALL getint ;SWAP: (int)
  762. CALL ecode
  763. B $02,$86,$C4 ;* XCHG AH,AL
  764. RET ;"
  765. fodd CALL getint ;ODD: (int)
  766. CALL ecode
  767. B $03,$25,$01,$00 ;* AND AX,#0001
  768. MOV CL,#$0B ;boolean result
  769. RET ;"
  770. fkeypres MOV AX,#xkeypres ;KEYPRESSED
  771. MOV CL,#$0B ;result: boolean
  772. JMP ecall ;"emit call
  773. ford CALL getscal ;ORD: (scalar)
  774. MOV CL,#$0A ;result: integer
  775. RET ;"
  776. fchr CALL getint ;CHR: (int)
  777. MOV CL,#$0C ;result: char
  778. RET ;"
  779. flength CALL ebrack1 ;! ( : LENGTH
  780. MOV AX,#xlength
  781. flen2 PUSH AX ;save addr
  782. CALL exstr ;get string expression
  783. CALL ebrack2 ;! )
  784. POP AX ;restore addr
  785. JMP frndemit ;"int result, emit call
  786. fpos CALL ebrack1 ;! ( : POS
  787. CALL exstr ;get string expression
  788. CALL ecomma ;! ,
  789. MOV AX,#xpos
  790. JMP flen2 ;"get second string expr
  791. fcopy CALL ebrack1 ;! ( : COPY
  792. CALL exstr ;get string expr
  793. CALL ecomma ;! ,
  794. CALL exint ;get int expr
  795. CALL ecomma ;! ,
  796. CALL epushax ;* PUSH AX
  797. CALL exint ;get int expr
  798. MOV AX,#xcopy
  799. CALL ecall ;emit call
  800. fcopemit CALL ebrack2 ;! )
  801. MOV CL,#$08 ;result: string
  802. RET ;"
  803. fconcat CALL ebrack1 ;! ( : CONCAT
  804. CALL exstr ;get string expr
  805. fconlp CALL ccomma ;, ?
  806. JNZ fcopemit ;no:end it
  807. CALL exstr ;get string expr
  808. MOV AX,#xconcat
  809. CALL ecall ;emit call
  810. JMP fconlp ;"another string ?
  811. fparmcnt MOV AX,#xparmcnt ;PARAMCOUNT
  812. JMP frndemit ;"result: integer
  813. fparmstr CALL getint ;PARAMSTR: (int)
  814. MOV AX,#xparmstr
  815. MOV CL,#$08 ;result: string
  816. JMP ecall ;"emit call
  817. frandom CALL cbrack1 ;RANDOM: ( ?
  818. MOV AX,#xrandom ;(random real)
  819. MOV CL,#$09 ;result: real
  820. JNZ frndreal ;no (: take real
  821. CALL exint ;get int expr
  822. CALL ebrack2 ;! )
  823. MOV AX,#irandom ;(random int)
  824. femitint MOV CL,#$0A ;result: integer
  825. frndreal JMP ecall ;"emit call
  826. fiores MOV AX,#xiores ;IORESULT
  827. JMP femitint ;"-> integer
  828. feof CALL getfil ;EOF: (file)
  829. MOV BX,#veof ;ptr to vector table
  830. CALL ecallio ;emit call for I/O
  831. femitboo MOV CL,#$0B ;result: boolean
  832. RET ;"
  833. fseekeof MOV AX,#xseekeof ;SEEKEOF
  834. JMP.b feo2 ;'
  835. fseekeol MOV AX,#xseekeol ;SEEKEOLN
  836. JMP.b feo2 ;'
  837. feoln MOV AX,#xeoln ;EOLN
  838. feo2 PUSH AX ;save addr
  839. CALL getfil ;(file)
  840. CMP.B CL,#$06 ;text file ?
  841. CALL errnz ;no:
  842. B $23 ;35:Textfile expected
  843. POP AX ;restore addr
  844. CALL ecall ;emit call
  845. JMP femitboo ;"result: boolean
  846. ffilpos MOV AX,#xfilepos ;FILEPOS
  847. JMP.b ffil2 ;'
  848. ffilsize MOV AX,#xfilesiz ;FILESIZE
  849. ffil2 PUSH AX ;save addr
  850. CALL getfil ;(file)
  851. POP AX ;addr
  852. CMP.B CL,#$06 ;text file ?
  853. CALL errz ;yes:
  854. B $3F ;63:Textfiles are not allowed here
  855. JMP femitint ;"int result, emit call
  856. flfilpos MOV AX,#xlfilpos ;LONGFILEPOS
  857. JMP.b flf2 ;'
  858. flfilsiz MOV AX,#xlfilsiz ;LONGFILESIZE
  859. flf2 PUSH AX ;save addr
  860. CALL getfil ;(file)
  861. POP AX ;addr
  862. CMP.B CL,#$06 ;text file ?
  863. CALL errz ;yes:
  864. B $3F ;63:Textfiles are not allowed here
  865. MOV CL,#$09 ;result: real
  866. JMP ecall ;"emit call
  867. fmemavl MOV AX,#xmemavl ;MEMAVAIL
  868. JMP femitint ;"int result, emit call
  869. fmaxavl MOV AX,#xmaxavl ;MAXAVAIL
  870. JMP femitint ;"int result, emit call
  871. faddr CALL ebrack1 ;! ( : ADDR
  872. CALL varptr ;get var ptr
  873. CALL ecode ;* POP DX
  874. B $02,$5A,$97 ;* XCHG DI,AX
  875. fretptr CALL ebrack2 ;! )
  876. MOV CL,#$04 ;result: pointer
  877. MOV functp,#$0000 ;untyped
  878. RET ;"
  879. fptr CALL ebrack1 ;! ( : PTR
  880. CALL exint ;get int expr
  881. CALL ecomma ;! ,
  882. CALL epushax ;* PUSH AX
  883. CALL exint ;get int expr
  884. CALL ecode ;* POP DX (segment)
  885. B $01,$5A
  886. JMP fretptr ;"expect ), pointer
  887. fofs CALL ebrack1 ;! ( : OFS
  888. MOV CX,#$0500 ;search procedure
  889. CALL search
  890. JZ fofsproc ;:found
  891. MOV CX,#$0600 ;search function
  892. CALL search
  893. JNZ fofsvar ;:not found
  894. fofsproc MOV AX,[BP]-$08 ;get offset
  895. fofsimme CALL emovaxi ;* MOV AX,#proc_offset
  896. JMP.b fofsint ;'type: integer
  897. fofsvar CALL rdvar ;get var
  898. CALL errnz ;not found:
  899. B $29 ;41:Unknown ID or syntax error
  900. CALL loadoffs ;get offset
  901. CALL ecode ;* XCHG DI,AX
  902. B $01,$97 ;(offset -> AX)
  903. fofsint CALL ebrack2 ;! )
  904. MOV CL,#$0A ;result: integer
  905. RET ;"
  906. fseg CALL ebrack1 ;! ( : SEG
  907. CALL rdvar ;get var
  908. CALL errnz ;not found:
  909. B $29 ;41:Unknown ID or syntax error
  910. MOV AL,#$8C ;(MOV AX,DS)
  911. MOV AH,#$D8
  912. CMP.B varseg,#$FF ;DS ?
  913. JZ fsegemit ;yes: ok
  914. MOV AH,#$C0 ;(MOV AX,ES)
  915. CMP.B varseg,#$FD ;ES ?
  916. JZ fsegemit ;yes: ok
  917. MOV AH,#$D0 ;(MOV AX,SS)
  918. JB fsegemit ;below: ok
  919. MOV AH,#$C8 ;(MOV AX,CS)
  920. fsegemit CALL eword ;emit word
  921. JMP fofsint ;"expect ), integer
  922. fsizeof CALL ebrack1 ;! ( : SIZEOF
  923. MOV CX,#$0300 ;search type
  924. CALL search
  925. JNZ fszvar ;:not found
  926. MOV BP,[BP]-$02 ;type ptr
  927. MOV AX,[BP]-$02 ;get component size
  928. CALL emovaxi ;* MOV AX,#compo_size
  929. JMP fofsimme ;'(Bug: redundant load !)
  930. fszvar CALL rdvar ;get var
  931. CALL errnz ;not found:
  932. B $29 ;41:Unknown ID or syntax error
  933. MOV AX,varsize ;get component size
  934. JMP fofsimme ;"emit MOV AX,#.., integer
  935. fdseg CALL ecode ;DSEG
  936. B $02,$8C,$D8 ;* MOV AX,DS
  937. JMP.b fsseg2 ;'int result
  938. fcseg CALL ecode ;CSEG
  939. B $02,$8C,$C8 ;* MOV AX,CS
  940. JMP.b fsseg2 ;'int result
  941. fsseg CALL ecode ;SSEG
  942. B $02,$8C,$D0 ;* MOV AX,SS
  943. fsseg2 MOV CL,#$0A ;integer
  944. RET ;"
  945. fportw MOV AL,#$ED ;PORTW
  946. JMP.b fprt2 ;'(IN AX,[DX])
  947. fport MOV AL,#$EC ;PORT (INB AL,[DX])
  948. fprt2 PUSH AX ;save opcode
  949. CALL esqr1 ;! [
  950. CALL exint ;get int expr
  951. CALL esqr2 ;! ]
  952. CALL ecode
  953. B $01,$92 ;* XCHG DX,AX (port number)
  954. POP AX ;restore opcode
  955. CALL ebyte ;emit it
  956. CMP AL,#$ED ;integer ?
  957. JZ fsseg2 ;:yes
  958. CALL ecode ;byte:
  959. B $02,$32,$E4 ;* XOR AH,AH
  960. JMP fsseg2 ;"int result
  961. fupcase CALL getscal ;UPCASE: (scalar)
  962. MOV CL,#$0C ;result: char
  963. MOV AX,#xupcase
  964. JMP ecall ;"emit call
  965. fwherex MOV AX,#xwherex ;WHEREX
  966. JMP femitint ;"int result, emit call
  967. fwherey MOV AX,#xwherey ;WHEREY
  968. JMP femitint ;"int result, emit call
  969. veof W xeofty,xeoftx,xeofty ;"EOF vector table
  970. getint CALL ebrack1 ;! ( : get (int)
  971. CALL exint ;get int expr
  972. JMP ebrack2 ;"! )
  973. getnum CALL ebrack1 ;! ( : get (num)
  974. CALL exnum ;get num expr
  975. JMP ebrack2 ;"! )
  976. getscal CALL ebrack1 ;! ( : get (scalar)
  977. CALL exscal ;get scalar expr
  978. JMP ebrack2 ;"! )
  979. getfil CALL cbrack1 ;get (file): ( ?
  980. JNZ gtfstd ;:no
  981. CALL rdfilvar ;get file var
  982. JNB gtf2 ;:ok
  983. CALL err ;41:Unknown ID or syntax error
  984. B $29 ;'
  985. gtf2 CALL errnz ;not file var:
  986. B $15 ;21:File var expected
  987. JMP ebrack2 ;'! )
  988. gtfstd CALL ecode ;set ptr to std input file
  989. B $04,$BF,$5A,$01,$1E ;* MOV DI,#stdin
  990. MOV CL,#$06 ;* PUSH DS
  991. MOV.B varctp,CL ;type: text file
  992. RET ;"
  993. fullvar CALL rdconst ;Do full var: read constant
  994. JNZ rdvar ;no good: read var
  995. CMP.B CL,#$08 ;string constant ?
  996. CALL errnz ;no:
  997. B $3C ;60:Constants are not allowed here
  998. MOV AL,#$EB ;JMP
  999. MOV.B AH,CH ;offset: length of string
  1000. CALL eword ;emit branch around string constant
  1001. MOV AX,pc ;save current pos
  1002. MOV varofs,AX ;-> offset of var
  1003. MOV.B indflg,#$00 ;not indexed
  1004. MOV.B varseg,#$FE ;segment CS
  1005. MOV.B varctp,#$01 ;type: array
  1006. MOV AX,ptcbeg ;std type: char
  1007. SUB AX,#$0062
  1008. MOV lower,AX ;-> type pointer
  1009. XOR AX,AX ;no index type
  1010. MOV upper,AX
  1011. MOV.B AL,CH ;length -> component size
  1012. MOV varsize,AX
  1013. CALL estr2 ;emit array of char
  1014. XOR AX,AX ;ok
  1015. RET ;'
  1016. rdvar CALL indwith ;do WITH-indexing
  1017. JZ rdvarlp ;:done
  1018. MOV CX,#$0400 ;search var
  1019. CALL search
  1020. JNZ rvamem ;not found: try MEM
  1021. CALL getvprm ;get var parms
  1022. rdvarind MOV.B indflg,#$00 ;flag: not indexed
  1023. CMP.B indptflg,#$00 ;indirect by ptr ?
  1024. JZ rdvarlp ;:no
  1025. CALL indptrld ;get ptr to var
  1026. rdvarlp CALL indarray ;do array indexing
  1027. JZ rdvarlp ;done: loop
  1028. CALL indrec ;do record indexing
  1029. JZ rdvarlp ;done: loop
  1030. CALL indptr ;do pointer indexing
  1031. JZ rdvarlp ;done: loop
  1032. CALL indstr ;do string indexing
  1033. XOR AX,AX ;ok
  1034. RET ;'
  1035. rvamem CALL ckey ;search keyword:
  1036. B $01 ;MEM / MEMW
  1037. W tkmem
  1038. JNZ rvaret ;not found: ret
  1039. CS:
  1040. MOV.B AL,[BX] ;get component size
  1041. PUSH AX ;save it
  1042. CALL esqr1 ;! [
  1043. CALL exint ;get int expr
  1044. CALL epushax ;* PUSH AX (segment)
  1045. CALL ecolon ;! :
  1046. CALL exint ;get int expr
  1047. CALL esqr2 ;! ]
  1048. CALL ecode ;* XCHG DI,AX
  1049. B $02,$97,$07 ;* POP ES
  1050. POP AX ;get length flag
  1051. XOR.B AH,AH ;clr hi
  1052. MOV varsize,AX ;-> component size
  1053. MOV.B varctp,#$0A ;type integer
  1054. CMP AL,#$01 ;byte ?
  1055. JNZ rvamemw ;:no
  1056. MOV lower,#$0000 ;set lower, upper bound
  1057. MOV upper,#$00FF
  1058. JMP.b rvamemb ;'
  1059. rvamemw MOV lower,#$8000 ;set lower, upper bound
  1060. MOV upper,#$7FFF
  1061. rvamemb MOV varofs,#$0000 ;var offset: none
  1062. MOV.B indflg,#$FF ;indexed
  1063. MOV.B varseg,#$FD ;segment ES
  1064. XOR AX,AX ;ok
  1065. rvaret RET ;"
  1066. indwith MOV.B BL,withnest ;Do WITH indexing
  1067. XOR.B BH,BH ;with nesting -> count
  1068. iwloop DEC BX ;count down
  1069. JNS iw1 ;:another level to test
  1070. RET ;'
  1071. iw1 PUSH BX ;save counter
  1072. SHL BX,1 ;* 4
  1073. SHL BX,1 ;-> pointer into with-table
  1074. MOV CX,[BX]withtab ;type
  1075. PUSH CX
  1076. PUSH [BX]withtab1 ;position
  1077. MOV CH,#$04 ;search var (record num)
  1078. CALL search
  1079. POP AX ;restore pos, type, counter
  1080. POP CX
  1081. POP BX
  1082. JNZ iwloop ;not found: do next level
  1083. MOV.B indflg,#$00 ;flag: not indexed
  1084. CMP AX,#$FFFF ;indexed WITH ?
  1085. JZ iwvar ;:yes
  1086. MOV.B varseg,CH ;get offset from with-table
  1087. MOV varofs,AX
  1088. JMP.b iwconst ;'do record indexing
  1089. iwvar PUSH BP ;save symtab pos
  1090. MOV.B BL,CH ;get stack offset
  1091. SHL BX,1
  1092. MOV AX,varspc ;stack usage
  1093. SUB AX,BX ;- position
  1094. MOV varofs,AX ;-> offset
  1095. MOV AL,lexnest ;lexical nesting
  1096. MOV varseg,AL ;-> var segment
  1097. CALL indptrld ;get pointer to var
  1098. POP BP ;restore symtab ptr
  1099. iwconst JMP iraddofs ;"do record indexing
  1100. indstr CMP.B varctp,#$08 ;Do string indexing
  1101. JNZ iaret ;no string: ret
  1102. CALL csqr1 ;[ ?
  1103. JNZ iaret ;no: ret
  1104. MOV AX,ptcbeg ;point to char type
  1105. SUB AX,#$0062
  1106. MOV lower,AX ;-> type ptr
  1107. JMP.b ialoop ;"get index
  1108. indarray CMP.B varctp,#$01 ;Do array indexing
  1109. JNZ iaret ;no array: ret
  1110. CALL csqr1 ;[ ?
  1111. JZ ialoop ;yes: do it
  1112. iaret RET ;'
  1113. ialoop MOV AX,flgpshes ;flag: emit PUSH ES
  1114. CMP.B varseg,#$FD ;segment ES ?
  1115. JNZ ialp2 ;:no
  1116. MOV.B flgpshes,#$01 ;set flag
  1117. ialp2 CMP.B indflg,#$00 ;indexed ?
  1118. JZ ianoind ;:no
  1119. MOV.B flgpshdi,#$01 ;set flag: emit PUSH DI
  1120. ianoind CALL pushe1 ;push entry
  1121. PUSH pc ;save PC, flag
  1122. PUSH AX
  1123. CALL expr ;evaluate expression
  1124. POP AX ;restore
  1125. CMP flgpshes,#$00 ;flag = 0 ?
  1126. JZ iarest ;:yes
  1127. MOV flgpshes,AX ;restore flag
  1128. iarest POP AX ;old PC
  1129. SUB AX,pc ;anything emitted ?
  1130. OR.B CH,CH ;constant ?
  1131. JZ ianosto ;:yes
  1132. PUSH AX ;save
  1133. PUSH CX
  1134. CALL expload ;load result
  1135. POP CX
  1136. POP AX
  1137. ianosto CALL pope1 ;restore entry
  1138. OR AX,AX ;test flag
  1139. JZ ianopop ;:not set
  1140. CMP.B indflg,#$00 ;indexed ?
  1141. JZ ianoind2 ;:no
  1142. CALL ecode ;* POP DI
  1143. B $01,$5F
  1144. ianoind2 CMP.B varseg,#$FD ;segment ES ?
  1145. JNZ ianopop ;:no
  1146. CALL ecode ;* POP ES
  1147. B $01,$07
  1148. ianopop CMP.B varctp,#$08 ;string ?
  1149. JNZ ianostr ;:no
  1150. MOV.B var2ctp,#$0A ;component type = scalar
  1151. MOV lower2,#$0000 ;lower bound
  1152. MOV AX,varsize ;component size - 1
  1153. DEC AX
  1154. MOV upper2,AX ;-> upper bound
  1155. JMP.b iastr ;'
  1156. ianostr MOV BP,upper ;index type ptr
  1157. CALL getparm ;get type parms
  1158. iastr MOV BP,lower ;type ptr
  1159. CALL getvprm2 ;get type parms
  1160. CMP.B CL,var2ctp ;type = index type ?
  1161. CALL errnz ;no:
  1162. B $2C ;44:Type mismatch
  1163. OR.B CH,CH ;constant index ?
  1164. JNZ iavarind ;:no
  1165. MOV AX,exres ;get result
  1166. CMP AX,lower2 ;< lower bound ?
  1167. JL iaerr ;yes: error
  1168. CMP AX,upper2 ;> upper bound ?
  1169. JLE iacnind ;no: ok
  1170. iaerr CALL err ;45:Constant out of range
  1171. B $2D ;'
  1172. iacnind SUB AX,lower2 ;subtract lower bound
  1173. MOV CX,varsize ;* component size
  1174. MUL CX
  1175. ADD varofs,AX ;add to var offset
  1176. JMP iaind ;'store it
  1177. iavarind MOV AX,lower2 ;lower bound
  1178. TEST direcsv,#$0002 ;range check ?
  1179. JNZ iarngind ;:yes
  1180. MOV CX,varsize ;lower bound * component size
  1181. MUL CX
  1182. SUB varofs,AX ;subtract from var offset
  1183. JMP.b iacnind2 ;'-> faster array indexing
  1184. iarngind OR AX,AX ;subtract lower bound from index
  1185. JZ iaoff2 ;0:done
  1186. CMP AX,#$0001 ;1 ?
  1187. JNZ iaoff ;:no
  1188. CALL ecode
  1189. B $01,$48 ;* DEC AX
  1190. JMP.b iaoff2 ;'
  1191. iaoff CALL ecode
  1192. B $01,$2D ;* SUB AX,#lower_bound
  1193. CALL eword
  1194. iaoff2 MOV AX,upper2 ;upper bound-lower bound+1
  1195. SUB AX,lower2
  1196. INC AX
  1197. CALL emovcxi ;* MOV CX,#ind_count
  1198. MOV AX,#xindchk ;(range check)
  1199. CALL ecall ;* CALL xindchk
  1200. iacnind2 MOV AX,varsize ;index * component size
  1201. CMP AX,#$0001 ;component size = 1 ?
  1202. JZ iacsend ;yes: ok
  1203. CMP AX,#$0002 ;= 2 ?
  1204. JNZ iacs4 ;:no
  1205. CALL ecode
  1206. B $02,$D1,$E0 ;* SHL AX,1
  1207. JMP.b iacsend ;'
  1208. iacs4 CMP AX,#$0004 ;= 4 ?
  1209. JNZ iacs6 ;:no
  1210. CALL ecode ;* SHL AX,1
  1211. B $04,$D1,$E0,$D1,$E0 ;* SHL AX,1
  1212. JMP.b iacsend ;'
  1213. iacs6 CMP AX,#$0006 ;= 6 ?
  1214. JNZ iacs ;:no
  1215. CALL ecode ;* SHL AX,1
  1216. B $08,$D1,$E0,$8B,$C8 ;* MOV CX,AX
  1217. B $D1,$E0,$03,$C1 ;* SHL AX,1
  1218. JMP.b iacsend ;'* ADD AX,CX
  1219. iacs CALL emovcxi ;* MOV CX,#compo_size
  1220. CALL ecode
  1221. B $02,$F7,$E1 ;* MUL CX
  1222. iacsend CMP.B indflg,#$00 ;already indexed ?
  1223. JZ ianotind ;:no
  1224. CALL ecode ;add to previous index
  1225. B $02,$03,$F8 ;* ADD DI,AX
  1226. JMP.b iaind ;'
  1227. ianotind CALL ecode
  1228. B $01,$97 ;* XCHG DI,AX
  1229. MOV.B indflg,#$FF ;flag: indexed
  1230. iaind CMP.B varctp,#$01 ;component type = array ?
  1231. JNZ iaend ;no: end it
  1232. CALL ccomma ;, ?
  1233. JNZ iaend ;no: end it
  1234. JMP ialoop ;'get next index
  1235. iaend CALL esqr2 ;! ]
  1236. XOR AX,AX ;ok
  1237. RET ;"
  1238. indrec CMP.B varctp,#$02 ;Do record indexing
  1239. JNZ irret ;no record: ret
  1240. CALL cdot ;. ?
  1241. JNZ irret ;no: ret
  1242. MOV.B CL,varnest ;record nesting level
  1243. MOV CH,#$04 ;var
  1244. CALL search ;search subvar
  1245. CALL errnz ;not found:
  1246. B $29 ;41:Unknown ID or syntax error
  1247. iraddofs PUSH indptflg ;save base parms
  1248. PUSH varofs
  1249. CALL getvprm ;get var parms
  1250. POP AX ;restore offset
  1251. ADD varofs,AX ;add to new offset
  1252. POP indptflg ;restore indirection ptr
  1253. XOR AX,AX ;ok
  1254. irret RET ;"
  1255. indptr CMP.B varctp,#$04 ;Do pointer indexing
  1256. JNZ iptret ;no pointer: ret
  1257. CALL cptr ;^ ?
  1258. JNZ iptret ;no: ret
  1259. MOV BP,lower ;type ptr
  1260. CALL getvprm2 ;get type parms
  1261. indptrld MOV DX,#$38C4 ;* LES DI,pointer_var
  1262. CALL einstr ;emit instruction
  1263. MOV varofs,#$0000 ;offset = 0
  1264. MOV.B varseg,#$FD ;segment = ES
  1265. MOV.B indflg,#$FF ;indexed
  1266. XOR AX,AX ;ok
  1267. iptret RET ;"
  1268. einstr MOV AL,varseg ;Emit instruction with addressing
  1269. CMP AL,#$FD ;ES ?
  1270. JB eistk ;:stack segment
  1271. CALL esegment ;emit segment prefix
  1272. CMP.B indflg,#$00 ;indexed ?
  1273. JNZ eiind ;:yes
  1274. MOV CH,#$06 ;mode: direct
  1275. OR.B DH,CH
  1276. CALL emitdx ;emit DX
  1277. MOV AX,varofs ;get offset
  1278. CALL eword ;emit offset
  1279. JMP.b eiret ;'ret
  1280. eiind MOV AX,varofs ;get offset
  1281. OR AX,AX ;test offset
  1282. MOV CH,#$05 ;[DI]
  1283. JZ eiindofs ;:yes
  1284. CALL offslen ;short or long offset ?
  1285. MOV CH,#$45 ;short
  1286. JZ eiindofs ;:ok
  1287. MOV CH,#$85 ;long offset
  1288. eiindofs OR.B DH,CH ;set addressing mode
  1289. CALL emitdx ;emit opcode
  1290. TEST.B DH,#$C0 ;offset ?
  1291. JZ eiret ;no: ret
  1292. JMP.b eioffs ;'emit offset
  1293. eistk CMP.B AL,lexnest ;in current procedure ?
  1294. MOV CX,#$0306 ;[BP]offs / [BP+DI]offs
  1295. JZ eistk2 ;:yes
  1296. CALL ecode ;* MOV BX,[BP]lex_level
  1297. B $02,$8B,$5E ;(get ptr from display)
  1298. ADD.B AL,AL ;- nesting level * 2
  1299. NEG.B AL
  1300. CALL ebyte ;emit offset
  1301. MOV AL,#$36 ;* SS:
  1302. CALL ebyte
  1303. MOV CX,#$0107 ;[BX]offs / [BX+DI]offs
  1304. eistk2 CMP.B indflg,#$00 ;indexed ?
  1305. JZ eistk3 ;:no
  1306. MOV.B CL,CH ;use [B.+DI]
  1307. eistk3 MOV AX,varofs ;get offset
  1308. CALL offslen ;short or long ?
  1309. MOV CH,#$40 ;short
  1310. JZ eistksh ;:ok
  1311. MOV CH,#$80 ;long
  1312. eistksh OR.B DH,CL ;set addressing mode
  1313. OR.B DH,CH
  1314. CALL emitdx ;emit opcode
  1315. eioffs MOV AX,varofs ;get offset
  1316. TEST.B DH,#$40 ;long ?
  1317. JNZ eioffbyt ;:no
  1318. CALL eword ;emit word offset
  1319. JMP.b eiret ;'
  1320. eioffbyt CALL ebyte ;emit byte offset
  1321. eiret RET ;"
  1322. offslen OR.B AL,AL ;Short or long offset ?
  1323. JS offneg ;:negative
  1324. OR.B AH,AH ;high byte must be zero
  1325. RET ;'
  1326. offneg CMP.B AH,#$FF ;high byte must be FF
  1327. RET ;"
  1328. esegment CMP.B varseg,#$FF ;emit segment prefix
  1329. JZ eseges ;DS:no prefix needed
  1330. CMP.B varseg,#$FD ;ES ?
  1331. MOV AL,#$26 ;(ES:)
  1332. JZ esegret ;:yes
  1333. MOV AL,#$2E ;(CS:)
  1334. esegret CALL ebyte ;emit prefix
  1335. eseges RET ;"
  1336. loadoffs CMP.B varseg,#$FD ;Get offset
  1337. JB ldostk ;:stack segment
  1338. MOV AX,varofs ;var offset
  1339. CMP.B indflg,#$00 ;indexed ?
  1340. JNZ ldoind ;:yes
  1341. JMP emovdii ;'* MOV DI,#offset
  1342. ldoind OR AX,AX ;test offset
  1343. JZ eseges ;0:ret
  1344. CALL offslen ;short or long offset ?
  1345. MOV DX,#$C783 ;(ADD DI,#byte)
  1346. JZ ldobyt ;:short
  1347. MOV DL,#$81 ;(ADD DI,#word)
  1348. ldobyt PUSH AX ;save offset
  1349. CALL emitdx ;emit operation
  1350. POP AX ;offset
  1351. TEST.B DL,#$02 ;short ?
  1352. JZ ldoword ;:no
  1353. JMP ebyte ;'emit byte offset
  1354. ldoword JMP eword ;'emit word offset
  1355. ldostk MOV DX,#$388D ;(LEA DI,..)
  1356. JMP einstr ;"get effective addr -> DI
  1357. varptr CALL rdvar ;Get var ptr: get var
  1358. CALL errnz ;not found:
  1359. B $29 ;41:Unknown ID or syntax error
  1360. varptr2 CALL loadoffs ;get offset -> DI
  1361. MOV AL,#$1E ;(PUSH DS) push offset
  1362. CMP.B varseg,#$FF ;DS ?
  1363. JZ varptret ;:yes
  1364. MOV AL,#$06 ;(PUSH ES)
  1365. CMP.B varseg,#$FD ;ES ?
  1366. JZ varptret ;:yes
  1367. MOV AL,#$16 ;(PUSH SS)
  1368. JB varptret ;:yes
  1369. MOV AL,#$0E ;(PUSH CS)
  1370. varptret JMP ebyte ;"emit op
  1371. eload CMP.B varctp,#$0A ;Load var
  1372. JB eldptr ;:no scalar
  1373. CMP.B varseg,#$FD ;ES ?
  1374. JB eldstk ;:SS: no shortcuts
  1375. CMP.B indflg,#$00 ;indexed ?
  1376. JZ elddir ;:no
  1377. eldstk MOV DL,#$8B ;(MOV)
  1378. CMP varsize,#$01 ;byte ?
  1379. JA eldword ;:no
  1380. MOV DL,#$8A ;(MOVB)
  1381. eldword MOV DH,#$00 ;MOV AX,...
  1382. CALL einstr ;emit instruction
  1383. JMP.b eldpbyt ;'byte: clr hi byte
  1384. elddir CALL esegment ;emit segment prefix
  1385. MOV AL,#$A1 ;(MOV AX,var)
  1386. CMP varsize,#$01 ;byte ?
  1387. JA elddbyt ;:no
  1388. MOV AL,#$A0 ;(MOVB AL,var)
  1389. elddbyt CALL ebyte ;emit operation
  1390. MOV AX,varofs ;emit offset
  1391. CALL eword
  1392. eldpbyt CMP varsize,#$01 ;byte ?
  1393. JA eldret ;:no
  1394. CALL ecode
  1395. B $02,$32,$E4 ;* XOR AL,AL
  1396. eldret RET ;'
  1397. eldptr CMP.B varctp,#$04 ;load other types
  1398. JNZ eldreal ;:no ptr
  1399. MOV DX,#$00C4 ;LES AX,ptr_var
  1400. CALL einstr ;emit instruction
  1401. CALL ecode
  1402. B $02,$8C,$C2 ;* MOV DX,ES
  1403. RET ;'
  1404. eldreal CALL varptr2 ;get ptr -> DI,stack
  1405. MOV AX,#xldreal ;(load real)
  1406. CMP.B varctp,#$09 ;real ?
  1407. JZ eldemit ;:yes
  1408. MOV AX,#strload ;(load string)
  1409. CMP.B varctp,#$08 ;string ?
  1410. JZ eldemit ;:yes
  1411. CALL esetfac ;emit set crunch factor
  1412. MOV AX,#xldset ;(load set)
  1413. eldemit JMP ecall ;"emit call
  1414. estore CALL erngchk ;Store var: emit range check
  1415. estore2 CMP.B varctp,#$0A ;scalar ?
  1416. JB estcpl ;:no
  1417. eststo CMP.B varseg,#$FD ;SS ?
  1418. JB eststk ;yes: no shortcuts
  1419. CMP.B indflg,#$00 ;indexed ?
  1420. JZ estdir ;no: optimize
  1421. eststk MOV DL,#$89 ;(MOV dest_var,AX)
  1422. CMP varsize,#$01 ;byte ?
  1423. JA estword ;:no
  1424. MOV DL,#$88 ;(MOVB dest_var,AL)
  1425. estword MOV DH,#$00 ;mode
  1426. JMP einstr ;'emit instruction
  1427. estdir CALL esegment ;emit segment prefix
  1428. MOV AL,#$A3 ;(MOV var,AX)
  1429. CMP varsize,#$01 ;byte ?
  1430. JA estdbyt ;:no
  1431. MOV AL,#$A2 ;(MOVB var,AL)
  1432. estdbyt CALL ebyte ;emit opcode
  1433. MOV AX,varofs ;emit var offset
  1434. JMP eword ;'
  1435. estptr CALL eststo ;store ptr: emit store AX
  1436. ADD varofs,#$02 ;offs second word
  1437. MOV DX,#$1089 ;emit store DX
  1438. JMP einstr ;'emit instruction
  1439. estcpl CMP.B varctp,#$04 ;pointer ?
  1440. JZ estptr ;:yes
  1441. MOV AX,#xstoreal ;(store real)
  1442. CMP.B varctp,#$09 ;real ?
  1443. JZ estemit ;:yes
  1444. CMP.B varctp,#$08 ;string ?
  1445. JNZ estset ;:no
  1446. MOV.B AH,varsize ;get string length
  1447. DEC.B AH
  1448. MOV AL,#$B1
  1449. CALL eword ;* MOV CL,max_len
  1450. MOV AX,#strstore ;(store string)
  1451. JMP.b estemit ;'emit call
  1452. estset CALL esetfac ;set crunch factor
  1453. MOV AX,#setsto ;(store set)
  1454. estemit JMP ecall ;"emit call
  1455. esetfac MOV BP,lower ;calculate set crunch factor
  1456. CALL getparm ;get parms of base type
  1457. MOV AL,varsize ;component size
  1458. MOV.B AH,lower2 ;lower bound/8
  1459. MOV CL,#$03
  1460. SHR.B AH,CL
  1461. JMP emovcxi ;"* MOV CX,#crunch
  1462. erngchk CMP.B varctp,#$0A ;Emit range check
  1463. JB erngret ;no scalar: ret
  1464. TEST direcsv,#$0002 ;range checking on ?
  1465. JZ erngret ;:no
  1466. MOV AX,lower ;lower bound-1 = upper bound ?
  1467. DEC AX
  1468. CMP AX,upper
  1469. JZ erngret ;yes: no check
  1470. INC AX ;restore lower
  1471. CALL emovcxi ;* MOV CX,#lower_bound
  1472. MOV AX,upper ;upper bound
  1473. CALL emovdxi ;* MOV DX,#upper_bound
  1474. MOV AX,#xrngchk ;(range check)
  1475. CALL ecall ;emit call
  1476. erngret RET ;"
  1477. rdnumcn CALL rdconst ;read numeric constant
  1478. snerror CALL errnz ;no good:
  1479. B $29 ;41:Unknown ID or syntax error
  1480. RET ;"
  1481. rdintcn CALL rdnumcn ;get integer constant
  1482. testint CMP.B CL,#$0A ;integer ?
  1483. CALL errnz ;no:
  1484. B $16 ;22:Integer constant expected
  1485. RET ;"
  1486. rdstrcn CALL rdnumcn ;get string constant
  1487. CMP.B CL,#$08 ;string ?
  1488. JZ rdstrret ;yes: ok
  1489. CMP.B CL,#$0C ;char ?
  1490. CALL errnz ;no:
  1491. B $20 ;32:String constant expected
  1492. MOV CL,#$08 ;convert to string
  1493. rdstrret RET ;"
  1494. rdconst CALL testsign ;Read constant: test sign
  1495. PUSH DX ;save it
  1496. CALL constel ;get constant element
  1497. POP DX ;restore sign
  1498. JZ donegate ;:ok
  1499. OR DX,DX ;didn't work
  1500. CALL errnz ;25:Int or real const expected
  1501. B $19
  1502. DEC DX ;ok
  1503. rdcnret RET ;'
  1504. donegate CALL testnum ;test type
  1505. JZ rdcnret ;:ret - no negation
  1506. CMP.B CL,#$09 ;real ?
  1507. JNZ rdcnnegi ;:no
  1508. CMP.B creal1,#$00 ;0 ?
  1509. JZ rdcnok ;yes: don't negate
  1510. XOR.B cresign,#$80 ;negate it
  1511. JMP.b rdcnok ;'ok
  1512. rdcnnegi NEG BX ;negate result
  1513. rdcnok XOR DX,DX ;ok
  1514. RET ;"
  1515. testsign MOV DI,chptr ;Test sign:test char
  1516. MOV DX,#$FFFF ;flag: negative
  1517. CMP.B [DI],#$2D ;- ?
  1518. JZ tsminus ;:yes
  1519. INC DX ;clear neg flag
  1520. CMP.B [DI],#$2B ;+ ?
  1521. JNZ tsret ;no: don't skip char
  1522. INC DX ;set + flag
  1523. tsminus INC DI ;skip that char
  1524. CALL skipdi ;read next word
  1525. tsret RET ;"
  1526. testnum OR DX,DX ;Test type
  1527. JZ tnret ;:no negation - ok
  1528. CMP.B CL,#$0A ;integer ?
  1529. JZ tndec ;:ok
  1530. CMP.B CL,#$09 ;real ?
  1531. CALL errnz ;no:
  1532. B $19 ;25:Int or real constant expected
  1533. tndec DEC DX ;clear plus flag
  1534. tnret RET ;"
  1535. constel CALL immecn ;Get const element: immediate const
  1536. JNZ clconst ;:no
  1537. RET ;'
  1538. clconst MOV CX,#$0200 ;search constant
  1539. CALL search
  1540. JNZ clret ;:not found
  1541. MOV.B CL,[BP]-$01 ;get component type
  1542. CMP.B CL,#$0A ;scalar ?
  1543. JB clreal ;:no
  1544. MOV BX,[BP]-$03 ;get value
  1545. JMP.b clok ;'ok
  1546. clreal CMP.B CL,#$09 ;real ?
  1547. JNZ clstring ;:no
  1548. MOV AX,[BP]-$07 ;get real const
  1549. MOV creal1,AX ;store in buffer
  1550. MOV AX,[BP]-$05
  1551. MOV creal2,AX
  1552. MOV AX,[BP]-$03
  1553. MOV creal3,AX
  1554. JMP.b clok ;'ok
  1555. clstring MOV.B CH,[BP]-$02 ;string: get length
  1556. MOV.B DL,CH
  1557. MOV BX,#wordbuf ;dest buffer
  1558. clstrlp OR.B DL,DL ;test len
  1559. JZ clok ;:done
  1560. DEC BP ;stored backwards !
  1561. MOV.B AL,[BP]-$02 ;get char
  1562. MOV.B [BX],AL ;copy into buffer
  1563. INC BX ;next pos
  1564. DEC.B DL ;another char ?
  1565. JMP clstrlp ;'
  1566. clok XOR DX,DX ;ok
  1567. clret RET ;"
  1568. immecn MOV DI,chptr ;get immediate constant
  1569. MOV.B AL,[DI] ;current char
  1570. CMP AL,#$27 ; ' ?
  1571. JZ icstr ;yes: string const
  1572. CMP AL,#$5E ;^ ?
  1573. JZ icstr ;yes: string const
  1574. CMP AL,#$23 ;# ?
  1575. JNZ icnum ;no: numeric const
  1576. icstr MOV BX,#wordbuf ;dest buffer
  1577. MOV CH,#$00 ;length = 0
  1578. icsloop MOV.B AL,[DI] ;current char
  1579. CMP AL,#$5E ;^ ?
  1580. JZ icscntrl ;:yes
  1581. CMP AL,#$23 ;# ?
  1582. JZ icsnum ;:yes
  1583. CMP AL,#$27 ; ' ?
  1584. JNZ icsend ;no: end of string const
  1585. icslp2 INC DI ;next char
  1586. MOV.B AL,[DI] ;get char
  1587. OR.B AL,AL ;line end ?
  1588. CALL perrz ;yes:
  1589. B $37 ;55:String constant exceeds line
  1590. CMP AL,#$27 ; ' ?
  1591. JNZ icssto ;:no
  1592. INC DI ;test next char: may be ''
  1593. CMP.B [DI],#$27 ; ' ?
  1594. JNZ icsloop ;no: end of string
  1595. icssto MOV.B [BX],AL ;store in buffer
  1596. INC BX ;next pos
  1597. INC.B CH ;count length
  1598. JMP icslp2 ;'continue
  1599. icscntrl INC DI ;next char: do ^char
  1600. MOV.B AL,[DI] ;get it