Math stuff

This commit is contained in:
Maxwell 2025-04-24 12:12:21 +10:00
parent ce3cc010dc
commit b3aff16a2f
5 changed files with 128 additions and 15 deletions

23
.fleet/run.json Normal file
View File

@ -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"]
}
]
}

8
.fleet/settings.json Normal file
View File

@ -0,0 +1,8 @@
{
"plugins": [
{
"type": "add",
"pluginName": "fleet.vim"
}
]
}

BIN
mx

Binary file not shown.

View File

@ -135,29 +135,49 @@ class SyntaxError {
private:
public:
void fnTypeMismatch(string function, vector<string> 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<Token> tokens;
map<string, Value> 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<int>(before.value.value) + get<int>(after.value.value);
}
else if (newToken.type == valtype::DEC) {
newToken.value.value = get<double>(before.value.value) + get<double>(after.value.value);
}
else if (newToken.type == valtype::STR) {
newToken.value.value = get<string>(before.value.value) + get<string>(after.value.value);
} else {
syntaxError.mathCannotDoOperationOnType("+", "bool");
}
}
else if (currentInstruction[i].keyword == keywords::SUBTRACT) {
if (newToken.type == valtype::INT) {
newToken.value.value = get<int>(before.value.value) - get<int>(after.value.value);
}
else if (newToken.type == valtype::DEC) {
newToken.value.value = get<double>(before.value.value) - get<double>(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<int>(before.value.value) * get<int>(after.value.value);
}
else if (newToken.type == valtype::DEC) {
newToken.value.value = get<double>(before.value.value) * get<double>(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<int>(before.value.value) / get<int>(after.value.value);
}
else if (newToken.type == valtype::DEC) {
newToken.value.value = get<double>(before.value.value) / get<double>(after.value.value);
} else {
syntaxError.mathCannotDoOperationOnType("/", "bool or string");
}
} else {
syntaxError.generalError("Da math aint mathing");
}
}
}
// Execute the instruction
executeCode(currentInstruction);
}

5
test.fish Normal file
View File

@ -0,0 +1,5 @@
#!/usr/bin/fish
bob
./mx test.mx