PCM.Mod 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  1. (* Paco, Copyright 2000 - 2002, Patrik Reali, ETH Zurich *)
  2. MODULE PCM; (** AUTHOR "prk"; PURPOSE "Parallel Compiler: input and output module"; *)
  3. IMPORT
  4. SYSTEM,
  5. KernelLog, Modules, Objects, Streams, Files, Diagnostics,
  6. StringPool, PCDebug, Strings, Reflection,Machine;
  7. CONST
  8. (* value of constant NIL *)
  9. nilval* = 0;
  10. (* target machine minimum values of basic types expressed in host machine format: *)
  11. MinSInt* = -80H;
  12. MinInt* = -8000H;
  13. MinLInt* = LONGINT(80000000H); (* i386: -2147483648*)
  14. (* target machine maximum values of basic types expressed in host machine format: *)
  15. MaxSInt* = 7FH;
  16. MaxInt* = 7FFFH;
  17. MaxLInt* = 7FFFFFFFH; (* i386: 2147483647*)
  18. MaxSet* = 31; (* must be >= 15, else the bootstraped compiler cannot run (IN-tests) *)
  19. (* parametrization of numeric scanner: *)
  20. MaxHDig* = 8; (* maximal hexadecimal longint length *)
  21. MaxHHDig* = 16; (* maximal hexadecimal hugeint length *)
  22. MaxRExp* = 38; (* maximal real exponent *)
  23. MaxLExp* = 308; (* maximal longreal exponent *)
  24. (** code generator options *)
  25. ArrayCheck* = 0; (* x - perform array boundary checks *)
  26. OverflowCheck* = 1; (* v - perform overflow check *)
  27. NilCheck* = 2; (* N - explicit hard-coded nil checks *)
  28. TypeCheck*= 3; (* t - perform type checks *)
  29. PtrInit* = 5; (* p - initialize pointers to NIL *)
  30. AssertCheck* = 6; (* a - evaluate asserts *)
  31. Optimize* = 13;
  32. FullStackInit* = 20; (* z - clear all values on stack *)
  33. AlignedStack*=21; (* A - generate code with stack alignment for unix Aos *)
  34. ExportDefinitions* = 30;
  35. UseDefinitions* = 31;
  36. (** parser options *)
  37. NewSF* = 16; (* s - generation of new symbol file allowed *)
  38. ExtSF* = 17; (* e - generation of extended symbol file allowed *)
  39. Breakpoint* = 18; (* f - find position in code *)
  40. CacheImports* = 19; (* c - Cache imported modules *)
  41. NoFiles* = 21; (* n - don't generate files, parse only*)
  42. NoOpOverloading* = 22; (* o - do NOT allow operator overloading *)
  43. BigEndian* = 23; (* b - generate big endian code, makes only sense together with ARM backend *)
  44. Warnings* = 24; (* W - display warnings *)
  45. SkipOldSFImport* = 25; (* S - skip old symbol file import in PCOM.Export, avoids compiler error when migrating to new object file *) (* ug *)
  46. MultipleModules*= 26; (* M - allow compilation of multiple modules within one file *)
  47. (** sysflags and objflags written to and read from symbol file *)
  48. Untraced* = 4; (** global vars + fields - weak pointer *)
  49. WinAPIParam* = 13; (* ejz *)
  50. CParam*=14; (* fof for linux *)
  51. ReadOnly* = 15; (* fof *)
  52. RealtimeProc* = 21; (* ug *)
  53. RealtimeProcType* = 21; (* ug *)
  54. (** compiler generated traps *)
  55. WithTrap* = 1;
  56. CaseTrap* = 2;
  57. ReturnTrap* = 3;
  58. TypeEqualTrap* = 5;
  59. TypeCheckTrap* = 6;
  60. IndexCheckTrap* = 7;
  61. AssertTrap* = 8;
  62. ArraySizeTrap* = 9;
  63. ArrayFormTrap*=10; (* fof: indicates that array cannot be (re-)allocated since shape, type or size does not match *)
  64. (** file names and extentions *)
  65. FileTag = 0BBX; (* same constants are defined in Linker and Loader *)
  66. NoZeroCompress = 0ADX; (* do. *)
  67. FileVersion* = 0B1X; (* do. *)
  68. FileVersionOC*=0B2X; (* fof, preparation for new compiler *)
  69. LocalUnicodeSupport* = TRUE;
  70. ExportedUnicodeSupport* = FALSE;
  71. InitErrMsgSize = 300; (* initial size of array of error messages *)
  72. MaxErrors = 100; (* maximum number of diagnostic messages *)
  73. MaxWarnings = 100;
  74. TYPE
  75. SymReader* = Files.Reader;
  76. Rider* = RECORD
  77. symmodF, symF, objF, refF: Files.File;
  78. symmod, sym, obj, ref: Files.Writer; (*temp modlist, temp symfile, main file*)
  79. END;
  80. Attribute* = OBJECT END Attribute;
  81. ErrorMsgs = POINTER TO ARRAY OF StringPool.Index;
  82. VAR
  83. bigEndian*: BOOLEAN;
  84. (** fof >> *)
  85. tracebackOnError: BOOLEAN;
  86. (** << fof *)
  87. (** status *)
  88. codeOptions*, parserOptions*: SET;
  89. error*: BOOLEAN; (** actual compilation status *)
  90. errors, warnings: LONGINT; (* number of errors and warnings *)
  91. errMsg: ErrorMsgs; (*error messages*)
  92. (** input *)
  93. breakpc*: LONGINT; (** code offset to be found or MAX(LONGINT) *)
  94. breakpos*: LONGINT; (** text pos corresponding to breakpc (err 400 pos) *)
  95. (** output *)
  96. prefix*, suffix*: ARRAY 128 OF CHAR;
  97. (** procedure to dump (/D option) *)
  98. dump*: ARRAY 32 OF CHAR;
  99. source-: Files.FileName;
  100. log-: Streams.Writer;
  101. diagnostics-: Diagnostics.Diagnostics;
  102. (** ---------- low level functions --------------------- *)
  103. PROCEDURE GetProcessID*(): ADDRESS;
  104. BEGIN
  105. RETURN SYSTEM.VAL(ADDRESS, Objects.ActiveObject())
  106. END GetProcessID;
  107. (** ---------- file IO functions --------------------- *)
  108. PROCEDURE MakeFileName(VAR file: ARRAY OF CHAR; CONST name, prefix, suffix: ARRAY OF CHAR);
  109. VAR i, j: LONGINT;
  110. BEGIN
  111. i := 0; WHILE prefix[i] # 0X DO file[i] := prefix[i]; INC(i) END;
  112. j := 0; WHILE name[j] # 0X DO file[i+j] := name[j]; INC(j) END;
  113. INC(i, j);
  114. j := 0; WHILE suffix[j] # 0X DO file[i+j] := suffix[j]; INC(j) END;
  115. file[i+j] := 0X;
  116. END MakeFileName;
  117. PROCEDURE WriteString(w: Streams.Writer; CONST s: ARRAY OF CHAR);
  118. VAR i: INTEGER; ch: CHAR;
  119. BEGIN
  120. i:=0; ch:=s[0];
  121. WHILE ch # 0X DO
  122. w.Char(ch); INC(i); ch := s[i];
  123. END;
  124. w.Char(0X);
  125. END WriteString;
  126. (** OpenSymFile - Open a symfile for reading *)
  127. PROCEDURE OpenSymFile*(CONST name: ARRAY OF CHAR; VAR r: SymReader; VAR version: CHAR; VAR zeroCompress: BOOLEAN): BOOLEAN;
  128. VAR res: BOOLEAN; file: Files.FileName; f: Files.File; dummy: LONGINT; ch: CHAR;
  129. BEGIN
  130. res := FALSE; zeroCompress := TRUE;
  131. MakeFileName(file, name, prefix, suffix);
  132. f := Files.Old(file);
  133. IF f # NIL THEN
  134. Files.OpenReader(r, f, 0);
  135. r.Char(ch);
  136. IF ch = FileTag THEN
  137. r.Char(version);
  138. IF version = NoZeroCompress THEN
  139. zeroCompress := FALSE;
  140. r.Char(version);
  141. END;
  142. IF version = FileVersion THEN
  143. r.RawNum(dummy); (*skip symfile size*)
  144. ELSIF version = FileVersionOC THEN
  145. r.RawLInt(dummy);
  146. END;
  147. res := TRUE
  148. END
  149. END;
  150. RETURN res
  151. END OpenSymFile;
  152. PROCEDURE SymW*(VAR R: Rider; ch: CHAR);
  153. BEGIN R.sym.Char(ch) END SymW;
  154. PROCEDURE SymWNum*(VAR R: Rider; i: LONGINT);
  155. BEGIN R.sym.RawNum(i) END SymWNum;
  156. PROCEDURE SymWSet*(VAR R: Rider; s: SET);
  157. BEGIN R.sym.RawNum(SYSTEM.VAL(LONGINT, s)) END SymWSet;
  158. PROCEDURE SymWString*(VAR R: Rider; CONST str: ARRAY OF CHAR);
  159. BEGIN WriteString(R.sym, str) END SymWString;
  160. PROCEDURE SymWMod*(VAR R: Rider; CONST str: ARRAY OF CHAR);
  161. BEGIN WriteString(R.symmod, str) END SymWMod;
  162. PROCEDURE SymWReal*(VAR R: Rider; r: REAL);
  163. BEGIN R.sym.RawReal(r) END SymWReal;
  164. PROCEDURE SymWLReal*(VAR R: Rider; r: LONGREAL);
  165. BEGIN R.sym.RawLReal(r) END SymWLReal;
  166. PROCEDURE ObjWGetPos*(VAR R: Rider; VAR pos: LONGINT);
  167. BEGIN pos := R.obj.Pos()
  168. END ObjWGetPos;
  169. PROCEDURE ObjW*(VAR R: Rider; ch: CHAR);
  170. BEGIN R.obj.Char(ch)
  171. END ObjW;
  172. PROCEDURE ObjWNum*(VAR R: Rider; i: LONGINT);
  173. BEGIN R.obj.RawNum(i)
  174. END ObjWNum;
  175. PROCEDURE ObjWInt*(VAR R: Rider; i: INTEGER);
  176. BEGIN R.obj.RawInt(i)
  177. END ObjWInt;
  178. PROCEDURE ObjWIntAt*(VAR R: Rider; pos: LONGINT; i: INTEGER);
  179. VAR w: Files.Writer;
  180. BEGIN
  181. R.obj.Update;
  182. Files.OpenWriter(w, R.objF, pos);
  183. w.RawInt(i);
  184. w.Update
  185. END ObjWIntAt;
  186. PROCEDURE ObjWLInt*(VAR R: Rider; i: LONGINT);
  187. BEGIN R.obj.RawLInt(i)
  188. END ObjWLInt;
  189. PROCEDURE ObjWLIntAt*(VAR R: Rider; pos: LONGINT; i: LONGINT);
  190. VAR w: Files.Writer;
  191. BEGIN
  192. R.obj.Update;
  193. Files.OpenWriter(w, R.objF, pos);
  194. w.RawLInt(i);
  195. w.Update
  196. END ObjWLIntAt;
  197. PROCEDURE ObjWName*(VAR R: Rider; CONST str: ARRAY OF CHAR);
  198. BEGIN R.obj.RawString(str)
  199. END ObjWName;
  200. PROCEDURE RefW*(VAR R: Rider; ch: CHAR);
  201. BEGIN R.ref.Char(ch)
  202. END RefW;
  203. PROCEDURE RefWNum*(VAR R: Rider; i: LONGINT);
  204. BEGIN R.ref.RawNum(i)
  205. END RefWNum;
  206. PROCEDURE RefWString*(VAR R: Rider; CONST str: ARRAY OF CHAR);
  207. BEGIN R.ref.RawString(str)
  208. END RefWString;
  209. PROCEDURE Open*(CONST name: ARRAY OF CHAR; VAR R: Rider; VAR version: CHAR);
  210. VAR file: Files.FileName;
  211. BEGIN
  212. MakeFileName(file, name, prefix, suffix);
  213. R.symmodF := Files.New("");
  214. R.symF := Files.New("");
  215. R.objF := Files.New(file);
  216. R.refF := Files.New("");
  217. Files.OpenWriter(R.symmod, R.symmodF, 0);
  218. Files.OpenWriter(R.sym, R.symF, 0);
  219. Files.OpenWriter(R.obj, R.objF, 0);
  220. Files.OpenWriter(R.ref, R.refF, 0);
  221. R.obj.Char(FileTag);
  222. R.obj.Char(NoZeroCompress);
  223. R.obj.Char(version)
  224. END Open;
  225. PROCEDURE AppendFile(f: Files.File; to: Streams.Writer);
  226. VAR buffer: ARRAY 1024 OF CHAR; r: Files.Reader; read: LONGINT;
  227. BEGIN
  228. Files.OpenReader(r, f, 0);
  229. REPEAT
  230. r.Bytes(buffer, 0, 1024, read);
  231. to.Bytes(buffer, 0, read)
  232. UNTIL read # 1024
  233. END AppendFile;
  234. PROCEDURE CloseSym*(VAR R: Rider);
  235. BEGIN
  236. R.symmod.Update; (* flush buffers to file *)
  237. R.sym.Update;
  238. (* IF OldFileFormat THEN
  239. R.obj.RawNum(R.symmod.sent + R.sym.sent);
  240. ELSE
  241. R.obj.RawNum(4 + R.symmod.sent + R.sym.sent);
  242. R.obj.RawSet(codeOptions)
  243. END; *)
  244. R.obj.RawNum(4 + R.symmod.sent + R.sym.sent);
  245. R.obj.RawSet(codeOptions);
  246. AppendFile(R.symmodF, R.obj);
  247. AppendFile(R.symF, R.obj)
  248. END CloseSym;
  249. PROCEDURE CloseObj*(VAR R: Rider);
  250. BEGIN
  251. R.ref.Update;
  252. AppendFile(R.refF, R.obj);
  253. R.obj.Update;
  254. Files.Register(R.objF)
  255. END CloseObj;
  256. PROCEDURE RefSize*(VAR R: Rider): LONGINT;
  257. BEGIN RETURN R.ref.Pos()
  258. END RefSize;
  259. (** ---------- text output functions --------------------- *)
  260. PROCEDURE GetMessage (err: LONGINT; CONST msg: ARRAY OF CHAR; VAR res: ARRAY OF CHAR);
  261. VAR str: ARRAY 128 OF CHAR;
  262. BEGIN
  263. COPY (msg, res);
  264. IF (errMsg # NIL) & (0 <= err) & (err < LEN(errMsg)) THEN
  265. StringPool.GetString(errMsg[err], str);
  266. Strings.Append(res, " ");
  267. Strings.Append(res, str);
  268. END;
  269. END GetMessage;
  270. PROCEDURE TraceBackThis( eip, ebp: ADDRESS ); (* do a stack trace back w.r.t. given instruction and frame pointers *)
  271. BEGIN
  272. log.Ln; log.String( "##################" );
  273. log.Ln; log.String( "# Debugging.TraceBack #" );
  274. log.Ln; log.String( "##################" );
  275. log.Ln; Reflection.StackTraceBack( log, eip, ebp, ebp, 0, TRUE , FALSE );
  276. log.Update;
  277. END TraceBackThis;
  278. PROCEDURE TraceBack*; (* do a stack trace back starting at the calling instruction position *)
  279. BEGIN
  280. TraceBackThis( Machine.CurrentPC(), Machine.CurrentBP() );
  281. END TraceBack;
  282. PROCEDURE Error* (err, pos: LONGINT; CONST msg: ARRAY OF CHAR);
  283. VAR str: ARRAY 128 OF CHAR;
  284. BEGIN {EXCLUSIVE}
  285. (** fof >> *)
  286. IF tracebackOnError THEN TraceBack() END;
  287. (** << fof *)
  288. error := error OR (err <= 400) OR (err >= 404);
  289. IF err = 400 THEN breakpos := pos END;
  290. GetMessage (err, msg, str);
  291. IF (err < 400) OR (err > 403) THEN
  292. INC (errors);
  293. IF errors > MaxErrors THEN
  294. RETURN
  295. ELSIF errors = MaxErrors THEN
  296. err := Diagnostics.Invalid; pos := Diagnostics.Invalid; str := "too many errors"
  297. END;
  298. IF diagnostics # NIL THEN
  299. diagnostics.Error (source, pos, err, str);
  300. END;
  301. ELSE
  302. IF diagnostics # NIL THEN
  303. diagnostics.Information (source, pos, err, str);
  304. END;
  305. END;
  306. END Error;
  307. PROCEDURE ErrorN* (err, pos: LONGINT; msg: StringPool.Index);
  308. VAR str: ARRAY 256 OF CHAR;
  309. BEGIN
  310. StringPool.GetString(msg, str);
  311. Error(err, pos, str)
  312. END ErrorN;
  313. PROCEDURE Warning* (err, pos: LONGINT; CONST msg: ARRAY OF CHAR);
  314. VAR str: ARRAY 128 OF CHAR;
  315. BEGIN {EXCLUSIVE}
  316. IF ~(Warnings IN parserOptions) THEN RETURN END;
  317. INC (warnings);
  318. IF warnings > MaxWarnings THEN
  319. RETURN
  320. ELSIF warnings = MaxWarnings THEN
  321. err := Diagnostics.Invalid; pos := Diagnostics.Invalid; str := "too many warnings"
  322. ELSE
  323. GetMessage (err, msg, str);
  324. END;
  325. IF diagnostics # NIL THEN
  326. diagnostics.Warning (source, pos, err, str);
  327. END;
  328. END Warning;
  329. PROCEDURE LogW* (ch: CHAR);
  330. BEGIN log.Char(ch)
  331. END LogW;
  332. PROCEDURE LogWStr* (CONST str: ARRAY OF CHAR);
  333. BEGIN log.String(str)
  334. END LogWStr;
  335. PROCEDURE LogWStr0* (str: StringPool.Index);
  336. VAR str0: ARRAY 256 OF CHAR;
  337. BEGIN
  338. StringPool.GetString(str, str0); LogWStr(str0)
  339. END LogWStr0;
  340. PROCEDURE LogWHex* (i: LONGINT);
  341. BEGIN log.Hex(i, 0)
  342. END LogWHex;
  343. PROCEDURE LogWNum* (i: LONGINT);
  344. BEGIN log.Int(i, 0)
  345. END LogWNum;
  346. PROCEDURE LogWBool* (b: BOOLEAN);
  347. BEGIN
  348. IF b THEN LogWStr("TRUE") ELSE LogWStr("FALSE") END
  349. END LogWBool;
  350. PROCEDURE LogWType* (p: ANY);
  351. VAR name: ARRAY 32 OF CHAR;
  352. BEGIN
  353. PCDebug.GetTypeName(p, name); LogWStr(name)
  354. END LogWType;
  355. PROCEDURE LogWLn*;
  356. BEGIN log.Ln
  357. END LogWLn;
  358. PROCEDURE LogFlush*;
  359. BEGIN log.Update
  360. END LogFlush;
  361. (** ---------- configuration functions --------------------- *)
  362. (** Init - Prepare module for a new compilation *)
  363. PROCEDURE Init*(CONST s: ARRAY OF CHAR; l: Streams.Writer; d: Diagnostics.Diagnostics); (* don't assume Reset is executed *)
  364. BEGIN
  365. COPY (s, source);
  366. log := l;
  367. IF log = NIL THEN Streams.OpenWriter( log, KernelLog.Send ) END;
  368. diagnostics := d;
  369. error := FALSE;
  370. errors := 0; warnings := 0;
  371. PCDebug.ResetToDo;
  372. END Init;
  373. (** Reset - allow deallocation of structures*)
  374. PROCEDURE Reset*;
  375. BEGIN
  376. PCDebug.ResetToDo;
  377. END Reset;
  378. (** SetErrorMsg - Set message for error n *)
  379. PROCEDURE SetErrorMsg*(n: LONGINT; CONST msg: ARRAY OF CHAR);
  380. BEGIN
  381. IF errMsg = NIL THEN NEW(errMsg, InitErrMsgSize) END;
  382. WHILE LEN(errMsg^) < n DO Expand(errMsg) END;
  383. StringPool.GetIndex(msg, errMsg[n])
  384. END SetErrorMsg;
  385. PROCEDURE Expand(VAR oldAry: ErrorMsgs);
  386. VAR
  387. len, i: LONGINT;
  388. newAry: ErrorMsgs;
  389. BEGIN
  390. IF oldAry = NIL THEN RETURN END;
  391. len := LEN(oldAry^);
  392. NEW(newAry, len * 2);
  393. FOR i := 0 TO len-1 DO
  394. newAry[i] := oldAry[i];
  395. END;
  396. oldAry := newAry;
  397. END Expand;
  398. PROCEDURE InitMod;
  399. BEGIN
  400. PCDebug.ResetToDo
  401. END InitMod;
  402. PROCEDURE SwapBytes*(VAR p: ARRAY OF SYSTEM.BYTE; offset, len: LONGINT);
  403. VAR i: LONGINT;
  404. tmp: SYSTEM.BYTE;
  405. BEGIN
  406. FOR i := 0 TO (len-1) DIV 2 DO
  407. tmp := p[offset+i];
  408. p[offset+i] := p[offset+len-1-i];
  409. p[offset+len-1-i] := tmp;
  410. END;
  411. END SwapBytes;
  412. PROCEDURE MakeErrorFile*;
  413. VAR f: Files.File; w: Files.Writer;
  414. msg, code: ARRAY 256 OF CHAR; i: LONGINT;
  415. BEGIN
  416. f := Files.New("Errors2.XML");
  417. IF f # NIL THEN
  418. Files.OpenWriter(w, f, 0);
  419. WHILE i < LEN(errMsg)-1 DO
  420. StringPool.GetString(errMsg[i], msg);
  421. w.String(" <Error code="); w.Char(CHR(34));
  422. Strings.IntToStr(i, code); w.String(code);
  423. w.Char(CHR(34)); w.String(">");
  424. w.String(msg);
  425. w.String("</Error>");
  426. w.Ln;
  427. INC(i);
  428. END;
  429. w.Update;
  430. Files.Register(f);
  431. ELSE
  432. KernelLog.String("Could not create file"); KernelLog.Ln;
  433. END;
  434. END MakeErrorFile;
  435. (** fof >> *)
  436. PROCEDURE TracebackOnError*;
  437. BEGIN
  438. tracebackOnError := ~tracebackOnError;
  439. IF tracebackOnError THEN LogWStr( "TracebackOnError=TRUE" ); ELSE LogWStr( "TracebackOnError=FALSE" ) END;
  440. LogWLn; LogFlush;
  441. END TracebackOnError;
  442. (** << fof *)
  443. BEGIN
  444. Streams.OpenWriter( log, KernelLog.Send );
  445. InitMod;
  446. prefix := "";
  447. COPY(Modules.extension[0], suffix)
  448. END PCM.
  449. (*
  450. 15.11.06 ug new compiler option /S added, FileVersion incremented
  451. 20.09.03 prk "/Dcode" compiler option added
  452. 24.06.03 prk Remove TDMask (no need to mask typedescriptors)
  453. 22.02.02 prk unicode support
  454. 22.01.02 prk cosmetic changes, some constants renamed
  455. 22.01.02 prk ToDo list moved to PCDebug
  456. 18.01.02 prk AosFS used instead of Files
  457. 10.12.01 prk ENTIER: rounding mode set to chop, rounding modes caches as globals
  458. 22.11.01 prk improved flag handling
  459. 19.11.01 prk definitions
  460. 23.07.01 prk read error messages into stringpool
  461. 05.07.01 prk optional explicit NIL checks
  462. 27.06.01 prk StringPool cleaned up
  463. 14.06.01 prk type descs for dynamic arrays of ptrs generated by the compiler
  464. 17.05.01 prk Delegates
  465. 26.04.01 prk separation of RECORD and OBJECT in the parser
  466. 25.04.01 prk array allocation: if length < 0 then trap PCM.ArraySizeTrap
  467. 30.03.01 prk object file version changed to 01X
  468. 29.03.01 prk Java imports
  469. *)