CPS.txt 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. MODULE LindevCPS;
  2. (* THIS IS TEXT COPY OF CPS.odc *)
  3. (* DO NOT EDIT *)
  4. (* SEE XXX BELOW *)
  5. IMPORT SYSTEM, Math, DevCPM := LindevCPM, DevCPT := LindevCPT;
  6. CONST
  7. MaxIdLen = 256;
  8. TYPE
  9. (*
  10. Name* = ARRAY MaxIdLen OF SHORTCHAR;
  11. String* = POINTER TO ARRAY OF SHORTCHAR;
  12. *)
  13. (* name, str, numtyp, intval, realval, realval are implicit results of Get *)
  14. VAR
  15. name*: DevCPT.Name;
  16. str*: DevCPT.String;
  17. lstr*: POINTER TO ARRAY OF CHAR;
  18. numtyp*: SHORTINT; (* 1 = char, 2 = integer, 4 = real, 5 = int64, 6 = real32, 7 = real64 *)
  19. intval*: INTEGER; (* integer value or string length (incl. 0X) *)
  20. realval*: REAL;
  21. CONST
  22. (* numtyp values *)
  23. char = 1; integer = 2; real = 4; int64 = 5; real32 = 6; real64 = 7;
  24. (*symbol values*)
  25. null = 0; times = 1; slash = 2; div = 3; mod = 4;
  26. and = 5; plus = 6; minus = 7; or = 8; eql = 9;
  27. neq = 10; lss = 11; leq = 12; gtr = 13; geq = 14;
  28. in = 15; is = 16; arrow = 17; dollar = 18; period = 19;
  29. comma = 20; colon = 21; upto = 22; rparen = 23; rbrak = 24;
  30. rbrace = 25; of = 26; then = 27; do = 28; to = 29;
  31. by = 30; not = 33;
  32. lparen = 40; lbrak = 41; lbrace = 42; becomes = 44;
  33. number = 45; nil = 46; string = 47; ident = 48; semicolon = 49;
  34. bar = 50; end = 51; else = 52; elsif = 53; until = 54;
  35. if = 55; case = 56; while = 57; repeat = 58; for = 59;
  36. loop = 60; with = 61; exit = 62; return = 63; array = 64;
  37. record = 65; pointer = 66; begin = 67; const = 68; type = 69;
  38. var = 70; out = 71; procedure = 72; close = 73; import = 74;
  39. module = 75; eof = 76;
  40. VAR
  41. ch: SHORTCHAR; (*current character*)
  42. PROCEDURE err(n: SHORTINT);
  43. BEGIN DevCPM.err(n)
  44. END err;
  45. PROCEDURE Str(VAR sym: BYTE);
  46. VAR i: SHORTINT; och: SHORTCHAR; lch: CHAR; long: BOOLEAN;
  47. s: ARRAY 256 OF CHAR; t: POINTER TO ARRAY OF CHAR;
  48. BEGIN i := 0; och := ch; long := FALSE;
  49. LOOP DevCPM.GetL(lch);
  50. IF lch = och THEN EXIT END ;
  51. IF (lch < " ") & (lch # 9X) THEN err(3); EXIT END;
  52. IF lch > 0FFX THEN long := TRUE END;
  53. IF i < LEN(s) - 1 THEN s[i] := lch
  54. ELSIF i = LEN(s) - 1 THEN s[i] := 0X; NEW(lstr, 2 * LEN(s)); lstr^ := s$; lstr[i] := lch
  55. ELSIF i < LEN(lstr^) - 1 THEN lstr[i] := lch
  56. ELSE t := lstr; t[i] := 0X; NEW(lstr, 2 * LEN(t^)); lstr^ := t^$; lstr[i] := lch
  57. END;
  58. INC(i)
  59. END ;
  60. IF i = 1 THEN sym := number; numtyp := 1; intval := ORD(s[0])
  61. ELSE
  62. sym := string; numtyp := 0; intval := i + 1; NEW(str, intval);
  63. IF long THEN
  64. IF i < LEN(s) THEN s[i] := 0X; NEW(lstr, intval); lstr^ := s$
  65. ELSE lstr[i] := 0X
  66. END;
  67. str^ := SHORT(lstr$)
  68. ELSE
  69. IF i < LEN(s) THEN s[i] := 0X; str^ := SHORT(s$);
  70. ELSE lstr[i] := 0X; str^ := SHORT(lstr$)
  71. END;
  72. lstr := NIL
  73. END
  74. END;
  75. DevCPM.Get(ch)
  76. END Str;
  77. PROCEDURE Identifier(VAR sym: BYTE);
  78. VAR i: SHORTINT;
  79. BEGIN i := 0;
  80. REPEAT
  81. name[i] := ch; INC(i); DevCPM.Get(ch)
  82. UNTIL (ch < "0")
  83. OR ("9" < ch) & (CAP(ch) < "A")
  84. OR ("Z" < CAP(ch)) & (ch # "_") & (ch < "À")
  85. OR (ch = "×")
  86. OR (ch = "÷")
  87. OR (i = MaxIdLen);
  88. IF i = MaxIdLen THEN err(240); DEC(i) END ;
  89. name[i] := 0X; sym := ident
  90. END Identifier;
  91. PROCEDURE Number;
  92. VAR i, j, m, n, d, e, a: INTEGER; f, g, x: REAL; expCh, tch: SHORTCHAR; neg: BOOLEAN; r: SHORTREAL;
  93. dig: ARRAY 30 OF SHORTCHAR; arr: ARRAY 2 OF INTEGER;
  94. PROCEDURE Ord(ch: SHORTCHAR; hex: BOOLEAN): SHORTINT;
  95. BEGIN (* ("0" <= ch) & (ch <= "9") OR ("A" <= ch) & (ch <= "F") *)
  96. IF ch <= "9" THEN RETURN SHORT(ORD(ch) - ORD("0"))
  97. ELSIF hex THEN RETURN SHORT(ORD(ch) - ORD("A") + 10)
  98. ELSE err(2); RETURN 0
  99. END
  100. END Ord;
  101. BEGIN (* ("0" <= ch) & (ch <= "9") *)
  102. i := 0; m := 0; n := 0; d := 0;
  103. LOOP (* read mantissa *)
  104. IF ("0" <= ch) & (ch <= "9") OR (d = 0) & ("A" <= ch) & (ch <= "F") THEN
  105. IF (m > 0) OR (ch # "0") THEN (* ignore leading zeros *)
  106. IF n < LEN(dig) THEN dig[n] := ch; INC(n) END;
  107. INC(m)
  108. END;
  109. DevCPM.Get(ch); INC(i)
  110. ELSIF ch = "." THEN DevCPM.Get(ch);
  111. IF ch = "." THEN (* ellipsis *) ch := 7FX; EXIT
  112. ELSIF d = 0 THEN (* i > 0 *) d := i
  113. ELSE err(2)
  114. END
  115. ELSE EXIT
  116. END
  117. END; (* 0 <= n <= m <= i, 0 <= d <= i *)
  118. IF d = 0 THEN (* integer *) realval := 0; numtyp := integer;
  119. IF n = m THEN intval := 0; i := 0;
  120. IF ch = "X" THEN (* character *) DevCPM.Get(ch); numtyp := char;
  121. IF n <= 4 THEN
  122. WHILE i < n DO intval := intval*10H + Ord(dig[i], TRUE); INC(i) END
  123. ELSE err(203)
  124. END
  125. ELSIF (ch = "H") OR (ch = "S") THEN (* hex 32bit *)
  126. tch := ch; DevCPM.Get(ch);
  127. IF (ch = "L") & (DevCPM.oberon IN DevCPM.options) THEN (* old syntax: hex 64bit *)
  128. DevCPM.searchpos := DevCPM.curpos - 2; DevCPM.Get(ch);
  129. IF n <= 16 THEN
  130. IF (n = 16) & (dig[0] > "7") THEN realval := -1 END;
  131. WHILE (i < n) & (i < 10) DO realval := realval * 10H + Ord(dig[i], TRUE); INC(i) END;
  132. WHILE i < n DO realval := realval * 10H; intval := intval * 10H + Ord(dig[i], TRUE); INC(i) END;
  133. numtyp := int64
  134. ELSE err(203)
  135. END
  136. ELSIF n <= 8 THEN
  137. IF (n = 8) & (dig[0] > "7") THEN (* prevent overflow *) intval := -1 END;
  138. WHILE i < n DO intval := intval*10H + Ord(dig[i], TRUE); INC(i) END;
  139. IF tch = "S" THEN (* 32 bit hex float *)
  140. r := SYSTEM.VAL(SHORTREAL, intval);
  141. realval := r; intval := 0; numtyp := real32
  142. END
  143. ELSE err(203)
  144. END
  145. ELSIF ch = "L" THEN (* hex 64bit *)
  146. DevCPM.searchpos := DevCPM.curpos - 1; DevCPM.Get(ch);
  147. IF n <= 16 THEN
  148. IF (n = 16) & (dig[0] > "7") THEN realval := -1 END;
  149. WHILE (i < n) & (i < 10) DO realval := realval * 10H + Ord(dig[i], TRUE); INC(i) END;
  150. WHILE i < n DO realval := realval * 10H; intval := intval * 10H + Ord(dig[i], TRUE); INC(i) END;
  151. numtyp := int64
  152. ELSE err(203)
  153. END
  154. ELSIF ch = "R" THEN (* hex float 64bit *)
  155. DevCPM.searchpos := DevCPM.curpos - 1; DevCPM.Get(ch);
  156. IF n <= 16 THEN
  157. a := 0; IF (n = 16) & (dig[0] > "7") THEN (* prevent overflow *) a := -1 END;
  158. WHILE i < n-8 DO a := a*10H + Ord(dig[i], TRUE); INC(i) END;
  159. IF DevCPM.LEHost THEN arr[1] := a ELSE arr[0] := a END;
  160. a := 0; IF (n >= 8) & (dig[i] > "7") THEN (* prevent overflow *) a := -1 END;
  161. WHILE i < n DO a := a*10H + Ord(dig[i], TRUE); INC(i) END;
  162. IF DevCPM.LEHost THEN arr[0] := a ELSE arr[1] := a END;
  163. realval := SYSTEM.VAL(REAL, arr);
  164. intval := 0; numtyp := real64
  165. ELSE err(203)
  166. END
  167. ELSE (* decimal *)
  168. WHILE i < n DO d := Ord(dig[i], FALSE); INC(i);
  169. a := (MAX(INTEGER) - d) DIV 10;
  170. IF intval > a THEN
  171. a := (intval - a + 65535) DIV 65536 * 65536;
  172. realval := realval + a; intval := intval - a
  173. END;
  174. realval := realval * 10; intval := intval * 10 + d
  175. END;
  176. IF realval = 0 THEN numtyp := integer
  177. ELSIF intval < 9223372036854775808.0E0 - realval THEN numtyp := int64 (* 2^63 *)
  178. ELSE intval := 0; err(203)
  179. END
  180. END
  181. ELSE err(203)
  182. END
  183. ELSE (* fraction *)
  184. f := 0; g := 0; e := 0; j := 0; expCh := "E";
  185. WHILE (j < 15) & (j < n) DO g := g * 10 + Ord(dig[j], FALSE); INC(j) END; (* !!! *)
  186. WHILE n > j DO (* 0 <= f < 1 *) DEC(n); f := (Ord(dig[n], FALSE) + f)/10 END;
  187. IF (ch = "E") OR (ch = "D") & (DevCPM.oberon IN DevCPM.options) THEN
  188. expCh := ch; DevCPM.searchpos := DevCPM.curpos - 1; DevCPM.Get(ch); neg := FALSE;
  189. IF ch = "-" THEN neg := TRUE; DevCPM.Get(ch)
  190. ELSIF ch = "+" THEN DevCPM.Get(ch)
  191. END;
  192. IF ("0" <= ch) & (ch <= "9") THEN
  193. REPEAT n := Ord(ch, FALSE); DevCPM.Get(ch);
  194. IF e <= (MAX(SHORTINT) - n) DIV 10 THEN e := SHORT(e*10 + n)
  195. ELSE err(203)
  196. END
  197. UNTIL (ch < "0") OR ("9" < ch);
  198. IF neg THEN e := -e END
  199. ELSE err(2)
  200. END
  201. END;
  202. DEC(e, i-d-m); (* decimal point shift *)
  203. IF e < -308 - 16 THEN
  204. realval := 0.0
  205. ELSIF e < -308 + 14 THEN
  206. realval := (f + g) / Math.IntPower(10, j-e-30) / 1.0E15 / 1.0E15
  207. ELSIF e < j THEN
  208. realval := (f + g) / Math.IntPower(10, j-e) (* Ten(j-e) *)
  209. ELSIF e <= 308 THEN
  210. realval := (f + g) * Math.IntPower(10, e-j) (* Ten(e-j) *)
  211. ELSIF e = 308 + 1 THEN
  212. realval := (f + g) * (Math.IntPower(10, e-j) / 16);
  213. IF realval <= DevCPM.MaxReal64 / 16 THEN realval := realval * 16
  214. ELSE err(203)
  215. END
  216. ELSE err(203)
  217. END;
  218. numtyp := real
  219. END
  220. END Number;
  221. PROCEDURE Get*(VAR sym: BYTE);
  222. VAR s: BYTE; old: INTEGER;
  223. PROCEDURE Comment; (* do not read after end of file *)
  224. BEGIN DevCPM.Get(ch);
  225. LOOP
  226. LOOP
  227. WHILE ch = "(" DO DevCPM.Get(ch);
  228. IF ch = "*" THEN Comment END
  229. END ;
  230. IF ch = "*" THEN DevCPM.Get(ch); EXIT END ;
  231. IF ch = DevCPM.Eot THEN EXIT END ;
  232. DevCPM.Get(ch)
  233. END ;
  234. IF ch = ")" THEN DevCPM.Get(ch); EXIT END ;
  235. IF ch = DevCPM.Eot THEN err(5); EXIT END
  236. END
  237. END Comment;
  238. BEGIN
  239. DevCPM.errpos := DevCPM.curpos-1;
  240. WHILE (ch <= " ") OR (ch = 0A0X) DO (*ignore control characters*)
  241. IF ch = DevCPM.Eot THEN sym := eof; RETURN
  242. ELSE DevCPM.Get(ch)
  243. END
  244. END ;
  245. DevCPM.startpos := DevCPM.curpos - 1;
  246. CASE ch OF (* ch > " " *)
  247. | 22X, 27X : Str(s)
  248. | "#" : s := neq; DevCPM.Get(ch)
  249. | "&" : s := and; DevCPM.Get(ch)
  250. | "(" : DevCPM.Get(ch);
  251. IF ch = "*" THEN Comment; old := DevCPM.errpos; Get(s); DevCPM.errpos := old;
  252. ELSE s := lparen
  253. END
  254. | ")" : s := rparen; DevCPM.Get(ch)
  255. | "*" : s := times; DevCPM.Get(ch)
  256. | "+" : s := plus; DevCPM.Get(ch)
  257. | "," : s := comma; DevCPM.Get(ch)
  258. | "-" : s := minus; DevCPM.Get(ch)
  259. | "." : DevCPM.Get(ch);
  260. IF ch = "." THEN DevCPM.Get(ch); s := upto ELSE s := period END
  261. | "/" : s := slash; DevCPM.Get(ch)
  262. | "0".."9": Number; s := number
  263. | ":" : DevCPM.Get(ch);
  264. IF ch = "=" THEN DevCPM.Get(ch); s := becomes ELSE s := colon END
  265. | ";" : s := semicolon; DevCPM.Get(ch)
  266. | "<" : DevCPM.Get(ch);
  267. IF ch = "=" THEN DevCPM.Get(ch); s := leq ELSE s := lss END
  268. | "=" : s := eql; DevCPM.Get(ch)
  269. | ">" : DevCPM.Get(ch);
  270. IF ch = "=" THEN DevCPM.Get(ch); s := geq ELSE s := gtr END
  271. | "A": Identifier(s); IF name = "ARRAY" THEN s := array END
  272. | "B": Identifier(s);
  273. IF name = "BEGIN" THEN s := begin
  274. ELSIF name = "BY" THEN s := by
  275. END
  276. | "C": Identifier(s);
  277. IF name = "CASE" THEN s := case
  278. ELSIF name = "CONST" THEN s := const
  279. ELSIF name = "CLOSE" THEN s := close
  280. END
  281. | "D": Identifier(s);
  282. IF name = "DO" THEN s := do
  283. ELSIF name = "DIV" THEN s := div
  284. END
  285. | "E": Identifier(s);
  286. IF name = "END" THEN s := end
  287. ELSIF name = "ELSE" THEN s := else
  288. ELSIF name = "ELSIF" THEN s := elsif
  289. ELSIF name = "EXIT" THEN s := exit
  290. END
  291. | "F": Identifier(s); IF name = "FOR" THEN s := for END
  292. | "I": Identifier(s);
  293. IF name = "IF" THEN s := if
  294. ELSIF name = "IN" THEN s := in
  295. ELSIF name = "IS" THEN s := is
  296. ELSIF name = "IMPORT" THEN s := import
  297. END
  298. | "L": Identifier(s); IF name = "LOOP" THEN s := loop END
  299. | "M": Identifier(s);
  300. IF name = "MOD" THEN s := mod
  301. ELSIF name = "MODULE" THEN s := module
  302. END
  303. | "N": Identifier(s); IF name = "NIL" THEN s := nil END
  304. | "O": Identifier(s);
  305. IF name = "OR" THEN s := or
  306. ELSIF name = "OF" THEN s := of
  307. ELSIF name = "OUT" THEN s := out
  308. END
  309. | "P": Identifier(s);
  310. IF name = "PROCEDURE" THEN s := procedure
  311. ELSIF name = "POINTER" THEN s := pointer
  312. END
  313. | "R": Identifier(s);
  314. IF name = "RECORD" THEN s := record
  315. ELSIF name = "REPEAT" THEN s := repeat
  316. ELSIF name = "RETURN" THEN s := return
  317. END
  318. | "T": Identifier(s);
  319. IF name = "THEN" THEN s := then
  320. ELSIF name = "TO" THEN s := to
  321. ELSIF name = "TYPE" THEN s := type
  322. END
  323. | "U": Identifier(s); IF name = "UNTIL" THEN s := until END
  324. | "V": Identifier(s); IF name = "VAR" THEN s := var END
  325. | "W": Identifier(s);
  326. IF name = "WHILE" THEN s := while
  327. ELSIF name = "WITH" THEN s := with
  328. END
  329. | "G".."H", "J", "K", "Q", "S", "X".."Z", "a".."z", "_" (* XXX *): Identifier(s)
  330. | "[" : s := lbrak; DevCPM.Get(ch)
  331. | "]" : s := rbrak; DevCPM.Get(ch)
  332. | "^" : s := arrow; DevCPM.Get(ch)
  333. | "$" : s := dollar; DevCPM.Get(ch)
  334. | "{" : s := lbrace; DevCPM.Get(ch);
  335. | "|" : s := bar; DevCPM.Get(ch)
  336. | "}" : s := rbrace; DevCPM.Get(ch)
  337. | "~" : s := not; DevCPM.Get(ch)
  338. | 7FX : s := upto; DevCPM.Get(ch)
  339. ELSE s := null; DevCPM.Get(ch)
  340. END ;
  341. sym := s
  342. END Get;
  343. PROCEDURE Init*;
  344. BEGIN ch := " "
  345. END Init;
  346. END LindevCPS.