CPM.txt 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853
  1. MODULE DevCPM;
  2. (* THIS IS TEXT COPY OF BlackBox 1.6-rc6 Dev/Mod/CPM.odc *)
  3. (* DO NOT EDIT *)
  4. IMPORT SYSTEM, Kernel, Files, Stores, Models, Views, TextModels, TextMappers, StdLog, DevMarkers;
  5. CONST
  6. ProcSize* = 4; (* PROCEDURE type *)
  7. PointerSize* = 4; (* POINTER type *)
  8. DArrSizeA* = 8; (* dyn array descriptor *)
  9. DArrSizeB* = 4; (* size = A + B * typ.n *)
  10. MaxSet* = 31;
  11. MaxIndex* = 7FFFFFFFH; (* maximal index value for array declaration *)
  12. MinReal32Pat = 0FF7FFFFFH; (* most positive, 32-bit pattern *)
  13. MinReal64PatL = 0FFFFFFFFH; (* most negative, lower 32-bit pattern *)
  14. MinReal64PatH = 0FFEFFFFFH; (* most negative, higher 32-bit pattern *)
  15. MaxReal32Pat = 07F7FFFFFH; (* most positive, 32-bit pattern *)
  16. MaxReal64PatL = 0FFFFFFFFH; (* most positive, lower 32-bit pattern *)
  17. MaxReal64PatH = 07FEFFFFFH; (* most positive, higher 32-bit pattern *)
  18. InfRealPat = 07F800000H; (* real infinity pattern *)
  19. (* inclusive range of parameter of standard procedure HALT *)
  20. MinHaltNr* = 0;
  21. MaxHaltNr* = 128;
  22. (* inclusive range of register number of procedures SYSTEM.GETREG and SYSTEM.PUTREG *)
  23. MinRegNr* = 0;
  24. MaxRegNr* = 31;
  25. (* maximal value of flag used to mark interface structures *)
  26. MaxSysFlag* = 127; (* shortint *)
  27. CProcFlag* = 1; (* code procedures *)
  28. (* maximal condition value of parameter of SYSTEM.CC *)
  29. MaxCC* = 15;
  30. (* initialization of constant address, must be different from any valid constant address *)
  31. ConstNotAlloc* = -1;
  32. (* whether hidden pointer fields have to be nevertheless exported *)
  33. ExpHdPtrFld* = TRUE;
  34. HdPtrName* = "@ptr";
  35. (* whether hidden untagged pointer fields have to be nevertheless exported *)
  36. ExpHdUtPtrFld* = TRUE;
  37. HdUtPtrName* = "@utptr";
  38. (* whether hidden procedure fields have to be nevertheless exported (may be used for System.Free) *)
  39. ExpHdProcFld* = TRUE;
  40. HdProcName* = "@proc";
  41. (* whether hidden bound procedures have to be nevertheless exported *)
  42. ExpHdTProc* = FALSE;
  43. HdTProcName* = "@tproc";
  44. (* maximal number of exported stuctures: *)
  45. MaxStruct* = 16000; (* must be < MAX(INTEGER) DIV 2 in object model *)
  46. (* maximal number of record extensions: *)
  47. MaxExts* = 15; (* defined by type descriptor layout *)
  48. (* whether field leaf of pointer variable p has to be set to FALSE, when NEW(p) or SYSTEM.NEW(p, n) is used *)
  49. NEWusingAdr* = FALSE;
  50. (* special character (< " ") returned by procedure Get, if end of text reached *)
  51. Eot* = 0X;
  52. (* warnings *)
  53. longreal* = 0; largeint* = 1; realConst* = 2; copy* = 3; lchr* = 4; lentier* = 5; invar* = 6; outvar* = 7;
  54. (* language options *)
  55. interface* = 1;
  56. com* = 2; comAware* = 3;
  57. som* = 4; somAware* = 5;
  58. oberon* = 6;
  59. java* = 7; javaAware* = 8;
  60. noCode* = 9;
  61. allSysVal* = 14;
  62. sysImp* = 15;
  63. trap* = 31;
  64. sys386 = 10; sys68k = 20; (* processor type in options if system imported *)
  65. CONST
  66. SFdir = "Sym";
  67. OFdir = "Code";
  68. SYSdir = "System";
  69. SFtag = 6F4F5346H; (* symbol file tag *)
  70. OFtag = 6F4F4346H; (* object file tag *)
  71. maxErrors = 64;
  72. TYPE
  73. File = POINTER TO RECORD next: File; f: Files.File END;
  74. VAR
  75. LEHost*: BOOLEAN; (* little or big endian host *)
  76. MinReal32*, MaxReal32*, InfReal*,
  77. MinReal64*, MaxReal64*: REAL;
  78. noerr*: BOOLEAN; (* no error found until now *)
  79. curpos*, startpos*, errpos*: INTEGER; (* character, start, and error position in source file *)
  80. searchpos*: INTEGER; (* search position in source file *)
  81. errors*: INTEGER;
  82. breakpc*: INTEGER; (* set by OPV.Init *)
  83. options*: SET; (* language options *)
  84. file*: Files.File; (* used for sym file import *)
  85. codeDir*: ARRAY 16 OF CHAR;
  86. symDir*: ARRAY 16 OF CHAR;
  87. checksum*: INTEGER; (* symbol file checksum *)
  88. lastpos: INTEGER;
  89. realpat: INTEGER;
  90. lrealpat: RECORD H, L: INTEGER END;
  91. fpi, fpj: SHORTINT; fp: ARRAY 4 OF SHORTCHAR;
  92. ObjFName: Files.Name;
  93. in: TextModels.Reader;
  94. oldSymFile, symFile, objFile: Files.File;
  95. inSym: Files.Reader;
  96. outSym, outObj: Files.Writer;
  97. errNo, errPos: ARRAY maxErrors OF INTEGER;
  98. lineReader: TextModels.Reader;
  99. lineNum: INTEGER;
  100. crc32tab: ARRAY 256 OF INTEGER;
  101. PROCEDURE^ err* (n: INTEGER);
  102. PROCEDURE Init* (source: TextModels.Reader; logtext: TextModels.Model);
  103. BEGIN
  104. in := source;
  105. DevMarkers.Unmark(in.Base());
  106. noerr := TRUE; options := {};
  107. curpos := in.Pos(); errpos := curpos; lastpos := curpos - 11; errors := 0;
  108. codeDir := OFdir; symDir := SFdir
  109. END Init;
  110. PROCEDURE Close*;
  111. BEGIN
  112. oldSymFile := NIL; inSym := NIL;
  113. symFile := NIL; outSym := NIL;
  114. objFile := NIL; outObj := NIL;
  115. in := NIL; lineReader := NIL
  116. END Close;
  117. PROCEDURE Get* (VAR ch: SHORTCHAR);
  118. VAR ch1: CHAR;
  119. BEGIN
  120. REPEAT in.ReadChar(ch1); INC(curpos) UNTIL (ch1 < 100X) & (ch1 # TextModels.viewcode);
  121. ch := SHORT(ch1)
  122. END Get;
  123. PROCEDURE GetL* (VAR ch: CHAR);
  124. BEGIN
  125. REPEAT in.ReadChar(ch); INC(curpos) UNTIL ch # TextModels.viewcode;
  126. END GetL;
  127. PROCEDURE LineOf* (pos: INTEGER): INTEGER;
  128. VAR ch: CHAR;
  129. BEGIN
  130. IF lineReader = NIL THEN lineReader := in.Base().NewReader(NIL); lineReader.SetPos(0); lineNum := 0 END;
  131. IF lineReader.Pos() > pos THEN lineReader.SetPos(0); lineNum := 0 END;
  132. WHILE lineReader.Pos() < pos DO
  133. lineReader.ReadChar(ch);
  134. IF ch = 0DX THEN INC(lineNum) END
  135. END;
  136. RETURN lineNum
  137. END LineOf;
  138. PROCEDURE LoWord (r: REAL): INTEGER;
  139. VAR x: INTEGER;
  140. BEGIN
  141. x := SYSTEM.ADR(r);
  142. IF ~LEHost THEN INC(x, 4) END;
  143. SYSTEM.GET(x, x);
  144. RETURN x
  145. END LoWord;
  146. PROCEDURE HiWord (r: REAL): INTEGER;
  147. VAR x: INTEGER;
  148. BEGIN
  149. x := SYSTEM.ADR(r);
  150. IF LEHost THEN INC(x, 4) END;
  151. SYSTEM.GET(x, x);
  152. RETURN x
  153. END HiWord;
  154. PROCEDURE Compound (lo, hi: INTEGER): REAL;
  155. VAR r: REAL;
  156. BEGIN
  157. IF LEHost THEN
  158. SYSTEM.PUT(SYSTEM.ADR(r), lo); SYSTEM.PUT(SYSTEM.ADR(r) + 4, hi)
  159. ELSE
  160. SYSTEM.PUT(SYSTEM.ADR(r) + 4, lo); SYSTEM.PUT(SYSTEM.ADR(r), hi)
  161. END;
  162. RETURN r
  163. END Compound;
  164. (* sysflag control *)
  165. PROCEDURE ValidGuid* (VAR str: ARRAY OF SHORTCHAR): BOOLEAN;
  166. VAR i: SHORTINT; ch: SHORTCHAR;
  167. BEGIN
  168. IF (LEN(str$) # 38) OR (str[0] # "{") & (str[37] # "}") THEN RETURN FALSE END;
  169. i := 1;
  170. WHILE i < 37 DO
  171. ch := str[i];
  172. IF (i = 9) OR (i = 14) OR (i = 19) OR (i = 24) THEN
  173. IF ch # "-" THEN RETURN FALSE END
  174. ELSE
  175. IF (ch < "0") OR (ch > "9") & (CAP(ch) < "A") OR (CAP(ch) > "Z") THEN RETURN FALSE END
  176. END;
  177. INC(i)
  178. END;
  179. RETURN TRUE
  180. END ValidGuid;
  181. PROCEDURE GetProcSysFlag* (id: ARRAY OF SHORTCHAR; num: SHORTINT; VAR flag: SHORTINT);
  182. BEGIN
  183. IF id # "" THEN
  184. IF id = "code" THEN num := 1
  185. ELSIF id = "callback" THEN num := 2
  186. ELSIF id = "nostkchk" THEN num := 4
  187. ELSIF id = "ccall" THEN num := -10
  188. ELSIF id = "guarded" THEN num := 8
  189. ELSIF id = "noframe" THEN num := 16
  190. ELSIF id = "native" THEN num := -33
  191. ELSIF id = "bytecode" THEN num := -35
  192. END
  193. END;
  194. IF (options * {sysImp, sys386, sys68k} # {}) & ((num = 1) OR (num = 2)) THEN INC(flag, num)
  195. ELSIF (sys68k IN options) & (num = 4) THEN INC(flag, num)
  196. ELSIF (options * {sys386, interface} # {}) & (num = -10) & (flag = 0) THEN flag := -10
  197. ELSIF (options * {sys386, com} # {}) & (num = 8) & (flag = 0) THEN flag := 8
  198. ELSIF (options * {sysImp, sys386} # {}) & (num = 16) & (flag = 0) THEN flag := 16
  199. ELSIF ({sysImp, java} - options = {}) & ((num= -33) OR (num = -35)) & (flag = 0) THEN flag := num
  200. ELSE err(225); flag := 0
  201. END
  202. END GetProcSysFlag;
  203. PROCEDURE GetVarParSysFlag* (id: ARRAY OF SHORTCHAR; num: SHORTINT; VAR flag: SHORTINT);
  204. VAR old: SHORTINT;
  205. BEGIN
  206. old := flag; flag := 0;
  207. IF (options * {sys386, sys68k, interface, com} # {}) THEN
  208. IF (num = 1) OR (id = "nil") THEN
  209. IF ~ODD(old) THEN flag := SHORT(old + 1) END
  210. ELSIF ((num = 2) OR (id = "in")) & (oberon IN options) THEN
  211. IF old <= 1 THEN flag := SHORT(old + 2) END
  212. ELSIF ((num = 4) OR (id = "out")) & (oberon IN options) THEN
  213. IF old <= 1 THEN flag := SHORT(old + 4) END
  214. ELSIF ((num = 8) OR (id = "new")) & (options * {com, interface} # {}) THEN
  215. IF old <= 1 THEN flag := SHORT(old + 8) END
  216. ELSIF ((num = 16) OR (id = "iid")) & (com IN options) THEN
  217. IF old <= 1 THEN flag := SHORT(old + 16) END
  218. END
  219. END;
  220. IF flag = 0 THEN err(225) END
  221. END GetVarParSysFlag;
  222. PROCEDURE GetRecordSysFlag* (id: ARRAY OF SHORTCHAR; num: SHORTINT; VAR flag: SHORTINT);
  223. VAR old: SHORTINT;
  224. BEGIN
  225. old := flag; flag := 0;
  226. IF (num = 1) OR (id = "untagged") THEN
  227. IF (options * {sysImp, sys386, sys68k, interface, com, som} # {}) & (old = 0) THEN flag := 1 END
  228. ELSIF (num = 3) OR (id = "noalign") THEN
  229. IF (options * {sys386, sys68k, interface, com, som} # {}) & (old = 0) THEN flag := 3 END
  230. ELSIF (num = 4) OR (id = "align2") THEN
  231. IF (options * {sys386, interface, com} # {}) & (old = 0) THEN flag := 4 END
  232. ELSIF (num = 5) OR (id = "align4") THEN
  233. IF (options * {sys386, interface, com} # {}) & (old = 0) THEN flag := 5 END
  234. ELSIF (num = 6) OR (id = "align8") THEN
  235. IF (options * {sys386, interface, com} # {}) & (old = 0) THEN flag := 6 END
  236. ELSIF (num = 7) OR (id = "union") THEN
  237. IF (options * {sys386, sys68k, interface, com} # {}) & (old = 0) THEN flag := 7 END
  238. ELSIF (num = 10) OR (id = "interface") OR ValidGuid(id) THEN
  239. IF (com IN options) & (old = 0) THEN flag := 10 END
  240. ELSIF (num = -11) OR (id = "jint") THEN
  241. IF (java IN options) & (old = 0) THEN flag := -11 END
  242. ELSIF (num = -13) OR (id = "jstr") THEN
  243. IF (java IN options) & (old = 0) THEN flag := -13 END
  244. ELSIF (num = 20) OR (id = "som") THEN
  245. IF (som IN options) & (old = 0) THEN flag := 20 END
  246. END;
  247. IF flag = 0 THEN err(225) END
  248. END GetRecordSysFlag;
  249. PROCEDURE GetArraySysFlag* (id: ARRAY OF SHORTCHAR; num: SHORTINT; VAR flag: SHORTINT);
  250. VAR old: SHORTINT;
  251. BEGIN
  252. old := flag; flag := 0;
  253. IF (num = 1) OR (id = "untagged") THEN
  254. IF (options * {sysImp, sys386, sys68k, interface, com, som} # {}) & (old = 0) THEN flag := 1 END
  255. ELSIF (num = -12) OR (id = "jarr") THEN
  256. IF (java IN options) & (old = 0) THEN flag := -12 END
  257. ELSIF (num = -13) OR (id = "jstr") THEN
  258. IF (java IN options) & (old = 0) THEN flag := -13 END
  259. END;
  260. IF flag = 0 THEN err(225) END
  261. END GetArraySysFlag;
  262. PROCEDURE GetPointerSysFlag* (id: ARRAY OF SHORTCHAR; num: SHORTINT; VAR flag: SHORTINT);
  263. VAR old: SHORTINT;
  264. BEGIN
  265. old := flag; flag := 0;
  266. IF (num = 1) OR (id = "untagged") THEN
  267. IF (options * {sys386, sys68k, interface, com, som} # {}) & (old = 0) THEN flag := 1 END
  268. ELSIF (num = 2) OR (id = "handle") THEN
  269. IF (sys68k IN options) & (old = 0) THEN flag := 2 END
  270. ELSIF (num = 10) OR (id = "interface") THEN
  271. IF (com IN options) & (old = 0) THEN flag := 10 END
  272. ELSIF (num = 20) OR (id = "som") THEN
  273. IF (som IN options) & (old = 0) THEN flag := 20 END
  274. END;
  275. IF flag = 0 THEN err(225) END
  276. END GetPointerSysFlag;
  277. PROCEDURE GetProcTypSysFlag* (id: ARRAY OF SHORTCHAR; num: SHORTINT; VAR flag: SHORTINT);
  278. BEGIN
  279. IF ((num = -10) OR (id = "ccall")) & (options * {sys386, interface} # {}) THEN flag := -10
  280. ELSE err(225); flag := 0
  281. END
  282. END GetProcTypSysFlag;
  283. PROCEDURE PropagateRecordSysFlag* (baseFlag: SHORTINT; VAR flag: SHORTINT);
  284. BEGIN
  285. IF (baseFlag = 1) OR (baseFlag >= 3) & (baseFlag <= 7) THEN (* propagate untagged .. union *)
  286. IF flag = 0 THEN flag := baseFlag
  287. ELSIF (flag = 6) & (baseFlag < 6) THEN (* OK *) (* special case for 8 byte aligned records *)
  288. ELSIF flag # baseFlag THEN err(225); flag := 0
  289. END
  290. ELSIF (baseFlag # 10) & (flag = 10) THEN err(225)
  291. END
  292. END PropagateRecordSysFlag;
  293. PROCEDURE PropagateRecPtrSysFlag* (baseFlag: SHORTINT; VAR flag: SHORTINT);
  294. BEGIN
  295. IF (baseFlag = 1) OR (baseFlag >= 3) & (baseFlag <= 7) THEN (* pointer to untagged .. union is untagged *)
  296. IF flag = 0 THEN flag := 1
  297. ELSIF (flag # 1) & (flag # 2) THEN err(225); flag := 0
  298. END
  299. ELSIF baseFlag = 10 THEN (* pointer to interface is interface *)
  300. IF flag = 0 THEN flag := 10
  301. ELSIF flag # 10 THEN err(225); flag := 0
  302. END
  303. ELSIF baseFlag = -11 THEN (* pointer to java interface is java interface *)
  304. IF flag # 0 THEN err(225) END;
  305. flag := -11
  306. ELSIF baseFlag = -13 THEN (* pointer to java string is java string *)
  307. IF flag # 0 THEN err(225) END;
  308. flag := -13
  309. END
  310. END PropagateRecPtrSysFlag;
  311. PROCEDURE PropagateArrPtrSysFlag* (baseFlag: SHORTINT; VAR flag: SHORTINT);
  312. BEGIN
  313. IF baseFlag = 1 THEN (* pointer to untagged or guid is untagged *)
  314. IF flag = 0 THEN flag := 1
  315. ELSIF (flag # 1) & (flag # 2) THEN err(225); flag := 0
  316. END
  317. ELSIF baseFlag = -12 THEN (* pointer to java array is java array *)
  318. IF flag # 0 THEN err(225) END;
  319. flag := -12
  320. ELSIF baseFlag = -13 THEN (* pointer to java string is java string *)
  321. IF flag # 0 THEN err(225) END;
  322. flag := -13
  323. END
  324. END PropagateArrPtrSysFlag;
  325. (* utf8 strings *)
  326. PROCEDURE PutUtf8* (VAR str: ARRAY OF SHORTCHAR; val: INTEGER; VAR idx: INTEGER);
  327. BEGIN
  328. ASSERT((val >= 0) & (val < 65536));
  329. IF val < 128 THEN
  330. str[idx] := SHORT(CHR(val)); INC(idx)
  331. ELSIF val < 2048 THEN
  332. str[idx] := SHORT(CHR(val DIV 64 + 192)); INC(idx);
  333. str[idx] := SHORT(CHR(val MOD 64 + 128)); INC(idx)
  334. ELSE
  335. str[idx] := SHORT(CHR(val DIV 4096 + 224)); INC(idx);
  336. str[idx] := SHORT(CHR(val DIV 64 MOD 64 + 128)); INC(idx);
  337. str[idx] := SHORT(CHR(val MOD 64 + 128)); INC(idx)
  338. END
  339. END PutUtf8;
  340. PROCEDURE GetUtf8* (VAR str: ARRAY OF SHORTCHAR; VAR val, idx: INTEGER);
  341. VAR ch: SHORTCHAR;
  342. BEGIN
  343. ch := str[idx]; INC(idx);
  344. IF ch < 80X THEN
  345. val := ORD(ch)
  346. ELSIF ch < 0E0X THEN
  347. val := ORD(ch) - 192;
  348. ch := str[idx]; INC(idx); val := val * 64 + ORD(ch) - 128
  349. ELSE
  350. val := ORD(ch) - 224;
  351. ch := str[idx]; INC(idx); val := val * 64 + ORD(ch) - 128;
  352. ch := str[idx]; INC(idx); val := val * 64 + ORD(ch) - 128
  353. END
  354. END GetUtf8;
  355. (* log output *)
  356. PROCEDURE LogW* (ch: SHORTCHAR);
  357. BEGIN
  358. StdLog.Char(ch)
  359. END LogW;
  360. PROCEDURE LogWStr* (s: ARRAY OF SHORTCHAR);
  361. VAR str: ARRAY 256 OF CHAR;
  362. BEGIN
  363. str := s$; StdLog.String(str)
  364. END LogWStr;
  365. PROCEDURE LogWNum* (i, len: INTEGER);
  366. BEGIN
  367. StdLog.Int(i)
  368. END LogWNum;
  369. PROCEDURE LogWLn*;
  370. BEGIN
  371. StdLog.Ln
  372. END LogWLn;
  373. (*
  374. PROCEDURE LogW* (ch: CHAR);
  375. BEGIN
  376. out.WriteChar(ch);
  377. END LogW;
  378. PROCEDURE LogWStr* (s: ARRAY OF CHAR);
  379. BEGIN
  380. out.WriteString(s);
  381. END LogWStr;
  382. PROCEDURE LogWNum* (i, len: LONGINT);
  383. BEGIN
  384. out.WriteChar(" "); out.WriteInt(i);
  385. END LogWNum;
  386. PROCEDURE LogWLn*;
  387. BEGIN
  388. out.WriteLn;
  389. Views.RestoreDomain(logbuf.Domain())
  390. END LogWLn;
  391. *)
  392. PROCEDURE Mark* (n, pos: INTEGER);
  393. BEGIN
  394. IF (n >= 0) & ~((oberon IN options) & (n >= 181) & (n <= 190)) THEN
  395. noerr := FALSE;
  396. IF pos < 0 THEN pos := 0 END;
  397. IF (pos < lastpos) OR (lastpos + 9 < pos) THEN
  398. lastpos := pos;
  399. IF errors < maxErrors THEN
  400. errNo[errors] := n; errPos[errors] := pos
  401. END;
  402. INC(errors)
  403. END;
  404. IF trap IN options THEN HALT(100) END;
  405. ELSIF (n <= -700) & (errors < maxErrors) THEN
  406. errNo[errors] := -n; errPos[errors] := pos; INC(errors)
  407. END
  408. END Mark;
  409. PROCEDURE err* (n: INTEGER);
  410. BEGIN
  411. Mark(n, errpos)
  412. END err;
  413. PROCEDURE InsertMarks* (text: TextModels.Model);
  414. VAR i, j, x, y, n: INTEGER; script: Stores.Operation;
  415. BEGIN
  416. n := errors;
  417. IF n > maxErrors THEN n := maxErrors END;
  418. (* sort *)
  419. i := 1;
  420. WHILE i < n DO
  421. x := errPos[i]; y := errNo[i]; j := i-1;
  422. WHILE (j >= 0) & (errPos[j] > x) DO errPos[j+1] := errPos[j]; errNo[j+1] := errNo[j]; DEC(j) END;
  423. errPos[j+1] := x; errNo[j+1] := y; INC(i)
  424. END;
  425. (* insert *)
  426. Models.BeginModification(Models.clean, text);
  427. Models.BeginScript(text, "#Dev:InsertMarkers", script);
  428. WHILE n > 0 DO DEC(n);
  429. DevMarkers.Insert(text, errPos[n], DevMarkers.dir.New(errNo[n]))
  430. END;
  431. Models.EndScript(text, script);
  432. Models.EndModification(Models.clean, text);
  433. END InsertMarks;
  434. (* fingerprinting *)
  435. PROCEDURE InitCrcTab;
  436. (* CRC32, high bit first, pre & post inverted *)
  437. CONST poly = {0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26}; (* CRC32 polynom *)
  438. VAR x, c, i: INTEGER;
  439. BEGIN
  440. x := 0;
  441. WHILE x < 256 DO
  442. c := x * 1000000H; i := 0;
  443. WHILE i < 8 DO
  444. IF c < 0 THEN c := ORD(BITS(c * 2) / poly)
  445. ELSE c := c * 2
  446. END;
  447. INC(i)
  448. END;
  449. crc32tab[ORD(BITS(x) / BITS(255))] := ORD(BITS(c) / BITS(255));
  450. INC(x)
  451. END
  452. END InitCrcTab;
  453. PROCEDURE FPrint* (VAR fp: INTEGER; val: INTEGER);
  454. VAR c: INTEGER;
  455. BEGIN
  456. (*
  457. fp := SYSTEM.ROT(ORD(BITS(fp) / BITS(val)), 1) (* bad collision detection *)
  458. *)
  459. (* CRC32, high bit first, pre & post inverted *)
  460. c := ORD(BITS(fp * 256) / BITS(crc32tab[ORD(BITS(fp DIV 1000000H) / BITS(val DIV 1000000H)) MOD 256]));
  461. c := ORD(BITS(c * 256) / BITS(crc32tab[ORD(BITS(c DIV 1000000H) / BITS(val DIV 10000H)) MOD 256]));
  462. c := ORD(BITS(c * 256) / BITS(crc32tab[ORD(BITS(c DIV 1000000H) / BITS(val DIV 100H)) MOD 256]));
  463. fp := ORD(BITS(c * 256) / BITS(crc32tab[ORD(BITS(c DIV 1000000H) / BITS(val)) MOD 256]));
  464. END FPrint;
  465. PROCEDURE FPrintSet* (VAR fp: INTEGER; set: SET);
  466. BEGIN FPrint(fp, ORD(set))
  467. END FPrintSet;
  468. PROCEDURE FPrintReal* (VAR fp: INTEGER; real: SHORTREAL);
  469. BEGIN FPrint(fp, SYSTEM.VAL(INTEGER, real))
  470. END FPrintReal;
  471. PROCEDURE FPrintLReal* (VAR fp: INTEGER; lr: REAL);
  472. VAR l, h: INTEGER;
  473. BEGIN
  474. FPrint(fp, LoWord(lr)); FPrint(fp, HiWord(lr))
  475. END FPrintLReal;
  476. PROCEDURE ChkSum (VAR fp: INTEGER; val: INTEGER); (* symbolfile checksum *)
  477. BEGIN
  478. (* same as FPrint, 8 bit only *)
  479. fp := ORD(BITS(fp * 256) / BITS(crc32tab[ORD(BITS(fp DIV 1000000H) / BITS(val)) MOD 256]))
  480. END ChkSum;
  481. (* compact format *)
  482. PROCEDURE WriteLInt (w: Files.Writer; i: INTEGER);
  483. BEGIN
  484. ChkSum(checksum, i);
  485. w.WriteByte(SHORT(SHORT(i MOD 256))); i := i DIV 256;
  486. ChkSum(checksum, i);
  487. w.WriteByte(SHORT(SHORT(i MOD 256))); i := i DIV 256;
  488. ChkSum(checksum, i);
  489. w.WriteByte(SHORT(SHORT(i MOD 256))); i := i DIV 256;
  490. ChkSum(checksum, i);
  491. w.WriteByte(SHORT(SHORT(i MOD 256)))
  492. END WriteLInt;
  493. PROCEDURE ReadLInt (r: Files.Reader; VAR i: INTEGER);
  494. VAR b: BYTE; x: INTEGER;
  495. BEGIN
  496. r.ReadByte(b); x := b MOD 256;
  497. ChkSum(checksum, b);
  498. r.ReadByte(b); x := x + 100H * (b MOD 256);
  499. ChkSum(checksum, b);
  500. r.ReadByte(b); x := x + 10000H * (b MOD 256);
  501. ChkSum(checksum, b);
  502. r.ReadByte(b); i := x + 1000000H * b;
  503. ChkSum(checksum, b)
  504. END ReadLInt;
  505. PROCEDURE WriteNum (w: Files.Writer; i: INTEGER);
  506. BEGIN (* old format of Oberon *)
  507. WHILE (i < -64) OR (i > 63) DO ChkSum(checksum, i MOD 128 - 128); w.WriteByte(SHORT(SHORT(i MOD 128 - 128))); i := i DIV 128 END;
  508. ChkSum(checksum, i MOD 128);
  509. w.WriteByte(SHORT(SHORT(i MOD 128)))
  510. END WriteNum;
  511. PROCEDURE ReadNum (r: Files.Reader; VAR i: INTEGER);
  512. VAR b: BYTE; s, y: INTEGER;
  513. BEGIN
  514. s := 0; y := 0; r.ReadByte(b);
  515. IF ~r.eof THEN ChkSum(checksum, b) END;
  516. WHILE b < 0 DO INC(y, ASH(b + 128, s)); INC(s, 7); r.ReadByte(b); ChkSum(checksum, b) END;
  517. i := ASH((b + 64) MOD 128 - 64, s) + y;
  518. END ReadNum;
  519. PROCEDURE WriteNumSet (w: Files.Writer; x: SET);
  520. BEGIN
  521. WriteNum(w, ORD(x))
  522. END WriteNumSet;
  523. PROCEDURE ReadNumSet (r: Files.Reader; VAR x: SET);
  524. VAR i: INTEGER;
  525. BEGIN
  526. ReadNum(r, i); x := BITS(i)
  527. END ReadNumSet;
  528. PROCEDURE WriteReal (w: Files.Writer; x: SHORTREAL);
  529. BEGIN
  530. WriteLInt(w, SYSTEM.VAL(INTEGER, x))
  531. END WriteReal;
  532. PROCEDURE ReadReal (r: Files.Reader; VAR x: SHORTREAL);
  533. VAR i: INTEGER;
  534. BEGIN
  535. ReadLInt(r, i); x := SYSTEM.VAL(SHORTREAL, i)
  536. END ReadReal;
  537. PROCEDURE WriteLReal (w: Files.Writer; x: REAL);
  538. BEGIN
  539. WriteLInt(w, LoWord(x)); WriteLInt(w, HiWord(x))
  540. END WriteLReal;
  541. PROCEDURE ReadLReal (r: Files.Reader; VAR x: REAL);
  542. VAR h, l: INTEGER;
  543. BEGIN
  544. ReadLInt(r, l); ReadLInt(r, h); x := Compound(l, h)
  545. END ReadLReal;
  546. (* read symbol file *)
  547. PROCEDURE SymRCh* (VAR ch: SHORTCHAR);
  548. VAR b: BYTE;
  549. BEGIN
  550. inSym.ReadByte(b); ch := SHORT(CHR(b));
  551. ChkSum(checksum, b)
  552. END SymRCh;
  553. PROCEDURE SymRInt* (): INTEGER;
  554. VAR k: INTEGER;
  555. BEGIN
  556. ReadNum(inSym, k); RETURN k
  557. END SymRInt;
  558. PROCEDURE SymRSet* (VAR s: SET);
  559. BEGIN
  560. ReadNumSet(inSym, s)
  561. END SymRSet;
  562. PROCEDURE SymRReal* (VAR r: SHORTREAL);
  563. BEGIN
  564. ReadReal(inSym, r)
  565. END SymRReal;
  566. PROCEDURE SymRLReal* (VAR lr: REAL);
  567. BEGIN
  568. ReadLReal(inSym, lr)
  569. END SymRLReal;
  570. PROCEDURE eofSF* (): BOOLEAN;
  571. BEGIN
  572. RETURN inSym.eof
  573. END eofSF;
  574. PROCEDURE OldSym* (VAR modName: ARRAY OF SHORTCHAR; VAR done: BOOLEAN);
  575. VAR tag: INTEGER; loc: Files.Locator; dir, name: Files.Name;
  576. BEGIN
  577. done := FALSE;
  578. IF modName = "@file" THEN
  579. oldSymFile := file
  580. ELSE
  581. name := modName$; Kernel.SplitName(name, dir, name);
  582. Kernel.MakeFileName(name, Kernel.symType);
  583. loc := Files.dir.This(dir); loc := loc.This(symDir);
  584. oldSymFile := Files.dir.Old(loc, name, Files.shared);
  585. IF (oldSymFile = NIL) & (dir = "") THEN
  586. loc := Files.dir.This(SYSdir); loc := loc.This(symDir);
  587. oldSymFile := Files.dir.Old(loc, name, Files.shared)
  588. END
  589. END;
  590. IF oldSymFile # NIL THEN
  591. inSym := oldSymFile.NewReader(inSym);
  592. IF inSym # NIL THEN
  593. ReadLInt(inSym, tag);
  594. IF tag = SFtag THEN done := TRUE ELSE err(151) END
  595. END
  596. END
  597. END OldSym;
  598. PROCEDURE CloseOldSym*;
  599. BEGIN
  600. IF oldSymFile # NIL THEN oldSymFile.Close; oldSymFile := NIL END
  601. END CloseOldSym;
  602. (* write symbol file *)
  603. PROCEDURE SymWCh* (ch: SHORTCHAR);
  604. BEGIN
  605. ChkSum(checksum, ORD(ch));
  606. outSym.WriteByte(SHORT(ORD(ch)))
  607. END SymWCh;
  608. PROCEDURE SymWInt* (i: INTEGER);
  609. BEGIN
  610. WriteNum(outSym, i)
  611. END SymWInt;
  612. PROCEDURE SymWSet* (s: SET);
  613. BEGIN
  614. WriteNumSet(outSym, s)
  615. END SymWSet;
  616. PROCEDURE SymWReal* (VAR r: SHORTREAL);
  617. BEGIN
  618. WriteReal(outSym, r)
  619. END SymWReal;
  620. PROCEDURE SymWLReal* (VAR r: REAL);
  621. BEGIN
  622. WriteLReal(outSym, r)
  623. END SymWLReal;
  624. PROCEDURE SymReset*;
  625. BEGIN
  626. outSym.SetPos(4)
  627. END SymReset;
  628. PROCEDURE NewSym* (VAR modName: ARRAY OF SHORTCHAR);
  629. VAR loc: Files.Locator; dir: Files.Name;
  630. BEGIN
  631. ObjFName := modName$; Kernel.SplitName(ObjFName, dir, ObjFName);
  632. loc := Files.dir.This(dir); loc := loc.This(symDir);
  633. symFile := Files.dir.New(loc, Files.ask);
  634. IF symFile # NIL THEN
  635. outSym := symFile.NewWriter(NIL);
  636. WriteLInt(outSym, SFtag)
  637. ELSE
  638. err(153)
  639. END
  640. END NewSym;
  641. PROCEDURE RegisterNewSym*;
  642. VAR res: INTEGER; name: Files.Name;
  643. BEGIN
  644. IF symFile # NIL THEN
  645. name := ObjFName$;
  646. Kernel.MakeFileName(name, Kernel.symType);
  647. symFile.Register(name, Kernel.symType, Files.ask, res);
  648. symFile := NIL
  649. END
  650. END RegisterNewSym;
  651. PROCEDURE DeleteNewSym*;
  652. BEGIN
  653. IF symFile # NIL THEN symFile.Close; symFile := NIL END
  654. END DeleteNewSym;
  655. (* write object file *)
  656. PROCEDURE ObjW* (ch: SHORTCHAR);
  657. BEGIN
  658. outObj.WriteByte(SHORT(ORD(ch)))
  659. END ObjW;
  660. PROCEDURE ObjWNum* (i: INTEGER);
  661. BEGIN
  662. WriteNum(outObj, i)
  663. END ObjWNum;
  664. PROCEDURE ObjWInt (i: SHORTINT);
  665. BEGIN
  666. outObj.WriteByte(SHORT(SHORT(i MOD 256)));
  667. outObj.WriteByte(SHORT(SHORT(i DIV 256)))
  668. END ObjWInt;
  669. PROCEDURE ObjWLInt* (i: INTEGER);
  670. BEGIN
  671. ObjWInt(SHORT(i MOD 65536));
  672. ObjWInt(SHORT(i DIV 65536))
  673. END ObjWLInt;
  674. PROCEDURE ObjWBytes* (VAR bytes: ARRAY OF SHORTCHAR; n: INTEGER);
  675. TYPE P = POINTER TO ARRAY [untagged] 100000H OF BYTE;
  676. VAR p: P;
  677. BEGIN
  678. p := SYSTEM.VAL(P, SYSTEM.ADR(bytes));
  679. outObj.WriteBytes(p^, 0, n)
  680. END ObjWBytes;
  681. PROCEDURE ObjLen* (): INTEGER;
  682. BEGIN
  683. RETURN outObj.Pos()
  684. END ObjLen;
  685. PROCEDURE ObjSet* (pos: INTEGER);
  686. BEGIN
  687. outObj.SetPos(pos)
  688. END ObjSet;
  689. PROCEDURE NewObj* (VAR modName: ARRAY OF SHORTCHAR);
  690. VAR loc: Files.Locator; dir: Files.Name;
  691. BEGIN
  692. errpos := 0;
  693. ObjFName := modName$; Kernel.SplitName(ObjFName, dir, ObjFName);
  694. loc := Files.dir.This(dir); loc := loc.This(codeDir);
  695. objFile := Files.dir.New(loc, Files.ask);
  696. IF objFile # NIL THEN
  697. outObj := objFile.NewWriter(NIL);
  698. WriteLInt(outObj, OFtag)
  699. ELSE
  700. err(153)
  701. END
  702. END NewObj;
  703. PROCEDURE RegisterObj*;
  704. VAR res: INTEGER; name: Files.Name;
  705. BEGIN
  706. IF objFile # NIL THEN
  707. name := ObjFName$;
  708. Kernel.MakeFileName(name, Kernel.objType);
  709. objFile.Register(name, Kernel.objType, Files.ask, res);
  710. objFile := NIL; outObj := NIL
  711. END
  712. END RegisterObj;
  713. PROCEDURE DeleteObj*;
  714. BEGIN
  715. IF objFile # NIL THEN objFile.Close; objFile := NIL END
  716. END DeleteObj;
  717. PROCEDURE InitHost;
  718. VAR test: SHORTINT; lo: SHORTCHAR;
  719. BEGIN
  720. test := 1; SYSTEM.GET(SYSTEM.ADR(test), lo); LEHost := lo = 1X;
  721. InfReal := SYSTEM.VAL(SHORTREAL, InfRealPat);
  722. MinReal32 := SYSTEM.VAL(SHORTREAL, MinReal32Pat);
  723. MaxReal32 := SYSTEM.VAL(SHORTREAL, MaxReal32Pat);
  724. MinReal64 := Compound(MinReal64PatL, MinReal64PatH);
  725. MaxReal64 := Compound(MaxReal64PatL, MaxReal64PatH)
  726. END InitHost;
  727. BEGIN
  728. InitCrcTab;
  729. InitHost
  730. END DevCPM.