CompileTest.mod 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. MODULE CompileTest ;
  2. (* Direct test harness for the TP3 compiler.
  3. Reads fixture paths from stdin, one per line, loads each into TextBuf
  4. exactly the way the shell's LoadWorkFile does, then calls Compiler.Compile
  5. and prints a one-line verdict plus a source excerpt with a caret under the
  6. error position.
  7. This is the fast loop for compiler work: no pty, no editor, no screen
  8. redraws - just Compile's own errNo / errPos, which is what actually
  9. matters. (The pty harness in matrix.py covers the shell/editor UI.)
  10. Usage: printf 'a.pas\nb.pas\n' | ./compiletest *)
  11. FROM Posix IMPORT read, write, open, close ;
  12. FROM TextBuf IMPORT TextLimit, Clear, Length, CharAt, InsertCh ;
  13. FROM Compiler IMPORT Compile, CodeBytes, DataBytes, CodeByteAt ;
  14. FROM SYSTEM IMPORT ADR, BYTE ;
  15. CONST
  16. STDIN = 0 ;
  17. STDOUT = 1 ;
  18. O_RDONLY = 0 ;
  19. VAR
  20. lineBuf : ARRAY [0..255] OF CHAR ;
  21. pathCopy : ARRAY [0..511] OF CHAR ;
  22. txt : ARRAY [0..79] OF CHAR ;
  23. mark : ARRAY [0..79] OF CHAR ;
  24. PROCEDURE PutCh (ch : CHAR) ;
  25. VAR n : LONGINT ;
  26. BEGIN
  27. n := write (STDOUT, ADR (ch), 1)
  28. END PutCh ;
  29. PROCEDURE PutStr (s : ARRAY OF CHAR) ;
  30. VAR i : CARDINAL ; n : LONGINT ;
  31. BEGIN
  32. i := 0 ;
  33. WHILE (i <= HIGH (s)) AND (s [i] # 0C) DO
  34. n := write (STDOUT, ADR (s [i]), 1) ;
  35. INC (i)
  36. END
  37. END PutStr ;
  38. PROCEDURE PutCard (n : CARDINAL) ;
  39. VAR dig : ARRAY [0..9] OF CHAR ; i : CARDINAL ;
  40. BEGIN
  41. IF n = 0 THEN
  42. PutCh ("0")
  43. ELSE
  44. i := 0 ;
  45. WHILE n > 0 DO
  46. dig [i] := CHR (ORD ("0") + (n MOD 10)) ;
  47. n := n DIV 10 ;
  48. INC (i)
  49. END ;
  50. WHILE i > 0 DO
  51. DEC (i) ;
  52. PutCh (dig [i])
  53. END
  54. END
  55. END PutCard ;
  56. PROCEDURE NL ;
  57. BEGIN
  58. PutCh (CHR (13)) ;
  59. PutCh (CHR (10))
  60. END NL ;
  61. PROCEDURE StrCopy (VAR dst : ARRAY OF CHAR ; src : ARRAY OF CHAR) ;
  62. VAR i : CARDINAL ;
  63. BEGIN
  64. i := 0 ;
  65. WHILE (i <= HIGH (dst)) AND (i <= HIGH (src)) AND (src [i] # 0C) DO
  66. dst [i] := src [i] ;
  67. INC (i)
  68. END ;
  69. IF i <= HIGH (dst) THEN
  70. dst [i] := 0C
  71. END
  72. END StrCopy ;
  73. PROCEDURE ReadLineStr (VAR s : ARRAY OF CHAR) : BOOLEAN ;
  74. (* one line from stdin; FALSE at EOF/blank line *)
  75. VAR ch : CHAR ; n : LONGINT ; i : CARDINAL ;
  76. BEGIN
  77. i := 0 ;
  78. s [0] := 0C ;
  79. LOOP
  80. n := read (STDIN, ADR (ch), 1) ;
  81. IF n # 1 THEN
  82. IF i = 0 THEN
  83. RETURN FALSE
  84. END ;
  85. s [i] := 0C ;
  86. RETURN TRUE
  87. END ;
  88. IF (ch = CHR (10)) OR (ch = CHR (13)) THEN
  89. IF i = 0 THEN
  90. RETURN FALSE
  91. END ;
  92. s [i] := 0C ;
  93. RETURN TRUE
  94. END ;
  95. IF i < HIGH (s) THEN
  96. s [i] := ch ;
  97. INC (i)
  98. END
  99. END
  100. END ReadLineStr ;
  101. PROCEDURE LoadFile (p : ARRAY OF CHAR) : BOOLEAN ;
  102. (* same CR/LF normalisation as the shell's LoadWorkFile *)
  103. VAR fd : INTEGER ; k : LONGINT ; b : BYTE ; prevCR : BOOLEAN ;
  104. BEGIN
  105. fd := open (ADR (p), O_RDONLY, 0) ;
  106. IF fd < 0 THEN
  107. RETURN FALSE
  108. END ;
  109. Clear ;
  110. prevCR := FALSE ;
  111. LOOP
  112. IF Length () >= TextLimit THEN
  113. EXIT
  114. END ;
  115. k := read (fd, ADR (b), 1) ;
  116. IF k # 1 THEN
  117. EXIT
  118. END ;
  119. IF b = 26 THEN
  120. EXIT (* ^Z ends the text *)
  121. ELSIF b = 10 THEN
  122. IF NOT prevCR THEN
  123. InsertCh (Length (), CHR (13)) (* lone LF -> CR *)
  124. END ;
  125. prevCR := FALSE
  126. ELSIF b = 13 THEN
  127. InsertCh (Length (), CHR (13)) ;
  128. prevCR := TRUE
  129. ELSE
  130. InsertCh (Length (), CHR (ORD (b))) ;
  131. prevCR := FALSE
  132. END
  133. END ;
  134. k := close (fd) ;
  135. RETURN TRUE
  136. END LoadFile ;
  137. PROCEDURE ShowAt (pos : CARDINAL) ;
  138. (* print the source around pos, with '^' under pos *)
  139. VAR s, e, i : CARDINAL ;
  140. BEGIN
  141. IF pos > 40 THEN
  142. s := pos - 40
  143. ELSE
  144. s := 0
  145. END ;
  146. e := pos + 30 ;
  147. IF e > Length () THEN
  148. e := Length ()
  149. END ;
  150. IF e > s + 78 THEN
  151. e := s + 78
  152. END ;
  153. i := 0 ;
  154. WHILE s + i < e DO
  155. txt [i] := CharAt (s + i) ;
  156. IF txt [i] = CHR (13) THEN
  157. txt [i] := " "
  158. END ;
  159. IF s + i = pos THEN
  160. mark [i] := "^"
  161. ELSE
  162. mark [i] := "-"
  163. END ;
  164. INC (i)
  165. END ;
  166. txt [i] := 0C ;
  167. mark [i] := 0C ;
  168. PutStr (" " ) ;
  169. PutStr (txt) ;
  170. NL ;
  171. PutStr (" " ) ;
  172. PutStr (mark) ;
  173. NL
  174. END ShowAt ;
  175. VAR
  176. errNo, errPos : CARDINAL ;
  177. ok : BOOLEAN ;
  178. dump : BOOLEAN ;
  179. PROCEDURE Hex (b : BYTE ; VAR out : ARRAY OF CHAR) ;
  180. (* ISO will not index a plain string constant as an array, so compute the
  181. two nibbles instead of using a "0123456789ABCDEF" lookup. *)
  182. VAR d : CARDINAL ;
  183. BEGIN
  184. d := VAL (CARDINAL, b) DIV 16 ; (* BYTE arith yields BYTE *)
  185. IF d < 10 THEN
  186. out [0] := CHR (ORD ("0") + d)
  187. ELSE
  188. out [0] := CHR (ORD ("A") + d - 10)
  189. END ;
  190. d := VAL (CARDINAL, b) MOD 16 ;
  191. IF d < 10 THEN
  192. out [1] := CHR (ORD ("0") + d)
  193. ELSE
  194. out [1] := CHR (ORD ("A") + d - 10)
  195. END
  196. END Hex ;
  197. PROCEDURE PutCardHex4 (n : CARDINAL) ;
  198. VAR hx : ARRAY [0..1] OF CHAR ; b : BYTE ; d : CARDINAL ;
  199. BEGIN
  200. d := 4096 ; (* 16^3, no "**" needed *)
  201. WHILE d > 0 DO
  202. b := VAL (BYTE, (n DIV d) MOD 16) ;
  203. Hex (b, hx) ;
  204. PutCh (hx [0]) ;
  205. PutCh (hx [1]) ;
  206. d := d DIV 16
  207. END ;
  208. PutStr (": ")
  209. END PutCardHex4 ;
  210. PROCEDURE DumpCode () ;
  211. (* hex dump of the emitted image, 16 bytes per line *)
  212. VAR i, n : CARDINAL ;
  213. hx : ARRAY [0..1] OF CHAR ;
  214. b : BYTE ;
  215. BEGIN
  216. i := 0 ;
  217. WHILE i < CodeBytes () DO
  218. PutStr (" " ) ;
  219. PutCardHex4 (i) ;
  220. n := 0 ;
  221. WHILE (n < 16) AND (i + n < CodeBytes ()) DO
  222. b := CodeByteAt (i + n) ;
  223. Hex (b, hx) ;
  224. PutCh (hx [0]) ;
  225. PutCh (hx [1]) ;
  226. PutCh (" ") ;
  227. INC (n)
  228. END ;
  229. NL ;
  230. i := i + 16
  231. END
  232. END DumpCode ;
  233. PROCEDURE IsDumpCmd () : BOOLEAN ;
  234. (* the line "@dump" switches the hex dump on for the rest of the run *)
  235. VAR i : CARDINAL ;
  236. BEGIN
  237. IF lineBuf [0] # "@" THEN
  238. RETURN FALSE
  239. END ;
  240. i := 0 ;
  241. WHILE (i <= HIGH (lineBuf)) AND (lineBuf [i] # 0C) DO
  242. INC (i)
  243. END ;
  244. IF (i # 5) OR (lineBuf [1] # "d") OR (lineBuf [2] # "u") OR
  245. (lineBuf [3] # "m") OR (lineBuf [4] # "p") THEN
  246. RETURN FALSE
  247. END ;
  248. RETURN TRUE
  249. END IsDumpCmd ;
  250. BEGIN
  251. PutStr ("FIXTURE RESULT") ;
  252. NL ;
  253. WHILE ReadLineStr (lineBuf) DO
  254. IF IsDumpCmd () THEN
  255. dump := TRUE (* "@dump": hex-dump from here on *)
  256. ELSE
  257. StrCopy (pathCopy, lineBuf) ;
  258. IF LoadFile (pathCopy) THEN
  259. ok := Compile (errNo, errPos) ;
  260. IF ok THEN
  261. PutStr (lineBuf) ;
  262. PutStr (" OK code=") ;
  263. PutCard (CodeBytes ()) ;
  264. PutStr (" data=") ;
  265. PutCard (DataBytes ()) ;
  266. NL ;
  267. IF dump THEN
  268. DumpCode ()
  269. END
  270. ELSE
  271. PutStr (lineBuf) ;
  272. PutStr (" ERROR ") ;
  273. PutCard (errNo) ;
  274. PutStr (" at pos ") ;
  275. PutCard (errPos) ;
  276. NL ;
  277. ShowAt (errPos)
  278. END
  279. ELSE
  280. PutStr (lineBuf) ;
  281. PutStr (" CANNOT OPEN") ;
  282. NL
  283. END
  284. END
  285. END
  286. END CompileTest.