commit a0a9a94107bd515230d44660067bc3fa6f2e41c0 Author: Maxwell Date: Mon Apr 21 16:26:14 2025 +1000 Upload files to "/" diff --git a/Bobfile b/Bobfile new file mode 100644 index 0000000..0224e7f --- /dev/null +++ b/Bobfile @@ -0,0 +1,4 @@ +compiler "g++"; +binary "mx"; +source "src/main.cpp"; +compile; diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..ad5012f --- /dev/null +++ b/main.cpp @@ -0,0 +1,248 @@ +#include +#include +#include +#include +#include +#include +#include + +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 value; + + string toString() const { + if (type == valtype::INT) { + return to_string(get(value)); + } + else if (type == valtype::DEC) { + return to_string(get(value)); + } + else if (type == valtype::STR) { + return get(value); + } + else if (type == valtype::BOOL) { + return to_string(get(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 lines; + vector termBuffer; + vector tokens; + vector> terms; + vector> things; + vector>> 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> 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 tokens; + int tokenIndex = 0; + Token consume() { + return tokens[tokenIndex++]; + } + Token peek(int index = 1) { + return tokens[tokenIndex + index]; + } + + public: + void interpret(vector 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; +} diff --git a/test.mx b/test.mx new file mode 100644 index 0000000..7cabac1 --- /dev/null +++ b/test.mx @@ -0,0 +1,3 @@ +fun int main() { + return 1; +}