bogus/main.cpp
2025-04-21 16:26:14 +10:00

249 lines
8.0 KiB
C++

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <variant>
#include <map>
#include <optional>
using namespace std;
enum class valtype {
INT, DEC, STR, BOOL, KEYWORD, UNKNOWN
};
enum class keywords {
IF, ELSE, WHILE, INT, DEC, STR, BOOL, FUN, RETURN,
OPARE, CPARE, OBRAC, CBRAC,
ADDTO, TAKEFROM, MULTIPLYTO, DIVIDEFROM,
ADD, SUBTRACT, MULTIPLY, DIVIDE,
EQUAL, INEQUAL, LESS, GREATER, EQLESS, EQGREATER,
INCREMENT, DECREMENT,
PRINT, INPUT,
VALUE, SEMICOLON
};
struct Token {
keywords keyword;
string value;
valtype type = valtype::KEYWORD;
};
struct var {
valtype type;
variant<int, double, string, bool> value;
string toString() const {
if (type == valtype::INT) {
return to_string(get<int>(value));
}
else if (type == valtype::DEC) {
return to_string(get<double>(value));
}
else if (type == valtype::STR) {
return get<string>(value);
}
else if (type == valtype::BOOL) {
return to_string(get<bool>(value));
} else {
return "unknown";
}
}
};
class Logger {
private:
bool isDebug = false;
string log;
void writeToLog(string type, string in) {
log += type + ": " + in + "\n";
}
public:
string getLog() {
return log;
}
void toggleDebugPrint() {
isDebug = !isDebug;
}
void error(string in) {
cout << "Error: " + in + "\n";
writeToLog("Error", in);
}
void fatalError(string in, int code) {
cout << "Error: " + in + "\n";
writeToLog("Error", in);
exit(code);
}
void info(string in) {
cout << "Info: " + in + "\n";
writeToLog("Info", in);
}
void debug(string in) {
if (isDebug) cout << "Debug: " + in + "\n";
writeToLog("Debug", in);
}
};
class Parser {
private:
string buffer;
vector<string> lines;
vector<string> termBuffer;
vector<Token> tokens;
vector<vector<string>> terms;
vector<vector<keywords>> things;
vector<vector<variant<var, keywords>>> stuff;
bool canInt(string in) {
try {
stoi(in);
return true;
} catch (...) {
return false;
}
}
bool canDec(string in) {
try {
stod(in);
return true;
} catch (...) {
return false;
}
}
public:
void parseLines(string in, Logger log) {
log.debug("Parsing lines...");
buffer = "";
bool isString = false;
for (int i = 0; i < in.size(); i++) {
if (in[i] == '"') {
isString = !isString;
} else if (in[i] == '\n') {
// whole lotta nothing
} else if (in[i] == ';' && !isString) {
// Push back and clear the buffer of terms
if (!buffer.empty()) termBuffer.push_back(buffer);
terms.push_back(termBuffer);
termBuffer.clear();
buffer = "";
} else if (in[i] == ',' && !isString) {
// Push back the buffer and the ',' seperately
termBuffer.push_back(buffer);
termBuffer.push_back(",");
buffer = "";
} else if (in[i] == '{' && !isString) {
// Push back the buffer and the '{' seperately
termBuffer.push_back(buffer);
termBuffer.push_back("{");
buffer = "";
} else if (in[i] == '}' && !isString) {
// Push back the buffer and the '}' seperately
termBuffer.push_back(buffer);
termBuffer.push_back("}");
buffer = "";
} else if (in[i] == '(' && !isString) {
// Push back the buffer and the '(' seperately
termBuffer.push_back(buffer);
termBuffer.push_back("(");
buffer = "";
} else if (in[i] == ')' && !isString) {
// Push back the buffer and the ')' seperately
termBuffer.push_back(buffer);
termBuffer.push_back(")");
buffer = "";
} else if (in[i] == ' ' && !isString) {
// Push back and reset buffer for that term
if (!buffer.empty()) termBuffer.push_back(buffer);
buffer = "";
} else {
buffer += in[i];
}
}
if (!buffer.empty()) termBuffer.push_back(buffer);
if (!termBuffer.empty()) terms.push_back(termBuffer);
string debugString;
log.debug("Lines have been parsed.");
for (int i = 0; i < terms.size(); i++) {
for (int j = 0; j < terms[i].size(); j++) {
debugString += terms[i][j] + ", ";
}
debugString += "\n";
}
log.debug(debugString);
}
void processLines() {
// Process vector<vector<string>> terms
for (int i = 0; i < terms.size(); i++) {
for (int j = 0; j < terms[i].size(); j++) {
Token token;
string ct = terms[i][j];
if (ct == " ") {}
// Oh boy here we go
else if (ct == "fun") token.keyword = keywords::FUN;
else if (ct == "return") token.keyword = keywords::RETURN;
else if (ct == "int") token.keyword = keywords::INT;
else if (ct == "{") token.keyword = keywords::OBRAC;
else if (ct == "}") token.keyword = keywords::CBRAC;
else if (ct == "(") token.keyword = keywords::OPARE;
else if (ct == ")") token.keyword = keywords::CPARE;
else if (ct == "+") token.keyword = keywords::ADD;
else if (ct == "-") token.keyword = keywords::SUBTRACT;
else if (ct == "*") token.keyword = keywords::MULTIPLY;
else if (ct == "/") token.keyword = keywords::DIVIDE;
else {
token.keyword = keywords::VALUE;
token.value = ct;
if (canInt(ct)) token.type = valtype::INT;
if (canDec(ct)) token.type = valtype::DEC;
if (ct == "true" || ct == "false") token.type = valtype::BOOL;
}
tokens.push_back(token);
}
Token semi;
semi.keyword = keywords::SEMICOLON;
tokens.push_back(semi);
}
}
};
class Interpreter {
private:
vector<Token> tokens;
int tokenIndex = 0;
Token consume() {
return tokens[tokenIndex++];
}
Token peek(int index = 1) {
return tokens[tokenIndex + index];
}
public:
void interpret(vector<Token> tokenList) {
tokens = tokenList;
while (tokenIndex < tokens.size()) {
}
}
};
int main(int argc, char* argv[]) {
// Initialise the logger and parser
Logger log;
log.toggleDebugPrint();
log.debug("Logger initialised!");
Parser parser;
// Exit if file doesn't exist
if (argc < 2) log.fatalError("Please provide a file", 1);
// Read the file
ifstream inputFile(argv[1]);
string input;
string file;
while(getline(inputFile, input)) {
file += input;
}
parser.parseLines(file, log);
parser.processLines();
return 0;
}