Mappers.txt 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. MODULE TextMappers;
  2. (* THIS IS TEXT COPY OF BlackBox 1.6-rc6 Text/Mod/Mappers.odc *)
  3. (* DO NOT EDIT *)
  4. IMPORT Strings, Views, Dialog, TextModels;
  5. CONST
  6. (** Scanner.opts **)
  7. returnCtrlChars* = 1;
  8. returnQualIdents* = 2; returnViews* = 3;
  9. interpretBools* = 4; interpretSets* = 5;
  10. maskViews* = 6;
  11. (** Scanner.type **)
  12. char* = 1; string* = 3; int* = 4; real* = 5;
  13. bool* = 6; (** iff interpretBools IN opts **)
  14. set* = 7; (** iff interpretSets IN opts **)
  15. view* = 8; (** iff returnViews IN opts **)
  16. tab* = 9; line* = 10; para* = 11; (** iff returnCtrlChars IN opts **)
  17. lint* = 16;
  18. eot* = 30;
  19. invalid* = 31; (** last Scan hit lexically invalid sequence **)
  20. (** Formatter.WriteIntForm base **)
  21. charCode* = Strings.charCode; decimal* = Strings.decimal; hexadecimal* = Strings.hexadecimal;
  22. (** Formatter.WriteIntForm showBase **)
  23. hideBase* = Strings.hideBase; showBase* = Strings.showBase;
  24. VIEW = TextModels.viewcode;
  25. TAB = TextModels.tab; LINE = TextModels.line; PARA = TextModels.para;
  26. acceptUnderscores = TRUE;
  27. TYPE
  28. String* = ARRAY 256 OF CHAR;
  29. Scanner* = RECORD
  30. opts-: SET;
  31. rider-: TextModels.Reader; (** prefetch state for single character look-ahead **)
  32. type*: INTEGER;
  33. start*, lines*, paras*: INTEGER; (** update by Skip **)
  34. char*: CHAR; (** valid iff type = char **)
  35. int*: INTEGER; (** valid iff type = int **)
  36. base*: INTEGER; (** valid iff type IN {int, lint} **)
  37. lint*: LONGINT; (** valid iff type IN {int, lint} **)
  38. real*: REAL; (** valid iff type = real **)
  39. bool*: BOOLEAN; (** valid iff type = bool **)
  40. set*: SET; (** valid iff type = set **)
  41. len*: INTEGER; (** valid iff type IN {string, int, lint} **)
  42. string*: String; (** valid iff type IN {string, int, lint, bool, char} **)
  43. view*: Views.View; w*, h*: INTEGER (** valid iff type = view **)
  44. END;
  45. Formatter* = RECORD
  46. rider-: TextModels.Writer
  47. END;
  48. (** Scanner **)
  49. PROCEDURE ^ (VAR s: Scanner) SetPos* (pos: INTEGER), NEW;
  50. PROCEDURE ^ (VAR s: Scanner) SetOpts* (opts: SET), NEW;
  51. PROCEDURE ^ (VAR s: Scanner) Skip* (OUT ch: CHAR), NEW;
  52. PROCEDURE ^ (VAR s: Scanner) Scan*, NEW;
  53. PROCEDURE Get (VAR s: Scanner; OUT ch: CHAR);
  54. BEGIN
  55. s.rider.ReadChar(ch)
  56. END Get;
  57. PROCEDURE Real (VAR s: Scanner);
  58. VAR res: INTEGER; ch: CHAR;
  59. BEGIN
  60. s.type := real;
  61. s.string[s.len] := "."; INC(s.len); Get(s, ch);
  62. WHILE ("0" <= ch) & (ch <= "9") & (s.len < LEN(s.string) - 1) DO
  63. s.string[s.len] := ch; INC(s.len); Get(s, ch)
  64. END;
  65. IF (ch = "E") OR (ch = "D") THEN
  66. s.string[s.len] := ch; INC(s.len); Get(s, ch);
  67. IF (ch = "-") OR (ch = "+") THEN s.string[s.len] := ch; INC(s.len); Get(s,ch) END;
  68. WHILE ("0" <= ch) & (ch <= "9") & (s.len < LEN(s.string) - 1) DO
  69. s.string[s.len] := ch; INC(s.len); Get(s, ch)
  70. END
  71. END;
  72. s.string[s.len] := 0X;
  73. Strings.StringToReal(s.string, s.real, res);
  74. IF res # 0 THEN s.type := invalid END
  75. END Real;
  76. PROCEDURE Integer (VAR s: Scanner);
  77. VAR n, k, res: INTEGER; ch: CHAR; hex: BOOLEAN;
  78. BEGIN
  79. s.type := int; hex := FALSE; ch := s.rider.char;
  80. IF ch = "%" THEN
  81. s.string[s.len] := "%"; INC(s.len); Get(s, ch); n:= 0;
  82. IF ("0" <= ch) & (ch <= "9") THEN
  83. k := ORD(ch) - ORD("0");
  84. REPEAT
  85. n := 10*n + k; s.string[s.len] := ch; INC(s.len);
  86. Get(s, ch); k := ORD(ch) - ORD("0")
  87. UNTIL (ch < "0") OR (ch > "9") OR (n > (MAX(INTEGER) - k) DIV 10) OR (s.len = LEN(s.string));
  88. IF ("0" <= ch) & (ch <= "9") THEN s.type := invalid ELSE s.base := n END
  89. ELSE s.type := invalid
  90. END
  91. ELSIF (ch = "H") OR (ch = "X") THEN
  92. hex := TRUE; s.base := 16;
  93. s.string[s.len] := ch; INC(s.len); Get(s, ch)
  94. ELSE
  95. s.base := 10
  96. END;
  97. s.string[s.len] := 0X;
  98. IF s.type # invalid THEN
  99. Strings.StringToInt(s.string, s.int, res);
  100. IF res = 0 THEN s.type := int;
  101. IF hex THEN (* Strings.StringToLInt(s.string, s.lint, res); ASSERT(res = 0, 100); *)
  102. IF s.int < 0 THEN s.lint := s.int + (LONG(MAX(INTEGER)) + 1) * 2
  103. ELSE s.lint := s.int
  104. END
  105. ELSE s.lint := s.int
  106. END
  107. ELSIF res = 1 THEN (* INTEGER overflow *)
  108. Strings.StringToLInt(s.string, s.lint, res);
  109. IF res = 0 THEN s.type := lint ELSE s.type := invalid END
  110. ELSE (* syntax error *)
  111. s.type := invalid
  112. END
  113. END
  114. END Integer;
  115. PROCEDURE Number (VAR s: Scanner; neg: BOOLEAN);
  116. VAR m: INTEGER; ch: CHAR;
  117. BEGIN
  118. s.len := 0; m := 0; ch := s.rider.char;
  119. IF neg THEN s.string[s.len] := "-"; INC(s.len) END;
  120. REPEAT
  121. IF (m > 0) OR (ch # "0") THEN (* ignore leading zeroes *)
  122. s.string[s.len] := ch; INC(s.len); INC(m)
  123. END;
  124. Get(s, ch)
  125. UNTIL (ch < "0") OR (ch > "9") & (ch < "A") OR (ch > "F")
  126. OR (s.len = LEN(s.string) - 1) OR s.rider.eot;
  127. IF (s.len = 0) OR (s.len = 1) & (s.string[0] = "-") THEN (* compensate for ignoring leading zeroes *)
  128. s.string[s.len] := "0"; INC(s.len)
  129. END;
  130. s.string[s.len] := 0X;
  131. IF ch = "." THEN Real(s) ELSE Integer(s) END
  132. END Number;
  133. PROCEDURE Cardinal (VAR s: Scanner; OUT n: INTEGER);
  134. VAR k: INTEGER; ch: CHAR;
  135. BEGIN
  136. n := 0; s.Skip(ch);
  137. IF ("0" <= ch) & (ch <= "9") THEN
  138. k := ORD(ch) - ORD("0");
  139. REPEAT
  140. n := n * 10 + k;
  141. Get(s, ch); k := ORD(ch) - ORD("0")
  142. UNTIL (ch < "0") OR (ch > "9") OR (n > (MAX(INTEGER) - k) DIV 10);
  143. IF ("0" <= ch) & (ch <= "9") THEN s.type := invalid END
  144. ELSE s.type := invalid
  145. END
  146. END Cardinal;
  147. PROCEDURE Set (VAR s: Scanner);
  148. VAR n, m: INTEGER; ch: CHAR;
  149. BEGIN
  150. s.type := set; Get(s, ch); s.Skip(ch); s.set := {};
  151. WHILE ("0" <= ch) & (ch <= "9") & (s.type = set) DO
  152. Cardinal(s, n); s.Skip(ch);
  153. IF (MIN(SET) <= n) & (n <= MAX(SET)) THEN
  154. INCL(s.set, n);
  155. IF ch = "," THEN
  156. Get(s, ch); s.Skip(ch)
  157. ELSIF ch = "." THEN
  158. Get(s, ch);
  159. IF ch = "." THEN
  160. Get(s, ch); s.Skip(ch); Cardinal(s, m); s.Skip(ch);
  161. IF ch = "," THEN Get(s, ch); s.Skip(ch) END;
  162. IF (n <= m) & (m <= MAX(SET)) THEN
  163. WHILE m > n DO INCL(s.set, m); DEC(m) END
  164. ELSE s.type := invalid
  165. END
  166. ELSE s.type := invalid
  167. END
  168. END
  169. ELSE s.type := invalid
  170. END
  171. END;
  172. IF s.type = set THEN
  173. s.Skip(ch);
  174. IF ch = "}" THEN Get(s, ch) ELSE s.type := invalid END
  175. END
  176. END Set;
  177. PROCEDURE Boolean (VAR s: Scanner);
  178. VAR ch: CHAR;
  179. BEGIN
  180. s.type := bool; Get(s, ch);
  181. IF (ch = "T") OR (ch = "F") THEN
  182. s.Scan;
  183. IF (s.type = string) & (s.string = "TRUE") THEN s.type := bool; s.bool := TRUE
  184. ELSIF (s.type = string) & (s.string = "FALSE") THEN s.type := bool; s.bool := FALSE
  185. ELSE s.type := invalid
  186. END
  187. ELSE s.type := invalid
  188. END
  189. END Boolean;
  190. PROCEDURE Name (VAR s: Scanner);
  191. VAR max: INTEGER; ch: CHAR;
  192. BEGIN
  193. s.type := string; s.len := 0; ch := s.rider.char; max := LEN(s.string);
  194. REPEAT
  195. s.string[s.len] := ch; INC(s.len); Get(s, ch)
  196. UNTIL
  197. ~( ("0" <= ch) & (ch <= "9")
  198. OR ("A" <= CAP(ch)) & (CAP(ch) <= "Z")
  199. OR (0C0X <= ch) & (ch <= 0FFX) & (ch # 0D7X) & (ch # 0F7X)
  200. OR acceptUnderscores & (ch = "_"))
  201. OR (s.len = max);
  202. IF (returnQualIdents IN s.opts) & (ch = ".") & (s.len < max) THEN
  203. REPEAT
  204. s.string[s.len] := ch; INC(s.len); Get(s, ch)
  205. UNTIL
  206. ~( ("0" <= ch) & (ch <= "9")
  207. OR ("A" <= CAP(ch)) & (CAP(ch) <= "Z")
  208. OR (0C0X <= ch) & (ch <= 0FFX) & (ch # 0D7X) & (ch # 0F7X)
  209. OR acceptUnderscores & (ch = "_") )
  210. OR (s.len = max)
  211. END;
  212. IF s.len = max THEN DEC(s.len); s.type := invalid END; (* ident too long *)
  213. s.string[s.len] := 0X
  214. END Name;
  215. PROCEDURE DoubleQuotedString (VAR s: Scanner);
  216. VAR max, pos: INTEGER; ch: CHAR;
  217. BEGIN
  218. pos := s.rider.Pos();
  219. s.type := string; s.len := 0; max := LEN(s.string) - 1; Get(s, ch);
  220. WHILE (ch # '"') & (ch # 0X) & (s.len < max) DO
  221. s.string[s.len] := ch; INC(s.len);
  222. Get(s, ch)
  223. END;
  224. s.string[s.len] := 0X;
  225. IF ch = '"' THEN Get(s, ch)
  226. ELSE s.type := invalid; s.rider.SetPos(pos (* s.rider.Pos() - s.len - 1 *)); Get(s, ch)
  227. END
  228. END DoubleQuotedString;
  229. PROCEDURE SingleQuotedString (VAR s: Scanner);
  230. VAR max, pos: INTEGER; ch: CHAR;
  231. BEGIN
  232. pos := s.rider.Pos();
  233. s.type := string; s.len := 0; max := LEN(s.string) - 1; Get(s, ch);
  234. WHILE (ch # "'") & (ch # 0X) & (s.len < max) DO
  235. s.string[s.len] := ch; INC(s.len);
  236. Get(s, ch)
  237. END;
  238. s.string[s.len] := 0X;
  239. IF s.len = 1 THEN s.type := char; s.char := s.string[0] END;
  240. IF ch = "'" THEN Get(s, ch)
  241. ELSE s.type := invalid; s.rider.SetPos(pos (* s.rider.Pos() - s.len - 1 *)); Get(s, ch)
  242. END
  243. END SingleQuotedString;
  244. PROCEDURE Char (VAR s: Scanner);
  245. VAR ch: CHAR;
  246. BEGIN
  247. ch := s.rider.char;
  248. IF ch # 0X THEN
  249. s.type := char; s.char := ch; s.string[0] := ch; s.string[1] := 0X; Get(s, ch)
  250. ELSE s.type := invalid
  251. END
  252. END Char;
  253. PROCEDURE View (VAR s: Scanner);
  254. VAR ch: CHAR;
  255. BEGIN
  256. s.type := view; s.view := s.rider.view; s.w := s.rider.w; s.h := s.rider.h;
  257. IF maskViews IN s.opts THEN
  258. IF s.rider.char # TextModels.viewcode THEN
  259. s.type := char; s.char := s.rider.char; s.string[0] := s.char; s.string[1] := 0X
  260. END
  261. END;
  262. Get(s, ch)
  263. END View;
  264. PROCEDURE (VAR s: Scanner) ConnectTo* (text: TextModels.Model), NEW;
  265. BEGIN
  266. IF text # NIL THEN
  267. s.rider := text.NewReader(s.rider); s.SetPos(0); s.SetOpts({})
  268. ELSE
  269. s.rider := NIL
  270. END
  271. END ConnectTo;
  272. PROCEDURE (VAR s: Scanner) SetPos* (pos: INTEGER), NEW;
  273. BEGIN
  274. s.rider.SetPos(pos); s.start := pos;
  275. s.lines := 0; s.paras := 0; s.type := invalid
  276. END SetPos;
  277. PROCEDURE (VAR s: Scanner) SetOpts* (opts: SET), NEW;
  278. BEGIN
  279. s.opts := opts
  280. END SetOpts;
  281. PROCEDURE (VAR s: Scanner) Pos* (): INTEGER, NEW;
  282. BEGIN
  283. RETURN s.rider.Pos()
  284. END Pos;
  285. PROCEDURE (VAR s: Scanner) Skip* (OUT ch: CHAR), NEW;
  286. VAR c, v: BOOLEAN;
  287. BEGIN
  288. IF s.opts * {returnCtrlChars, returnViews} = {} THEN
  289. ch := s.rider.char;
  290. WHILE ((ch <= " ") OR (ch = TextModels.digitspace) OR (ch = TextModels.nbspace))
  291. & ~s.rider.eot DO
  292. IF ch = LINE THEN INC(s.lines)
  293. ELSIF ch = PARA THEN INC(s.paras)
  294. END;
  295. Get(s, ch)
  296. END
  297. ELSE
  298. c := returnCtrlChars IN s.opts;
  299. v := returnViews IN s.opts;
  300. ch := s.rider.char;
  301. WHILE ((ch <= " ") OR (ch = TextModels.digitspace) OR (ch = TextModels.nbspace))
  302. & ~s.rider.eot
  303. & (~c OR (ch # TAB) & (ch # LINE) & (ch # PARA))
  304. & (~v OR (ch # VIEW) OR (s.rider.view = NIL)) DO
  305. IF ch = LINE THEN INC(s.lines)
  306. ELSIF ch = PARA THEN INC(s.paras)
  307. END;
  308. Get(s, ch)
  309. END
  310. END;
  311. IF ~s.rider.eot THEN s.start := s.rider.Pos() - 1
  312. ELSE s.start := s.rider.Base().Length(); s.type := eot
  313. END
  314. END Skip;
  315. PROCEDURE (VAR s: Scanner) Scan*, NEW;
  316. VAR sign, neg: BOOLEAN; ch: CHAR;
  317. BEGIN
  318. s.Skip(ch);
  319. IF s.type # eot THEN
  320. neg := (ch = "-"); sign := neg OR (ch = "+");
  321. IF sign THEN s.char := ch; Get(s, ch) END;
  322. IF ("0" <= ch) & (ch <= "9") THEN Number(s, neg)
  323. ELSIF sign THEN s.type := char; (* return prefetched sign w/o trailing number *)
  324. s.string[0] := s.char; s.string[1] := 0X
  325. ELSE
  326. CASE ch OF
  327. | "A" .. "Z", "a" .. "z", 0C0X .. 0D6X, 0D8X .. 0F6X, 0F8X .. 0FFX: Name(s)
  328. | '"': DoubleQuotedString(s)
  329. | "'": SingleQuotedString(s)
  330. | TAB: s.type := tab; Get(s, ch)
  331. | LINE: s.type := line; Get(s, ch)
  332. | PARA: s.type := para; Get(s, ch)
  333. | VIEW:
  334. IF s.rider.view # NIL THEN View(s) ELSE Char(s) END
  335. | "{":
  336. IF interpretSets IN s.opts THEN Set(s) ELSE Char(s) END
  337. | "$":
  338. IF interpretBools IN s.opts THEN Boolean(s) ELSE Char(s) END
  339. | "_":
  340. IF acceptUnderscores THEN Name(s) ELSE Char(s) END
  341. ELSE Char(s)
  342. END
  343. END
  344. END
  345. END Scan;
  346. (** scanning utilities **)
  347. PROCEDURE IsQualIdent* (IN s: ARRAY OF CHAR): BOOLEAN;
  348. VAR i: INTEGER; ch: CHAR;
  349. BEGIN
  350. ch := s[0]; i := 1;
  351. IF ("A" <= CAP(ch)) & (CAP(ch) <= "Z")
  352. OR (0C0X <= ch) & (ch <= 0FFX) & (ch # 0D0X) & (ch # 0D7X) & (ch # 0F7X) THEN
  353. REPEAT
  354. ch := s[i]; INC(i)
  355. UNTIL
  356. ~( ("0" <= ch) & (ch <= "9")
  357. OR ("A" <= CAP(ch)) & (CAP(ch) <= "Z")
  358. OR (0C0X <= ch) & (ch <= 0FFX) & (ch # 0D0X) & (ch # 0D7X) & (ch # 0F7X)
  359. OR (ch = "_") );
  360. IF ch = "." THEN
  361. INC(i);
  362. REPEAT
  363. ch := s[i]; INC(i)
  364. UNTIL
  365. ~( ("0" <= ch) & (ch <= "9")
  366. OR ("A" <= CAP(ch)) & (CAP(ch) <= "Z")
  367. OR (0C0X <= ch) & (ch <= 0FFX) & (ch # 0D0X) & (ch # 0D7X) & (ch # 0F7X)
  368. OR (ch = "_") );
  369. RETURN ch = 0X
  370. ELSE
  371. RETURN FALSE
  372. END
  373. ELSE
  374. RETURN FALSE
  375. END
  376. END IsQualIdent;
  377. PROCEDURE ScanQualIdent* (VAR s: Scanner; OUT x: ARRAY OF CHAR; OUT done: BOOLEAN);
  378. VAR mod: String; i, j, len, start: INTEGER; ch: CHAR;
  379. BEGIN
  380. done := FALSE;
  381. IF s.type = string THEN
  382. IF IsQualIdent(s.string) THEN
  383. IF s.len < LEN(x) THEN
  384. x := s.string$; done := TRUE
  385. END
  386. ELSE
  387. mod := s.string; len := s.len; start := s.start;
  388. s.Scan;
  389. IF (s.type = char) & (s.char = ".") THEN
  390. s.Scan;
  391. IF (s.type = string) & (len + 1 + s.len < LEN(x)) THEN
  392. i := 0; ch := mod[0]; WHILE ch # 0X DO x[i] := ch; INC(i); ch := mod[i] END;
  393. x[i] := "."; INC(i);
  394. j := 0; ch := s.string[0];
  395. WHILE ch # 0X DO x[i] := ch; INC(i); INC(j); ch := s.string[j] END;
  396. x[i] := 0X; done := TRUE
  397. END
  398. END;
  399. IF ~done THEN s.SetPos(start); s.Scan() END
  400. END
  401. END
  402. END ScanQualIdent;
  403. (** Formatter **)
  404. PROCEDURE ^ (VAR f: Formatter) SetPos* (pos: INTEGER), NEW;
  405. PROCEDURE ^ (VAR f: Formatter) WriteIntForm* (x: LONGINT;
  406. base, minWidth: INTEGER; fillCh: CHAR; showBase: BOOLEAN), NEW;
  407. PROCEDURE ^ (VAR f: Formatter) WriteRealForm* (x: REAL;
  408. precision, minW, expW: INTEGER; fillCh: CHAR), NEW;
  409. PROCEDURE ^ (VAR f: Formatter) WriteViewForm* (v: Views.View; w, h: INTEGER), NEW;
  410. PROCEDURE (VAR f: Formatter) ConnectTo* (text: TextModels.Model), NEW;
  411. BEGIN
  412. IF text # NIL THEN
  413. f.rider := text.NewWriter(f.rider); f.SetPos(text.Length())
  414. ELSE
  415. f.rider := NIL
  416. END
  417. END ConnectTo;
  418. PROCEDURE (VAR f: Formatter) SetPos* (pos: INTEGER), NEW;
  419. BEGIN
  420. f.rider.SetPos(pos)
  421. END SetPos;
  422. PROCEDURE (VAR f: Formatter) Pos* (): INTEGER, NEW;
  423. BEGIN
  424. RETURN f.rider.Pos()
  425. END Pos;
  426. PROCEDURE (VAR f: Formatter) WriteChar* (x: CHAR), NEW;
  427. BEGIN
  428. IF (x >= " ") & (x # 7FX) THEN
  429. f.rider.WriteChar(x)
  430. ELSE
  431. f.rider.WriteChar(" ");
  432. f.WriteIntForm(ORD(x), charCode, 3, "0", showBase);
  433. f.rider.WriteChar(" ")
  434. END
  435. END WriteChar;
  436. PROCEDURE (VAR f: Formatter) WriteInt* (x: LONGINT), NEW;
  437. BEGIN
  438. f.WriteIntForm(x, decimal, 0, TextModels.digitspace, hideBase)
  439. END WriteInt;
  440. PROCEDURE (VAR f: Formatter) WriteSString* (x: ARRAY OF SHORTCHAR), NEW;
  441. VAR i: INTEGER;
  442. BEGIN
  443. i := 0; WHILE x[i] # 0X DO f.WriteChar(x[i]); INC(i) END
  444. END WriteSString;
  445. PROCEDURE (VAR f: Formatter) WriteString* (x: ARRAY OF CHAR), NEW;
  446. VAR i: INTEGER;
  447. BEGIN
  448. i := 0; WHILE x[i] # 0X DO f.WriteChar(x[i]); INC(i) END
  449. END WriteString;
  450. PROCEDURE (VAR f: Formatter) WriteReal* (x: REAL), NEW;
  451. VAR m: ARRAY 256 OF CHAR;
  452. BEGIN
  453. Strings.RealToString(x, m); f.WriteString(m)
  454. END WriteReal;
  455. PROCEDURE (VAR f: Formatter) WriteBool* (x: BOOLEAN), NEW;
  456. BEGIN
  457. IF x THEN f.WriteString("$TRUE") ELSE f.WriteString("$FALSE") END
  458. END WriteBool;
  459. PROCEDURE (VAR f: Formatter) WriteSet* (x: SET), NEW;
  460. VAR i: INTEGER;
  461. BEGIN
  462. f.WriteChar("{"); i := MIN(SET);
  463. WHILE x # {} DO
  464. IF i IN x THEN f.WriteInt(i); EXCL(x, i);
  465. IF (i + 2 <= MAX(SET)) & (i+1 IN x) & (i+2 IN x) THEN f.WriteString("..");
  466. x := x - {i+1, i+2}; INC(i, 3);
  467. WHILE (i <= MAX(SET)) & (i IN x) DO EXCL(x, i); INC(i) END;
  468. f.WriteInt(i-1)
  469. END;
  470. IF x # {} THEN f.WriteString(", ") END
  471. END;
  472. INC(i)
  473. END;
  474. f.WriteChar("}")
  475. END WriteSet;
  476. PROCEDURE (VAR f: Formatter) WriteTab*, NEW;
  477. BEGIN
  478. f.rider.WriteChar(TAB)
  479. END WriteTab;
  480. PROCEDURE (VAR f: Formatter) WriteLn*, NEW;
  481. BEGIN
  482. f.rider.WriteChar(LINE)
  483. END WriteLn;
  484. PROCEDURE (VAR f: Formatter) WritePara*, NEW;
  485. BEGIN
  486. f.rider.WriteChar(PARA)
  487. END WritePara;
  488. PROCEDURE (VAR f: Formatter) WriteView* (v: Views.View), NEW;
  489. BEGIN
  490. f.WriteViewForm(v, Views.undefined, Views.undefined)
  491. END WriteView;
  492. PROCEDURE (VAR f: Formatter) WriteIntForm* (x: LONGINT;
  493. base, minWidth: INTEGER; fillCh: CHAR; showBase: BOOLEAN
  494. ), NEW;
  495. VAR s: ARRAY 80 OF CHAR;
  496. BEGIN
  497. Strings.IntToStringForm(x, base, minWidth, fillCh, showBase, s);
  498. f.WriteString(s)
  499. END WriteIntForm;
  500. PROCEDURE (VAR f: Formatter) WriteRealForm* (x: REAL;
  501. precision, minW, expW: INTEGER; fillCh: CHAR
  502. ), NEW;
  503. VAR s: ARRAY 256 OF CHAR;
  504. BEGIN
  505. Strings.RealToStringForm(x, precision, minW, expW, fillCh, s); f.WriteString(s)
  506. END WriteRealForm;
  507. PROCEDURE (VAR f: Formatter) WriteViewForm* (v: Views.View; w, h: INTEGER), NEW;
  508. BEGIN
  509. f.rider.WriteView(v, w, h)
  510. END WriteViewForm;
  511. PROCEDURE (VAR f: Formatter) WriteParamMsg* (msg, p0, p1, p2: ARRAY OF CHAR), NEW;
  512. VAR s: ARRAY 256 OF CHAR; i: INTEGER; ch: CHAR;
  513. BEGIN
  514. Dialog.MapParamString(msg, p0, p1, p2, s);
  515. i := 0; ch := s[0];
  516. WHILE ch # 0X DO
  517. IF ch = LINE THEN f.WriteLn
  518. ELSIF ch = PARA THEN f.WritePara
  519. ELSIF ch = TAB THEN f.WriteTab
  520. ELSIF ch >= " " THEN f.WriteChar(ch)
  521. END;
  522. INC(i); ch := s[i]
  523. END
  524. END WriteParamMsg;
  525. PROCEDURE (VAR f: Formatter) WriteMsg* (msg: ARRAY OF CHAR), NEW;
  526. BEGIN
  527. f.WriteParamMsg(msg, "", "", "")
  528. END WriteMsg;
  529. END TextMappers.