bf.pas 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. {*
  2. ===================================================================================
  3. Brainfuck v1.0 (build 100)
  4. Pascal version developed by ajack (aka Adrian Chiang) on 30-Jul-2005.
  5. Questions or comments, please e-mail me at: ajack2001my [at] yahoo.com
  6. - Array is 30001 bytes in size.
  7. - Size of array is 1 byte.
  8. - Nested loops can be 65535 generations into the loop.
  9. - Code size of a brainfuck program is 4MBsin size.
  10. Source code tested successfully with:
  11. Virtual Pascal v2.1 (build 279)
  12. Free Pascal 2.0.0
  13. Based on the brainfuck documentation found at:
  14. http://cydathria.com
  15. Brainfuck is a turing-complete programming language developed by
  16. Urban Mueller:
  17. http://wuarchive.wustl.edu/~umueller/ (DOWN)
  18. Difference from standard brainfuck implementations:
  19. - Added the '#' (debug) command. Will stop program and show contents
  20. of a[0..9] of array. Must add command line parameter '-debug'
  21. to work.
  22. ===================================================================================
  23. LEGALESSE
  24. This source code is public domain. The coder is not liable for anything
  25. whatsoever. The only guarantee it has is that it will take up storage space in
  26. your computer. Oh! It would be nice if you gave me credit if you use this source
  27. code (in whole or in part).
  28. ===================================================================================
  29. *}
  30. PROGRAM Brainfuck;
  31. USES
  32. SysUtils, {/* Use this library for the FileExists command */}
  33. CRT;
  34. CONST
  35. ASize = 30000; {* Brainfuck array size *}
  36. LSize = 65535; {* Loop command '[', ']' nested loop depth *}
  37. CSize = 1048576 * 4; {* Code size is 4MB *}
  38. ProgVer = '1.0';
  39. ProgBuild = '100';
  40. VAR
  41. Debug : Boolean;
  42. A : Array [0..ASize] of Byte;
  43. LP,
  44. P : Word;
  45. L : Array [0..LSize] of LongInt;
  46. C : Array [0..CSize] of Char;
  47. CEnd : LongInt;
  48. VCon : Text;
  49. PROCEDURE PushLoop (CP: LongInt);
  50. BEGIN
  51. L[LP] := CP;
  52. Inc (LP);
  53. END;
  54. PROCEDURE PopLoop (VAR CP: LongInt);
  55. BEGIN
  56. Dec (LP);
  57. CP := L[LP];
  58. END;
  59. PROCEDURE BF_Init;
  60. VAR
  61. I : LongInt;
  62. BEGIN
  63. FOR I := 0 TO ASize DO
  64. A[I] := 0;
  65. LP := 0;
  66. END;
  67. PROCEDURE BF_LoadProg;
  68. VAR
  69. Z,
  70. FN : String;
  71. T : Text;
  72. I : LongInt;
  73. BEGIN
  74. CEnd := 0;
  75. FN := UpperCase(ParamStr(2));
  76. IF FN = '-DEBUG' THEN
  77. Debug := True
  78. ELSE
  79. Debug := False;
  80. FN := ParamStr(1);
  81. IF NOT FileExists (FN) THEN
  82. BEGIN
  83. WriteLn ('Usage: BF <filename> [-debug]');
  84. Halt;
  85. END;
  86. Assign (T, FN);
  87. Reset (T);
  88. WHILE NOT Eof (T) DO
  89. BEGIN
  90. ReadLn (T, Z);
  91. FOR I := 1 TO Length(Z) DO
  92. BEGIN
  93. IF Z[I] IN ['<', '>', '+', '-', '.', ',', '[', ']', '#'] THEN
  94. BEGIN
  95. C[CEnd] := Z[I];
  96. Inc (CEnd);
  97. END;
  98. END;
  99. END;
  100. Close (T);
  101. WriteLn ('Program code size is ', CEnd, ' bytes.');
  102. WriteLn;
  103. END;
  104. PROCEDURE BF_Runtime;
  105. VAR
  106. I,
  107. Null,
  108. CWend,
  109. CNow : LongInt;
  110. PROCEDURE _Print (B: Byte);
  111. BEGIN
  112. IF B = 10 THEN
  113. WriteLn
  114. ELSE
  115. Write (Char(B));
  116. END;
  117. PROCEDURE _GetKey (VAR B: Byte);
  118. BEGIN
  119. B := Ord(ReadKey);
  120. Write (Char(B));
  121. END;
  122. PROCEDURE _LoopStart;
  123. VAR
  124. Done : Boolean;
  125. BEGIN
  126. IF A[P] > 0 THEN
  127. PushLoop (CNow)
  128. ELSE
  129. BEGIN
  130. CWend := 0;
  131. Done := False;
  132. I := CNow + 1;
  133. WHILE NOT Done DO
  134. BEGIN
  135. CASE C[I] OF
  136. '[' : Inc (CWend);
  137. ']' : BEGIN
  138. Dec (CWend);
  139. IF CWend < 0 THEN
  140. BEGIN
  141. CNow := I;
  142. Done := True;
  143. END;
  144. END;
  145. END;
  146. Inc (I);
  147. END;
  148. END;
  149. END;
  150. PROCEDURE _LoopEnd;
  151. BEGIN
  152. IF A[P] > 0 THEN
  153. BEGIN
  154. PopLoop (CNow);
  155. PushLoop (CNow);
  156. END
  157. ELSE
  158. PopLoop (Null);
  159. END;
  160. FUNCTION Filler (V, L: LongInt): String;
  161. VAR
  162. S : String;
  163. BEGIN
  164. Str (V, S);
  165. WHILE Length (S) < L DO
  166. S := '0' + S;
  167. Filler := S;
  168. END;
  169. PROCEDURE _Debug;
  170. VAR
  171. I : Byte;
  172. BEGIN
  173. WriteLn ('P=', Filler(P, 5), ' IP=', Filler(CNow, 7));
  174. WriteLn;
  175. FOR I := 0 TO 4 DO
  176. Write ('A[', I, ']=', Filler(A[I], 3), ' ');
  177. WriteLn;
  178. FOR I := 5 TO 9 DO
  179. Write ('A[', I, ']=', Filler(A[I], 3), ' ');
  180. WriteLn;
  181. Halt;
  182. END;
  183. BEGIN
  184. CNow := 0;
  185. WHILE CNow <= CEnd DO
  186. BEGIN
  187. CASE C[CNow] OF
  188. '>' : Inc (P);
  189. '<' : Dec (P);
  190. '+' : Inc (A[P]);
  191. '-' : Dec (A[P]);
  192. '.' : _Print (A[P]);
  193. ',' : _GetKey (A[P]);
  194. '[' : _LoopStart;
  195. ']' : _LoopEnd;
  196. '#' : IF Debug THEN _Debug;
  197. END;
  198. Inc (CNow);
  199. END;
  200. END;
  201. PROCEDURE BF_DeInit;
  202. BEGIN
  203. END;
  204. PROCEDURE BF_Hello;
  205. BEGIN
  206. WriteLn ('BF v', ProgVer, ' (Build ', ProgBuild, ') - Brainfuck interpreter. Created by Adrian Chiang.');
  207. WriteLn ('(c) Copyright Renegade Demo Group, 2005. All Rights Reserved.');
  208. WriteLn;
  209. END;
  210. BEGIN
  211. BF_Hello;
  212. BF_Init;
  213. BF_LoadProg;
  214. BF_Runtime;
  215. BF_DeInit;
  216. END.