aboutsummaryrefslogtreecommitdiff
path: root/rcc-legacy/tests/performance/05_brainfuck-bootstrap.sy
blob: 47b6aadf642c521daa1a93bc68e1aabd459dbaf3 (plain)
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// Brainfuck Interpreter
// Reads program from stdin, interprets and outputs to stdout.
//
// Main optimization targets:
// jump table, inline variables, etc.

int program_length = 0;
int program[65536] = {};
int tape[65536] = {};
int input[65536] = {};
int input_length = 0;
int output[65536] = {};
int output_length = 0;

int get_bf_char() {
  int get = getch();
  while (get != 62 && get != 60 && get != 43 && get != 45 && get != 91 &&
         get != 93 && get != 46 && get != 44 && get != 35) {
    get = getch();
  }
  return get;
}

void read_program() {
  int get = get_bf_char();
  while (get != 35) {
    program[program_length] = get;
    get = get_bf_char();
    program_length = program_length + 1;
  }

  // read input
  // input starts with an `i`
  int verify = getch();
  if (verify != 105) {
    return;
  }
  // and a length
  input_length = getint();
  // and a random char
  getch();
  int i = 0;
  while (i < input_length) {
    input[i] = getch();
    i = i + 1;
  }
}

void run_program() {
  int ip = 0;
  int read_head = 0;
  int input_head = 0;
  int return_address[512] = {};
  int return_address_top = 0;
  output_length = 0;
  while (ip < program_length) {
    int code = program[ip];
    if (code == 62) {
      read_head = read_head + 1;
    } else if (code == 60) {
      read_head = read_head - 1;
    } else if (code == 43) {
      tape[read_head] = tape[read_head] + 1;
    } else if (code == 45) {
      tape[read_head] = tape[read_head] - 1;
    } else if (code == 91) {
      int val = tape[read_head];
      if (val != 0) {
        return_address[return_address_top] = ip;
        return_address_top = return_address_top + 1;
      } else {
        // find the matching ]
        int loop = 1;
        while (loop > 0) {
          ip = ip + 1;
          if (program[ip] == 93) {
            loop = loop - 1;
          }
          if (program[ip] == 91) {
            loop = loop + 1;
          }
        }
      }
    } else if (code == 93) {
      int val = tape[read_head];
      if (val == 0) {
        return_address_top = return_address_top - 1;
      } else {
        ip = return_address[return_address_top - 1];
      }
    } else if (code == 46) {
      output[output_length] = tape[read_head];
      output_length = output_length + 1;
    } else if (code == 44) {
      if (input_head >= input_length) {
        tape[read_head] = 0;
      } else {
        tape[read_head] = input[input_head];
        input_head = input_head + 1;
      }
    }
    ip = ip + 1;
  }
}

void output_() {
  int i = 0;
  while (i < output_length) {
    putch(output[i]);
    i = i + 1;
  }
}

int main() {
  read_program();
  starttime();
  run_program();
  stoptime();
  output_();
  return 0;
}