Allow access to lists

This commit is contained in:
2025-05-13 11:06:40 +10:00
parent 8fe543b291
commit de3941337c
5 changed files with 40 additions and 30 deletions

View File

@@ -1 +1,2 @@
printlist args; printlist args;
println args[0];

View File

@@ -33,6 +33,7 @@ optional<Token> Interpreter::peek(int offset) {
void Interpreter::initInterpreter(vector<string> args) { void Interpreter::initInterpreter(vector<string> args) {
List arguments; List arguments;
arguments.type = valtype::STR;
for (int i = 0; i < args.size(); i++) { for (int i = 0; i < args.size(); i++) {
Value buf; Value buf;
buf.type = valtype::STR; buf.type = valtype::STR;
@@ -75,20 +76,13 @@ void Interpreter::interpret(vector<Token> tokenList) {
if (currentInstruction[i].type == valtype::STR) { if (currentInstruction[i].type == valtype::STR) {
string potentialVarName = get<string>(currentInstruction[i].value.value); string potentialVarName = get<string>(currentInstruction[i].value.value);
auto varIt = variables.find(potentialVarName); auto varIt = variables.find(potentialVarName);
if (varIt != variables.end()) { if (varIt != variables.end()) {
// This is pretty crappy code but it exists for now. Lists are gonna break this so much it's not even gonna be funny
//if (varIt->second.type == valtype::LIST) {
//} else {
// Replace the token with the variable's value
Token newToken; Token newToken;
newToken.keyword = keywords::VALUE; newToken.keyword = keywords::VALUE;
if (varIt->second.type == valtype::LIST) newToken.keyword = keywords::LISTOBJ; if (varIt->second.type == valtype::LIST) newToken.keyword = keywords::LISTOBJ;
newToken.type = varIt->second.type; newToken.type = varIt->second.type;
newToken.value = varIt->second; newToken.value = varIt->second;
currentInstruction[i] = newToken; currentInstruction[i] = newToken;
//}
} }
} else if (currentInstruction[i].keyword == keywords::INPUT) { } else if (currentInstruction[i].keyword == keywords::INPUT) {
Token newToken; Token newToken;
@@ -101,6 +95,31 @@ void Interpreter::interpret(vector<Token> tokenList) {
currentInstruction[i] = newToken; currentInstruction[i] = newToken;
} }
} }
// Allow users to get elements from list objects
for (int i = 0; i < currentInstruction.size(); i++) {
log.debug("Trying to find a list object");
if (currentInstruction[i].keyword == keywords::LISTOBJ || currentInstruction[i].value.type == valtype::LIST) {
log.debug("Found a list object");
if (i + 3 < currentInstruction.size()) {
log.debug("Instruction is large enough to have a list index");
if (currentInstruction[i + 1].keyword == keywords::OSQUA && currentInstruction[i + 3].keyword == keywords::CSQUA && currentInstruction[i + 2].value.type == valtype::INT) {
log.debug("Finding list object item");
if (currentInstruction[i + 2].value.type != valtype::INT) syntaxError.generalError("List index requires an int");
if (get<List>(currentInstruction[i].value.value).value.size() < get<int>(currentInstruction[i + 2].value.value)) syntaxError.listOutOfBounds();
Token newToken;
newToken.keyword = keywords::VALUE;
newToken.type = get<List>(currentInstruction[i].value.value).type;
newToken.value.type = get<List>(currentInstruction[i].value.value).type;
log.debug("Writing type " + log.getTypeString(newToken.type));
newToken.value = get<List>(currentInstruction[i].value.value).value[get<int>(currentInstruction[i + 2].value.value)];
currentInstruction[i] = newToken;
currentInstruction.erase(currentInstruction.begin() + i + 1);
currentInstruction.erase(currentInstruction.begin() + i + 1);
currentInstruction.erase(currentInstruction.begin() + i + 1);
}
}
}
}
// Do math // Do math
for (int i = 0; i < currentInstruction.size(); i++) { 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) { if (currentInstruction[i].keyword == keywords::ADD || currentInstruction[i].keyword == keywords::SUBTRACT || currentInstruction[i].keyword == keywords::MULTIPLY || currentInstruction[i].keyword == keywords::DIVIDE) {

View File

@@ -82,6 +82,12 @@ void SyntaxError::listTypeMismatch(string notes) {
exit(1); exit(1);
} }
void SyntaxError::listOutOfBounds(string notes) {
cerr << "GeneralError: List out of bounds access" << endl;
if (!notes.empty()) cerr << "Notes: " << notes << endl;
exit(1);
}
void SyntaxError::comparisonTypeError(string notes) { void SyntaxError::comparisonTypeError(string notes) {
cerr << "ComparisonError: cannot use a non-bool type in an if or while statement" << endl; cerr << "ComparisonError: cannot use a non-bool type in an if or while statement" << endl;
if (!notes.empty()) cerr << "Notes: " << notes << endl; if (!notes.empty()) cerr << "Notes: " << notes << endl;

View File

@@ -31,5 +31,6 @@ public:
void cannotCompareDifferentTypes(string notes = ""); void cannotCompareDifferentTypes(string notes = "");
void comparisonTypeError(string notes = ""); void comparisonTypeError(string notes = "");
void listTypeMismatch(string notes = ""); void listTypeMismatch(string notes = "");
void listOutOfBounds(string notes = "");
void generalError(string notes = ""); void generalError(string notes = "");
}; };

View File

@@ -64,23 +64,6 @@ struct Token {
struct var { struct var {
valtype type; valtype type;
variant<int, double, string, bool> value; 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";
}
}
}; };
// Global variable // Global variable