M3GL.MOD 51 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511
  1. IMPLEMENTATION MODULE M3GL; (*NW 19.5.83 / 25.6.85*)
  2. FROM FileSystem IMPORT
  3. File, Response, Lookup, WriteChar, WriteWord, SetOpen, Close, Delete;
  4. FROM M3DL IMPORT WordSize,
  5. ObjPtr, StrPtr, ParPtr, PDPtr, ObjClass, StrForm, ConstValue, KeyPtr,
  6. cardtyp, inttyp, booltyp, chartyp, realtyp, dbltyp, bitstyp, notyp,
  7. stringtyp, addrtyp, wordtyp, undftyp;
  8. FROM M2S IMPORT IdBuf, Mark, id, CloseScanner;
  9. CONST MaxCard = 177777B; MaxInt = 32767; MinInt = -32767;
  10. StrTabLength = 2000; StackDepth = 16;
  11. CodeLength = 12000; RelTabLength = 1000; ProcTabLength = 128;
  12. VAR sp: INTEGER; (*expression stack pointer*)
  13. relx: CARDINAL; (*relocation table index*)
  14. datasize: INTEGER; (*of global data*)
  15. exp: CARDINAL; (*side effect of clog*)
  16. strx: CARDINAL; (*string table index*)
  17. StrTab: ARRAY [0..StrTabLength-1] OF CHAR;
  18. code: ARRAY [0..CodeLength-1] OF CHAR;
  19. RelTab: ARRAY [0..RelTabLength-1] OF CARDINAL;
  20. ProcTab: ARRAY [0..ProcTabLength-1] OF CARDINAL;
  21. PROCEDURE ROR(s: BITSET; n: CARDINAL): BITSET;
  22. (*rotate s right by n*) CODE 275B
  23. END ROR;
  24. PROCEDURE COM(s: BITSET): BITSET;
  25. (* {0..15} - s *) CODE 323B
  26. END COM;
  27. PROCEDURE MSK(n: CARDINAL): BITSET;
  28. (* {0 .. n-1} *) CODE 326B
  29. END MSK;
  30. PROCEDURE err(n: CARDINAL);
  31. BEGIN Mark(n)
  32. END err;
  33. PROCEDURE PutWord(n: CARDINAL);
  34. BEGIN code[pc] := CHAR(n DIV 400B);
  35. code[pc+1] := CHAR(n MOD 400B); pc := pc+2
  36. END PutWord;
  37. PROCEDURE PutByte(n: CARDINAL);
  38. BEGIN code[pc] := CHAR(n); pc := pc+1
  39. END PutByte;
  40. PROCEDURE PutOp(n: CARDINAL; s: INTEGER);
  41. BEGIN code[pc] := CHAR(n); pc := pc+1; sp := sp + s;
  42. IF sp > StackDepth THEN err(215) END
  43. END PutOp;
  44. PROCEDURE PutOpZ(n: CARDINAL);
  45. BEGIN code[pc] := CHAR(n); pc := pc+1
  46. END PutOpZ;
  47. PROCEDURE PutOpU(n: CARDINAL);
  48. BEGIN code[pc] := CHAR(n); pc := pc+1; sp := sp + 1;
  49. IF sp > StackDepth THEN err(215) END
  50. END PutOpU;
  51. PROCEDURE PutOpD(n: CARDINAL);
  52. BEGIN code[pc] := CHAR(n); pc := pc+1; sp := sp - 1
  53. END PutOpD;
  54. PROCEDURE PutOpArg(m, n: CARDINAL; s: INTEGER); (*LGW, LLW, SGW, SLW, CLL*)
  55. BEGIN sp := sp + s;
  56. IF sp > StackDepth THEN err(215) END;
  57. IF n < 10H THEN code[pc] := CHAR(m+n); pc := pc+1
  58. ELSIF n < 100H THEN code[pc] := CHAR(m); code[pc+1] := CHAR(n); pc := pc+2
  59. ELSE err(211)
  60. END
  61. END PutOpArg;
  62. PROCEDURE PutOpArg1(m, n: CARDINAL; s: INTEGER); (*LSW, SSW*)
  63. BEGIN sp := sp + s;
  64. IF sp > StackDepth THEN err(215) END ;
  65. IF n < 10H THEN code[pc] := CHAR(m+n); pc := pc+1
  66. ELSIF n < 100H THEN code[pc] := CHAR(m+40B); code[pc+1] := CHAR(n); pc := pc+2
  67. ELSE err(211)
  68. END
  69. END PutOpArg1;
  70. PROCEDURE fixupByte(loc: CARDINAL);
  71. BEGIN code[loc] := CHAR(pc - loc)
  72. END fixupByte;
  73. PROCEDURE fixup(loc: CARDINAL);
  74. BEGIN
  75. code[loc] := CHAR((pc-loc) DIV 400B); code[loc+1] := CHAR((pc-loc) MOD 400B)
  76. END fixup;
  77. PROCEDURE fixupC(loc: CARDINAL);
  78. BEGIN
  79. IF loc+2 < pc THEN
  80. code[loc] := CHAR((pc-loc) DIV 400B); code[loc+1] := CHAR((pc-loc) MOD 400B)
  81. ELSE pc := pc-3
  82. END
  83. END fixupC;
  84. PROCEDURE reloc;
  85. BEGIN
  86. IF relx < RelTabLength THEN RelTab[relx] := pc; relx := relx + 1
  87. ELSE err(224)
  88. END
  89. END reloc;
  90. PROCEDURE PutLit(n: CARDINAL);
  91. BEGIN
  92. IF n < 10H THEN PutOpU(n) (*LIn*)
  93. ELSIF n < 100H THEN PutOpU(20B); PutByte(n) (*LIB*)
  94. ELSIF n = 177777B THEN PutOpU(325B) (*LIN*)
  95. ELSE PutOpU(22B); PutWord(n) (*LIW*)
  96. END
  97. END PutLit;
  98. PROCEDURE PutLd(obj: ObjPtr; size: INTEGER);
  99. VAR m, L: CARDINAL; a: INTEGER;
  100. BEGIN (*obj^.class = Var*)
  101. m := obj^.vmod; L := obj^.vlev; a := obj^.vadr;
  102. IF m = 0 THEN
  103. IF L = 0 THEN
  104. IF size # 2 THEN PutOpArg(100B,a,1) (*LGW*)
  105. ELSE PutOp(101B, 2); PutByte(a) (*LGD*)
  106. END
  107. ELSIF L = curLev THEN
  108. IF size # 2 THEN PutOpArg(40B,a,1) (*LLW*)
  109. ELSE PutOp(41B, 2); PutByte(a) (*LLD*)
  110. END
  111. ELSE
  112. IF L+1 = curLev THEN PutOpU(351B) (*GB1*)
  113. ELSE PutOpU(350B); PutByte(curLev-L)
  114. END ;
  115. IF size # 2 THEN PutOpArg1(140B,a,0) (*LSW*)
  116. ELSE PutOpU(201B); PutByte(a) (*LSD*)
  117. END
  118. END
  119. ELSE
  120. IF size # 2 THEN PutOpU(42B) (*LEW*) ELSE PutOp(43B,2) (*LED*) END ;
  121. reloc; PutByte(m); PutByte(a)
  122. END
  123. END PutLd;
  124. PROCEDURE PutSto(obj: ObjPtr; size: INTEGER);
  125. VAR m, L: CARDINAL; a: INTEGER;
  126. BEGIN (*obj^.class = Var*)
  127. IF size <= 2 THEN
  128. m := obj^.vmod; L := obj^.vlev; a := obj^.vadr;
  129. IF m = 0 THEN
  130. IF L = 0 THEN
  131. IF size = 1 THEN PutOpArg(120B,a,-1) (*SGW*)
  132. ELSE PutOp(121B,-2); PutByte(a) (*SGD*)
  133. END
  134. ELSIF L = curLev THEN
  135. IF size = 1 THEN PutOpArg(60B,a,-1) (*SLW*)
  136. ELSE PutOp(61B,-2); PutByte(a) (*SLD*)
  137. END
  138. ELSE err(213)
  139. END
  140. ELSE
  141. IF size = 1 THEN PutOpD(62B) (*SEW*) ELSE PutOp(63B,-2) (*SED*) END ;
  142. reloc; PutByte(m); PutByte(a)
  143. END
  144. ELSE PutLit(size); PutOp(340B,-3) (*MOV*)
  145. END
  146. END PutSto;
  147. PROCEDURE AllocString(s: CARDINAL; VAR adr, length: CARDINAL);
  148. VAR L: CARDINAL;
  149. BEGIN L := ORD(IdBuf[s]); length := L - 1;
  150. IF strx + L >= StrTabLength THEN err(225); strx := 0 END ;
  151. adr := strx DIV 2; (*word address*)
  152. WHILE L > 1 DO
  153. s := s+1; StrTab[strx] := IdBuf[s]; strx := strx + 1; L := L-1
  154. END ;
  155. StrTab[strx] := 0C; strx := strx + 1;
  156. IF ODD(strx) THEN strx := strx + 1 END
  157. END AllocString;
  158. PROCEDURE loadStrAdr(adr: CARDINAL);
  159. BEGIN
  160. IF adr <= 377B THEN
  161. PutOpU(204B); PutByte(adr) (*LSTA adr*)
  162. ELSE PutOpU(102B); PutLit(adr); PutOpD(270B) (*LGW2 LIW adr UADD*)
  163. END
  164. END loadStrAdr;
  165. PROCEDURE load(VAR x: Item);
  166. VAR s: INTEGER;
  167. BEGIN s := x.typ^.size;
  168. CASE x.mode OF
  169. conMd: CASE x.typ^.form OF
  170. Undef, Range, Array, Record, ProcTyp: |
  171. Bool, Char, Card, Int, Enum, Set, Pointer, Opaque:
  172. PutLit(x.val.C); x.mode := cldMd |
  173. Double, Real: PutOp(23B,2); PutWord(x.val.D0); PutWord(x.val.D1) |
  174. String: loadStrAdr(x.val.D0)
  175. END |
  176. typMd: err(101) |
  177. varMd: IF x.var^.param = {1} THEN (*var par*)
  178. PutLd(x.var, 1);
  179. IF s = 1 THEN PutOpZ(140B) (*LSW0*)
  180. ELSIF s = 2 THEN PutOpU(202B) (*LSD0*)
  181. END
  182. ELSE PutLd(x.var, s)
  183. END |
  184. fldMd: IF x.off <= 255 THEN
  185. IF s = 1 THEN PutOpArg1(140B, x.off,0) (*LSW0*)
  186. ELSIF s = 2 THEN PutOpU(201B); PutByte(x.off)
  187. ELSE PutOpZ(26B); PutByte(x.off) (*LSA*)
  188. END
  189. ELSE PutOpU(22B); PutWord(x.off); PutOpD(270B); (*LIW UADD*)
  190. IF s = 1 THEN PutOpZ(140B) (*LSW0*)
  191. ELSIF s = 2 THEN PutOpU(202B) (*LSD0*)
  192. END
  193. END |
  194. procMd, codMd: err(102) |
  195. expMd, cldMd: |
  196. adrMd: IF s = 1 THEN PutOpZ(140B) (*LSW0*)
  197. ELSIF s = 2 THEN PutOpU(202B) (*LSD0*)
  198. END |
  199. inxMd: IF s = 1 THEN
  200. IF x.typ = chartyp THEN PutOpD(205B) (*LXB*)
  201. ELSE PutOpD(206B) (*LXW*)
  202. END
  203. ELSIF s = 2 THEN PutOpZ(207B) (*LXD*)
  204. ELSE PutOpD(270B) (*UADD*)
  205. END
  206. END ;
  207. IF x.mode # cldMd THEN x.mode := expMd END
  208. END load;
  209. PROCEDURE loadAdr(VAR x: Item);
  210. BEGIN
  211. CASE x.mode OF
  212. conMd: err(103) |
  213. typMd: err(104) |
  214. varMd: IF (x.typ^.size > 2) OR (x.var^.param = {1}) OR
  215. (x.typ^.form = Array) & x.typ^.dyn THEN PutLd(x.var, 1)
  216. ELSE
  217. IF x.var^.vmod = 0 THEN
  218. IF x.var^.vlev = 0 THEN PutOpU(25B) (*LGA*)
  219. ELSIF x.var^.vlev = curLev THEN PutOpU(24B) (*LLA*)
  220. ELSE
  221. IF x.var^.vlev + 1 = curLev THEN PutOpU(351B) (*GB1*)
  222. ELSE PutOpU(350B); PutByte(curLev - x.var^.vlev)
  223. END ;
  224. PutOpZ(26B) (*LSA*)
  225. END
  226. ELSE PutOpU(27B); reloc; PutByte(x.var^.vmod) (*LEA*)
  227. END ;
  228. PutByte(x.var^.vadr)
  229. END |
  230. fldMd: IF x.off <= 255 THEN
  231. PutOpZ(26B); PutByte(x.off) (*LSA*)
  232. ELSE PutOpU(22B); PutWord(x.off); PutOpD(270B) (*LIW UADD*)
  233. END |
  234. procMd, codMd: err(105) |
  235. expMd, cldMd: err(106) |
  236. adrMd: |
  237. inxMd: IF x.typ^.size = 2 THEN
  238. PutLit(1); PutOpD(276B) (*SHL*)
  239. END ;
  240. PutOpD(270B); (*UADD*)
  241. IF x.typ = chartyp THEN err(212) END
  242. END ;
  243. x.mode := adrMd
  244. END loadAdr;
  245. PROCEDURE load2(VAR x, y: Item);
  246. BEGIN
  247. IF x.mode = conMd THEN load(y); load(x) ELSE load(x); load(y) END
  248. END load2;
  249. PROCEDURE loadLim(v: ObjPtr); (*index limit for dynamic arrays*)
  250. VAR L: CARDINAL; a: INTEGER;
  251. BEGIN a := v^.vadr + 1; L := v^.vlev;
  252. IF L = curLev THEN PutOpArg(40B,a,1) (*LLW*)
  253. ELSE
  254. IF L+1 = curLev THEN PutOpU(351B) (*GB1*)
  255. ELSE PutOpU(350B); PutByte(curLev-L)
  256. END ;
  257. PutOpArg1(140B,a,0) (*LSW*)
  258. END
  259. END loadLim;
  260. PROCEDURE SRTest(VAR x: Item);
  261. BEGIN
  262. IF (x.typ # NIL) & (x.typ^.form = Range) THEN x.typ := x.typ^.RBaseTyp END
  263. END SRTest;
  264. PROCEDURE GenItem(VAR x: Item; y, scope: ObjPtr);
  265. BEGIN
  266. IF y # NIL THEN
  267. x.typ := y^.typ;
  268. CASE y^.class OF
  269. Const: x.mode := conMd; x.val := y^.conval;
  270. IF (x.typ = stringtyp) & (x.val.D0 = 177777B) THEN
  271. AllocString(x.val.D2, x.val.D0, x.val.D1);
  272. (*imported string*) y^.conval.D0 := x.val.D0
  273. END |
  274. Typ: x.mode := typMd |
  275. Var: x.mode := varMd; x.var := y |
  276. Field: IF curLev = 0 THEN PutOpArg(100B, scope^.withadr, 1) (*LGW*)
  277. ELSE PutOpArg(40B, scope^.withadr, 1) (*LLW*)
  278. END ;
  279. x.mode := fldMd; x.off := y^.offset |
  280. Proc: x.mode := procMd; x.proc := y; x.typ := undftyp |
  281. Code: x.mode := codMd; x.cod := y; x.typ := undftyp |
  282. Module: x.mode := varMd; err(107) |
  283. Temp:
  284. END
  285. ELSE err(50); x.typ := undftyp; x.mode := expMd
  286. END
  287. END GenItem;
  288. PROCEDURE clog(x: CARDINAL): CARDINAL;
  289. BEGIN exp := 0;
  290. IF x > 0 THEN
  291. WHILE NOT ODD(x) DO
  292. x := x DIV 2; exp := exp + 1
  293. END
  294. END ;
  295. RETURN x
  296. END clog;
  297. PROCEDURE GenIndex(VAR x, y: Item);
  298. VAR i,m,n,sz: INTEGER; inxtyp, eltyp: StrPtr;
  299. BEGIN SRTest(y); (*x.mode = adrMd*)
  300. IF x.typ^.form = Array THEN
  301. eltyp := x.typ^.ElemTyp;
  302. IF x.typ^.dyn THEN load(y);
  303. IF y.typ = inttyp THEN PutOpZ(307B) (*CHKS*)
  304. ELSIF y.typ # cardtyp THEN err(109)
  305. END ;
  306. IF rngchk THEN loadLim(x.var); PutOpD(306B) END ; (*CHKZ*)
  307. IF eltyp^.size > 2 THEN
  308. IF clog(eltyp^.size) = 1 THEN
  309. PutLit(exp); PutOpD(276B) (*SHL*)
  310. ELSE PutLit(eltyp^.size); PutOpD(272B) (*UMUL*)
  311. END
  312. END ;
  313. x.mode := inxMd
  314. ELSE
  315. WITH x.typ^.IndexTyp^ DO
  316. inxtyp := RBaseTyp; m := min; n := max
  317. END ;
  318. IF y.mode = conMd THEN
  319. i := y.val.I;
  320. IF inxtyp # y.typ THEN
  321. IF (i < 0) OR (inxtyp = cardtyp) & (y.typ # inttyp) OR
  322. (inxtyp = inttyp) & (y.typ # cardtyp) THEN err(109)
  323. END
  324. END ;
  325. IF (m <= i) & (i <= n) THEN i := i - m
  326. ELSE err(108); i := m
  327. END ;
  328. sz := eltyp^.size * i;
  329. IF (sz < 400B) & (eltyp^.form # Char) THEN
  330. x.mode := fldMd; x.off := sz
  331. ELSE PutLit(sz); x.mode := inxMd
  332. END
  333. ELSE load(y);
  334. IF inxtyp # y.typ THEN
  335. IF (inxtyp = cardtyp) & (y.typ = inttyp) OR
  336. (inxtyp = inttyp) & (y.typ = cardtyp) THEN PutOpZ(307B)
  337. ELSE err(109)
  338. END
  339. END ;
  340. IF m # 0 THEN
  341. PutLit(CARDINAL(m)); PutOpD(331B) (*ISUB*)
  342. END ;
  343. IF rngchk THEN PutLit(n-m); PutOpD(306B) END ; (*CHKZ*)
  344. IF eltyp^.size > 2 THEN
  345. IF clog(eltyp^.size) = 1 THEN
  346. PutLit(exp); PutOpD(276B) (*SHL*)
  347. ELSE PutLit(eltyp^.size); PutOpD(272B) (*UMUL*)
  348. END
  349. END ;
  350. x.mode := inxMd
  351. END
  352. END ;
  353. x.typ := eltyp
  354. ELSE err(109)
  355. END
  356. END GenIndex;
  357. PROCEDURE GenField(VAR x: Item; f: ObjPtr);
  358. BEGIN (*x.typ^.form = Record*)
  359. IF (f # NIL) & (f^.class = Field) THEN
  360. IF x.mode = fldMd THEN x.off := x.off + f^.offset
  361. ELSE loadAdr(x); x.off := f^.offset
  362. END ;
  363. x.typ := f^.typ
  364. ELSIF (f # NIL) & (f^.class = Const) THEN
  365. x.mode := conMd; x.typ := f^.typ; x.val := f^.conval
  366. ELSE err(110); x.typ := undftyp; x.mode := fldMd; x.off := 0
  367. END ;
  368. x.mode := fldMd
  369. END GenField;
  370. PROCEDURE GenWith(VAR x: Item; adr: INTEGER);
  371. BEGIN (* WITH clause *) loadAdr(x);
  372. IF curLev = 0 THEN PutOpArg(120B, adr, -1) (*SGW*)
  373. ELSE PutOpArg(60B, adr, -1) (*SLW*)
  374. END
  375. END GenWith;
  376. PROCEDURE GenDeRef(VAR x: Item);
  377. BEGIN
  378. IF x.typ^.form = Pointer THEN
  379. load(x); x.typ := x.typ^.PBaseTyp
  380. ELSIF x.typ = addrtyp THEN load(x); x.typ := wordtyp
  381. ELSE err(111)
  382. END ;
  383. x.mode := adrMd
  384. END GenDeRef;
  385. PROCEDURE GenNeg(VAR x: Item);
  386. VAR f: StrForm;
  387. BEGIN SRTest(x); f := x.typ^.form;
  388. IF x.mode = conMd THEN
  389. IF (f = Int) OR (f = Card) & (x.val.C <= MaxInt) THEN
  390. IF x.val.I >= MinInt THEN
  391. x.val.I := -(INTEGER(x.val.C)); x.typ := inttyp
  392. ELSE err(201)
  393. END
  394. ELSIF f = Real THEN x.val.R := - x.val.R
  395. ELSE err(112)
  396. END
  397. ELSE load(x);
  398. IF f = Int THEN PutOpZ(317B) (*NEG*)
  399. ELSIF f = Card THEN PutOpZ(307B); PutOpZ(317B)
  400. ELSIF f = Real THEN PutOpZ(236B) (*FNEG*)
  401. ELSE err(112)
  402. END
  403. END
  404. END GenNeg;
  405. PROCEDURE GenNot(VAR x: Item);
  406. BEGIN
  407. IF x.typ^.form = Bool THEN
  408. IF x.mode = conMd THEN x.val.B := NOT x.val.B
  409. ELSE load(x); PutOpZ(327B) (*NOT*)
  410. END
  411. ELSE err(113)
  412. END
  413. END GenNot;
  414. PROCEDURE GenAnd(VAR x: Item);
  415. BEGIN
  416. IF x.typ^.form = Bool THEN
  417. load(x); PutOpD(37B); x.val.C := pc; PutByte(0) (*ANDJP*)
  418. ELSE err(122)
  419. END ;
  420. x.mode := expMd
  421. END GenAnd;
  422. PROCEDURE GenOr(VAR x: Item);
  423. BEGIN
  424. IF x.typ^.form = Bool THEN
  425. load(x); PutOpD(36B); x.val.C := pc; PutByte(0) (*ORJP*)
  426. ELSE err(125)
  427. END ;
  428. x.mode := expMd
  429. END GenOr;
  430. PROCEDURE GenIn(VAR x, y: Item);
  431. VAR f: StrForm;
  432. BEGIN SRTest(x); f := x.typ^.form;
  433. IF ((Bool <= f) & (f <= Int) OR (f = Enum)) & (y.typ^.form = Set) THEN
  434. y.typ := y.typ^.SBaseTyp;
  435. IF y.typ^.form = Range THEN y.typ := y.typ^.RBaseTyp END ;
  436. IF (x.typ = y.typ) OR (x.typ = inttyp) & (y.typ = cardtyp) THEN
  437. IF (x.mode = conMd) & (y.mode = conMd) THEN
  438. IF x.val.C < WordSize THEN x.val.B := x.val.C IN y.val.S
  439. ELSE x.val.B := FALSE; err(202)
  440. END
  441. ELSE load2(x, y); PutOpD(324B) (*IN*)
  442. END
  443. ELSE err(114); x.mode := expMd
  444. END
  445. ELSE err(115); x.mode := expMd
  446. END ;
  447. x.typ := booltyp
  448. END GenIn;
  449. PROCEDURE GenSet(VAR x, e1, e2: Item);
  450. VAR s: StrPtr; n: CARDINAL;
  451. BEGIN x.mode := expMd; SRTest(e1); SRTest(e2);
  452. (*x.typ^.form = Set*) s := x.typ^.SBaseTyp;
  453. IF s^.form = Range THEN s := s^.RBaseTyp END ;
  454. IF (e1.typ = s) & (e2.typ = s) THEN
  455. IF (e1.mode = conMd) & (e2.mode = conMd) THEN
  456. x.mode := conMd;
  457. IF (e2.val.C < WordSize) & (e1.val.C <= e2.val.C + 1) THEN
  458. n := e2.val.C + 1 - e1.val.C;
  459. IF n < 16 THEN x.val.S := ROR(MSK(n), e1.val.C)
  460. ELSE x.val.S := {0..15}
  461. END
  462. ELSE err(202)
  463. END
  464. ELSE err(214)
  465. END ;
  466. ELSE err(116)
  467. END
  468. END GenSet;
  469. PROCEDURE GenSingSet(VAR x, e: Item);
  470. VAR s: StrPtr;
  471. BEGIN x.mode := expMd; SRTest(e);
  472. (*x.typ^.form = Set*) s := x.typ^.SBaseTyp;
  473. IF s^.form = Range THEN s := s^.RBaseTyp END ;
  474. IF e.typ = s THEN
  475. IF e.mode = conMd THEN x.mode := conMd;
  476. IF e.val.C < WordSize THEN x.val.S := ROR({0}, e.val.C)
  477. ELSE err(202)
  478. END
  479. ELSE load(e); PutOpZ(335B) (*BIT*)
  480. END
  481. ELSE err(116)
  482. END
  483. END GenSingSet;
  484. PROCEDURE GenOp(op: CARDINAL; VAR x, y: Item);
  485. VAR f,g: StrForm;
  486. BEGIN SRTest(x); SRTest(y); f := x.typ^.form;
  487. IF x.typ # y.typ THEN g := y.typ^.form;
  488. IF (f = Int) & (g = Card) & (y.mode = conMd)
  489. & (y.val.C <= MaxInt) THEN y.typ := x.typ
  490. ELSIF (f = Card) & (g = Int) & ((x.mode = conMd) OR (x.mode = cldMd))
  491. & (x.val.C <= MaxInt) THEN x.typ := y.typ; f := Int
  492. ELSIF (x.typ = addrtyp) & (g = Pointer) THEN f := Pointer
  493. ELSIF ((f # Pointer) OR (y.typ # addrtyp)) &
  494. ((f # Card) OR (g # Card)) THEN err(117)
  495. END
  496. END ;
  497. IF (x.mode = conMd) & (y.mode = conMd) THEN
  498. CASE op OF
  499. 1: IF f = Card THEN
  500. IF (x.val.C = 0) OR (y.val.C <= MaxCard DIV x.val.C) THEN
  501. x.val.C := x.val.C * y.val.C
  502. ELSE err(203)
  503. END
  504. ELSIF f = Int THEN
  505. IF (x.val.I = 0) OR (ABS(y.val.I) <= MaxInt DIV ABS(x.val.I)) THEN
  506. x.val.I := x.val.I * y.val.I
  507. ELSE err(203)
  508. END
  509. ELSIF f = Real THEN
  510. IF (ABS(x.val.R) <= 1.0) OR
  511. (ABS(y.val.R) <= MAX(REAL)/ABS(x.val.R)) THEN
  512. x.val.R := x.val.R * y.val.R
  513. ELSE err(203)
  514. END
  515. ELSIF f = Set THEN x.val.S := x.val.S * y.val.S
  516. ELSE err(118)
  517. END |
  518. 2,3: IF f = Card THEN
  519. IF y.val.C > 0 THEN x.val.C := x.val.C DIV y.val.C
  520. ELSE err(205)
  521. END
  522. ELSIF f = Int THEN
  523. IF y.val.I # 0 THEN x.val.I := x.val.I DIV y.val.I
  524. ELSE err(205)
  525. END
  526. ELSIF (f = Real) & (op = 2) THEN
  527. IF (y.val.R >= 1.0) OR
  528. (ABS(x.val.R) <= ABS(y.val.R) * MAX(REAL)) THEN
  529. x.val.R := x.val.R / y.val.R
  530. ELSE err(204)
  531. END
  532. ELSIF (f = Set) & (op = 2) THEN x.val.S := x.val.S / y.val.S
  533. ELSE err(120)
  534. END |
  535. 4: IF f = Card THEN
  536. IF y.val.C > 0 THEN x.val.C := x.val.C MOD y.val.C
  537. ELSE err(205)
  538. END
  539. ELSIF f = Int THEN
  540. IF (x.val.I >= 0) & (y.val.I > 0) THEN
  541. x.val.I := x.val.I MOD y.val.I
  542. ELSE err(205)
  543. END
  544. ELSE err(121)
  545. END |
  546. 5: IF f = Bool THEN x.val.B := x.val.B & y.val.B
  547. ELSE err(122)
  548. END |
  549. 6: IF f = Card THEN
  550. IF y.val.C <= MaxCard - x.val.C THEN
  551. x.val.C := x.val.C + y.val.C
  552. ELSE err(206)
  553. END
  554. ELSIF f = Int THEN
  555. IF (x.val.I >= 0) & (y.val.I <= MaxInt - x.val.I) OR
  556. (x.val.I < 0) & (y.val.I >= MinInt - x.val.I) THEN
  557. x.val.I := x.val.I + y.val.I
  558. ELSE err(206)
  559. END
  560. ELSIF f = Real THEN
  561. IF (x.val.R >= 0.0) & (y.val.R <= MAX(REAL) - x.val.R) OR
  562. (x.val.R < 0.0) & (y.val.R >= MIN(REAL) - x.val.R) THEN
  563. x.val.R := x.val.R + y.val.R
  564. ELSE err(206)
  565. END
  566. ELSIF f = Set THEN x.val.S := x.val.S + y.val.S
  567. ELSE err(123)
  568. END |
  569. 7: IF f = Card THEN
  570. IF y.val.C <= x.val.C THEN x.val.C := x.val.C - y.val.C
  571. ELSIF y.val.C - x.val.C <= MaxInt THEN
  572. x.val.I := -INTEGER(y.val.C - x.val.C); x.typ := inttyp
  573. ELSE err(207)
  574. END
  575. ELSIF f = Int THEN
  576. IF (x.val.I >= 0) &
  577. ((y.val.I >= 0) OR (x.val.I <= MaxInt + y.val.I)) OR
  578. (x.val.I < 0) &
  579. ((y.val.I < 0) OR (x.val.I >= MinInt + y.val.I)) THEN
  580. x.val.I := x.val.I - y.val.I
  581. ELSE err(207)
  582. END
  583. ELSIF f = Real THEN
  584. IF (x.val.R >= 0.0) &
  585. ((y.val.R >= 0.0) OR (x.val.R <= MAX(REAL) + y.val.R)) THEN
  586. x.val.R := x.val.R - y.val.R
  587. ELSIF (x.val.R < 0.0) &
  588. ((y.val.R < 0.0) OR (x.val.R >= MIN(REAL) + y.val.R)) THEN
  589. x.val.R := x.val.R - y.val.R
  590. ELSE err(207)
  591. END
  592. ELSIF f = Set THEN x.val.S := x.val.S - y.val.S
  593. ELSE err(124)
  594. END |
  595. 8: IF f = Bool THEN x.val.B := x.val.B OR y.val.B
  596. ELSE err(125)
  597. END |
  598. 9: IF f = Card THEN x.val.B := x.val.C = y.val.C
  599. ELSIF f = Int THEN x.val.B := x.val.I = y.val.I
  600. ELSIF f = Real THEN x.val.B := x.val.R = y.val.R
  601. ELSIF f = Bool THEN x.val.B := x.val.B = y.val.B
  602. ELSIF f = Set THEN x.val.B := x.val.S = y.val.S
  603. ELSIF f = Char THEN x.val.B := x.val.Ch = y.val.Ch
  604. ELSE err(126)
  605. END ;
  606. x.typ := booltyp |
  607. 10: IF f = Card THEN x.val.B := x.val.C # y.val.C
  608. ELSIF f = Int THEN x.val.B := x.val.I # y.val.I
  609. ELSIF f = Real THEN x.val.B := x.val.R # y.val.R
  610. ELSIF f = Bool THEN x.val.B := x.val.B # y.val.B
  611. ELSIF f = Set THEN x.val.B := x.val.S # y.val.S
  612. ELSIF f = Char THEN x.val.B := x.val.Ch # y.val.Ch
  613. ELSE err(126)
  614. END ;
  615. x.typ := booltyp |
  616. 11: IF f = Card THEN x.val.B := x.val.C < y.val.C
  617. ELSIF f = Int THEN x.val.B := x.val.I < y.val.I
  618. ELSIF f = Real THEN x.val.B := x.val.R < y.val.R
  619. ELSIF f = Bool THEN x.val.B := x.val.B < y.val.B
  620. ELSIF f = Char THEN x.val.B := x.val.Ch < y.val.Ch
  621. ELSE err(126)
  622. END ;
  623. x.typ := booltyp |
  624. 12: IF f = Card THEN x.val.B := x.val.C <= y.val.C
  625. ELSIF f = Int THEN x.val.B := x.val.I <= y.val.I
  626. ELSIF f = Real THEN x.val.B := x.val.R <= y.val.R
  627. ELSIF f = Bool THEN x.val.B := x.val.B <= y.val.B
  628. ELSIF f = Set THEN x.val.B := x.val.S <= y.val.S
  629. ELSIF f = Char THEN x.val.B := x.val.Ch <= y.val.Ch
  630. ELSE err(126)
  631. END ;
  632. x.typ := booltyp |
  633. 13: IF f = Card THEN x.val.B := x.val.C > y.val.C
  634. ELSIF f = Int THEN x.val.B := x.val.I > y.val.I
  635. ELSIF f = Real THEN x.val.B := x.val.R > y.val.R
  636. ELSIF f = Bool THEN x.val.B := x.val.B > y.val.B
  637. ELSIF f = Char THEN x.val.B := x.val.Ch > y.val.Ch
  638. ELSE err(126)
  639. END ;
  640. x.typ := booltyp |
  641. 14: IF f = Card THEN x.val.B := x.val.C >= y.val.C
  642. ELSIF f = Int THEN x.val.B := x.val.I >= y.val.I
  643. ELSIF f = Real THEN x.val.B := x.val.R >= y.val.R
  644. ELSIF f = Bool THEN x.val.B := x.val.B >= y.val.B
  645. ELSIF f = Set THEN x.val.B := y.val.S >= x.val.S
  646. ELSIF f = Char THEN x.val.B := x.val.Ch >= y.val.Ch
  647. ELSE err(126)
  648. END ;
  649. x.typ := booltyp
  650. END
  651. ELSE
  652. CASE op OF
  653. 1: IF f = Card THEN
  654. IF (x.mode = conMd) & (clog(x.val.C) = 1) THEN
  655. load(y); PutLit(exp); PutOpD(276B); x.mode := expMd
  656. ELSIF (y.mode = conMd) & (clog(y.val.C) = 1) THEN
  657. load(x); PutLit(exp); PutOpD(276B) (*SHL*)
  658. ELSE load2(x, y); PutOpD(272B) (*UMUL*)
  659. END
  660. ELSIF f = Int THEN
  661. IF (x.mode = conMd) & (clog(x.val.C) = 1) THEN
  662. load(y); PutLit(exp); PutOpD(276B); x.mode := expMd
  663. ELSIF (y.mode = conMd) & (clog(y.val.C) = 1) THEN
  664. load(x); PutLit(exp); PutOpD(276B) (*SHL*)
  665. ELSE load2(x, y); PutOpD(332B) (*IMUL*)
  666. END
  667. ELSE load2(x, y);
  668. IF f = Double THEN err(216)
  669. ELSIF f = Real THEN PutOp(232B,-2) (*FMUL*)
  670. ELSIF f = Set THEN PutOpD(322B) (*AND*)
  671. ELSIF f # Undef THEN err(118)
  672. END
  673. END |
  674. 2: load(y);
  675. IF f = Card THEN PutOpD(273B) (*UDIV*)
  676. ELSIF f = Int THEN PutOpD(333B) (*IDIV*)
  677. ELSIF f = Real THEN PutOp(233B,-2) (*FDIV*)
  678. ELSIF f = Set THEN PutOpD(321B) (*XOR*)
  679. ELSIF f # Undef THEN err(119)
  680. END |
  681. 3: IF f = Card THEN (*DIV*)
  682. IF (y.mode = conMd) & (clog(y.val.C) = 1) THEN
  683. PutLit(exp); PutOpD(277B) (*SHR*)
  684. ELSE load(y); PutOpD(273B) (*UDIV*)
  685. END
  686. ELSE load(y);
  687. IF f = Int THEN PutOpD(333B) (*IDIV*)
  688. ELSIF f = Double THEN err(216)
  689. ELSIF f # Undef THEN err(120)
  690. END
  691. END |
  692. 4: IF f = Card THEN
  693. IF (y.mode = conMd) & (clog(y.val.C) = 1) THEN
  694. PutLit(CARDINAL(COM(MSK(WordSize-exp))));
  695. PutOpD(322B) (*AND*)
  696. ELSE load(y); PutOpD(274B) (*UMOD*)
  697. END
  698. ELSE load(y);
  699. IF f = Int THEN PutOpZ(307B); PutOpD(274B)
  700. ELSIF f # Undef THEN err(121)
  701. END
  702. END |
  703. 5: load(y);
  704. IF f = Bool THEN fixupByte(x.val.C)
  705. ELSIF f # Undef THEN err(122)
  706. END |
  707. 6: load2(x, y);
  708. IF f = Card THEN PutOpD(270B) (*UADD*)
  709. ELSIF f = Int THEN PutOpD(330B) (*IADD*)
  710. ELSIF f = Real THEN PutOp(230B,-2) (*FADD*)
  711. ELSIF f = Set THEN PutOpD(320B) (*OR*)
  712. ELSIF f = Double THEN PutOp(210B,-2) (*DADD*)
  713. ELSIF f # Undef THEN err(123)
  714. END |
  715. 7: load(y);
  716. IF f = Card THEN PutOpD(271B) (*USUB*)
  717. ELSIF f = Int THEN PutOpD(331B) (*ISUB*)
  718. ELSIF f = Real THEN PutOp(231B,-2) (*FSUB*)
  719. ELSIF f = Set THEN PutOpZ(323B); PutOpD(322B) (*COM AND*)
  720. ELSIF f = Double THEN PutOp(211B,-2) (*DSUB*)
  721. ELSIF f # Undef THEN err(124)
  722. END |
  723. 8: load(y);
  724. IF f = Bool THEN fixupByte(x.val.C)
  725. ELSIF f # Undef THEN err(125)
  726. END |
  727. 9: load(y); x.typ := booltyp;
  728. IF (f <= Int) OR (f = Enum) OR (f = Pointer) OR
  729. (f = Set) OR (f = Opaque) THEN PutOpD(310B) (*EQL*)
  730. ELSIF (f = Real) OR (f = Double) THEN PutOp(234B,-3); PutOpZ(310B)
  731. ELSE err(126)
  732. END |
  733. 10: load(y); x.typ := booltyp;
  734. IF (f <= Int) OR (f = Enum) OR (f = Pointer) OR
  735. (f = Set) OR (f = Opaque) THEN PutOpD(311B) (*NEQ*)
  736. ELSIF (f = Real) OR (f = Double) THEN PutOp(234B,-3); PutOpZ(311B)
  737. ELSE err(126)
  738. END |
  739. 11: load(y); x.typ := booltyp;
  740. IF (f <= Card) OR (f = Enum) THEN PutOpD(252B) (*ULSS*)
  741. ELSIF f = Int THEN PutOpD(312B) (*ILSS*)
  742. ELSIF (f = Real) OR (f = Double) THEN PutOp(234B,-3); PutOpZ(312B)
  743. ELSE err(126)
  744. END |
  745. 12: load(y); x.typ := booltyp;
  746. IF (f <= Card) OR (f = Enum) THEN PutOpD(253B) (*ULEQ*)
  747. ELSIF f = Int THEN PutOpD(313B) (*ILEQ*)
  748. ELSIF (f = Real) OR (f = Double) THEN PutOp(234B,-3); PutOpZ(313B)
  749. ELSIF f = Set THEN (*COM AND LI0 EQL*)
  750. PutOpZ(323B); PutOpZ(322B); PutOpZ(0); PutOpD(310B)
  751. ELSE err(126)
  752. END |
  753. 13: load(y); x.typ := booltyp;
  754. IF (f <= Card) OR (f = Enum) THEN PutOpD(254B) (*UGTR*)
  755. ELSIF f = Int THEN PutOpD(314B) (*IGTR*)
  756. ELSIF (f = Real) OR (f = Double) THEN PutOp(234B,-3); PutOpZ(314B)
  757. ELSE err(126)
  758. END |
  759. 14: load(y); x.typ := booltyp;
  760. IF (f <= Card) OR (f = Enum) THEN PutOpD(255B) (*UGEQ*)
  761. ELSIF f = Int THEN PutOpD(315B) (*IGEQ*)
  762. ELSIF (f = Real) OR (f = Double) THEN PutOp(234B,-3); PutOpZ(315B)
  763. ELSIF f = Set THEN (*COM OR LIN EQL*)
  764. PutOpZ(323B); PutOpZ(320B); PutOpZ(325B); PutOpD(310B)
  765. ELSE err(126)
  766. END
  767. END
  768. END
  769. END GenOp;
  770. PROCEDURE CheckAssComp(xt: StrPtr; VAR y: Item;
  771. param: BOOLEAN; VAR sz: INTEGER);
  772. VAR f,g: StrForm; xp, yp: ParPtr; vsz: INTEGER;
  773. BEGIN sz := xt^.size;
  774. IF (y.mode = procMd) & (xt^.form = ProcTyp) THEN
  775. (*procedure to proc. variable; check compatibility*)
  776. IF y.proc^.pd^.lev > 0 THEN err(127)
  777. ELSIF xt^.resTyp # y.proc^.typ THEN err(128)
  778. ELSE xp := xt^.firstPar; yp := y.proc^.firstParam;
  779. WHILE xp # NIL DO
  780. IF yp # NIL THEN
  781. IF (xp^.varpar # yp^.varpar) OR ((xp^.typ # yp^.typ) &
  782. ((xp^.typ^.form # Array) OR NOT xp^.typ^.dyn OR
  783. (yp^.typ^.form # Array) OR NOT yp^.typ^.dyn OR
  784. (xp^.typ^.ElemTyp # yp^.typ^.ElemTyp))) THEN err(129)
  785. END ;
  786. yp := yp^.next
  787. ELSE err(130)
  788. END ;
  789. xp := xp^.next
  790. END ;
  791. IF yp # NIL THEN err(131) END ;
  792. (*generate procedure descriptor*)
  793. PutOpU(22B) (*LIW*); reloc; PutByte(y.proc^.pmod); PutByte(y.proc^.pd^.num)
  794. END
  795. ELSE SRTest(y);
  796. IF xt^.form = Range THEN xt := xt^.RBaseTyp END ;
  797. IF y.typ = NIL THEN err(117)
  798. ELSIF (xt = y.typ) & ~((xt^.form = Array) & xt^.dyn) THEN load(y)
  799. ELSE
  800. f := xt^.form; g := y.typ^.form;
  801. IF (f = Card) & (g = Int) THEN
  802. IF y.mode = conMd THEN load(y);
  803. IF y.val.I < 0 THEN err(132) END
  804. ELSE load(y);
  805. IF rngchk THEN PutOpZ(307B) END (*CHKS*)
  806. END
  807. ELSIF (f = Int) & (g = Card) THEN
  808. IF y.mode = conMd THEN load(y);
  809. IF y.val.C > MaxInt THEN err(208) END
  810. ELSE load(y);
  811. IF rngchk THEN PutOpZ(307B) END (*CHKS*)
  812. END
  813. ELSIF (f = Pointer) & (y.typ = addrtyp)
  814. OR (g = Pointer) & (xt = addrtyp) THEN load(y)
  815. ELSIF f = Array THEN
  816. IF xt^.dyn THEN (*dynamic array parameter*)
  817. IF ~param THEN err(143)
  818. ELSIF (g = Array) & (xt^.ElemTyp = y.typ^.ElemTyp) THEN
  819. IF y.typ^.dyn THEN PutLd(y.var, 2)
  820. ELSE loadAdr(y); PutLit(y.typ^.IndexTyp^.max - y.typ^.IndexTyp^.min)
  821. END
  822. ELSIF xt^.ElemTyp = chartyp THEN
  823. IF g = String THEN
  824. load(y); PutLit(y.val.D1 - 1)
  825. ELSIF (g = Char) & (y.mode = conMd) THEN
  826. loadStrAdr(strx DIV 2); StrTab[strx] := y.val.Ch;
  827. StrTab[strx+1] := 0C; strx := strx+2; PutLit(0)
  828. ELSE err(133)
  829. END
  830. ELSIF xt^.ElemTyp = wordtyp THEN
  831. loadAdr(y); PutLit(y.typ^.size-1)
  832. ELSE err(133)
  833. END
  834. ELSIF xt^.ElemTyp = chartyp THEN
  835. IF g = String THEN (*string to array variable*)
  836. load(y); sz := y.val.D1; (*check length of string*)
  837. vsz := xt^.IndexTyp^.max - xt^.IndexTyp^.min + 1;
  838. IF sz < vsz THEN sz := sz+1 (*include 0C terminator*)
  839. ELSIF sz > vsz THEN err(146)
  840. END ;
  841. sz := (sz+1) DIV 2;
  842. IF param THEN
  843. IF vsz <= 2 THEN PutOpZ(140B) (*LSW0*)
  844. ELSIF vsz <= 4 THEN PutOpU(202B) (*LSD0*)
  845. END
  846. ELSIF sz = 1 THEN PutOpZ(140B) (*LSW0*)
  847. ELSIF sz = 2 THEN PutOpU(202B) (*LSD0*)
  848. END
  849. ELSIF g = Char THEN err(200)
  850. ELSE err(133)
  851. END
  852. ELSE err(133)
  853. END
  854. ELSIF param & (xt = wordtyp) & (y.typ^.size = 1) THEN load(y)
  855. ELSIF (f # Card) OR (g # Card) THEN err(133)
  856. ELSE load(y)
  857. END
  858. END
  859. END ;
  860. END CheckAssComp;
  861. PROCEDURE PrepAss(VAR x: Item);
  862. VAR L: CARDINAL;
  863. BEGIN
  864. IF (x.mode = conMd) OR (x.mode = procMd) THEN err(134) END ;
  865. IF x.typ^.size <= 2 THEN
  866. IF x.mode = varMd THEN
  867. IF x.var^.param = {1} THEN (*var par*)
  868. loadAdr(x); x.mode := adrMd
  869. ELSE L := x.var^.vlev;
  870. IF (L > 0) & (L < curLev) THEN
  871. IF L+1 = curLev THEN PutOpU(351B) (*GB1*)
  872. ELSE PutOpU(350B); PutByte(curLev-L) (*GB *)
  873. END ;
  874. x.mode := fldMd; x.off := x.var^.vadr
  875. END
  876. END
  877. END
  878. ELSE
  879. IF x.mode = varMd THEN
  880. IF x.var^.param = {1} THEN PutLd(x.var, 1) ELSE loadAdr(x) END
  881. ELSIF x.mode = inxMd THEN PutOpD(270B) (*UADD*)
  882. ELSIF x.mode = fldMd THEN PutOpZ(26B) (*LSA*); PutByte(x.off)
  883. END ;
  884. x.mode := adrMd
  885. END
  886. END PrepAss;
  887. PROCEDURE GenAssign(VAR x, y: Item);
  888. VAR s: INTEGER;
  889. BEGIN CheckAssComp(x.typ, y, FALSE, s);
  890. IF rngchk & (x.typ^.form = Range) THEN
  891. WITH x.typ^ DO
  892. IF min = 0 THEN PutLit(max); PutOpD(306B) (*CHKZ*)
  893. ELSE PutLit(CARDINAL(min)); PutLit(CARDINAL(max));
  894. IF min < 0 THEN PutOp(305B, -2) (*CHK*)
  895. ELSE PutOp(245B, -2) (*UCHK*)
  896. END
  897. END
  898. END
  899. END ;
  900. IF x.mode = varMd THEN
  901. PutSto(x.var, s)
  902. ELSIF x.mode = fldMd THEN
  903. IF s = 1 THEN PutOpArg1(160B, x.off, -2) (*SSW*)
  904. ELSIF s = 2 THEN PutOp(221B,-3); PutByte(x.off) (*SSD*)
  905. ELSE PutLit(s); PutOp(340B,-3) (*MOV*)
  906. END
  907. ELSIF x.mode = inxMd THEN
  908. IF s = 1 THEN (*SXB SXW*)
  909. IF x.typ = chartyp THEN PutOp(225B,-3) ELSE PutOp(226B,-3) END
  910. ELSIF s = 2 THEN PutOp(227B,-4) (*SXD*)
  911. ELSE PutLit(s); PutOp(340B,-3) (*MOV*)
  912. END
  913. ELSIF x.mode = adrMd THEN
  914. IF s = 1 THEN PutOp(160B,-2) (*SSW0*)
  915. ELSIF s = 2 THEN PutOp(222B,-3) (*SSD0*)
  916. ELSE PutLit(s); PutOp(340B,-3) (*MOV*)
  917. END
  918. ELSE err(134)
  919. END
  920. END GenAssign;
  921. PROCEDURE GenFJ(VAR loc: CARDINAL);
  922. BEGIN PutOpZ(31B); loc := pc; PutWord(0) (*JP*)
  923. END GenFJ;
  924. PROCEDURE GenCFJ(VAR x: Item; VAR loc: CARDINAL);
  925. BEGIN
  926. IF x.typ^.form = Bool THEN load(x) ELSE err(135) END ;
  927. PutOpD(30B); loc := pc; PutWord(0) (*JPC*)
  928. END GenCFJ;
  929. PROCEDURE GenBJ(loc: CARDINAL);
  930. BEGIN
  931. IF pc < loc+377B THEN PutOpZ(35B); PutByte(pc-loc) (*JPB*)
  932. ELSE PutOpZ(31B); PutWord(CARDINAL(-INTEGER(pc-loc)))
  933. END
  934. END GenBJ;
  935. PROCEDURE GenCBJ(VAR x: Item; loc: CARDINAL);
  936. BEGIN
  937. IF x.typ^.form = Bool THEN load(x) ELSE err(135) END ;
  938. IF pc < loc+377B THEN PutOpD(34B); PutByte(pc-loc)
  939. ELSE PutOpD(30B); PutWord(CARDINAL(-INTEGER(pc-loc)))
  940. END
  941. END GenCBJ;
  942. PROCEDURE PrepCall(VAR x: Item; VAR fpar: ParPtr);
  943. BEGIN x.sp := sp;
  944. IF x.mode = procMd THEN
  945. fpar := x.proc^.firstParam;
  946. IF sp > 0 THEN PutOpZ(262B); (*STORE*) sp := 0 END
  947. ELSIF x.mode = codMd THEN fpar := x.cod^.firstArg
  948. ELSIF x.typ^.form = ProcTyp THEN
  949. fpar := x.typ^.firstPar; load(x);
  950. IF sp > 1 THEN PutOpZ(263B); sp := 0 (*STOFV*)
  951. ELSE PutOpD(264B) (*STOT*)
  952. END
  953. ELSE err(136); fpar := NIL; x.typ := undftyp
  954. END
  955. END PrepCall;
  956. PROCEDURE GenParam(VAR ap: Item; fp: ParPtr);
  957. VAR sz: INTEGER; ftyp, inxtyp: StrPtr;
  958. BEGIN ftyp := fp^.typ;
  959. IF fp^.varpar THEN
  960. IF (ftyp^.form = Array) & ftyp^.dyn &
  961. (ap.typ^.form = Array) & (ap.typ^.ElemTyp = ftyp^.ElemTyp) THEN
  962. IF ap.typ^.dyn THEN PutLd(ap.var, 2)
  963. ELSE loadAdr(ap); inxtyp := ap.typ^.IndexTyp;
  964. PutLit(inxtyp^.max - inxtyp^.min)
  965. END
  966. ELSIF (ap.typ = ftyp) OR
  967. (ftyp = wordtyp) & (ap.typ^.size = 1) OR
  968. (ftyp = addrtyp) & (ap.typ^.form = Pointer) THEN loadAdr(ap)
  969. ELSIF (ftyp^.form = Array) & ftyp^.dyn & (ftyp^.ElemTyp = wordtyp) THEN
  970. IF (ap.typ^.form = Array) & ap.typ^.dyn THEN PutLd(ap.var, 2)
  971. ELSE loadAdr(ap); PutLit(ap.typ^.size-1)
  972. END
  973. ELSE err(137)
  974. END
  975. ELSE CheckAssComp(ftyp, ap, TRUE, sz)
  976. END
  977. END GenParam;
  978. PROCEDURE adjustStack(VAR x: Item);
  979. BEGIN (*after procedure call*)
  980. IF (x.typ = NIL) OR (x.typ = notyp) THEN sp := 0
  981. ELSE sp := x.sp;
  982. IF sp > 0 THEN
  983. IF x.typ^.size = 2 THEN PutOp(261B, 2) (*LODFD*)
  984. ELSE PutOpU(260B) (*LODFW*)
  985. END
  986. ELSE sp := x.typ^.size
  987. END
  988. END
  989. END adjustStack;
  990. PROCEDURE GenCall(VAR x: Item);
  991. VAR i, L: CARDINAL; pd: PDPtr;
  992. BEGIN
  993. IF x.mode = procMd THEN
  994. pd := x.proc^.pd; L := pd^.lev;
  995. IF x.proc^.pmod = 0 THEN
  996. IF (L = 0) OR (L = curLev) THEN PutOpArg(360B, pd^.num, 0) (*CL*) ELSE
  997. IF pd^.lev + 1 = curLev THEN PutOpU(351B) (*GB1*)
  998. ELSE PutOpU(350B); PutByte(curLev - pd^.lev)
  999. END ;
  1000. PutOpD(356B); PutByte(pd^.num) (*CI*)
  1001. END
  1002. ELSE PutOpZ(355B); reloc; PutByte(x.proc^.pmod); PutByte(pd^.num) (*CX*)
  1003. END ;
  1004. x.typ := x.proc^.typ; adjustStack(x)
  1005. ELSIF x.mode = codMd THEN
  1006. x.typ := x.cod^.typ; sp := INTEGER(x.typ^.size) + x.sp;
  1007. L := x.cod^.length; i := 0;
  1008. WHILE i < L DO
  1009. PutByte(CARDINAL(x.cod^.cd^.cod[i])); i := i+1
  1010. END
  1011. ELSIF x.mode = expMd THEN
  1012. PutOpZ(357B); PutOpZ(266B); (*CF DECS*)
  1013. x.typ := x.typ^.resTyp; adjustStack(x)
  1014. END ;
  1015. x.mode := expMd
  1016. END GenCall;
  1017. PROCEDURE unstack(par: ParPtr);
  1018. VAR a, s: INTEGER; tp: StrPtr;
  1019. BEGIN (*unstack parameters in reverse order when entering procedure*)
  1020. IF par # NIL THEN
  1021. unstack(par^.next); tp := par^.typ;
  1022. IF par^.varpar THEN
  1023. IF (tp^.form = Array) & tp^.dyn THEN
  1024. PutOpZ(61B); PutByte(par^.name) (*SLD*)
  1025. ELSE PutOpArg(60B, par^.name, 0) (*SLW*)
  1026. END
  1027. ELSE s := tp^.size; a := par^.name;
  1028. IF s = 1 THEN PutOpArg(60B, a, 0)
  1029. ELSIF (tp^.form = Array) & tp^.dyn THEN
  1030. PutOpZ(61B); PutByte(a); PutOpZ(41B); PutByte(a); (*SLD a, LLD a*)
  1031. IF tp^.ElemTyp = chartyp THEN PutOpZ(1); PutOpZ(277B) END ;
  1032. PutOpZ(26B); PutByte(1); (*LSA 1*)
  1033. IF tp^.ElemTyp^.size > 1 THEN
  1034. PutLit(tp^.ElemTyp^.size); PutOpD(272B) (*LIT s, UMUL*)
  1035. END ;
  1036. PutOpZ(267B); PutByte(a) (*PCOP a*)
  1037. ELSIF s = 2 THEN PutOpZ(61B); PutByte(a) (*SLD*)
  1038. ELSE PutLit(s); PutOpD(267B); PutByte(a) (*PCOP a*)
  1039. END
  1040. END
  1041. END
  1042. END unstack;
  1043. PROCEDURE GenEnter(VAR L: CARDINAL; proc: ObjPtr);
  1044. BEGIN
  1045. IF ODD(pc) THEN PutOpZ(336B) (*NOP*) END ;
  1046. ProcTab[proc^.pd^.num] := pc;
  1047. PutOpZ(353B) (*ENTR*); L := pc; PutByte(0);
  1048. IF curPrio > 0 THEN PutOpZ(250B); PutByte(curPrio) END ;
  1049. unstack(proc^.firstParam)
  1050. END GenEnter;
  1051. PROCEDURE GenEnterMod(mod: ObjPtr);
  1052. BEGIN
  1053. IF ODD(pc) THEN PutOpZ(336B) (*NOP*) END ;
  1054. ProcTab[mod^.modno] := pc;
  1055. IF curPrio > 0 THEN PutOpZ(250B); PutByte(curPrio) END
  1056. END GenEnterMod;
  1057. PROCEDURE FixupEnter(L: CARDINAL; size: INTEGER);
  1058. BEGIN code[L] := CHAR(size-4)
  1059. END FixupEnter;
  1060. PROCEDURE GenReturn;
  1061. BEGIN
  1062. IF curPrio > 0 THEN PutOpZ(251B) END ;
  1063. PutOpZ(354B) (*RTN*)
  1064. END GenReturn;
  1065. PROCEDURE GenResult(VAR x: Item; proc: ObjPtr);
  1066. VAR sz: INTEGER;
  1067. BEGIN CheckAssComp(proc^.typ, x, FALSE, sz); sp := 0
  1068. END GenResult;
  1069. PROCEDURE GenCase1(VAR x: Item; VAR L0: CARDINAL);
  1070. VAR f: StrForm;
  1071. BEGIN load(x); L0 := pc+1; f := x.typ^.form;
  1072. IF (f <= Int) OR (f = Enum) OR (f = Range) THEN
  1073. PutOpD(302B); PutWord(0) (*ENTC*)
  1074. ELSE err(140)
  1075. END
  1076. END GenCase1;
  1077. PROCEDURE GenCase2;
  1078. BEGIN PutOpZ(303B) (*EXC*)
  1079. END GenCase2;
  1080. PROCEDURE GenCase3(L0, L1, n: CARDINAL; VAR tab: ARRAY OF LabelRange);
  1081. VAR i: CARDINAL; j, lim: INTEGER;
  1082. BEGIN fixup(L0);
  1083. IF n > 0 THEN
  1084. PutWord(CARDINAL(tab[0].low)); PutWord(CARDINAL(tab[n-1].high))
  1085. ELSE PutWord(1); PutWord(0)
  1086. END ;
  1087. PutWord(177777B-pc+L1+1);
  1088. i := 0; j := tab[0].low;
  1089. WHILE i < n DO
  1090. lim := tab[i].high;
  1091. IF lim - j + INTEGER(pc) < CodeLength THEN
  1092. WHILE j < tab[i].low DO
  1093. PutWord(177777B-pc+L1+1); j := j+1 (*else*)
  1094. END ;
  1095. WHILE j <= lim DO
  1096. PutWord(177777B-pc+ tab[i].label +1); j := j+1
  1097. END
  1098. ELSE err(217)
  1099. END ;
  1100. i := i+1
  1101. END
  1102. END GenCase3;
  1103. PROCEDURE GenFor1(VAR v, e1: Item);
  1104. VAR f: StrForm; s: INTEGER;
  1105. BEGIN SRTest(v); f := v.typ^.form;
  1106. IF (f <= Int) OR (f = Enum) THEN
  1107. SRTest(e1); CheckAssComp(v.typ, e1, FALSE, s)
  1108. ELSE err(142)
  1109. END
  1110. END GenFor1;
  1111. PROCEDURE GenFor2(VAR v, e2: Item);
  1112. BEGIN SRTest(e2); load(e2);
  1113. IF v.typ # e2.typ THEN
  1114. IF (v.typ = inttyp) & (e2.typ = cardtyp) THEN
  1115. IF e2.mode = conMd THEN
  1116. IF e2.val.C > MaxInt THEN err(208) END
  1117. ELSE PutOpZ(307B)
  1118. END
  1119. ELSIF (v.typ = cardtyp) & (e2.typ = inttyp) THEN
  1120. IF e2.mode = conMd THEN
  1121. IF e2.val.I < 0 THEN err(132) END
  1122. ELSE PutOpZ(307B)
  1123. END
  1124. ELSE err(117)
  1125. END
  1126. END
  1127. END GenFor2;
  1128. PROCEDURE GenFor3(VAR e3: Item; VAR L0, L1: CARDINAL);
  1129. BEGIN PutOp(300B,-3); (*FOR1*)
  1130. IF e3.val.I > 0 THEN PutByte(0)
  1131. ELSIF e3.val.I < 0 THEN PutByte(1)
  1132. ELSE err(141)
  1133. END ;
  1134. L0 := pc; PutWord(0); L1 := pc
  1135. END GenFor3;
  1136. PROCEDURE GenFor4(VAR e3: Item; L0, L1: CARDINAL);
  1137. BEGIN PutOpZ(301B); PutByte(e3.val.C); PutWord(177777B-pc+L1+1); fixup(L0)
  1138. END GenFor4;
  1139. PROCEDURE GenTrap(n: CARDINAL);
  1140. BEGIN PutLit(n); PutOpD(304B) (*TRAP*)
  1141. END GenTrap;
  1142. PROCEDURE GenStParam(VAR p, x: Item; fctno, parno: CARDINAL);
  1143. VAR f: StrForm; ii: INTEGER;
  1144. BEGIN
  1145. IF parno = 0 THEN (*first parameter*)
  1146. CASE fctno OF
  1147. 0,1: |
  1148. 2: (*ABS*) SRTest(x);
  1149. IF x.typ = inttyp THEN load(x); PutOpZ(316B)
  1150. ELSIF x.typ = realtyp THEN load(x); PutOpZ(235B)
  1151. ELSE err(144)
  1152. END |
  1153. 3: (*CAP*) SRTest(x);
  1154. IF x.typ = chartyp THEN load(x); PutLit(137B); PutOpD(322B)
  1155. ELSE err(144); x.typ := chartyp
  1156. END |
  1157. 4: (*FLOAT*) SRTest(x);
  1158. IF x.typ = cardtyp THEN load(x); PutOpU(237B); PutByte(0)
  1159. ELSE err(144)
  1160. END ;
  1161. x.typ := realtyp |
  1162. 5: (*ODD*) SRTest(x);
  1163. IF (x.typ = cardtyp) OR (x.typ = inttyp) THEN
  1164. load(x); PutOpU(1); PutOpD(322B)
  1165. ELSE err(144)
  1166. END ;
  1167. x.typ := booltyp |
  1168. 6: (*ORD*) SRTest(x);
  1169. IF (x.typ^.form <= Card) OR (x.typ^.form = Enum) THEN load(x)
  1170. ELSE err(144)
  1171. END ;
  1172. x.typ := cardtyp |
  1173. 7: (*TRUNC*)
  1174. IF x.typ = realtyp THEN load(x); PutOpD(237B); PutByte(2)
  1175. ELSE err(144)
  1176. END ;
  1177. x.typ := cardtyp |
  1178. 8: (*SIZE, TSIZE*)
  1179. IF (x.mode = typMd) OR (x.mode = varMd) THEN x.val.I := x.typ^.size
  1180. ELSE err(145); x.val.I := 1
  1181. END ;
  1182. x.mode := conMd; x.typ := cardtyp |
  1183. 9: |
  1184. 10: (*ADR*) loadAdr(x); x.mode := expMd; x.typ := addrtyp |
  1185. 11: (*MIN*)
  1186. IF x.mode = typMd THEN x.mode := conMd;
  1187. CASE x.typ^.form OF
  1188. Bool: x.val.B := FALSE |
  1189. Char: x.val.Ch := 0C |
  1190. Int: x.val.C := 100000B |
  1191. Card: x.val.C := 0 |
  1192. Real: x.val.D0 := 177777B; x.val.D1 := 177777B |
  1193. Double: x.val.D0 := 100000B; x.val.D1 := 0 |
  1194. Enum: x.val.C := 0 |
  1195. Range: x.val.I := x.typ^.min; x.typ := x.typ^.RBaseTyp
  1196. ELSE err(144)
  1197. END
  1198. ELSE err(145)
  1199. END |
  1200. 12: (*MAX*)
  1201. IF x.mode = typMd THEN x.mode := conMd;
  1202. CASE x.typ^.form OF
  1203. Bool: x.val.B := TRUE |
  1204. Char: x.val.Ch := 377C |
  1205. Int: x.val.I := 77777B |
  1206. Card: x.val.C := 177777B |
  1207. Real: x.val.D0 := 77777B; x.val.D1 := 177777B |
  1208. Double: x.val.D0 := 77777B; x.val.D1 := 177777B |
  1209. Enum: x.val.C := x.typ^.NofConst - 1 |
  1210. Range: x.val.I := x.typ^.max; x.typ := x.typ^.RBaseTyp
  1211. ELSE err(144)
  1212. END
  1213. ELSE err(145)
  1214. END |
  1215. 13: (*HIGH*)
  1216. IF (x.mode = varMd) & (x.typ^.form = Array) THEN
  1217. IF x.typ^.dyn THEN loadLim(x.var); x.mode := expMd
  1218. ELSE x.mode := conMd; x.val.I := x.typ^.IndexTyp^.max
  1219. END
  1220. ELSE err(144)
  1221. END ;
  1222. x.typ := cardtyp |
  1223. 14: (*CHR*) SRTest(x);
  1224. IF (x.typ = cardtyp) OR (x.typ = inttyp) THEN load(x)
  1225. ELSE err(144)
  1226. END ;
  1227. x.typ := chartyp |
  1228. 15,16: (*INC, DEC*) f := x.typ^.form;
  1229. IF (f <= Int) OR (f = Range) OR (f = Enum) THEN
  1230. (*INC/DEC: adr COPT LSW0 LI1 UADD/IADD SSW0*)
  1231. SRTest(x); loadAdr(x); PutOpU(265B); PutOpZ(140B)
  1232. ELSE err(144)
  1233. END |
  1234. 17,18: (*INCL EXCL*)
  1235. IF x.typ^.form = Set THEN (*adr COPT LSW0*)
  1236. x.typ := x.typ^.SBaseTyp; loadAdr(x); PutOpU(265B); PutOpZ(140B)
  1237. ELSE err(144); x.typ := cardtyp
  1238. END |
  1239. 19: (*VAL*)
  1240. IF x.mode = typMd THEN f := x.typ^.form;
  1241. IF (f # Enum) & (f > Int) THEN err(144) END
  1242. END |
  1243. 20: (*LONG*) SRTest(x);
  1244. IF x.typ = cardtyp THEN load(x) ELSE err(144) END
  1245. END ;
  1246. p := x
  1247. ELSIF parno = 1 THEN (*second parameter*)
  1248. IF (fctno = 15) OR (fctno = 16) THEN (*INC/DEC*)
  1249. SRTest(x); CheckAssComp(p.typ, x, FALSE, ii)
  1250. ELSIF fctno = 17 THEN (*INCL: n BIT OR SSW0*)
  1251. SRTest(p); SRTest(x);
  1252. IF (x.typ = p.typ) OR (p.typ = cardtyp) & (x.typ = inttyp) THEN
  1253. load(x); PutOpZ(335B); PutOpD(320B); PutOp(160B,-2)
  1254. ELSE err(144)
  1255. END ;
  1256. p.typ := notyp
  1257. ELSIF fctno = 18 THEN (*EXCL: n BIT COM AND SSW0*)
  1258. SRTest(p); SRTest(x);
  1259. IF (x.typ = p.typ) OR (p.typ = cardtyp) & (x.typ = inttyp) THEN
  1260. load(x); PutOpZ(335B); PutOpZ(323B); PutOpD(322B); PutOp(160B,-2)
  1261. ELSE err(144)
  1262. END ;
  1263. p.typ := notyp
  1264. ELSIF fctno = 19 THEN (*VAL*)
  1265. IF x.typ^.size > 1 THEN err(144) END ;
  1266. x.typ := p.typ; p := x
  1267. ELSIF fctno = 20 THEN SRTest(x); (*LONG*)
  1268. IF x.typ = cardtyp THEN load(x) ELSE err(144) END ;
  1269. p.typ := dbltyp
  1270. ELSE err(64)
  1271. END
  1272. ELSE err(64)
  1273. END
  1274. END GenStParam;
  1275. PROCEDURE GenStFct(VAR p: Item; fctno, parno: CARDINAL);
  1276. BEGIN
  1277. IF parno < 1 THEN err(65)
  1278. ELSIF fctno = 15 THEN (*INC*)
  1279. IF parno = 1 THEN PutOpU(1) END ;
  1280. IF p.typ^.form = Int THEN PutOpD(330B) ELSE PutOpD(270B) END ;
  1281. PutOp(160B,-2); p.typ := notyp
  1282. ELSIF fctno = 16 THEN (*DEC*)
  1283. IF parno = 1 THEN PutOpU(1) END ;
  1284. IF p.typ^.form = Int THEN PutOpD(331B) ELSE PutOpD(271B) END ;
  1285. PutOp(160B,-2); p.typ := notyp
  1286. ELSIF (fctno > 16) & (parno < 2) THEN err(65)
  1287. END
  1288. END GenStFct;
  1289. PROCEDURE CheckStack;
  1290. CONST CodeLimit = CodeLength - RelTabLength;
  1291. BEGIN sp := 0;
  1292. IF pc > CodeLimit THEN err(226); CloseScanner; HALT END
  1293. END CheckStack;
  1294. PROCEDURE scanlist1(obj: ObjPtr);
  1295. (*generate code to allocate dataspace and set indirect adresses*)
  1296. VAR s: INTEGER;
  1297. BEGIN
  1298. WHILE obj # NIL DO
  1299. IF (obj^.class = Var) & (obj^.param = {}) & (obj^.typ^.size > 2) THEN
  1300. s := obj^.typ^.size;
  1301. IF curLev = 0 THEN
  1302. IF obj^.vmod = 0 THEN
  1303. datasize := datasize + s; PutOpU(265B); PutOpArg(120B, obj^.vadr,-1);
  1304. IF s < 400B THEN PutOpZ(26B); PutByte(s)
  1305. ELSE PutLit(s); PutOpD(270B) (*UADD*)
  1306. END
  1307. END
  1308. ELSE
  1309. PutLit(s); PutOpZ(352B); PutOpArg(60B, obj^.vadr,-1)
  1310. END
  1311. ELSIF obj^.class = Module THEN
  1312. scanlist1(obj^.firstObj)
  1313. END ;
  1314. obj := obj^.next
  1315. END
  1316. END scanlist1;
  1317. PROCEDURE scanlist2(obj: ObjPtr);
  1318. BEGIN (*generate code for initialization calls of modules*)
  1319. WHILE obj # NIL DO
  1320. IF obj^.class = Module THEN
  1321. scanlist2(obj^.firstObj); PutOpArg(360B, obj^.modno, 0) (*CL*)
  1322. END ;
  1323. obj := obj^.next
  1324. END
  1325. END scanlist2;
  1326. PROCEDURE GenEndDecl(ancestor: ObjPtr; modno: CARDINAL);
  1327. VAR s: CARDINAL; obj: ObjPtr;
  1328. BEGIN
  1329. IF ancestor^.class = Proc THEN obj := ancestor^.firstLocal
  1330. ELSE obj := ancestor^.firstObj
  1331. END ;
  1332. scanlist1(obj);
  1333. IF curLev = 0 THEN (*main*)
  1334. PutOpZ(122B); (*SGW2*) s := 1; (*initialize imports*)
  1335. WHILE s < modno DO
  1336. PutOpZ(355B); reloc; PutByte(s); PutByte(0); s := s+1
  1337. END
  1338. END ;
  1339. scanlist2(obj); sp := 0
  1340. END GenEndDecl;
  1341. PROCEDURE OutCodeFile(VAR name: ARRAY OF CHAR; stamp: KeyPtr;
  1342. adr: INTEGER; pno, id, modn: CARDINAL; mods: ObjPtr);
  1343. VAR i,pcw: CARDINAL;
  1344. out: File;
  1345. PROCEDURE W(n: CARDINAL);
  1346. BEGIN WriteWord(out, n)
  1347. END W;
  1348. PROCEDURE WriteNameAndKey(id: CARDINAL; stamp: KeyPtr);
  1349. VAR k,L: CARDINAL;
  1350. BEGIN L := CARDINAL(IdBuf[id])-1; k := id+L;
  1351. WHILE id < k DO id := id+1; WriteChar(out, IdBuf[id]) END ;
  1352. IF ODD(L) THEN WriteChar(out, 0C) END ;
  1353. WHILE L < 15 DO W(0); L := L+2 END ;
  1354. W(stamp^.k0); W(stamp^.k1); W(stamp^.k2)
  1355. END WriteNameAndKey;
  1356. BEGIN PutOpZ(354B);
  1357. IF ODD(pc) THEN PutOpZ(336B) END ;
  1358. code[7] := CHAR(adr); pcw := pc DIV 2;
  1359. Lookup(out, name, TRUE);
  1360. IF out.res = done THEN
  1361. (*version and header blocks*)
  1362. W(200B); W(1); W(4);
  1363. W(201B); W(14); WriteNameAndKey(id, stamp);
  1364. W(CARDINAL(adr)+CARDINAL(datasize)+(strx DIV 2)); W(pno+pcw); W(0);
  1365. IF modn > 1 THEN (*imports*)
  1366. W(202B); W((modn-1)*11); mods := mods^.next^.next;
  1367. REPEAT
  1368. WriteNameAndKey(mods^.name, mods^.key); mods := mods^.next
  1369. UNTIL mods = NIL
  1370. END ;
  1371. (*data and string blocks*)
  1372. W(204B); W(3); W(1); W(0); W(0);
  1373. IF strx > 0 THEN
  1374. W(204B); W(strx DIV 2 +1); W(adr+datasize);
  1375. FOR i := 0 TO strx-1 DO WriteChar(out, StrTab[i]) END
  1376. END ;
  1377. (*code blocks*)
  1378. W(203B); W(pno+1); W(0);
  1379. FOR i := 0 TO pno-1 DO W(ProcTab[i] + 2*pno) END ;
  1380. W(203B); W(pcw+1); W(pno);
  1381. FOR i := 0 TO pc-1 DO WriteChar(out, code[i]) END ;
  1382. (*relocation block*)
  1383. IF relx > 0 THEN
  1384. W(205B); W(relx);
  1385. FOR i := 0 TO relx-1 DO W(RelTab[i] + 2*pno) END
  1386. END ;
  1387. SetOpen(out);
  1388. IF out.res # done THEN err(223); Delete(out) ELSE Close(out) END
  1389. ELSE err(222)
  1390. END
  1391. END OutCodeFile;
  1392. PROCEDURE InitGenerator;
  1393. BEGIN pc := 0; sp := 0; ProcTab[0] := 0;
  1394. strx := 0; datasize := 0; relx := 0;
  1395. (*LGA 1, TS, JPFC 2, RTN, LGA 0*)
  1396. PutOpZ(25B); PutByte(1); PutOpZ(224B); PutOpZ(32B); PutByte(2);
  1397. PutOpZ(354B); PutOpZ(25B); PutByte(0)
  1398. END InitGenerator;
  1399. BEGIN
  1400. END M3GL.