i am writing a simple compiler for a language called "brainfuck" which consists of 8 signs (commands) and the problem i encounter as following:
-i open a file containing the "brainfuck" code and check for syntax (its a .txt file) i.e. any other signs than [ ] < > + - . ,
-than i reset the get pointer with clear() and seekg(0,std::ios::beg) and check for other errors such as parentheses that are open i.e the are opened ( [ ) and not closed or closed ( ] )but no opening or if the user tries to change a negative address
-and that i use clear() and seekg(0,std::ios::beg) to reset the get pointer and here starts the problem when i tested the tellg() it says the value is -1 both if i dont use clear() and seekg(0,std::ios::beg) or if i do use clear() and seekg(0,std::ios::beg) any idea why one time it works and the other it doesn't ?
NOTE:look at line 153-157 here you can see that the clear and seekg have no effect + other than that the code works as i intended and is still in progress
**closing and reopening the file solves the problem but i want to find where is the bug in my code.
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 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
#include<iostream>
#include<fstream>
#include<stdlib.h>
#include<exception>
enum class errorCode {
fopenFail,
syntaxFail,
negativeAddress,
badParentheses,
badMemAlloc
};
class Debug {
protected:
uint8_t buffer{};
uint16_t commands{};
std::ifstream bfCode;
private:
void debugStageOne();
void debugStageTwo();
public:
void debug(std::string& bfSourceCode);
};
void Debug::debug(std::string& bfSourceCode) {
bfCode.open(bfSourceCode, std::ios::in);
if (bfCode.is_open()) {
debugStageOne();
debugStageTwo();
}
else {
std::cout << "Error code #" << static_cast<int>(errorCode::fopenFail) << '\n';
exit(EXIT_FAILURE);
}
}
void Debug::debugStageOne() {
while (bfCode.good()) {
bfCode >> buffer;
if (bfCode.eof()) break;
switch (buffer) {
case '+':
case '-':
case '<':
case '>':
case '[':
case ']':
case '.':
case ',':
++commands;
break;
default: {
bfCode.close();
std::cout << "Error code #" << static_cast<int>(errorCode::syntaxFail) << '\n';
exit(EXIT_FAILURE);
}
} //switch
} //while
std::cout << "stage one complete\n"; //test
std::cout << commands << '\n'; //test
}
void Debug::debugStageTwo() {
int16_t address{};
int16_t openParentheses{};
bfCode.clear();
bfCode.seekg(0, std::ios::beg);
while (bfCode.good()) {
bfCode >> buffer;
if (bfCode.eof()) break;
switch (buffer) {
case '+':
case '-':
case '.':
case ',':
if (address < 0) {
bfCode.close();
std::cout << "Error code #" << static_cast<int>(errorCode::negativeAddress) << '\n';
exit(EXIT_FAILURE);
}
break;
case '>':
++address;
break;
case '<':
--address;
break;
case '[':
++openParentheses;
break;
case ']':
{
--openParentheses;
if (openParentheses < 0) {
bfCode.close();
std::cout << "Error code #" << static_cast<int>(errorCode::badParentheses) << '\n';
exit(EXIT_FAILURE);
}
} //case ']'
break;
} //switch
} //while
if (openParentheses != 0) {
bfCode.close();
std::cout << "Error code #" << static_cast<int>(errorCode::badParentheses) << '\n';
exit(EXIT_FAILURE);
}
std::cout << "stage two complete\n"; //test
}
class Compile : private Debug {
private:
//uint8_t buffer is inherited
//int16_t commands is inherited
//std::ifstream bfCode is inherited
uint8_t* currentAddress;
//private member functions
void nextAddress();
void prevAddress();
void incrementCurrentValue();
void decrementCurrentValue();
void printCurrentValue();
void readToCurrentAddress();
public:
void compile();
};
void Compile::nextAddress() {
++currentAddress;
}
void Compile::prevAddress() {
--currentAddress;
}
void Compile::incrementCurrentValue() {
++(*currentAddress);
}
void Compile::decrementCurrentValue() {
--(*currentAddress);
}
void Compile::printCurrentValue() {
std::cout << *currentAddress;
}
void Compile::readToCurrentAddress() {
std::cin >> *currentAddress;
}
void Compile::compile() {
bfCode.clear();
bfCode.seekg(0, std::ios::beg);
std::cout << static_cast<int>(bfCode.tellg()) << '\n';
}
int main() {
Debug test;
Compile compiler;
std::string loc{ "C:/Users/User/Desktop/brainfuck.txt" };
test.debug(loc);
compiler.compile();
return 0;
}
|