Out.ob07 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. (*
  2. BSD 2-Clause License
  3. Copyright (c) 2016, 2018, 2020-2021 Anton Krotov
  4. All rights reserved.
  5. *)
  6. MODULE Out;
  7. IMPORT HOST, SYSTEM;
  8. PROCEDURE Char* (c: CHAR);
  9. BEGIN
  10. HOST.OutChar(c)
  11. END Char;
  12. PROCEDURE String* (s: ARRAY OF CHAR);
  13. VAR
  14. i, n: INTEGER;
  15. BEGIN
  16. n := LENGTH(s) - 1;
  17. FOR i := 0 TO n DO
  18. Char(s[i])
  19. END
  20. END String;
  21. PROCEDURE Int* (x, width: INTEGER);
  22. VAR
  23. i, a: INTEGER;
  24. str: ARRAY 21 OF CHAR;
  25. BEGIN
  26. IF x = ROR(1, 1) THEN
  27. str := "-9223372036854775808";
  28. DEC(width, 20)
  29. ELSE
  30. i := 0;
  31. IF x < 0 THEN
  32. x := -x;
  33. i := 1;
  34. str[0] := "-"
  35. END;
  36. a := x;
  37. REPEAT
  38. INC(i);
  39. a := a DIV 10
  40. UNTIL a = 0;
  41. str[i] := 0X;
  42. DEC(width, i);
  43. REPEAT
  44. DEC(i);
  45. str[i] := CHR(x MOD 10 + ORD("0"));
  46. x := x DIV 10
  47. UNTIL x = 0
  48. END;
  49. WHILE width > 0 DO
  50. Char(20X);
  51. DEC(width)
  52. END;
  53. String(str)
  54. END Int;
  55. PROCEDURE IsNan (x: REAL): BOOLEAN;
  56. CONST
  57. INF = LSR(ASR(ROR(1, 1), 10), 1);
  58. NINF = ASR(ASR(ROR(1, 1), 10), 1);
  59. VAR
  60. a: INTEGER;
  61. BEGIN
  62. SYSTEM.GET(SYSTEM.ADR(x), a)
  63. RETURN (a > INF) OR (a < 0) & (a > NINF)
  64. END IsNan;
  65. PROCEDURE Inf (x: REAL; width: INTEGER);
  66. VAR
  67. s: ARRAY 5 OF CHAR;
  68. BEGIN
  69. DEC(width, 4);
  70. IF IsNan(x) THEN
  71. s := " Nan"
  72. ELSIF x = SYSTEM.INF() THEN
  73. s := "+Inf"
  74. ELSIF x = -SYSTEM.INF() THEN
  75. s := "-Inf"
  76. END;
  77. WHILE width > 0 DO
  78. Char(20X);
  79. DEC(width)
  80. END;
  81. String(s)
  82. END Inf;
  83. PROCEDURE Ln*;
  84. BEGIN
  85. Char(0DX);
  86. Char(0AX)
  87. END Ln;
  88. PROCEDURE unpk10 (VAR x: REAL; VAR n: INTEGER);
  89. VAR
  90. a, b: REAL;
  91. BEGIN
  92. ASSERT(x > 0.0);
  93. n := 0;
  94. WHILE x < 1.0 DO
  95. x := x * 10.0;
  96. DEC(n)
  97. END;
  98. a := 10.0;
  99. b := 1.0;
  100. WHILE a <= x DO
  101. b := a;
  102. a := a * 10.0;
  103. INC(n)
  104. END;
  105. x := x / b
  106. END unpk10;
  107. PROCEDURE _Real (x: REAL; width: INTEGER);
  108. VAR
  109. n, k, p: INTEGER;
  110. BEGIN
  111. p := MIN(MAX(width - 8, 1), 15);
  112. width := width - p - 8;
  113. WHILE width > 0 DO
  114. Char(20X);
  115. DEC(width)
  116. END;
  117. IF x < 0.0 THEN
  118. Char("-");
  119. x := -x
  120. ELSE
  121. Char(20X)
  122. END;
  123. unpk10(x, n);
  124. k := FLOOR(x);
  125. Char(CHR(k + 30H));
  126. Char(".");
  127. WHILE p > 0 DO
  128. x := (x - FLT(k)) * 10.0;
  129. k := FLOOR(x);
  130. Char(CHR(k + 30H));
  131. DEC(p)
  132. END;
  133. Char("E");
  134. IF n >= 0 THEN
  135. Char("+")
  136. ELSE
  137. Char("-")
  138. END;
  139. n := ABS(n);
  140. Char(CHR(n DIV 100 + 30H)); n := n MOD 100;
  141. Char(CHR(n DIV 10 + 30H));
  142. Char(CHR(n MOD 10 + 30H))
  143. END _Real;
  144. PROCEDURE Real* (x: REAL; width: INTEGER);
  145. BEGIN
  146. IF IsNan(x) OR (ABS(x) = SYSTEM.INF()) THEN
  147. Inf(x, width)
  148. ELSIF x = 0.0 THEN
  149. WHILE width > 23 DO
  150. Char(20X);
  151. DEC(width)
  152. END;
  153. DEC(width, 9);
  154. String(" 0.0");
  155. WHILE width > 0 DO
  156. Char("0");
  157. DEC(width)
  158. END;
  159. String("E+000")
  160. ELSE
  161. _Real(x, width)
  162. END
  163. END Real;
  164. PROCEDURE _FixReal (x: REAL; width, p: INTEGER);
  165. VAR
  166. n, k: INTEGER;
  167. minus: BOOLEAN;
  168. BEGIN
  169. minus := x < 0.0;
  170. IF minus THEN
  171. x := -x
  172. END;
  173. unpk10(x, n);
  174. DEC(width, 3 + MAX(p, 0) + MAX(n, 0));
  175. WHILE width > 0 DO
  176. Char(20X);
  177. DEC(width)
  178. END;
  179. IF minus THEN
  180. Char("-")
  181. ELSE
  182. Char(20X)
  183. END;
  184. IF n < 0 THEN
  185. INC(n);
  186. Char("0");
  187. Char(".");
  188. WHILE (n < 0) & (p > 0) DO
  189. Char("0");
  190. INC(n);
  191. DEC(p)
  192. END
  193. ELSE
  194. WHILE n >= 0 DO
  195. k := FLOOR(x);
  196. Char(CHR(k + 30H));
  197. x := (x - FLT(k)) * 10.0;
  198. DEC(n)
  199. END;
  200. Char(".")
  201. END;
  202. WHILE p > 0 DO
  203. k := FLOOR(x);
  204. Char(CHR(k + 30H));
  205. x := (x - FLT(k)) * 10.0;
  206. DEC(p)
  207. END
  208. END _FixReal;
  209. PROCEDURE FixReal* (x: REAL; width, p: INTEGER);
  210. BEGIN
  211. IF IsNan(x) OR (ABS(x) = SYSTEM.INF()) THEN
  212. Inf(x, width)
  213. ELSIF x = 0.0 THEN
  214. DEC(width, 3 + MAX(p, 0));
  215. WHILE width > 0 DO
  216. Char(20X);
  217. DEC(width)
  218. END;
  219. String(" 0.");
  220. WHILE p > 0 DO
  221. Char("0");
  222. DEC(p)
  223. END
  224. ELSE
  225. _FixReal(x, width, p)
  226. END
  227. END FixReal;
  228. PROCEDURE Open*;
  229. END Open;
  230. END Out.