More stuff related to lists
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||

|
||||

|
||||
|
||||
# Iodine - a statically typed, interpreted language
|
||||
|
||||
|
@@ -1 +0,0 @@
|
||||
println args;
|
1
examples/list.io
Normal file
1
examples/list.io
Normal file
@@ -0,0 +1 @@
|
||||
printlist ["This is an element in the list" "And this is another" "Oh look another list element" "How fun!"];
|
@@ -249,6 +249,34 @@ void Interpreter::interpret(vector<Token> tokenList) {
|
||||
i -= 1;
|
||||
}
|
||||
}
|
||||
// Find lists and create list objects
|
||||
for (int i = 0; i < currentInstruction.size(); i++) {
|
||||
if (currentInstruction[i].keyword == keywords::OSQUA) {
|
||||
log.debug("Making a list");
|
||||
int startIndex = i;
|
||||
currentInstruction.erase(currentInstruction.begin() + i);
|
||||
List buf;
|
||||
buf.type = currentInstruction[i].value.type;
|
||||
while (currentInstruction[i].keyword != keywords::CSQUA) {
|
||||
if (buf.type == currentInstruction[i].value.type) {
|
||||
buf.value.push_back(currentInstruction[i].value);
|
||||
currentInstruction.erase(currentInstruction.begin() + i);
|
||||
} else {
|
||||
syntaxError.listTypeMismatch();
|
||||
}
|
||||
}
|
||||
currentInstruction.erase(currentInstruction.begin() + i);
|
||||
Value newValue;
|
||||
newValue.type = valtype::LIST;
|
||||
newValue.value = buf;
|
||||
Token newToken;
|
||||
newToken.type = valtype::LIST;
|
||||
newToken.value.type = valtype::LIST;
|
||||
newToken.value.value = buf;
|
||||
newToken.keyword = keywords::LIST;
|
||||
currentInstruction.insert(currentInstruction.begin() + startIndex, newToken);
|
||||
}
|
||||
}
|
||||
// Execute the instruction
|
||||
log.debug("Length of line is " + to_string(lengthOfLine));
|
||||
executeCode(currentInstruction);
|
||||
@@ -285,7 +313,7 @@ void Interpreter::executeCode(vector<Token> tokens) {
|
||||
}
|
||||
if (tokens[i].keyword == keywords::PRINTLN) {
|
||||
i++;
|
||||
if (tokens.size() <= i) break;
|
||||
if (tokens.size() <= i) syntaxError.fnNotSufficientArgs("println", 1, 1, 0);
|
||||
Token nextToken = tokens[i];
|
||||
// Handle different value types
|
||||
if (nextToken.keyword == keywords::VALUE) {
|
||||
@@ -307,7 +335,7 @@ void Interpreter::executeCode(vector<Token> tokens) {
|
||||
syntaxError.fnTypeMismatch("println", validTypes, nextToken.type);
|
||||
}
|
||||
} else {
|
||||
syntaxError.fnNotSufficientArgs("println", 1, 1, 0);
|
||||
syntaxError.fnTypeMismatch("println", {}, nextToken.type);
|
||||
}
|
||||
} else if (tokens[i].keyword == keywords::PRINT) {
|
||||
i++;
|
||||
@@ -335,6 +363,39 @@ void Interpreter::executeCode(vector<Token> tokens) {
|
||||
} else {
|
||||
syntaxError.fnNotSufficientArgs("print", 1, 1, 0);
|
||||
}
|
||||
} else if (tokens[i].keyword == keywords::PRINTLIST) {
|
||||
i++;
|
||||
if (tokens.size() <= i) syntaxError.fnNotSufficientArgs("printlist", 1, 1, 0);
|
||||
Token nextToken = tokens[i];
|
||||
log.debug("Printing a list. Type of next token is " + log.getTypeString(nextToken.value.type));
|
||||
if (nextToken.keyword == keywords::LIST && nextToken.type == valtype::LIST) {
|
||||
List list = get<List>(nextToken.value.value);
|
||||
log.debug("List obtained");
|
||||
if (list.value[0].type == valtype::INT) {
|
||||
for (int j = 0; j < list.value.size(); j++) {
|
||||
cout << get<int>(list.value[j].value) << ", ";
|
||||
}
|
||||
}
|
||||
else if (list.value[0].type == valtype::DEC) {
|
||||
for (int j = 0; j < list.value.size(); j++) {
|
||||
cout << get<double>(list.value[j].value) << ", ";
|
||||
}
|
||||
}
|
||||
else if (list.value[0].type == valtype::STR) {
|
||||
for (int j = 0; j < list.value.size(); j++) {
|
||||
cout << get<string>(list.value[j].value) << ", ";
|
||||
}
|
||||
}
|
||||
else if (list.value[0].type == valtype::BOOL) {
|
||||
for (int j = 0; j < list.value.size(); j++) {
|
||||
cout << (get<bool>(list.value[j].value) ? "true" : "false") << ", ";
|
||||
}
|
||||
}
|
||||
cout << endl;
|
||||
} else {
|
||||
syntaxError.fnTypeMismatch("printlist", {}, valtype::UNKNOWN);
|
||||
}
|
||||
break;
|
||||
} else if (tokens[i].keyword == keywords::EXIT) {
|
||||
i++;
|
||||
if (tokens.size() <= i) break;
|
||||
|
@@ -52,3 +52,25 @@ void Logger::debug(string in) {
|
||||
if (isDebug) cout << "Debug: " + in + "\n";
|
||||
writeToLog("Debug", in);
|
||||
}
|
||||
|
||||
string Logger::getTypeString(valtype in) {
|
||||
switch (in) {
|
||||
case valtype::STR:
|
||||
return "string";
|
||||
case valtype::INT:
|
||||
return "int";
|
||||
case valtype::DEC:
|
||||
return "dec";
|
||||
case valtype::BOOL:
|
||||
return "bool";
|
||||
case valtype::LIST:
|
||||
return "list";
|
||||
case valtype::KEYWORD:
|
||||
return "keyword";
|
||||
case valtype::UNKNOWN:
|
||||
return "unknown";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
return "error";
|
||||
}
|
||||
|
@@ -32,4 +32,5 @@ public:
|
||||
void fatalError(string in, int code);
|
||||
void info(string in);
|
||||
void debug(string in);
|
||||
string getTypeString(valtype in);
|
||||
};
|
||||
|
@@ -72,7 +72,7 @@ void Parser::parseLines(string in, Logger log) {
|
||||
}
|
||||
terms.push_back(termBuffer);
|
||||
termBuffer.clear();
|
||||
} else if ((c == ',' || c == '{' || c == '}' || c == '(' || c == ')') && !isString) {
|
||||
} else if ((c == ',' || c == '{' || c == '}' || c == '(' || c == ')' || c == '[' || c == ']') && !isString) {
|
||||
if (!buffer.empty()) {
|
||||
termBuffer.push_back(buffer);
|
||||
buffer.clear();
|
||||
@@ -120,6 +120,7 @@ void Parser::processLines() {
|
||||
else if (ct == "let") token.keyword = keywords::LET;
|
||||
else if (ct == "print") token.keyword = keywords::PRINT;
|
||||
else if (ct == "println") token.keyword = keywords::PRINTLN;
|
||||
else if (ct == "printlist") token.keyword = keywords::PRINTLIST;
|
||||
else if (ct == "input") token.keyword = keywords::INPUT;
|
||||
else if (ct == "return") token.keyword = keywords::RETURN;
|
||||
else if (ct == "exit") token.keyword = keywords::EXIT;
|
||||
|
@@ -30,7 +30,8 @@ void SyntaxError::fnTypeMismatch(string function, vector<string> validTypes, val
|
||||
else if (typeGiven == valtype::DEC) cerr << "dec";
|
||||
else if (typeGiven == valtype::STR) cerr << "str";
|
||||
else if (typeGiven == valtype::BOOL) cerr << "bool";
|
||||
else cerr << "unknown";
|
||||
else if (typeGiven == valtype::LIST) cerr << "list";
|
||||
else cerr << "other or unknown";
|
||||
cerr << "' instead" << endl;
|
||||
if (!notes.empty()) cerr << "Notes: " << notes << endl;
|
||||
exit(1);
|
||||
@@ -75,6 +76,12 @@ void SyntaxError::cannotCompareDifferentTypes(string notes) {
|
||||
if (!notes.empty()) cerr << "Notes: " << notes << endl;
|
||||
exit(1);
|
||||
}
|
||||
void SyntaxError::listTypeMismatch(string notes) {
|
||||
cerr << "TypeError: List type mismatch" << endl;
|
||||
if (!notes.empty()) cerr << "Notes: " << notes << endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void SyntaxError::comparisonTypeError(string notes) {
|
||||
cerr << "ComparisonError: cannot use a non-bool type in an if or while statement" << endl;
|
||||
if (!notes.empty()) cerr << "Notes: " << notes << endl;
|
||||
|
@@ -30,5 +30,6 @@ public:
|
||||
void mathCannotDoOperationOnType(string operatorUsed, string type, string notes = "");
|
||||
void cannotCompareDifferentTypes(string notes = "");
|
||||
void comparisonTypeError(string notes = "");
|
||||
void listTypeMismatch(string notes = "");
|
||||
void generalError(string notes = "");
|
||||
};
|
||||
|
@@ -38,8 +38,8 @@ enum class keywords {
|
||||
ADD, SUBTRACT, MULTIPLY, DIVIDE,
|
||||
EQUAL, INEQUAL, LESS, GREATER, EQLESS, EQGREATER,
|
||||
INCREMENT, DECREMENT,
|
||||
PRINT, PRINTLN, LET, INPUT, EXIT,
|
||||
VALUE, SEMICOLON, VARIABLE,
|
||||
PRINT, PRINTLN, PRINTLIST, LET, INPUT, EXIT,
|
||||
VALUE, LIST, SEMICOLON, VARIABLE,
|
||||
COMMENT
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user