/include/brainfuck.h

https://github.com/FabianM/brainfuck · C Header · 303 lines · 62 code · 29 blank · 212 comment · 0 complexity · 9c9fa5fc7f3698c7fe2739fd49717de5 MD5 · raw file

  1. /*
  2. * Copyright 2016 Fabian Mastenbroek
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef BRAINFUCK_H
  17. #define BRAINFUCK_H
  18. #define BRAINFUCK_TAPE_SIZE 30000
  19. /* 1: EOF leaves cell unchanged; 0: EOF == 0; 1: EOF == 1 */
  20. #define BRAINFUCK_EOF_BEHAVIOR 1
  21. #define BRAINFUCK_TOKEN_PLUS '+'
  22. #define BRAINFUCK_TOKEN_MINUS '-'
  23. #define BRAINFUCK_TOKEN_PREVIOUS '<'
  24. #define BRAINFUCK_TOKEN_NEXT '>'
  25. #define BRAINFUCK_TOKEN_OUTPUT '.'
  26. #define BRAINFUCK_TOKEN_INPUT ','
  27. #define BRAINFUCK_TOKEN_LOOP_START '['
  28. #define BRAINFUCK_TOKEN_LOOP_END ']'
  29. #ifdef BRAINFUCK_EXTENSION_DEBUG
  30. # define BRAINFUCK_TOKEN_BREAK '#'
  31. #else
  32. # define BRAINFUCK_TOKEN_BREAK -10
  33. #endif
  34. #define READLINE_HIST_SIZE 20
  35. /**
  36. * Represents a brainfuck instruction.
  37. */
  38. typedef struct BrainfuckInstruction {
  39. /**
  40. * The difference between the value of the byte at the currect pointer and
  41. * the value we want.
  42. */
  43. int difference;
  44. /**
  45. * The type of this instruction.
  46. */
  47. char type;
  48. /**
  49. * The next instruction in the linked list.
  50. */
  51. struct BrainfuckInstruction *next;
  52. /**
  53. * The previous instruction in the linked list.
  54. */
  55. struct BrainfuckInstruction *previous;
  56. /**
  57. * The first instruction of a loop if this instruction is a loop. Otherwise
  58. * <code>NULL</code>
  59. */
  60. struct BrainfuckInstruction *loop;
  61. } BrainfuckInstruction;
  62. /**
  63. * The state structure contains the head and the root of the linked list containing
  64. * the instructions of the program.
  65. */
  66. typedef struct BrainfuckState {
  67. /**
  68. * The root instruction of the instruction linked list.
  69. */
  70. struct BrainfuckInstruction *root;
  71. /**
  72. * The head instruction of the instruction linked list.
  73. */
  74. struct BrainfuckInstruction *head;
  75. } BrainfuckState;
  76. /**
  77. * The callback that will be invoked when the BRAINFUCK_TOKEN_OUTPUT token is found.
  78. *
  79. * @param chr The value of the current cell.
  80. */
  81. typedef int (*BrainfuckOutputHandler) (int chr);
  82. /**
  83. * The callback that will be invoked when the BRAINFUCK_TOKEN_INPUT token is found.
  84. *
  85. * @return The character that is read.
  86. */
  87. typedef char (*BrainfuckInputHandler) (void);
  88. /**
  89. * This structure is used as a layer between a brainfuck program and
  90. * the outside. It allows control over input, output and memory.
  91. */
  92. typedef struct BrainfuckExecutionContext {
  93. /**
  94. * The callback that will be invoked when the BRAINFUCK_TOKEN_OUTPUT token is found.
  95. */
  96. BrainfuckOutputHandler output_handler;
  97. /**
  98. * The callback that will be invoked when the BRAINFUCK_TOKEN_INPUT token is found.
  99. */
  100. BrainfuckInputHandler input_handler;
  101. /**
  102. * An array containing the memory cells the program can use.
  103. */
  104. unsigned char *tape;
  105. /**
  106. * Index into <code>tape</code>. Modified during execution.
  107. */
  108. int tape_index;
  109. /**
  110. * size of the tape in number of cells.
  111. */
  112. size_t tape_size;
  113. /**
  114. * A flag that, if set to true, indicates that execution should stop.
  115. */
  116. int shouldStop;
  117. } BrainfuckExecutionContext;
  118. /**
  119. * Creates a new state.
  120. */
  121. BrainfuckState * brainfuck_state();
  122. /**
  123. * Creates a new context.
  124. *
  125. * @param size The size of the tape.
  126. */
  127. BrainfuckExecutionContext * brainfuck_context(int);
  128. /**
  129. * Removes the given instruction from the linked list.
  130. *
  131. * @param state The state
  132. * @param instruction The instruction to remove.
  133. * @return The instruction that is removed.
  134. */
  135. BrainfuckInstruction * brainfuck_remove(struct BrainfuckState *, struct BrainfuckInstruction *);
  136. /**
  137. * Adds an instruction to the instruction list.
  138. *
  139. * @param state The state.
  140. * @param instruction The instruction to add.
  141. * @return The instruction that is given.
  142. */
  143. BrainfuckInstruction * brainfuck_add(struct BrainfuckState *state, struct BrainfuckInstruction *);
  144. /**
  145. * Adds an instruction to the front of the instruction list.
  146. *
  147. * @param state The state.
  148. * @param instruction The instruction to add.
  149. * @return The instruction that is given.
  150. */
  151. BrainfuckInstruction * brainfuck_add_first(struct BrainfuckState *state, struct BrainfuckInstruction *);
  152. /**
  153. * Adds an instruction to the instruction list.
  154. *
  155. * @param state The state.
  156. * @param before The instruction you want to add another instruction before.
  157. * @param instruction The instruction to add.
  158. * @return The instruction that is given.
  159. */
  160. BrainfuckInstruction * brainfuck_insert_before(struct BrainfuckState *, struct BrainfuckInstruction *,
  161. struct BrainfuckInstruction *);
  162. /**
  163. * Adds an instruction to the instruction list.
  164. *
  165. * @param state The state.
  166. * @param after The instruction you want to add another instruction after.
  167. * @param instruction The instruction to add.
  168. * @return The instruction that is given.
  169. */
  170. BrainfuckInstruction * brainfuck_insert_after(struct BrainfuckState *, struct BrainfuckInstruction *,
  171. struct BrainfuckInstruction *);
  172. /**
  173. * Reads a character, converts it to an instruction and repeats until the EOF character
  174. * occurs and will then return a linked list containing all instructions.
  175. *
  176. * @param stream The stream to read from.
  177. * @param The head of the linked list containing the instructions.
  178. */
  179. BrainfuckInstruction * brainfuck_parse_stream(FILE *);
  180. /**
  181. * Reads a character, converts it to an instruction and repeats until the given character
  182. * occurs and will then return a linked list containing all instructions.
  183. *
  184. * @param stream The stream to read from.
  185. * @param until If this character is found in the stream, we will quit reading and return.
  186. * @param The head of the linked list containing the instructions.
  187. */
  188. BrainfuckInstruction * brainfuck_parse_stream_until(FILE *, int);
  189. /**
  190. * Reads a character, converts it to an instruction and repeats until the string ends
  191. * and will then return a linked list containing all instructions.
  192. *
  193. * @param str The string to read from.
  194. * @param The head of the linked list containing the instructions.
  195. */
  196. BrainfuckInstruction * brainfuck_parse_string(char *);
  197. /**
  198. * Reads a character, converts it to an instruction and repeats until the string ends
  199. * and will then return a linked list containing all instructions.
  200. *
  201. * @param str The string to read from.
  202. * @param begin The index you want to start parsing at.
  203. * @param end The index you want to stop parsing at.
  204. * When <code>-1</code> is given, it will stop at the end of the string.
  205. * @param The head of the linked list containing the instructions.
  206. */
  207. BrainfuckInstruction * brainfuck_parse_substring(char *, int, int);
  208. /**
  209. * Reads a character, converts it to an instruction and repeats until the string ends
  210. * and will then return a linked list containing all instructions.
  211. * This method is special because it uses the begin index as counter, so this variable
  212. * will increase.
  213. *
  214. * @param str The string to read from.
  215. * @param ptr The pointer to the integer holding the index you want to start parsing at.
  216. * Since this will be used as counter, the value of the pointer will be increased.
  217. * @param end The index you want to stop parsing at.
  218. * When <code>-1</code> is given, it will stop at the end of the string.
  219. * @param The head of the linked list containing the instructions.
  220. */
  221. BrainfuckInstruction * brainfuck_parse_substring_incremental(char *, int *, int);
  222. /**
  223. * Converts the given character to an instruction.
  224. *
  225. * @param c The character to convert.
  226. * @param The character that's converted into an instruction.
  227. */
  228. BrainfuckInstruction * brainfuck_parse_character(char);
  229. /**
  230. * Destroys the given instruction.
  231. *
  232. * @param instruction The instruction to destroy.
  233. */
  234. void brainfuck_destroy_instruction(struct BrainfuckInstruction *);
  235. /**
  236. * Destroys a linked list containing instructions.
  237. *
  238. * @param head The start of the instruction list.
  239. */
  240. void brainfuck_destroy_instructions(struct BrainfuckInstruction *);
  241. /**
  242. * Destroys a state.
  243. *
  244. * @param state The state to destroy
  245. */
  246. void brainfuck_destroy_state(struct BrainfuckState *);
  247. /**
  248. * Destroys a context.
  249. *
  250. * @param context The context to destroy
  251. */
  252. void brainfuck_destroy_context(struct BrainfuckExecutionContext *);
  253. /**
  254. * Executes the given linked list containing instructions.
  255. *
  256. * @param root The start of the linked list of instructions you want
  257. * to execute.
  258. * @param context The context of this execution that contains the tape and
  259. * other execution related variables.
  260. */
  261. void brainfuck_execute(struct BrainfuckInstruction *, struct BrainfuckExecutionContext *);
  262. /**
  263. * Stops the currently running program referenced by the given execution context.
  264. *
  265. * @param context The context of this execution that contains the tape and
  266. * other execution related variables.
  267. */
  268. void brainfuck_execution_stop(BrainfuckExecutionContext *);
  269. /**
  270. * Reads exactly one char from stdin.
  271. * @return The character read from stdin.
  272. */
  273. char brainfuck_getchar(void);
  274. #endif /* BRAINFUCK_H */