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

|

|
||||||
|
|
||||||
# Iodine - a statically typed, interpreted language
|
# 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;
|
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
|
// Execute the instruction
|
||||||
log.debug("Length of line is " + to_string(lengthOfLine));
|
log.debug("Length of line is " + to_string(lengthOfLine));
|
||||||
executeCode(currentInstruction);
|
executeCode(currentInstruction);
|
||||||
@@ -285,7 +313,7 @@ void Interpreter::executeCode(vector<Token> tokens) {
|
|||||||
}
|
}
|
||||||
if (tokens[i].keyword == keywords::PRINTLN) {
|
if (tokens[i].keyword == keywords::PRINTLN) {
|
||||||
i++;
|
i++;
|
||||||
if (tokens.size() <= i) break;
|
if (tokens.size() <= i) syntaxError.fnNotSufficientArgs("println", 1, 1, 0);
|
||||||
Token nextToken = tokens[i];
|
Token nextToken = tokens[i];
|
||||||
// Handle different value types
|
// Handle different value types
|
||||||
if (nextToken.keyword == keywords::VALUE) {
|
if (nextToken.keyword == keywords::VALUE) {
|
||||||
@@ -307,7 +335,7 @@ void Interpreter::executeCode(vector<Token> tokens) {
|
|||||||
syntaxError.fnTypeMismatch("println", validTypes, nextToken.type);
|
syntaxError.fnTypeMismatch("println", validTypes, nextToken.type);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
syntaxError.fnNotSufficientArgs("println", 1, 1, 0);
|
syntaxError.fnTypeMismatch("println", {}, nextToken.type);
|
||||||
}
|
}
|
||||||
} else if (tokens[i].keyword == keywords::PRINT) {
|
} else if (tokens[i].keyword == keywords::PRINT) {
|
||||||
i++;
|
i++;
|
||||||
@@ -335,6 +363,39 @@ void Interpreter::executeCode(vector<Token> tokens) {
|
|||||||
} else {
|
} else {
|
||||||
syntaxError.fnNotSufficientArgs("print", 1, 1, 0);
|
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) {
|
} else if (tokens[i].keyword == keywords::EXIT) {
|
||||||
i++;
|
i++;
|
||||||
if (tokens.size() <= i) break;
|
if (tokens.size() <= i) break;
|
||||||
|
@@ -52,3 +52,25 @@ void Logger::debug(string in) {
|
|||||||
if (isDebug) cout << "Debug: " + in + "\n";
|
if (isDebug) cout << "Debug: " + in + "\n";
|
||||||
writeToLog("Debug", in);
|
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 fatalError(string in, int code);
|
||||||
void info(string in);
|
void info(string in);
|
||||||
void debug(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);
|
terms.push_back(termBuffer);
|
||||||
termBuffer.clear();
|
termBuffer.clear();
|
||||||
} else if ((c == ',' || c == '{' || c == '}' || c == '(' || c == ')') && !isString) {
|
} else if ((c == ',' || c == '{' || c == '}' || c == '(' || c == ')' || c == '[' || c == ']') && !isString) {
|
||||||
if (!buffer.empty()) {
|
if (!buffer.empty()) {
|
||||||
termBuffer.push_back(buffer);
|
termBuffer.push_back(buffer);
|
||||||
buffer.clear();
|
buffer.clear();
|
||||||
@@ -120,6 +120,7 @@ void Parser::processLines() {
|
|||||||
else if (ct == "let") token.keyword = keywords::LET;
|
else if (ct == "let") token.keyword = keywords::LET;
|
||||||
else if (ct == "print") token.keyword = keywords::PRINT;
|
else if (ct == "print") token.keyword = keywords::PRINT;
|
||||||
else if (ct == "println") token.keyword = keywords::PRINTLN;
|
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 == "input") token.keyword = keywords::INPUT;
|
||||||
else if (ct == "return") token.keyword = keywords::RETURN;
|
else if (ct == "return") token.keyword = keywords::RETURN;
|
||||||
else if (ct == "exit") token.keyword = keywords::EXIT;
|
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::DEC) cerr << "dec";
|
||||||
else if (typeGiven == valtype::STR) cerr << "str";
|
else if (typeGiven == valtype::STR) cerr << "str";
|
||||||
else if (typeGiven == valtype::BOOL) cerr << "bool";
|
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;
|
cerr << "' instead" << endl;
|
||||||
if (!notes.empty()) cerr << "Notes: " << notes << endl;
|
if (!notes.empty()) cerr << "Notes: " << notes << endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -75,6 +76,12 @@ void SyntaxError::cannotCompareDifferentTypes(string notes) {
|
|||||||
if (!notes.empty()) cerr << "Notes: " << notes << endl;
|
if (!notes.empty()) cerr << "Notes: " << notes << endl;
|
||||||
exit(1);
|
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) {
|
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;
|
||||||
|
@@ -30,5 +30,6 @@ public:
|
|||||||
void mathCannotDoOperationOnType(string operatorUsed, string type, string notes = "");
|
void mathCannotDoOperationOnType(string operatorUsed, string type, string notes = "");
|
||||||
void cannotCompareDifferentTypes(string notes = "");
|
void cannotCompareDifferentTypes(string notes = "");
|
||||||
void comparisonTypeError(string notes = "");
|
void comparisonTypeError(string notes = "");
|
||||||
|
void listTypeMismatch(string notes = "");
|
||||||
void generalError(string notes = "");
|
void generalError(string notes = "");
|
||||||
};
|
};
|
||||||
|
@@ -38,8 +38,8 @@ enum class keywords {
|
|||||||
ADD, SUBTRACT, MULTIPLY, DIVIDE,
|
ADD, SUBTRACT, MULTIPLY, DIVIDE,
|
||||||
EQUAL, INEQUAL, LESS, GREATER, EQLESS, EQGREATER,
|
EQUAL, INEQUAL, LESS, GREATER, EQLESS, EQGREATER,
|
||||||
INCREMENT, DECREMENT,
|
INCREMENT, DECREMENT,
|
||||||
PRINT, PRINTLN, LET, INPUT, EXIT,
|
PRINT, PRINTLN, PRINTLIST, LET, INPUT, EXIT,
|
||||||
VALUE, SEMICOLON, VARIABLE,
|
VALUE, LIST, SEMICOLON, VARIABLE,
|
||||||
COMMENT
|
COMMENT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user