diff --git a/.fleet/run.json b/.fleet/run.json new file mode 100644 index 0000000..dd0ce1f --- /dev/null +++ b/.fleet/run.json @@ -0,0 +1,23 @@ +{ + "configurations": [ + { + "type": "command", + "name": "Compile", + "program": "bob" + }, + { + "type": "command", + "name": "Run", + "program": "$PROJECT_DIR$/mx", + "workingDir": "$PROJECT_DIR$", + "args": ["test.mx"] + }, + { + "type": "command", + "name": "Compile and run", + "program": "fish", + "workingDir": "$PROJECT_DIR$", + "args": ["test.fish"] + } + ] +} \ No newline at end of file diff --git a/.fleet/settings.json b/.fleet/settings.json new file mode 100644 index 0000000..17d0949 --- /dev/null +++ b/.fleet/settings.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + { + "type": "add", + "pluginName": "fleet.vim" + } + ] +} \ No newline at end of file diff --git a/mx b/mx index 8f1f4ba..cf7cacb 100755 Binary files a/mx and b/mx differ diff --git a/src/main.cpp b/src/main.cpp index 04bfbe4..746662b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -135,29 +135,49 @@ class SyntaxError { private: public: void fnTypeMismatch(string function, vector validTypes, valtype typeGiven, string notes = "") { - cout << "TypeError: function type mismatch" << endl; - cout << "Function '" << function << "' expected one of the following types: "; + cerr << "TypeError: function type mismatch" << endl; + cerr << "Function '" << function << "' expected one of the following types: "; for (int i = 0; i < validTypes.size(); i++) { - if (i != 0) cout << ", "; - cout << validTypes[i]; + if (i != 0) cerr << ", "; + cerr << validTypes[i]; } - cout << endl << "Got type '"; - if (typeGiven == valtype::INT) cout << "int"; - else if (typeGiven == valtype::DEC) cout << "dec"; - else if (typeGiven == valtype::STR) cout << "str"; - else if (typeGiven == valtype::BOOL) cout << "bool"; - else cout << "unknown"; - cout << "' instead" << endl; - if (!notes.empty()) cout << "Notes: " << notes << endl; + cerr << endl << "Got type '"; + if (typeGiven == valtype::INT) cerr << "int"; + else if (typeGiven == valtype::DEC) cerr << "dec"; + else if (typeGiven == valtype::STR) cerr << "str"; + else if (typeGiven == valtype::BOOL) cerr << "bool"; + else cerr << "unknown"; + cerr << "' instead" << endl; + if (!notes.empty()) cerr << "Notes: " << notes << endl; exit(1); } void fnNotSufficientArgs(string function, int minArgs, int maxArgs, int argsGiven) { - cout << "TypeError: function not sufficient arguments" << endl; - cout << "Function '" << function << "' expected between " << minArgs << " and " << maxArgs << " arguments, got " << argsGiven << endl; + cerr << "TypeError: function not sufficient arguments" << endl; + cerr << "Function '" << function << "' expected between " << minArgs << " and " << maxArgs << " arguments, got " << argsGiven << endl; exit(1); } void unknownFn() { - cout << "TypeError: unknown function" << endl; + cerr << "TypeError: unknown function" << endl; + exit(1); + } + void mathTypeMismatch(string notes = "") { + cerr << "MathError: cannot add two different types together" << endl; + if (!notes.empty()) cerr << "Notes: " << notes << endl; + exit(1); + } + void mathTooFewArgs(string notes = "") { + cerr << "MathError: too few things to add together" << endl; + if (!notes.empty()) cerr << "Notes: " << notes << endl; + exit(1); + } + void mathCannotDoOperationOnType(string operatorUsed, string type, string notes = "") { + cerr << "MathError: cannot use operator '" + operatorUsed + " on type '" + type + "'" << endl; + if (!notes.empty()) cerr << "Notes: " << notes << endl; + exit(1); + } + void generalError(string notes = "") { + cerr << "GeneralError: Something went awfully wrong and we don't know why lmao" << endl; + if (!notes.empty()) cerr << "Notes: " << notes << endl; exit(1); } }; @@ -328,6 +348,7 @@ class Parser { class Interpreter { private: + SyntaxError syntaxError; vector tokens; map variables; Logger log; @@ -380,6 +401,62 @@ class Interpreter { } } } + // Do math + for (int i = 0; i < currentInstruction.size(); i++) { + if (currentInstruction[i].keyword == keywords::ADD || currentInstruction[i].keyword == keywords::SUBTRACT || currentInstruction[i].keyword == keywords::MULTIPLY || currentInstruction[i].keyword == keywords::DIVIDE) { + Token newToken; + if (currentInstruction.size() < i + 1) syntaxError.mathTooFewArgs(); + Token before = currentInstruction[i - 1]; + Token after = currentInstruction[i + 1]; + if (before.type != after.type) syntaxError.mathTypeMismatch(); + newToken.type = before.type; + if (currentInstruction[i].keyword == keywords::ADD) { + if (newToken.type == valtype::INT) { + newToken.value.value = get(before.value.value) + get(after.value.value); + } + else if (newToken.type == valtype::DEC) { + newToken.value.value = get(before.value.value) + get(after.value.value); + } + else if (newToken.type == valtype::STR) { + newToken.value.value = get(before.value.value) + get(after.value.value); + } else { + syntaxError.mathCannotDoOperationOnType("+", "bool"); + } + } + else if (currentInstruction[i].keyword == keywords::SUBTRACT) { + if (newToken.type == valtype::INT) { + newToken.value.value = get(before.value.value) - get(after.value.value); + } + else if (newToken.type == valtype::DEC) { + newToken.value.value = get(before.value.value) - get(after.value.value); + } else { + syntaxError.mathCannotDoOperationOnType("-", "bool or string"); + } + } + else if (currentInstruction[i].keyword == keywords::MULTIPLY) { + if (newToken.type == valtype::INT) { + newToken.value.value = get(before.value.value) * get(after.value.value); + } + else if (newToken.type == valtype::DEC) { + newToken.value.value = get(before.value.value) * get(after.value.value); + } else { + syntaxError.mathCannotDoOperationOnType("*", "bool or string"); + } + } + else if (currentInstruction[i].keyword == keywords::DIVIDE) { + if (newToken.type == valtype::INT) { + newToken.value.value = get(before.value.value) / get(after.value.value); + } + else if (newToken.type == valtype::DEC) { + newToken.value.value = get(before.value.value) / get(after.value.value); + } else { + syntaxError.mathCannotDoOperationOnType("/", "bool or string"); + } + } else { + syntaxError.generalError("Da math aint mathing"); + } + } + } // Execute the instruction executeCode(currentInstruction); } diff --git a/test.fish b/test.fish new file mode 100644 index 0000000..9e82140 --- /dev/null +++ b/test.fish @@ -0,0 +1,5 @@ +#!/usr/bin/fish + +bob + +./mx test.mx \ No newline at end of file