-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbf.hpp
82 lines (66 loc) · 3.14 KB
/
bf.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// This module assumes `unsigned char` to be an 8-bit integer (uint8_t).
// We avoid the use of uint8_t as eVC4 doesn't have stdint.h.
#ifndef BF_HPP_
#define BF_HPP_
#include <stdlib.h>
class Brainfuck {
public:
// Used to define a desired behavior for the input instruction when no input is given.
enum noinput_t { NOINPUT_ERROR, NOINPUT_ZERO, NOINPUT_FF };
// Execution result returned from the next() function.
enum result_t { RESULT_RUN, RESULT_BREAK, RESULT_FIN, RESULT_ERR };
// Initializes the internal state.
Brainfuck()
: program(NULL), input(NULL), memLen(1), wrapInt(true), signedness(true), debug(false), noInput(NOINPUT_ZERO) {
reset();
}
// Initializes the internal state and registers a program and an input.
// You must call reset() whenever you want to modify the program and the input.
// Pass a program and an input as dedicated malloc()-ed data and don't free() them. This module takes care of it.
Brainfuck(unsigned progLen, wchar_t *program, unsigned inLen, void *input)
: program(NULL), input(NULL), memLen(1), wrapInt(true), signedness(true), debug(false), noInput(NOINPUT_ZERO) {
reset(progLen, program, inLen, input);
}
~Brainfuck() {
if (program) free(program);
if (input) free(input);
}
// Resets the internal state.
void reset();
// Resets the internal state and registers a program and an input.
// You must call reset() whenever you want to modify the program and the input.
// Pass a program and an input as dedicated malloc()-ed data and don't free() them. This module takes care of it.
void reset(unsigned progLen, wchar_t *program, unsigned inLen, void *input);
// Change implementation-defined behaviors.
// If wrapInt is false, next() throws an exception when overflowed or underflowed.
// If wrapInt is true, signedness doen't have any effect.
// If debug is true, breakpoint instruction ("@") is enabled.
// The default behavior is [zero for no input, wrap around integer, signed integer (no effects in this case), no
// debug].
void setBehavior(enum noinput_t noInput = NOINPUT_ZERO, bool wrapInt = true, bool signedness = true,
bool debug = false);
// Executes the next code, and writes its output on `output` if any.
// Returns the result of an execution, which is running, breakpoint, finished, and error.
enum result_t next(unsigned char *output, bool *didOutput);
// Returns the memory and writes its size to `size`.
// The returned content becomes invalid on reset() and next().
const unsigned char *getMemory(unsigned *size) {
*size = memLen;
return memory;
}
// Returns the value of memory pointer.
unsigned getMemPtr() { return memIndex; }
// Returns the value of program pointer.
unsigned getProgPtr() { return progIndex; }
// Returns the last error.
const wchar_t *getLastError() { return lastError; }
private:
wchar_t *program; // Program
unsigned char *input; // Input stream
unsigned char memory[65536]; // Memory
unsigned memIndex, progIndex, inIndex, progLen, inLen, memLen;
bool wrapInt, signedness, debug;
enum noinput_t noInput;
wchar_t lastError[128];
};
#endif