Upload files to "/"
This commit is contained in:
commit
a0a9a94107
4
Bobfile
Normal file
4
Bobfile
Normal file
|
@ -0,0 +1,4 @@
|
|||
compiler "g++";
|
||||
binary "mx";
|
||||
source "src/main.cpp";
|
||||
compile;
|
248
main.cpp
Normal file
248
main.cpp
Normal file
|
@ -0,0 +1,248 @@
|
|||
#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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user