@@ -13,104 +13,129 @@ Error execute(ByteCode instructions) {
1313
1414 // Debug debug{instructions};
1515
16- next:
17- // debug.trackInstruction(static_cast<size_t>(instruction - instructions.data()));
18- switch (instruction->type ) {
19- case DATA_POINTER_ADD:
20- data_pointer += instruction->offset ;
21- break ;
22- case INSTRUCTION_POINTER_SET_IF_NOT_ZERO: {
23- const auto offset_data_pointer = data_pointer + instruction->offset ;
24- if (data[offset_data_pointer] % 256 != 0 ) {
25- instruction = &instructions[static_cast <size_t >(instruction->value )];
26- goto next;
27- }
28- break ;
29- }
30- case DATA_TRANSFER: {
31- const auto offset_data_pointer = data_pointer + instruction->offset ;
32- data[offset_data_pointer + instruction->value ] += data[offset_data_pointer];
33- data[offset_data_pointer] = 0 ;
34- break ;
35- }
36- case DATA_ADD: {
37- data[data_pointer + instruction->offset ] += instruction->value ;
38- break ;
39- }
40- case DATA_MULTIPLY: {
41- const auto offset_data_pointer = data_pointer + instruction->offset ;
42- const auto outputs = instruction->value ;
43- for (auto i = 0 ; i < outputs; i++) {
44- instruction++;
45- data[offset_data_pointer + instruction->offset ] += instruction->value * data[offset_data_pointer];
46- }
47- data[offset_data_pointer] = 0 ;
48- break ;
49- }
50- case DATA_SET: {
51- const auto offset_data_pointer = data_pointer + instruction->offset ;
52- data[offset_data_pointer] = instruction->value ;
53- break ;
54- }
55- case INSTRUCTION_POINTER_SET_IF_ZERO: {
56- const auto offset_data_pointer = data_pointer + instruction->offset ;
57- if (data[offset_data_pointer] % 256 == 0 ) {
58- instruction = &instructions[static_cast <size_t >(instruction->value )];
59- goto next;
60- }
61- break ;
62- }
63- case DATA_POINTER_ADD_WHILE_NOT_ZERO:
64- while (data[data_pointer + instruction->offset ] % 256 != 0 ) {
65- data_pointer += instruction->value ;
66- }
67- break ;
68- case DATA_PRINT: {
69- const auto offset_data_pointer = data_pointer + instruction->offset ;
70- for (int i = 0 ; i < instruction->value ; i++) {
71- std::cout << static_cast <char >(data[offset_data_pointer] % 256 );
72- }
73- break ;
74- }
75- case DATA_SET_FROM_INPUT: {
76- const auto offset_data_pointer = data_pointer + instruction->offset ;
77- for (int i = 0 ; i < instruction->value ; i++) {
78- char input;
79- std::cin >> std::noskipws >> input;
80- if (!std::cin.eof ()) {
81- data[offset_data_pointer] = input;
82- }
83- }
84- break ;
85- }
86- case DATA_MULTIPLY_AND_DIVIDE: {
87- const auto offset_data_pointer = data_pointer + instruction->offset ;
88- const auto outputs = instruction->value ;
89- instruction++;
90- Value iterations = 0 ;
91- while (data[offset_data_pointer] % 256 != 0 ) {
92- data[offset_data_pointer] += instruction->value ;
93- iterations++;
94- }
95-
96- for (auto i = 0 ; i < outputs; i++) {
97- instruction++;
98- data[offset_data_pointer + instruction->offset ] += instruction->value * iterations;
99- }
100- break ;
16+ static void * jumpTable[] = {
17+ &&NOOP,
18+ &&DONE,
19+ &&DATA_ADD,
20+ &&DATA_SET,
21+ &&DATA_TRANSFER,
22+ &&DATA_MULTIPLY,
23+ &&DATA_MULTIPLY_AND_DIVIDE,
24+ &&DATA_SET_FROM_INPUT,
25+ &&DATA_PRINT,
26+ &&DATA_POINTER_ADD,
27+ &&DATA_POINTER_ADD_WHILE_NOT_ZERO,
28+ &&INSTRUCTION_POINTER_SET_IF_ZERO,
29+ &&INSTRUCTION_POINTER_SET_IF_NOT_ZERO,
30+ };
31+
32+ goto * jumpTable[instruction->type ];
33+
34+ DATA_POINTER_ADD:
35+ data_pointer += instruction->offset ;
36+ goto AFTER;
37+
38+ INSTRUCTION_POINTER_SET_IF_NOT_ZERO: {
39+ const auto offset_data_pointer = data_pointer + instruction->offset ;
40+ if (data[offset_data_pointer] % 256 != 0 ) {
41+ instruction = &instructions[static_cast <size_t >(instruction->value )];
42+ goto * jumpTable[instruction->type ];
43+ }
44+ goto AFTER;
45+ }
46+
47+ DATA_TRANSFER: {
48+ const auto offset_data_pointer = data_pointer + instruction->offset ;
49+ data[offset_data_pointer + instruction->value ] += data[offset_data_pointer];
50+ data[offset_data_pointer] = 0 ;
51+ goto AFTER;
52+ }
53+
54+ DATA_ADD: {
55+ data[data_pointer + instruction->offset ] += instruction->value ;
56+ goto AFTER;
57+ }
58+
59+ DATA_MULTIPLY: {
60+ const auto offset_data_pointer = data_pointer + instruction->offset ;
61+ const auto outputs = instruction->value ;
62+ for (auto i = 0 ; i < outputs; i++) {
63+ instruction++;
64+ data[offset_data_pointer + instruction->offset ] += instruction->value * data[offset_data_pointer];
65+ }
66+ data[offset_data_pointer] = 0 ;
67+ goto AFTER;
68+ }
69+
70+ DATA_SET: {
71+ const auto offset_data_pointer = data_pointer + instruction->offset ;
72+ data[offset_data_pointer] = instruction->value ;
73+ goto AFTER;
74+ }
75+
76+ INSTRUCTION_POINTER_SET_IF_ZERO: {
77+ const auto offset_data_pointer = data_pointer + instruction->offset ;
78+ if (data[offset_data_pointer] % 256 == 0 ) {
79+ instruction = &instructions[static_cast <size_t >(instruction->value )];
80+ goto * jumpTable[instruction->type ];
81+ }
82+ goto AFTER;
83+ }
84+
85+ DATA_POINTER_ADD_WHILE_NOT_ZERO:
86+ while (data[data_pointer + instruction->offset ] % 256 != 0 ) {
87+ data_pointer += instruction->value ;
88+ }
89+ goto AFTER;
90+
91+ DATA_PRINT: {
92+ const auto offset_data_pointer = data_pointer + instruction->offset ;
93+ for (int i = 0 ; i < instruction->value ; i++) {
94+ std::cout << static_cast <char >(data[offset_data_pointer] % 256 );
95+ }
96+ goto AFTER;
97+ }
98+
99+ DATA_SET_FROM_INPUT: {
100+ const auto offset_data_pointer = data_pointer + instruction->offset ;
101+ for (int i = 0 ; i < instruction->value ; i++) {
102+ char input;
103+ std::cin >> std::noskipws >> input;
104+ if (!std::cin.eof ()) {
105+ data[offset_data_pointer] = input;
101106 }
102- case DONE:
103- // debug.done();
104- return Error::NONE;
105- case NOOP:
106- break ;
107- default :
108- __builtin_unreachable ();
109107 }
108+ goto AFTER;
109+ }
110110
111+ DATA_MULTIPLY_AND_DIVIDE: {
112+ const auto offset_data_pointer = data_pointer + instruction->offset ;
113+ const auto outputs = instruction->value ;
111114 instruction++;
115+ Value iterations = 0 ;
116+ while (data[offset_data_pointer] % 256 != 0 ) {
117+ data[offset_data_pointer] += instruction->value ;
118+ iterations++;
119+ }
120+
121+ for (auto i = 0 ; i < outputs; i++) {
122+ instruction++;
123+ data[offset_data_pointer + instruction->offset ] += instruction->value * iterations;
124+ }
125+ goto AFTER;
126+ }
112127
113- goto next;
128+ DONE:
129+ // debug.done();
130+ return Error::NONE;
131+
132+ NOOP:
133+ goto AFTER;
134+
135+ AFTER:
136+ // debug.trackInstruction(static_cast<size_t>(instruction - instructions.data()));
137+ instruction++;
138+ goto * jumpTable[instruction->type ];
114139};
115140
116141} // namespace brainfuck
0 commit comments