PascalS.mod 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. IMPLEMENTATION MODULE PascalS;
  2. (* Scanner generated by Coco/R - assuming ISO IO library will be available. *)
  3. IMPORT Storage, IOChan;
  4. CONST
  5. noSYMB = 62; (*error token code*)
  6. (* not only for errors but also for not finished states of scanner analysis *)
  7. eof = 32C (* MS-DOS Keyboard eof char *);
  8. EOF = 0C;
  9. EOL = 15C;
  10. CR = 15C;
  11. LF = 12C;
  12. Long0 = 0;
  13. Long1 = 1;
  14. BlkSize = 16384;
  15. TYPE
  16. BufBlock = ARRAY [0 .. BlkSize-1] OF CHAR;
  17. Buffer = ARRAY [0 .. 31] OF POINTER TO BufBlock;
  18. StartTable = ARRAY [0 .. 255] OF INTEGER;
  19. GetCH = PROCEDURE (INT32): CHAR;
  20. VAR
  21. lastCh,
  22. ch: CHAR; (*current input character*)
  23. curLine: INTEGER; (*current input line (may be higher than line)*)
  24. lineStart: INT32; (*start position of current line*)
  25. apx: INT32; (*length of appendix (CONTEXT phrase)*)
  26. oldEols: INTEGER; (*number of EOLs in a comment*)
  27. bp, bp0: INT32; (*current position in buf
  28. (bp0: position of current token)*)
  29. inputLen: INT32; (*source file size*)
  30. buf: Buffer; (*source buffer for low-level access*)
  31. start: StartTable; (*start state for every character*)
  32. CurrentCh: GetCH;
  33. PROCEDURE ORDL (n: INT32): CARDINAL;
  34. BEGIN
  35. RETURN VAL(CARDINAL, n)
  36. END ORDL;
  37. PROCEDURE Err (nr, line, col: INTEGER; pos: INT32);
  38. BEGIN
  39. INC(errors)
  40. END Err;
  41. PROCEDURE NextCh;
  42. (* Return global variable ch *)
  43. BEGIN
  44. lastCh := ch; INC(bp); ch := CurrentCh(bp);
  45. IF (ch = EOL) OR (ch = LF) AND (lastCh # EOL) THEN
  46. INC(curLine); lineStart := bp
  47. END
  48. END NextCh;
  49. PROCEDURE Comment (): BOOLEAN;
  50. VAR
  51. level, startLine: INTEGER;
  52. oldLineStart: INT32;
  53. BEGIN
  54. level := 1; startLine := curLine; oldLineStart := lineStart;
  55. IF (ch = "{") THEN
  56. NextCh;
  57. LOOP
  58. IF (ch = "}") THEN
  59. DEC(level); oldEols := curLine - startLine; NextCh;
  60. IF level = 0 THEN RETURN TRUE END;
  61. ELSIF ch = EOF THEN RETURN FALSE
  62. ELSE NextCh END;
  63. END; (* LOOP *)
  64. END;
  65. IF (ch = "(") THEN
  66. NextCh;
  67. IF (ch = "*") THEN
  68. NextCh;
  69. LOOP
  70. IF (ch = "*") THEN
  71. NextCh;
  72. IF (ch = ")") THEN
  73. DEC(level); NextCh;
  74. IF level = 0 THEN RETURN TRUE END
  75. END;
  76. ELSIF ch = EOF THEN RETURN FALSE
  77. ELSE NextCh END;
  78. END; (* LOOP *)
  79. ELSE
  80. IF (ch = CR) OR (ch = LF) THEN
  81. DEC(curLine); lineStart := oldLineStart
  82. END;
  83. DEC(bp); ch := lastCh;
  84. END;
  85. END;
  86. RETURN FALSE;
  87. END Comment;
  88. PROCEDURE Get (VAR sym: CARDINAL);
  89. VAR
  90. state: CARDINAL;
  91. PROCEDURE Equal (s: ARRAY OF CHAR): BOOLEAN;
  92. VAR
  93. i: CARDINAL;
  94. q: INT32;
  95. BEGIN
  96. IF nextLen # LENGTH(s) THEN RETURN FALSE END;
  97. i := 1; q := bp0; INC(q);
  98. WHILE i < nextLen DO
  99. IF CurrentCh(q) # s[i] THEN RETURN FALSE END;
  100. INC(i); INC(q)
  101. END;
  102. RETURN TRUE
  103. END Equal;
  104. PROCEDURE CheckLiteral;
  105. BEGIN
  106. CASE CurrentCh(bp0) OF
  107. "A": IF Equal("AND") THEN sym := 59;
  108. ELSIF Equal("ARRAY") THEN sym := 20;
  109. END
  110. | "B": IF Equal("BEGIN") THEN sym := 34;
  111. END
  112. | "C": IF Equal("CASE") THEN sym := 29;
  113. ELSIF Equal("CONST") THEN sym := 12;
  114. END
  115. | "D": IF Equal("DIV") THEN sym := 57;
  116. ELSIF Equal("DO") THEN sym := 38;
  117. ELSIF Equal("DOWNTO") THEN sym := 46;
  118. END
  119. | "E": IF Equal("ELSE") THEN sym := 43;
  120. ELSIF Equal("END") THEN sym := 25;
  121. END
  122. | "F": IF Equal("FILE") THEN sym := 27;
  123. ELSIF Equal("FOR") THEN sym := 44;
  124. ELSIF Equal("FORWARD") THEN sym := 33;
  125. ELSIF Equal("FUNCTION") THEN sym := 32;
  126. END
  127. | "G": IF Equal("GOTO") THEN sym := 36;
  128. END
  129. | "I": IF Equal("IF") THEN sym := 41;
  130. ELSIF Equal("IN") THEN sym := 53;
  131. END
  132. | "L": IF Equal("LABEL") THEN sym := 10;
  133. END
  134. | "M": IF Equal("MOD") THEN sym := 58;
  135. END
  136. | "N": IF Equal("NIL") THEN sym := 61;
  137. ELSIF Equal("NOT") THEN sym := 60;
  138. END
  139. | "O": IF Equal("OF") THEN sym := 23;
  140. ELSIF Equal("OR") THEN sym := 54;
  141. END
  142. | "P": IF Equal("PACKED") THEN sym := 17;
  143. ELSIF Equal("PROCEDURE") THEN sym := 31;
  144. ELSIF Equal("PROGRAM") THEN sym := 5;
  145. END
  146. | "R": IF Equal("RECORD") THEN sym := 24;
  147. ELSIF Equal("REPEAT") THEN sym := 39;
  148. END
  149. | "S": IF Equal("SET") THEN sym := 26;
  150. END
  151. | "T": IF Equal("THEN") THEN sym := 42;
  152. ELSIF Equal("TO") THEN sym := 45;
  153. ELSIF Equal("TYPE") THEN sym := 16;
  154. END
  155. | "U": IF Equal("UNTIL") THEN sym := 40;
  156. END
  157. | "V": IF Equal("VAR") THEN sym := 30;
  158. END
  159. | "W": IF Equal("WHILE") THEN sym := 37;
  160. ELSIF Equal("WITH") THEN sym := 47;
  161. END
  162. ELSE
  163. END
  164. END CheckLiteral;
  165. BEGIN (*Get*)
  166. WHILE (ch = ' ') OR
  167. ((ch >= CHR(9)) & (ch <= CHR(13))) DO NextCh END;
  168. IF ((ch = "{") OR (ch = "(")) & Comment() THEN Get(sym); RETURN END;
  169. pos := nextPos; nextPos := bp;
  170. col := nextCol; nextCol := VAL(INTEGER, bp - lineStart);
  171. line := nextLine; nextLine := curLine;
  172. len := nextLen; nextLen := 0;
  173. apx := 0; state := start[ORD(ch)]; bp0 := bp;
  174. LOOP
  175. NextCh; INC(nextLen);
  176. CASE state OF
  177. 1: IF ((ch >= "0") & (ch <= "9") OR
  178. (ch >= "A") & (ch <= "Z")) THEN
  179. ELSE sym := 1; CheckLiteral; RETURN
  180. END;
  181. | 2: bp := bp - apx - Long1; DEC(nextLen, ORDL(apx)); NextCh; sym := 2; RETURN
  182. | 3: IF ((ch >= "0") & (ch <= "9")) THEN
  183. ELSIF (ch = "E") THEN state := 4;
  184. ELSE sym := 3; RETURN
  185. END;
  186. | 4: IF ((ch >= "0") & (ch <= "9")) THEN state := 6;
  187. ELSIF ((ch = "+") OR
  188. (ch = "-")) THEN state := 5;
  189. ELSE sym := noSYMB; RETURN
  190. END;
  191. | 5: IF ((ch >= "0") & (ch <= "9")) THEN state := 6;
  192. ELSE sym := noSYMB; RETURN
  193. END;
  194. | 6: IF ((ch >= "0") & (ch <= "9")) THEN
  195. ELSE sym := 3; RETURN
  196. END;
  197. | 7: IF ((ch >= "0") & (ch <= "9")) THEN state := 9;
  198. ELSIF ((ch = "+") OR
  199. (ch = "-")) THEN state := 8;
  200. ELSE sym := noSYMB; RETURN
  201. END;
  202. | 8: IF ((ch >= "0") & (ch <= "9")) THEN state := 9;
  203. ELSE sym := noSYMB; RETURN
  204. END;
  205. | 9: IF ((ch >= "0") & (ch <= "9")) THEN
  206. ELSE sym := 3; RETURN
  207. END;
  208. | 10: IF ((ch <= CHR(12)) OR
  209. (ch >= CHR(14)) & (ch <= "&") OR
  210. (ch >= "(")) THEN
  211. ELSIF (ch = "'") THEN state := 12;
  212. ELSE sym := noSYMB; RETURN
  213. END;
  214. | 11: IF ((ch >= "0") & (ch <= "9")) THEN
  215. ELSIF (ch = ".") THEN state := 13; INC(apx)
  216. ELSIF (ch = "E") THEN state := 7;
  217. ELSE sym := 2; RETURN
  218. END;
  219. | 12: IF (ch = "'") THEN state := 10;
  220. ELSE sym := 4; RETURN
  221. END;
  222. | 13: IF ((ch >= "0") & (ch <= "9")) THEN state := 3; apx := Long0
  223. ELSIF (ch = ".") THEN state := 2; INC(apx)
  224. ELSE sym := noSYMB; RETURN
  225. END;
  226. | 14: sym := 6; RETURN
  227. | 15: IF (ch = ".") THEN state := 23;
  228. ELSE sym := 7; RETURN
  229. END;
  230. | 16: sym := 8; RETURN
  231. | 17: sym := 9; RETURN
  232. | 18: sym := 11; RETURN
  233. | 19: sym := 13; RETURN
  234. | 20: sym := 14; RETURN
  235. | 21: sym := 15; RETURN
  236. | 22: sym := 18; RETURN
  237. | 23: sym := 19; RETURN
  238. | 24: sym := 21; RETURN
  239. | 25: sym := 22; RETURN
  240. | 26: IF (ch = "=") THEN state := 27;
  241. ELSE sym := 28; RETURN
  242. END;
  243. | 27: sym := 35; RETURN
  244. | 28: IF (ch = "=") THEN state := 30;
  245. ELSIF (ch = ">") THEN state := 32;
  246. ELSE sym := 48; RETURN
  247. END;
  248. | 29: IF (ch = "=") THEN state := 31;
  249. ELSE sym := 49; RETURN
  250. END;
  251. | 30: sym := 50; RETURN
  252. | 31: sym := 51; RETURN
  253. | 32: sym := 52; RETURN
  254. | 33: sym := 55; RETURN
  255. | 34: sym := 56; RETURN
  256. | 35: sym := 0; ch := 0C; DEC(bp); RETURN
  257. ELSE sym := noSYMB; RETURN (*NextCh already done*)
  258. END
  259. END
  260. END Get;
  261. PROCEDURE GetString (pos: INT32; len: CARDINAL; VAR s: ARRAY OF CHAR);
  262. VAR
  263. i: CARDINAL;
  264. p: INT32;
  265. BEGIN
  266. IF len > HIGH(s) THEN len := HIGH(s) END;
  267. p := pos; i := 0;
  268. WHILE i < len DO
  269. s[i] := CharAt(p); INC(i); INC(p)
  270. END;
  271. s[len] := 0C;
  272. END GetString;
  273. PROCEDURE GetName (pos: INT32; len: CARDINAL; VAR s: ARRAY OF CHAR);
  274. VAR
  275. i: CARDINAL;
  276. p: INT32;
  277. BEGIN
  278. IF len > HIGH(s) THEN len := HIGH(s) END;
  279. p := pos; i := 0;
  280. WHILE i < len DO
  281. s[i] := CurrentCh(p); INC(i); INC(p)
  282. END;
  283. s[len] := 0C;
  284. END GetName;
  285. PROCEDURE CharAt (pos: INT32): CHAR;
  286. VAR
  287. ch: CHAR;
  288. BEGIN
  289. IF pos >= inputLen THEN RETURN EOF END;
  290. ch := buf[ORD(pos DIV BlkSize)]^[ORD(pos MOD BlkSize)];
  291. IF ch # eof THEN RETURN ch ELSE RETURN EOF END
  292. END CharAt;
  293. PROCEDURE CapChAt (pos: INT32): CHAR;
  294. VAR
  295. ch: CHAR;
  296. BEGIN
  297. IF pos >= inputLen THEN RETURN EOF END;
  298. ch := CAP(buf[ORD(pos DIV BlkSize)]^[ORD(pos MOD BlkSize)]);
  299. IF ch # eof THEN RETURN ch ELSE RETURN EOF END
  300. END CapChAt;
  301. PROCEDURE Reset;
  302. VAR
  303. i, read: CARDINAL;
  304. BEGIN (*assert: src has been opened*)
  305. i := 0; inputLen := 0;
  306. REPEAT
  307. Storage.ALLOCATE(buf[i], BlkSize);
  308. IOChan.RawRead(src, buf[i], BlkSize, read);
  309. INC(i); INC(inputLen, VAL(INT32, read))
  310. UNTIL read # BlkSize;
  311. buf[i-1]^[read] := EOF;
  312. curLine := 1; lineStart := -2; bp := -1;
  313. oldEols := 0; apx := 0; errors := 0;
  314. NextCh;
  315. END Reset;
  316. BEGIN
  317. CurrentCh := CapChAt;
  318. start[ 0] := 35; start[ 1] := 36; start[ 2] := 36; start[ 3] := 36;
  319. start[ 4] := 36; start[ 5] := 36; start[ 6] := 36; start[ 7] := 36;
  320. start[ 8] := 36; start[ 9] := 36; start[ 10] := 36; start[ 11] := 36;
  321. start[ 12] := 36; start[ 13] := 36; start[ 14] := 36; start[ 15] := 36;
  322. start[ 16] := 36; start[ 17] := 36; start[ 18] := 36; start[ 19] := 36;
  323. start[ 20] := 36; start[ 21] := 36; start[ 22] := 36; start[ 23] := 36;
  324. start[ 24] := 36; start[ 25] := 36; start[ 26] := 36; start[ 27] := 36;
  325. start[ 28] := 36; start[ 29] := 36; start[ 30] := 36; start[ 31] := 36;
  326. start[ 32] := 36; start[ 33] := 36; start[ 34] := 36; start[ 35] := 36;
  327. start[ 36] := 36; start[ 37] := 36; start[ 38] := 36; start[ 39] := 10;
  328. start[ 40] := 16; start[ 41] := 17; start[ 42] := 33; start[ 43] := 20;
  329. start[ 44] := 18; start[ 45] := 21; start[ 46] := 15; start[ 47] := 34;
  330. start[ 48] := 11; start[ 49] := 11; start[ 50] := 11; start[ 51] := 11;
  331. start[ 52] := 11; start[ 53] := 11; start[ 54] := 11; start[ 55] := 11;
  332. start[ 56] := 11; start[ 57] := 11; start[ 58] := 26; start[ 59] := 14;
  333. start[ 60] := 28; start[ 61] := 19; start[ 62] := 29; start[ 63] := 36;
  334. start[ 64] := 36; start[ 65] := 1; start[ 66] := 1; start[ 67] := 1;
  335. start[ 68] := 1; start[ 69] := 1; start[ 70] := 1; start[ 71] := 1;
  336. start[ 72] := 1; start[ 73] := 1; start[ 74] := 1; start[ 75] := 1;
  337. start[ 76] := 1; start[ 77] := 1; start[ 78] := 1; start[ 79] := 1;
  338. start[ 80] := 1; start[ 81] := 1; start[ 82] := 1; start[ 83] := 1;
  339. start[ 84] := 1; start[ 85] := 1; start[ 86] := 1; start[ 87] := 1;
  340. start[ 88] := 1; start[ 89] := 1; start[ 90] := 1; start[ 91] := 24;
  341. start[ 92] := 36; start[ 93] := 25; start[ 94] := 22; start[ 95] := 36;
  342. start[ 96] := 36; start[ 97] := 36; start[ 98] := 36; start[ 99] := 36;
  343. start[100] := 36; start[101] := 36; start[102] := 36; start[103] := 36;
  344. start[104] := 36; start[105] := 36; start[106] := 36; start[107] := 36;
  345. start[108] := 36; start[109] := 36; start[110] := 36; start[111] := 36;
  346. start[112] := 36; start[113] := 36; start[114] := 36; start[115] := 36;
  347. start[116] := 36; start[117] := 36; start[118] := 36; start[119] := 36;
  348. start[120] := 36; start[121] := 36; start[122] := 36; start[123] := 36;
  349. start[124] := 36; start[125] := 36; start[126] := 36; start[127] := 36;
  350. start[128] := 36; start[129] := 36; start[130] := 36; start[131] := 36;
  351. start[132] := 36; start[133] := 36; start[134] := 36; start[135] := 36;
  352. start[136] := 36; start[137] := 36; start[138] := 36; start[139] := 36;
  353. start[140] := 36; start[141] := 36; start[142] := 36; start[143] := 36;
  354. start[144] := 36; start[145] := 36; start[146] := 36; start[147] := 36;
  355. start[148] := 36; start[149] := 36; start[150] := 36; start[151] := 36;
  356. start[152] := 36; start[153] := 36; start[154] := 36; start[155] := 36;
  357. start[156] := 36; start[157] := 36; start[158] := 36; start[159] := 36;
  358. start[160] := 36; start[161] := 36; start[162] := 36; start[163] := 36;
  359. start[164] := 36; start[165] := 36; start[166] := 36; start[167] := 36;
  360. start[168] := 36; start[169] := 36; start[170] := 36; start[171] := 36;
  361. start[172] := 36; start[173] := 36; start[174] := 36; start[175] := 36;
  362. start[176] := 36; start[177] := 36; start[178] := 36; start[179] := 36;
  363. start[180] := 36; start[181] := 36; start[182] := 36; start[183] := 36;
  364. start[184] := 36; start[185] := 36; start[186] := 36; start[187] := 36;
  365. start[188] := 36; start[189] := 36; start[190] := 36; start[191] := 36;
  366. start[192] := 36; start[193] := 36; start[194] := 36; start[195] := 36;
  367. start[196] := 36; start[197] := 36; start[198] := 36; start[199] := 36;
  368. start[200] := 36; start[201] := 36; start[202] := 36; start[203] := 36;
  369. start[204] := 36; start[205] := 36; start[206] := 36; start[207] := 36;
  370. start[208] := 36; start[209] := 36; start[210] := 36; start[211] := 36;
  371. start[212] := 36; start[213] := 36; start[214] := 36; start[215] := 36;
  372. start[216] := 36; start[217] := 36; start[218] := 36; start[219] := 36;
  373. start[220] := 36; start[221] := 36; start[222] := 36; start[223] := 36;
  374. start[224] := 36; start[225] := 36; start[226] := 36; start[227] := 36;
  375. start[228] := 36; start[229] := 36; start[230] := 36; start[231] := 36;
  376. start[232] := 36; start[233] := 36; start[234] := 36; start[235] := 36;
  377. start[236] := 36; start[237] := 36; start[238] := 36; start[239] := 36;
  378. start[240] := 36; start[241] := 36; start[242] := 36; start[243] := 36;
  379. start[244] := 36; start[245] := 36; start[246] := 36; start[247] := 36;
  380. start[248] := 36; start[249] := 36; start[250] := 36; start[251] := 36;
  381. start[252] := 36; start[253] := 36; start[254] := 36; start[255] := 36;
  382. Error := Err; lastCh := EOF;
  383. END PascalS.