M3RL.mod 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  1. IMPLEMENTATION MODULE M3RL; (*JG 6.11.85 / NW 31.10.85*)
  2. FROM FileSystem IMPORT File, Response, Lookup, SetOpen, Close, ReadWord,
  3. WriteWord;
  4. FROM M2S IMPORT IdBuf, id, Diff, Mark;
  5. FROM M3DL IMPORT ObjClass, Object, ObjPtr, StrForm, Structure, StrPtr,
  6. Parameter, ParPtr, PDesc, Key, KeyPtr, undftyp, booltyp, chartyp, inttyp,
  7. cardtyp, dbltyp, realtyp, stringtyp, wordtyp, addrtyp, bitstyp,
  8. proctyp, notyp, mainmod, ALLOCATE, ResetHeap;
  9. CONST REFFILE = 333B;
  10. CTL = 170000B; anchor = 0; ModTag = 1; ProcTag = 2; RefTag = 3; linkage = 4;
  11. STR = 171000B; enum = 0; range = 1; pointer = 2; set = 3; procTyp = 4;
  12. funcTyp = 5; array = 6; dynarr = 7; record = 8; opaque = 9;
  13. CMP = 172000B; parref = 0; par = 1; field = 2;
  14. OBJ = 173000B; varref = 0; var = 1; const = 2; string = 3; type = 4;
  15. proc = 5; func = 6; module = 7; svc = 8;
  16. maxM = 64; minS = 32 (*first non-standard structure*); maxS = 1024;
  17. VAR CurStr: CARDINAL;
  18. f: File; err: BOOLEAN;
  19. Temps, Fields: ObjPtr;
  20. Params, lastPar: ParPtr;
  21. PROCEDURE ReadId;
  22. VAR i, l, L: CARDINAL; u: CARDINAL;
  23. BEGIN i := id; l := 0;
  24. ReadWord(f, u); L := u DIV 256;
  25. LOOP
  26. IdBuf[i] := CHR(u DIV 256); i := i+1; l := l+1; IF l = L THEN EXIT END;
  27. IdBuf[i] := CHR(u MOD 256); i := i+1; l := l+1; IF l = L THEN EXIT END;
  28. ReadWord(f, u)
  29. END;
  30. id := i
  31. END ReadId;
  32. PROCEDURE InitRef;
  33. BEGIN
  34. WITH mainmod^ DO left := NIL; right := NIL; next := NIL END;
  35. ALLOCATE(ModList, SIZE(Object)); ALLOCATE(Temps, SIZE(Object));
  36. ALLOCATE(Fields, SIZE(Object)); ALLOCATE(Params, SIZE(Parameter));
  37. WITH ModList^ DO class := Header;
  38. next := mainmod; last := mainmod; left := NIL; right := NIL
  39. END;
  40. ModNo := 1;
  41. WITH Temps^ DO class := Header;
  42. next := NIL; last := Temps; left := NIL; right := NIL
  43. END;
  44. WITH Fields^ DO class := Header;
  45. next := NIL; last := Fields; left := NIL; right := NIL
  46. END;
  47. Params^.next := NIL; lastPar := Params
  48. END InitRef;
  49. PROCEDURE Insert(root, obj: ObjPtr): ObjPtr;
  50. VAR ob0, ob1: ObjPtr; d: INTEGER;
  51. BEGIN ob0 := root; ob1 := ob0^.right; d := 1;
  52. LOOP
  53. IF ob1 # NIL THEN
  54. d := Diff(obj^.name, ob1^.name);
  55. IF d < 0 THEN ob0 := ob1; ob1 := ob1^.left
  56. ELSIF d > 0 THEN ob0 := ob1; ob1 := ob1^.right
  57. ELSE EXIT
  58. END
  59. ELSE ob1 := obj;
  60. IF d < 0 THEN ob0^.left := ob1 ELSE ob0^.right := ob1 END ;
  61. ob1^.left := NIL; ob1^.right := NIL; EXIT
  62. END
  63. END;
  64. RETURN ob1
  65. END Insert;
  66. PROCEDURE InRef(VAR filename: ARRAY OF CHAR; VAR hdr: ObjPtr;
  67. VAR adr: INTEGER; VAR pno: CARDINAL);
  68. VAR GlbMod: ARRAY [0..maxM] OF ObjPtr;
  69. Struct: ARRAY [0..maxS] OF StrPtr;
  70. CurMod, FileType, block, m, p, s, id0: CARDINAL;
  71. lev0, newobj, obj: ObjPtr;
  72. newpar: ParPtr; newstr: StrPtr;
  73. BEGIN
  74. Lookup(f, filename, FALSE);
  75. IF f.res = done THEN ReadWord(f, FileType);
  76. IF FileType = REFFILE THEN
  77. Struct[1] := undftyp; Struct[2] := booltyp; Struct[3] := chartyp;
  78. Struct[4] := inttyp; Struct[5] := cardtyp; Struct[6] := dbltyp;
  79. Struct[7] := realtyp; Struct[8] := NIL; Struct[9] := stringtyp;
  80. Struct[10] := wordtyp; Struct[11] := addrtyp; Struct[12] := bitstyp;
  81. Struct[13] := proctyp;
  82. CurMod := 0; CurStr := minS; err := FALSE;
  83. id0 := id; ALLOCATE(lev0, 0);
  84. LOOP ReadWord(f, block);
  85. IF block >= OBJ THEN block := block - OBJ;
  86. IF block > svc THEN err := TRUE; Mark(86); EXIT END;
  87. ALLOCATE(newobj, SIZE(Object)); m := 0;
  88. WITH newobj^ DO next := NIL;
  89. CASE block OF
  90. var : class := Var; ReadWord(f, s); typ := Struct[s];
  91. param := {}; vmod := GlbMod[0]^.right^.modno;
  92. ReadWord(f, vlev); ReadWord(f, vadr)
  93. | const : class := Const; ReadWord(f, s); typ := Struct[s];
  94. ReadWord(f, m);
  95. ReadWord(f, conval.D0); ReadWord(f, conval.D1)
  96. | string : class := Const; ReadWord(f, s); typ := Struct[s];
  97. conval.D2 := id; ReadId;
  98. conval.D1 := id - conval.D2;
  99. conval.D0 := 177777B
  100. | type : class := Typ; ReadWord(f, s); typ := Struct[s];
  101. IF typ^.strobj = NIL THEN typ^.strobj := newobj END;
  102. ReadWord(f, m); mod := GlbMod[m]^.right
  103. | proc, func : class := Proc;
  104. IF block = func THEN ReadWord(f, s); typ := Struct[s]
  105. ELSE typ := notyp
  106. END;
  107. ALLOCATE(pd, SIZE(PDesc));
  108. ReadWord(f, pd^.num); ReadWord(f, pd^.lev);
  109. ReadWord(f, pd^.adr); ReadWord(f, pd^.size);
  110. firstLocal := NIL; firstParam := Params^.next;
  111. Params^.next := NIL; lastPar := Params;
  112. pmod := GlbMod[0]^.right^.modno
  113. | svc : class := Code; ReadWord(f, cnum);
  114. typ := NIL; firstArg := Params^.next;
  115. Params^.next := NIL; lastPar := Params
  116. END;
  117. name := id; ReadId; exported := TRUE;
  118. obj := Insert(GlbMod[m]^.right, newobj);
  119. IF obj = newobj THEN (*new object*)
  120. GlbMod[m]^.last^.next := newobj; GlbMod[m]^.last := newobj;
  121. IF (class = Const) & (typ^.form = Enum) THEN
  122. conval.prev := typ^.ConstLink; typ^.ConstLink := newobj
  123. END;
  124. id0 := id; ALLOCATE(lev0, 0)
  125. ELSE
  126. IF obj^.class = Typ THEN Struct[s] := obj^.typ END;
  127. id := id0; ResetHeap(lev0)
  128. END
  129. END
  130. ELSIF block >= CMP THEN block := block - CMP;
  131. IF block > field THEN err := TRUE; Mark(86); EXIT END;
  132. IF block = field THEN
  133. ALLOCATE(newobj, SIZE(Object));
  134. WITH newobj^ DO
  135. class := Field; next := NIL;
  136. ReadWord(f, s); typ := Struct[s];
  137. ReadWord(f, offset); name := id; ReadId;
  138. newobj := Insert(Fields, newobj)
  139. END;
  140. Fields^.last^.next := newobj; Fields^.last := newobj
  141. ELSE (*parameter*)
  142. ALLOCATE(newpar, SIZE(Parameter));
  143. WITH newpar^ DO
  144. next := NIL; ReadWord(f, s); typ := Struct[s];
  145. name := 0; varpar := block = parref;
  146. lastPar^.next := newpar; lastPar := newpar
  147. END
  148. END
  149. ELSIF block >= STR THEN block := block - STR;
  150. IF block > opaque THEN err := TRUE; Mark(86); EXIT END;
  151. ALLOCATE(newstr, SIZE(Structure));
  152. WITH newstr^ DO
  153. strobj := NIL; ReadWord(f, size); ref := 0;
  154. CASE block OF
  155. enum : form := Enum; ReadWord(f, NofConst);
  156. ConstLink := NIL
  157. | range : form := Range;
  158. ReadWord(f, s); RBaseTyp := Struct[s];
  159. ReadWord(f, min); ReadWord(f, max)
  160. | pointer : form := Pointer; PBaseTyp := NIL;
  161. BaseId := 0
  162. | set : form := Set; ReadWord(f, s);
  163. SBaseTyp := Struct[s]
  164. | procTyp, funcTyp : form := ProcTyp;
  165. IF block = funcTyp THEN
  166. ReadWord(f, s); resTyp := Struct[s]
  167. ELSE resTyp := notyp
  168. END;
  169. firstPar := Params^.next;
  170. Params^.next := NIL; lastPar := Params
  171. | array : form := Array; ReadWord(f, s);
  172. ElemTyp := Struct[s]; dyn := FALSE;
  173. ReadWord(f, s); IndexTyp := Struct[s]
  174. | dynarr : form := Array; ReadWord(f, s);
  175. ElemTyp := Struct[s]; dyn := TRUE;
  176. IndexTyp := NIL
  177. | record : form := Record;
  178. firstFld := Fields^.right; Fields^.right := NIL;
  179. Fields^.next := NIL; Fields^.last := Fields
  180. | opaque : form := Opaque
  181. END
  182. END;
  183. IF CurStr > maxS THEN err := TRUE; Mark(98); EXIT END;
  184. Struct[CurStr] := newstr;
  185. CurStr := CurStr + 1
  186. ELSIF block >= CTL THEN block := block - CTL;
  187. IF block = linkage THEN ReadWord(f, s); ReadWord(f, p);
  188. IF Struct[p]^.PBaseTyp # NIL THEN
  189. id := id0; ResetHeap(lev0)
  190. ELSE Struct[p]^.PBaseTyp := Struct[s];
  191. id0 := id; ALLOCATE(lev0, 0)
  192. END
  193. ELSIF block = ModTag THEN (*main module*) ReadWord(f, m)
  194. ELSIF block = anchor THEN
  195. ALLOCATE(newobj, SIZE(Object));
  196. WITH newobj^ DO
  197. class := Module; typ := NIL; left := NIL; right := NIL;
  198. ALLOCATE(key, SIZE(Key));
  199. ReadWord(f, key^.k0); ReadWord(f, key^.k1); ReadWord(f, key^.k2);
  200. firstObj := NIL; root := NIL; name := id; ReadId
  201. END;
  202. IF CurMod > maxM THEN Mark(96); EXIT END;
  203. ALLOCATE(GlbMod[CurMod], SIZE(Object));
  204. id0 := id; ALLOCATE(lev0, 0);
  205. WITH GlbMod[CurMod]^ DO
  206. class := Header; kind := Module; typ := NIL;
  207. next := NIL; left := NIL; last := GlbMod[CurMod];
  208. obj := ModList^.next; (*find mod*)
  209. WHILE (obj # NIL) & (Diff(obj^.name, newobj^.name) # 0) DO
  210. obj := obj^.next
  211. END;
  212. IF obj # NIL THEN GlbMod[CurMod]^.right := obj;
  213. IF (CurMod = 0) & (obj = mainmod) THEN
  214. (*newobj is own definition module*)
  215. obj^.key^ := newobj^.key^
  216. ELSIF (obj^.key^.k0 # newobj^.key^.k0)
  217. OR (obj^.key^.k1 # newobj^.key^.k1)
  218. OR (obj^.key^.k2 # newobj^.key^.k2) THEN Mark(85)
  219. ELSIF (CurMod = 0) & (obj^.firstObj # NIL) THEN
  220. CurMod := 1; EXIT (*module already loaded*)
  221. END;
  222. id := id0; ResetHeap(lev0)
  223. ELSE GlbMod[CurMod]^.right := newobj;
  224. newobj^.next := NIL; newobj^.modno := ModNo; INC(ModNo);
  225. ModList^.last^.next := newobj; ModList^.last := newobj;
  226. id0 := id; ALLOCATE(lev0, 0)
  227. END
  228. END;
  229. CurMod := CurMod + 1
  230. ELSIF block = RefTag THEN
  231. ReadWord(f, adr); ReadWord(f, pno); EXIT
  232. ELSE err := TRUE; Mark(86); EXIT
  233. END
  234. ELSE (*line block*) err := TRUE; Mark(86); EXIT
  235. END
  236. END;
  237. IF NOT err & (CurMod # 0) THEN hdr := GlbMod[0];
  238. hdr^.right^.root := hdr^.right^.right;
  239. (*leave hdr^.right.right for later searches*)
  240. hdr^.right^.firstObj := hdr^.next
  241. ELSE hdr := NIL
  242. END
  243. ELSE Mark(86); hdr := NIL
  244. END;
  245. Close(f)
  246. ELSE Mark(88); hdr := NIL
  247. END
  248. END InRef;
  249. PROCEDURE WriteId(i: CARDINAL);
  250. VAR l, L: CARDINAL; u: CARDINAL;
  251. BEGIN l := 0; L := ORD(IdBuf[i]);
  252. REPEAT
  253. u := ORD(IdBuf[i])*256; i := i+1; l := l+1;
  254. IF l # L THEN u := u + ORD(IdBuf[i]); i := i+1; l := l+1 END;
  255. WriteWord(RefFile, u)
  256. UNTIL l = L
  257. END WriteId;
  258. PROCEDURE OpenRef;
  259. VAR obj: ObjPtr;
  260. BEGIN WriteWord(RefFile, REFFILE);
  261. obj := ModList^.next;
  262. WHILE obj # NIL DO
  263. WriteWord(RefFile, CTL+anchor);
  264. WITH obj^ DO WriteWord(RefFile, key^.k0);
  265. WriteWord(RefFile, key^.k1); WriteWord(RefFile, key^.k2);
  266. WriteId(name)
  267. END;
  268. obj := obj^.next
  269. END;
  270. CurStr := minS
  271. END OpenRef;
  272. PROCEDURE OutPar(prm: ParPtr);
  273. BEGIN
  274. WHILE prm # NIL DO (*out param*)
  275. WITH prm^ DO
  276. IF varpar THEN WriteWord(RefFile, CMP+parref)
  277. ELSE WriteWord(RefFile, CMP+par)
  278. END;
  279. WriteWord(RefFile, typ^.ref)
  280. END;
  281. prm := prm^.next
  282. END
  283. END OutPar;
  284. PROCEDURE OutStr(str: StrPtr);
  285. VAR obj: ObjPtr; par: ParPtr;
  286. PROCEDURE OutFldStrs(fld: ObjPtr);
  287. BEGIN
  288. WHILE fld # NIL DO
  289. IF fld^.typ^.ref = 0 THEN OutStr(fld^.typ) END;
  290. fld := fld^.next
  291. END
  292. END OutFldStrs;
  293. PROCEDURE OutFlds(fld: ObjPtr);
  294. BEGIN
  295. WHILE fld # NIL DO
  296. WITH fld^ DO
  297. WriteWord(RefFile, CMP+field); WriteWord(RefFile, typ^.ref);
  298. WriteWord(RefFile, offset); WriteId(name)
  299. END;
  300. fld := fld^.next
  301. END
  302. END OutFlds;
  303. BEGIN
  304. WITH str^ DO
  305. CASE form OF
  306. Enum : WriteWord(RefFile, STR+enum); WriteWord(RefFile, size);
  307. WriteWord(RefFile, NofConst)
  308. | Range : IF RBaseTyp^.ref = 0 THEN OutStr(RBaseTyp) END;
  309. WriteWord(RefFile, STR+range); WriteWord(RefFile, size);
  310. WriteWord(RefFile, RBaseTyp^.ref);
  311. WriteWord(RefFile, min); WriteWord(RefFile, max)
  312. | Pointer : ALLOCATE(obj, SIZE(Object));
  313. WITH obj^ DO left := NIL; next := NIL;
  314. class := Temp; typ := PBaseTyp; baseref := CurStr;
  315. Temps^.last^.next := obj; Temps^.last := obj
  316. END;
  317. WriteWord(RefFile, STR+pointer); WriteWord(RefFile, size)
  318. | Set : IF SBaseTyp^.ref = 0 THEN OutStr(SBaseTyp) END;
  319. WriteWord(RefFile, STR+set); WriteWord(RefFile, size);
  320. WriteWord(RefFile, SBaseTyp^.ref)
  321. | ProcTyp : par := firstPar;
  322. WHILE par # NIL DO (*out param structure*)
  323. IF par^.typ^.ref = 0 THEN OutStr(par^.typ) END;
  324. par := par^.next
  325. END;
  326. OutPar(firstPar);
  327. IF resTyp # notyp THEN
  328. IF resTyp^.ref = 0 THEN OutStr(resTyp) END;
  329. WriteWord(RefFile, STR+funcTyp); WriteWord(RefFile, size);
  330. WriteWord(RefFile, resTyp^.ref)
  331. ELSE WriteWord(RefFile, STR+procTyp); WriteWord(RefFile, size)
  332. END
  333. | Array : IF ElemTyp^.ref = 0 THEN OutStr(ElemTyp) END;
  334. IF dyn THEN WriteWord(RefFile, STR+dynarr);
  335. WriteWord(RefFile, size); WriteWord(RefFile, ElemTyp^.ref)
  336. ELSE
  337. IF IndexTyp^.ref = 0 THEN OutStr(IndexTyp) END;
  338. WriteWord(RefFile, STR+array); WriteWord(RefFile, size);
  339. WriteWord(RefFile, ElemTyp^.ref);
  340. WriteWord(RefFile, IndexTyp^.ref)
  341. END
  342. | Record : OutFldStrs(firstFld); OutFlds(firstFld);
  343. WriteWord(RefFile, STR+record); WriteWord(RefFile, size)
  344. | Opaque : WriteWord(RefFile, STR+opaque); WriteWord(RefFile, size)
  345. END;
  346. ref := CurStr; CurStr := CurStr + 1
  347. END
  348. END OutStr;
  349. PROCEDURE OutExt(str: StrPtr);
  350. VAR obj: ObjPtr; par: ParPtr;
  351. PROCEDURE OutFlds(fld: ObjPtr);
  352. BEGIN
  353. WHILE fld # NIL DO
  354. IF fld^.typ^.ref = 0 THEN OutExt(fld^.typ) END;
  355. fld := fld^.next
  356. END
  357. END OutFlds;
  358. BEGIN
  359. WITH str^ DO
  360. CASE form OF
  361. Range : IF RBaseTyp^.ref = 0 THEN OutExt(RBaseTyp) END
  362. | Set : IF SBaseTyp^.ref = 0 THEN OutExt(SBaseTyp) END
  363. | ProcTyp : par := firstPar;
  364. WHILE par # NIL DO
  365. IF par^.typ^.ref = 0 THEN OutExt(par^.typ) END;
  366. par := par^.next
  367. END;
  368. IF (resTyp # notyp) & (resTyp^.ref = 0) THEN OutExt(resTyp) END
  369. | Array : IF ElemTyp^.ref = 0 THEN OutExt(ElemTyp) END;
  370. IF NOT dyn THEN OutExt(IndexTyp) END
  371. | Record : OutFlds(firstFld)
  372. | Enum, Pointer, Opaque :
  373. END;
  374. IF (strobj # NIL) & (strobj^.mod^.modno # 0) THEN
  375. IF ref = 0 THEN OutStr(str) END;
  376. IF form = Enum THEN obj := ConstLink;
  377. WHILE obj # NIL DO
  378. WriteWord(RefFile, OBJ+const);
  379. WriteWord(RefFile, ref);
  380. WriteWord(RefFile, strobj^.mod^.modno);
  381. WriteWord(RefFile, obj^.conval.D0);
  382. WriteWord(RefFile, obj^.conval.D1);
  383. WriteId(obj^.name);
  384. obj := obj^.conval.prev
  385. END
  386. END;
  387. WriteWord(RefFile, OBJ+type);
  388. WriteWord(RefFile, ref);
  389. WriteWord(RefFile, strobj^.mod^.modno);
  390. WriteId(strobj^.name)
  391. END
  392. END
  393. END OutExt;
  394. PROCEDURE OutObj(obj: ObjPtr);
  395. VAR par: ParPtr;
  396. BEGIN
  397. WITH obj^ DO
  398. CASE class OF
  399. Module : WriteWord(RefFile, OBJ+module); WriteWord(RefFile, modno)
  400. | Proc : par := firstParam;
  401. WHILE par # NIL DO
  402. IF par^.typ^.ref = 0 THEN OutExt(par^.typ) END;
  403. par := par^.next
  404. END;
  405. IF (typ # notyp) & (typ^.ref = 0) THEN OutExt(typ) END;
  406. par := firstParam;
  407. WHILE par # NIL DO (*out param structure*)
  408. IF par^.typ^.ref = 0 THEN OutStr(par^.typ) END;
  409. par := par^.next
  410. END;
  411. IF (typ # notyp) & (typ^.ref = 0) THEN OutStr(typ) END;
  412. OutPar(firstParam);
  413. IF typ # notyp THEN
  414. WriteWord(RefFile, OBJ+func); WriteWord(RefFile, typ^.ref)
  415. ELSE WriteWord(RefFile, OBJ+proc)
  416. END;
  417. WriteWord(RefFile, pd^.num); WriteWord(RefFile, pd^.lev);
  418. WriteWord(RefFile, pd^.adr); WriteWord(RefFile, pd^.size)
  419. | Code : par := firstArg;
  420. WHILE par # NIL DO
  421. IF par^.typ^.ref = 0 THEN OutExt(par^.typ) END;
  422. par := par^.next
  423. END;
  424. par := firstArg;
  425. WHILE par # NIL DO (*out param structure*)
  426. IF par^.typ^.ref = 0 THEN OutStr(par^.typ) END;
  427. par := par^.next
  428. END;
  429. OutPar(firstArg);
  430. WriteWord(RefFile, OBJ+svc); WriteWord(RefFile, cnum)
  431. | Const : IF typ^.ref = 0 THEN OutExt(typ) END;
  432. IF typ^.ref = 0 THEN OutStr(typ) END;
  433. IF typ^.form = String THEN WriteWord(RefFile, OBJ+string);
  434. WriteWord(RefFile, typ^.ref); WriteId(conval.D2)
  435. ELSE WriteWord(RefFile, OBJ+const);
  436. WriteWord(RefFile, typ^.ref);
  437. WriteWord(RefFile, 0); (*main*)
  438. WriteWord(RefFile, conval.D0); WriteWord(RefFile, conval.D1)
  439. END
  440. | Typ : IF typ^.ref = 0 THEN OutExt(typ) END;
  441. IF typ^.ref = 0 THEN OutStr(typ) END;
  442. WriteWord(RefFile, OBJ+type);
  443. WriteWord(RefFile, typ^.ref); WriteWord(RefFile, 0) (*main*)
  444. | Var : IF typ^.ref = 0 THEN OutExt(typ) END;
  445. IF typ^.ref = 0 THEN OutStr(typ) END;
  446. IF 1 IN param THEN WriteWord(RefFile, OBJ+varref)
  447. ELSE WriteWord(RefFile, OBJ+var)
  448. END;
  449. WriteWord(RefFile, typ^.ref);
  450. WriteWord(RefFile, vlev); WriteWord(RefFile, vadr)
  451. | Temp :
  452. END;
  453. WriteId(name)
  454. END
  455. END OutObj;
  456. PROCEDURE OutLink;
  457. VAR obj: ObjPtr;
  458. BEGIN obj := Temps^.next;
  459. WHILE obj # NIL DO
  460. WITH obj^ DO
  461. IF typ^.ref = 0 THEN OutExt(typ) END;
  462. IF typ^.ref = 0 THEN OutStr(typ) END;
  463. WriteWord(RefFile, CTL+linkage);
  464. WriteWord(RefFile, typ^.ref);
  465. WriteWord(RefFile, baseref)
  466. END;
  467. obj := obj^.next
  468. END;
  469. Temps^.next := NIL; Temps^.last := Temps
  470. END OutLink;
  471. PROCEDURE OutUnit(unit: ObjPtr);
  472. VAR lev0, obj: ObjPtr;
  473. BEGIN ALLOCATE(lev0, 0);
  474. IF unit^.class = Proc THEN obj := unit^.firstLocal;
  475. WHILE obj # NIL DO OutObj(obj); obj := obj^.next END;
  476. OutLink;
  477. WriteWord(RefFile, CTL+ProcTag);
  478. WriteWord(RefFile, unit^.pd^.num)
  479. ELSIF unit^.class = Module THEN obj := unit^.firstObj;
  480. WHILE obj # NIL DO OutObj(obj); obj := obj^.next END;
  481. OutLink;
  482. WriteWord(RefFile, CTL+ModTag);
  483. WriteWord(RefFile, unit^.modno)
  484. END;
  485. ResetHeap(lev0)
  486. END OutUnit;
  487. PROCEDURE OutPos(sourcepos, pc: CARDINAL);
  488. BEGIN
  489. IF pc < CTL THEN
  490. WriteWord(RefFile, pc); WriteWord(RefFile, sourcepos)
  491. ELSE Mark(226)
  492. END
  493. END OutPos;
  494. PROCEDURE CloseRef(adr: INTEGER; pno: CARDINAL);
  495. BEGIN
  496. WriteWord(RefFile, CTL+RefTag);
  497. WriteWord(RefFile, adr); WriteWord(RefFile, pno);
  498. SetOpen(RefFile);
  499. IF RefFile.res # done THEN Mark(88) END
  500. END CloseRef;
  501. BEGIN
  502. undftyp^.ref := 1; booltyp^.ref := 2; chartyp^.ref := 3; inttyp^.ref := 4;
  503. cardtyp^.ref := 5; dbltyp^.ref := 6; realtyp^.ref := 7;
  504. stringtyp^.ref := 9; wordtyp^.ref := 10; addrtyp^.ref := 11; bitstyp^.ref := 12;
  505. proctyp^.ref := 13
  506. END M3RL.